DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics
Index: T U

⟦efab24827⟧ TextFile

    Length: 2208343 (0x21b257)
    Types: TextFile
    Notes: Uncompressed file

Derivation

└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89
    └─⟦efce158d9⟧ »./gcc.diff-1.35-1.36.Z« 
        └─⟦this⟧ 

TextFile

Changes for GNU CC version 1.36, from version 1.35.
Changes in files that can be reconstructed with tex,
etags, bison or M-x texinfo-format-buffer have been omitted.

diff -rc2N gcc-1.35/ChangeLog gcc-1.36/ChangeLog
*** gcc-1.35/ChangeLog	Wed Apr 26 02:45:35 1989
--- gcc-1.36/ChangeLog	Sun Sep 24 01:27:28 1989
***************
*** 1,3 ****
--- 1,2320 ----
+ Sun Sep 24 00:21:24 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* Version 1.36 released.
+ 
+ 	* genextract.c (main): Pass `insn' as arg to `fatal_insn_not_found'.
+ 
+ 	* tahoe.md (casel patterns): Use %@ for operand of .align.
+ 	* tm-tahoe.h (PRINT_OPERAND): %@ prints `1'.
+ 	* tm-harris.h (PRINT_OPERAND): Redefine it; %@ prints `2'.
+ 
+ 	* config.gcc (decstation): New entry.
+ 
+ 	* tm-harris.h: New file, using tm-tahoe.h.
+ 
+ 	* tm-decstatn.h, tm-mips-bsd.h, tm-mips-sysv.h: New files.
+ 
+ Sat Sep 23 00:28:14 1989  Alain Lichnewsky  (lich at glenlivet)
+ 
+ 	* added -Zxxx flag in tm-mips.h. (-Z stands for systype)
+ 
+ 	  used as -ZSYSV or -ZBSD43 on RISC_OS. I suppose
+ 	  that at somepoint -ZPOSIX might be required for Ultrix. 
+ 
+ 	* changed command issued to loader to set -systype and to get
+           crt1 crtn instead of crt0.
+ 
+         * changed predefines for cpp to agree with RISC-OS
+ 
+ 	* tm-mips.h checks for machine type ( defined(ultrix) == DECSTATION)
+ 	  so that user does not have to go in and change tm-mips.h anymore
+ 
+ 	* cpp defines mips host_mips unix and SYSTYPE_SYSV
+ 	  or SYSTYPE_BSD43. 
+ 
+ Fri Sep 22 00:31:29 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* pyr.md (andsi3): Flush spurious paren.
+ 
+ 	* Makefile (hard-params): Don't use LIBS or LIBDEPS.
+ 
+ 	* rtl.c (init_rtl):
+ 	Use malloc to allocate the string for format of CONST_DOUBLE.
+ 	Don't fail to store in rtx_format.
+ 
+ Thu Sep 21 00:33:13 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* print-tree.c (dump): Move decl of P in REAL_CST case.
+ 
+ 	* fold-const.c (fold): For ABS_EXPR, handle REAL_IS_NOT_DOUBLE.
+ 
+ 	* c-convert.c (convert_to_real): Use REAL_VALUE_ATOF to make 0.
+ 
+ 	* mips.md (movdi): Handle constant with or without WORDS_BIG_ENDIAN.
+ 	For alternative 2, output just 2 store insns, not 3.
+ 
+ 	* dbxout.c (dbxout_symbol): Optionally go to .data for
+ 	a static file-scope variable.
+ 	* tm-vax.h: Define DBX_STATIC_STAB_DATA_SECTION to request this.
+ 
+ 	* varasm.c (output_constant, force_const_mem):
+ 	ASM_OUTPUT_DOUBLE_INT now takes rtx as argument.
+ 
+ 	* gvarargs.h [__NeXT__]: Undefine macros defined by stdardg.h.
+ 	Define _VARARGS_H.
+ 
+ 	* stddef.h (size_t): Don't define it if _SIZE_T macro is defined.
+ 	(NULL): Undef any previous defn.
+ 
+ 	* cexp.y (NULL): Don't define if already defined.
+ 
+ 	* emit-rtl.c (force_next_line_note): New function.
+ 	* stmt.c (expand_function_start): Call that just before returning.
+ 
+ Wed Sep 20 01:22:16 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* c-parse.y (asm_clobbers):
+ 	Allow string concatenation: call combine_strings.
+ 
+ Mon Sep 18 00:04:06 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* expr.c (expand_call): If calling const function, don't defer
+ 	pops for this call.
+ 
+ 	* c-parse.y (yylex): When float constant ends in `f',
+ 	actually truncate to a single-float.
+ 
+ Sun Sep 17 01:36:43 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* gcc.c (SWITCH_TAKES_ARG): -A takes an arg.
+ 	(link_spec): Inhibit start files when -A.
+ 
+ 	* convex.md (call, call_value): Supply dummy arg to RETURN_POPS_ARGS.
+ 
+ 	* gnulib2.c (__fixunsdfdi): After removing top half, A can be neg.
+ 	(__cmpdi2, __ucmpdi2): Was misusing macros HIGH and LOW--
+ 	use .s.high and .s.low to extract words from long_long.
+ 
+ 	* Makefile (gnulib2): Run `./gcc'.
+ 
+ 	* Makefile (float.h): Use `make', not `$(MAKE)'.
+ 	(hard-params.o): Use `$(srcdir)' in deps as in commands.
+ 
+ 	* out-tahoe.c (output_move_double): Handle constant operand 1.
+ 
+ Sat Sep 16 01:15:24 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* reload1.c (emit_reload_insns): Put death note for input reload reg
+ 	even if reload was inherited.
+ 
+ 	* out-i860.c (output_block_move): Typo loading size of block.
+ 
+ 	* m68k.md (dbra patterns): Do CC_STATUS_INIT.
+ 
+ 	* cse.c (fold_rtx): Check GET_MODE_CLASS before floating negate.
+ 
+ Fri Sep 15 00:39:44 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* combine.c (subst): Don't combine (subreg (mem))
+ 	if subreg's mode is wider than mem's mode.
+ 
+ Thu Sep 14 04:33:51 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* Makefile (clean): Delete temp files used in making gnulib.
+ 
+ 	* tm-next.h (LINK_SPEC): Pass -Z and -seglinkedit options.
+ 
+ Tue Sep 12 01:06:39 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* stor-layout.c (layout_type): Ignore MAX_FIXED_MODE_SIZE for ints.
+ 
+ 	* mips.md (cmpsi + bleu peephole): Should output unsigned insn.
+ 
+ 	* expmed.c (store_bit_field, extract_bit_field): If loading mem
+ 	into reg for bit field insn, don't use a larger mode than insn wants.
+ 
+ 	* Makefile (stamp-gnulib2): Depend on gcc, cc1, cpp to avoid
+ 	wrong order of making when parallel.
+ 
+ 	* Makefile (float.h): Do use $(MAKE) to run recursive make.
+ 
+ Mon Sep 11 00:49:11 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* cccp.c (main): Test for missing arg after -o, etc.
+ 
+ 	* tm-next.h: Nearly completely new.
+ 
+ 	* gcc.c (SWITCH_TAKES_ARG, WORD_SWITCH_TAKES_ARG): Move after config.h.
+ 
+ 	* cccp.c: Cast some args to strcpy and strcat.
+ 
+ 	* genoutput.c (error): Declare arg S.
+ 
+ 	* tm-pyr.h, pyr.md, out-pyr.c, xm-pyr.h: New files.
+ 	* config.gcc: New item for pyr.
+ 
+ 	* gvarargs.h: If __pyr__, use va-pyr.h.
+ 
+ Sun Sep 10 00:48:43 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* reload1.c (inc_for_reload): Really return the first of the insns.
+ 
+ 	* stor-layout.c (build_int): Memoize size nodes for sizes <= 32.
+ 
+ 	* loop.c (check_dbra_loop): Don't reverse a biv that is used
+ 	in between its update and the loop endtest insn.
+ 
+ Sat Sep  9 02:10:49 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* stor-layout.c (genop): Don't use `combine' for nonexplicit constants.
+ 	Handle some identity elements, etc., directly.
+ 	(layout_basetypes): Function deleted.
+ 	(layout_record): Ignore any TYPE_DECLs in the fieldlist.
+ 	Don't do PCC_BUTFIELD_TYPE_MATTERS hack on field with ERROR_MARK type.
+ 	(layout_union): Delete error check for base types.
+ 	Ignore any TYPE_DECLs in the fieldlist.
+ 	(layout_type): Copy layout info directly into all variants of type.
+ 	Delete unused local `x'.
+ 
+ 	* mips.md (movdi): Handle constant source operand.
+ 	(movsi): Some output code moved to output_load_immediate.
+ 	* out-mips.c (output_load_immediate): New function.
+ 
+ 	* config.gcc (iris): Use tm-iris.h and xm-iris.h.
+ 
+ 	* integrate.c (copy_for_inline): Copy all nonconstant MEM addresses.
+ 
+ 	* tm-3b1.h (ASM_OUTPUT_SPACE): New override defn, to output explicit
+ 	bytes of 0 if in text segment.
+ 
+ Fri Sep  8 19:15:08 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* combine.c (try_combine): Don't do i3dest stuff if i3 isn't a SET.
+ 
+ Thu Sep  7 00:16:32 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* integrate.c (function_cannot_inline_p): Fn is "not even close"
+ 	only if > 3 * max_insns.
+ 
+ 	* toplev.c (fatal_insn_not_found): New fn.
+ 	* genextract.c (main): Make insn_extract call that fn.
+ 
+ 	* integrate.c (expand_inline_function): Don't abort about bad offset
+ 	in a parm whose type is error_mark_node.
+ 	Make another syntax level to hold parm destructors.
+ 
+ 	* tm-mips.h (FUNCTION_PROLOGUE, FUNCTION_EPILOGUE):
+ 	Increment push_loc after, not before, each reg save or restore.
+ 	When storing reg 9 or 29, use offset tsize-4.
+ 	Make tsize larger by 4 initially.
+ 	(STARTING_FRAME_OFFSET): -8, not -4.
+ 
+ 	* gcc.c (choose_temp_base): Make use of TMPDIR and P_tmpdir
+ 	if they exist.
+ 
+ 	* toplev.c, gcc.c, cccp.c, gen*.c (fancy_abort):
+ 	New function which can be used to replace `abort'.
+ 
+ 	* toplev.c (main): Save argv, argc in save_argv, save_argc.
+ 
+ 	* jump.c (delete_insn): Always advance NEXT across deleted insns,
+ 	in case not optimizing.  Fixes setting current_function_returns_null.
+ 
+ 	* symout.c: Include stddef.h with <...>.
+ 
+ Wed Sep  6 00:39:35 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* gcc.c (find_exec_file): Was using `argbuf[0]' where wanted `prog'.
+ 
+ 	* combine.c (combine_instructions): Dont call record_dead_and_set_regs
+ 	if insn has become a NOTE.
+ 
+ 	* reload.c (combine_reloads): Update reload_when_needed.
+ 
+ 	* jump.c (delete_insn): If delete label on ADDR_VEC, delete table too.
+ 	(jump_optimize): If ADDR_DIFF_VEC label has 1 ref, delete it and table.
+ 
+ 	* gunlib2.c (__fixunsdfdi, __floatdfdi): Make the long long,
+ 	and/or its two halves, unsigned.
+ 
+ 	* reload1.c (reload): When setting double_reg_address_ok,
+ 	require it to be offsettable.
+ 	* out-sparc.c (output_fp_move_double): Now safe to use std
+ 	for all reg+reg addresses.
+ 
+ 	* vax.md: Add another simplified-casesi pattern for operand 0 constant.
+ 
+ 	* cse.c (fold_rtx): Don't truncate VAL at end if WIDTH is 0.
+ 	Don't alter WIDTH for that purpose based on the operands.
+ 
+ 	* stmt.c (warn_if_unused_value): && or || is ok if 2nd op has effect.
+ 
+ 	* c-parse.y (ALIGNOF unary_expr): Find a larger value if possible.
+ 
+ 	* reload.c (combine_reloads): Don't combine an output address reload.
+ 	(find_reloads): Call combine_reloads after setting reload_when_needed.
+ 	(find_reloads_address): Update OPERAND if copy the operand.
+ 
+ 	* cccp.c (macroexpand): Missing arg no error in 1-arg macro if -trad.
+ 
+ Tue Sep  5 14:12:23 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* reload.c (find_dummy_reload): Don't use the output reg if it is
+ 	a fixed reg which can overlap with other regs.
+ 
+ 	* cse.c (exp_equiv_p): Two vectors must have same length.
+ 
+ 	* tree.def (WITH_CLEANUP_EXPR): Print-name string was wrong.
+ 
+ 	* optabs.c (expand_fix): Undo previous change (unsigned conversion).
+ 	It doesn't work.
+ 
+ 	* gcc.c: Pass -i option to cpp.  It takes an arg.
+ 
+ 	* cccp.c (cplusplus_include_defaults) [VMS]: Typo in array indices.
+ 
+ 	* Makefile (gnulib): Create it in tmpgnulib, then rename at the end.
+ 
+ 	* i860.md (movdi from constant pattern): Fix `st' opcode typos.
+ 
+ 	* Makefile (hard-params*): Use CCLIBFLAGS, not CFLAGS.
+ 
+ Fri Sep  1 03:43:50 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* tm-i386gas.h (ASM_OUTPUT_ALIGN): .align arg isn't a log, in gas.
+ 	(ASM_OUTPUT_ALIGN_CODE): Align labels, etc. to 4-byte boundary.
+ 
+ 	* integrate.c (save_for_inline): Delete NOTE_INSN_DELETED notes.
+ 
+ 	* Makefile (clean): Delete dbr and jump2 dumps.
+ 
+ 	* Makefile (gnulib, gnulib2): Compile in main dir, not libtemp subdir.
+ 	This avoids trouble with -I options, etc.
+ 
+ Thu Aug 31 15:07:19 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* reload1.c (emit_reload_insns):
+ 	Be specific moving REG_DEAD notes to an output reload.
+ 	Sometimes move them to output-operand-address reloads.
+ 
+ 	* out-sparc.c (output_fp_move_double): Very cautious about std.
+ 	Use it only for something visibly aligned, or for an array element.
+ 
+ 	* cccp.c (main) [VMS]: Remove dirs and extension from PROGNAME.
+ 	(pfatal_with_name) [VMS]: Return VMS system call error code as status.
+ 	(cplusplus_include_defaults) [VMS]: Add GNU_GXX_INCLUDE.
+ 
+ 	* xm-vms.h (FATAL_EXIT_CODE): Now (44 | 0x10000000).
+ 
+ 	* expr.c (do_store_flag): Allow more values of STORE_FLAG_VALUE.
+ 
+ 	* gnulib2.c (__fixunsdfdi): Explicitly cast doubles to `long int'
+ 	to avoid infinite recursion.
+ 
+ Wed Aug 30 13:28:54 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* loop.c (skip_consec_insns): Skip NOTEs.
+ 
+ 	* loop.c (general_induction_var): If G or V is a nonreplaceable giv,
+ 	give up.  If G is allocated here, consider it replaceable.
+ 
+ 	* stupid.c: Make uid_suid, reg_where_born and reg_where_dead
+ 	vectors of ints, not short.
+ 
+ Tue Aug 29 00:21:13 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* tm-iris.h: Fix typo in formfeed char.
+ 
+ 	* out-i860.c (singlemove_string): Add missing `.l' to `st', `ld'.
+ 
+ 	* loop.c (general_induction_var): Don't set G from 2nd op. of MINUS,
+ 	since that would negate the result.
+ 
+ Mon Aug 28 00:16:36 1989  Richard Stallman  (rms at apple-gunkies.ai.mit.edu)
+ 
+ 	* dbxout.c (dbxout_symbol): When we need a pointer type, don't
+ 	record it in TYPE_POINTER_TO, lest it not live as long as its target.
+ 
+ 	* tm-hp9k320.h (CPP_PREDEFINES): Delete __hp9000s300 and _HPUX_SOURCE.
+ 
+ 	* Makefile (gnulib): Deleted stamp-gnulib2 in wrong dir.
+ 	(hard-params.o): Copy it into current dir before compiling.
+ 	(STAGESTUFF): Include the stamp-*.[ch] files.
+ 
+ Sun Aug 27 13:59:39 1989  Richard Stallman  (rms at apple-gunkies.ai.mit.edu)
+ 
+ 	* out-i860.c (output_size_for_block_move): Typo in CC_KNOW_HI_R31.
+ 
+ 	* integrate.c (expand_inline_function): Ignore insns to set value reg
+ 	if we don't want the value.
+ 
+ 	* varasm.c (make_function_rtl, make_decl_rtl): Use DECL_ASSEMBLER_NAME.
+ 
+ 	* Makefile (stamp-gnulib2): Don't explicitly delete old members,
+ 	just replace them.
+ 
+ 	* m68k.md, alliant.md (trunchiqi): Use movew if moving from memory
+ 	or from a const_int.
+ 
+ 	* integrate.c (expand_inline_function): Set first_parm_offset
+ 	later on, after computing the args, in case those args
+ 	contain inline function calls.
+ 
+ 	* alliant.md (movqi): Like recent change in m68k.md.
+ 
+ Sat Aug 26 00:26:03 1989  Richard Stallman  (rms at apple-gunkies.ai.mit.edu)
+ 
+ 	* tm-hp9k320.h (CPP_PREDEFINES): Take out m68k and mc68000.
+ 	* tm-news.h (CPP_PREDEFINES): Add mc68000.
+ 
+ Fri Aug 25 15:37:35 1989  Richard Stallman  (rms at apple-gunkies.ai.mit.edu)
+ 
+ 	* optabs.c (expand_fix): Can convert to unsigned int
+ 	by subtracting 2**(N-1), converting to signed, and adding 2**(N-1).
+ 
+ 	* reload.c (find_reloads_address): For out-of-range stack slot,
+ 	reload the displacement into a reg.
+ 	(find_reloads_toplev): For subreg of a reg with a reg_equiv_address,
+ 	turn the whole thing into a memref.
+ 
+ Thu Aug 24 14:07:03 1989  Richard Stallman  (rms at apple-gunkies.ai.mit.edu)
+ 
+ 	* c-decl.c (grokdeclarator): If function is declared `extern inline',
+ 	set current_extern_inline.
+ 	(start_function): In that case, set TREE_EXTERN in function decl.
+ 	* toplev.c (rest_of_compilation): In that case, don't really compile.
+ 	(compile_file): Don't output such functions at the end either.
+ 
+ 	* c-typeck.c (build_function_call): Do set NAME if we have one.
+ 
+ 	* Prevent any variability in results of qsort.
+ 	* stupid.c (stupid_reg_compare): Compare by regno as last resort.
+ 	* global-alloc.c (allocno_compare): Same idea.
+ 	* local-alloc.c (qty_compare_1): Same idea.
+ 	* reload1.c (hard_reg_use_compare, reload_reg_class_lower): Same idea.
+ 
+ 	* cccp.c (macroexpand): If read one arg, but it's whitespace,
+ 	consider that 0 args for checking number of args.
+ 	Improve plurals in error messages.
+ 
+ 	* expr.h (inhibit_defer_pop): New name for current_args_size,
+ 	now declared here.
+ 	(NO_DEFER_POP, OK_DEFER_POP): Moved here.
+ 	* expr.c: Names related to current_args_size renamed.
+ 	(clear_current_args_size): Deleted.
+ 	* stmt.c (expand_function_start): Init inhibit_defer_pop here.
+ 
+ 	* stmt.c (expand_start_stmt_expr): Do NO_DEFER_POP.
+ 	(expand_end_stmt_expr): Do OK_DEFER_POP, and don't do deferred pops.
+ 
+ 	* Makefile (c-parse.tab.c): Pass -o option to Bison.
+ 
+ Wed Aug 23 23:14:06 1989  Richard Stallman  (rms at apple-gunkies.ai.mit.edu)
+ 
+ 	* expmed.c (store_bit_field, extract_bit_field):
+ 	Use GET_MODE_WIDER_MODE to scan possible modes for bestmode.
+ 
+ 	* Makefile (stamp-gnulib2): Discard error messages from `ar d'.
+ 
+ Tue Aug 22 00:31:51 1989  Richard Stallman  (rms at apple-gunkies.ai.mit.edu)
+ 
+ 	* final.c (output_source_line): In COFF, don't output `.ln 0'.
+ 
+ 	* Makefile (stamp-gnulib2): Depend on gnulib.  For parallel make.
+ 
+ 	* stmt.c (uninitialized_vars_warning): Don't crash if DECL_RTL is 0.
+ 
+ 	* i386.md (truncdfsf2): Pay attention whether stack top is dead.
+ 
+ Mon Aug 21 22:02:40 1989  Richard Stallman  (rms at apple-gunkies.ai.mit.edu)
+ 
+ 	* reload1.c (choose_reload_regs): Don't use regno uninitialized,
+ 	in the code that does find_equiv_reg.
+ 
+ Sun Aug 20 00:06:47 1989  Richard Stallman  (rms at apple-gunkies.ai.mit.edu)
+ 
+ 	* m68k.md (movqi): Was outputting bad code for areg->mem and mem->areg.
+ 
+ 	* explow.c (memory_address): Handle a hard reg in wrong reg class.
+ 
+ 	* stmt.c (expand_function_end): Set REG_FUNCTION_VALUE_P in return
+ 	reg when returning address of structure value block.
+ 
+ 	* integrate.c (save_for_inline): Preserve integrated bit on insns.
+ 
+ Sat Aug 19 14:20:07 1989  Richard Stallman  (rms at apple-gunkies.ai.mit.edu)
+ 
+ 	* combine.c (subst): Don't change (subreg:M (mem:N ...)) to 
+ 	(mem:M ...) if address is mode-dependent.
+ 
+ 	* config.gcc: Copy and alter Makefile for any srcdir except `.'.
+ 	In that case, make a .gdbinit as well.
+ 
+ 	* sparc.md (andcbsi3, iorcbsi3, xorcbsi3): These are not commutative.
+ 
+ 	* vax.md (cmpv and cmpzv patterns): Use COMPARE, not MINUS.
+ 
+ Fri Aug 18 12:24:52 1989  Richard Stallman  (rms at hobbes.ai.mit.edu)
+ 
+ 	* alliant.md (movqi): Change move to mov in assembler code.
+ 
+ 	* integrate.c (expand_inline_function):
+ 	Handle args passed in regs and copied to slots reached via arg ptr.
+ 
+ 	* out-sparc.c (output_delayed_branch):
+ 	Do alter_subreg on operands of delay insn.
+ 
+ 	* reload1.c (choose_reload_regs): Look for a reg to share
+ 	before one that we won't share.
+ 
+ 	* expr.h: Define OPTAB_MUST_WIDEN.
+ 	* optabs.c (expand_binop): Handle that case.
+ 	* expmed.c (expand_shift): Use that when widening lshift to ashift.
+ 
+ 	* optabs.c (emit_cmp_insn): Use CONST0_RTX, not individual vars.
+ 
+ 	* gnulib2.c (lsh*di3, ash*di3): Return right away if count is zero.
+ 	Otherwise tried to shift by 32.
+ 	Also replace constant 32 by something symbolic.
+ 
+ 	* final.c (output_source_line): Output line number in COFF
+ 	even if wrong file.
+ 
+ Thu Aug 17 15:16:34 1989  Richard Stallman  (rms at hobbes.ai.mit.edu)
+ 
+ 	* Makefile (version.o): Make this a target; specify source file.
+ 	(obstack.o): Likewise.
+ 
+ 	* config.gcc (i860): New alternative.
+ 
+ 	* i860.md (movstrsi): Record the alignment as operand 3.
+ 	Renumber following (internal) operands.
+ 	* out-i860.c (output_block_move): Rewrite as in out-sparc.c.
+ 	(output_size_for_block_move): Likewise.  And don't
+ 	subtract alignment from the size.
+ 
+ Wed Aug 16 13:27:12 1989  Richard Stallman  (rms at hobbes.ai.mit.edu)
+ 
+ 	* loop.c (combine_movables): Don't combine zero-extend
+ 	registers that live outside the loop.
+ 
+ 	* integrate.c (expand_inline_function): Use copy_to_mode_reg
+ 	to set up this_struct_value_rtx, to handle sums right.
+ 
+ 	* Makefile: Use $(srcdir) in bison output files used as deps.
+ 	Supply some missing deps.
+ 	(*.info, doc): *.info files go in srcdir.
+ 
+ Tue Aug 15 00:11:12 1989  Richard Stallman  (rms at hobbes.ai.mit.edu)
+ 
+ 	* i860.md, tm-i860.h, out-i860.c: New files.
+ 
+ 	* c-decl.c (duplicate_decls): Fix bug determining whether NEWDECL
+ 	is a definition or just a decl.
+ 	Combine code to preserve various things from old definition
+ 	through a declaration.
+ 
+ 	* config.gcc: Scan all args at beginning, setting variables.
+ 	Arg of form -srcdir=... sets srcdir explicitly.
+ 	srcdir now doesn't contain a slash, and is used with a slash.
+ 
+ 	* Makefile (install): Copy header files and gcc.1 from srcdir.
+ 	But copy float.h from current dir.  (Remove that from USER_H.)
+ 	(various): Use new variable INCLUDES to get the -I options.
+ 	Add -I. at the beginning of these.
+ 	(gnulib, gnulib2): Likewise, use SUBDIR_INCLUDES.
+ 	Also, get source file from srcdir.
+ 	Also, depend on $(CONFIG_H).
+ 	(alloca.o): Get alloca.c from srcdir.
+ 
+ 	* reload1.c (emit_reload_insns): Bug in last change:
+ 	don't fail to set this_reload_insn.
+ 
+ 	* Makefile (Bison rules): Specify $(srcdir) for target and source.
+ 	(Explicit C rules): Specify $(srcdir)/ for source in commands.
+ 	Use sed to eliminate `./' in normal case.
+ 	(insn-*.c): Use $(srcdir) to run move-if-change.
+ 
+ 	* config.gcc: Check . and .. for the sources.
+ 	If in .., use that when making links.
+ 	Also, copy Makefile, alter srcdir in it, and add a VPATH.	
+ 
+ 	* stmt.c (expand_end_case): When converting CONST_INT index
+ 	to an INTEGER_CST, sign-extend if signed type.
+ 
+ Mon Aug 14 13:51:08 1989  Richard Stallman  (rms at hobbes.ai.mit.edu)
+ 
+ 	* c-decl.c (duplicate_decls): Warn for qualifier mismatch
+ 	only if pedantic; don't consider it a type mismatch.
+ 	Merge the qualifiers of the two decls if the types match.
+ 
+ 	* expmed.c (store_bit_field): For insv, memref displacement
+ 	always counts in bytes, regardless of unit fetched.
+ 	When checking predicate of op0, accept any mode.
+ 
+ 	* optabs.c (expand_float): One call to can_float_p had args backwards.
+ 
+ 	* loop.c (check_dbra_loop): Set the JUMP_LABEL of the new jump insn.
+ 	Increment label's use count rather than storing 2.
+ 
+ 	* Makefile: Instead of $<, which fails in certain makes,
+ 	use $@ and then substitute in the name with sed.
+ 
+ 	* out-sparc.c (output_scc_insn): Handle CC_REVERSED for ordered tests.
+ 	Use orcc insns to store the result and set cc's for it.
+ 
+ 	* sparc.md (scc combination patterns):
+ 	Use operands[0] as basis for recorded cc value.
+ 
+ 	* gnulib2.c (floatdidf, fixdfdi, fixunsdfdi): New functions.
+ 
+ 	* gnulib.c (floatdidf, fixdfdi, fixunsdfdi): Deleted.
+ 	(union longlong, union double_di): Deleted.
+ 	(HIGH, LOW): Deleted.
+ 	These were deleted because most did not handle full range of DI
+ 	and they didn't use the right calling convention for DI.
+ 
+ Sun Aug 13 13:06:45 1989  Richard Stallman  (rms at hobbes.ai.mit.edu)
+ 
+ 	* c-typeck.c (comptypes): Qualifiers must match.
+ 	(Was already true for scalars.)
+ 	Also, array elt qualifiers must match.
+ 
+ 	* tm-apollo68.h (STRUCT_VALUE): Make it 0.
+ 	(This was done before and lost.)
+ 	* out-i386.c (function_epilogue): Use ret $4 to pop structure address.
+ 	(This was done before and lost.)
+ 
+ 	* out-i386.c (call_top_dead_p): Don't fail to check
+ 	the rtx code of the insns themselves.
+ 	(This was done before and lost.)
+ 
+ 	* out-sparc.c (output_block_move): If align is 8, make it 4.
+ 
+ 	* typeclass.h: New file.
+ 	* expr.c: Include it.
+ 	(expand_builtin): Use those codes in __builtin_classify_type.
+ 
+ 	* Makefile (all, lang-c): Reinstall gnulib2.
+ 
+ 	* Makefile (gnulib2): Don't give up if `ar d' fails.
+ 
+ 	* expr.c (emit_library_call): New 2nd arg NO_QUEUE.
+ 	All callers changed to pass it.
+ 	* optabs.c (expand_binop, expand_unop): Don't call emit_queue.
+ 	Instead, pass 1 for NO_QUEUE to emit_library_call.
+ 
+ Sat Aug 12 12:05:22 1989  Richard Stallman  (rms at hobbes.ai.mit.edu)
+ 
+ 	* reload1.c (emit_reload_insns): Decision for where to put input
+ 	reload insn is now common to ordinary case and auto-increment.
+ 	Likewise, updating these positions afterward.
+ 
+ 	* stmt.c (assign_parms): Treat last named arg as nameless.
+ 	* expr.c (expand_call): Likewise.
+ 
+ 	* explow.c (copy_to_mode_reg): Use force_operand for PLUS or MULT.
+ 	(copy_addr_to_reg): Use copy_to_mode_reg.
+ 
+ 	* expmed.c (store_bit_field): Handle case where insv rejects memrefs.
+ 
+ 	* tm-convex.h (ASM_OUTPUT_ALIGN): Magic to handle the fact
+ 	that this is not called when LOG is 0.
+ 
+ Fri Aug 11 16:39:51 1989  Richard Stallman  (rms at hobbes.ai.mit.edu)
+ 
+ 	* emit-rtl.c (get_lowpart): For multi-word, in error check,
+ 	test the unit size of the containing mode.
+ 
+ 	* cccp.c (macroexpand, dump_all_macros): Return void.
+ 	(macroexpand): Cast sprintf arg to char*.
+ 	(error, warning, error_with_line): Declare first arg char*.
+ 
+ Thu Aug 10 21:42:13 1989  Richard Stallman  (rms at hobbes.ai.mit.edu)
+ 
+ 	* expr.c (expand_call):
+ 	Use force_operand to copy arithmetic to register.
+ 
+ 	* dbxout.c (dbxout_symbol): Go back to N_FUN for const variable.
+ 
+ 	* integrate.c (expand_inline_function): Use proper machine mode
+ 	for a structure value in memory at address passed by caller.
+ 
+ Wed Aug  9 15:21:36 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* config.gcc: Delete unnecessary variable assignments in case stmt.
+ 	(isi68-nfp): New alternative.
+ 
+ 	* combine.c (try_combine): Don't substitute for a register
+ 	which is being explicitly clobbered.
+ 
+ 	* This change was requested for C++.
+ 	* varasm.c (decode_reg_name, make_decl_rtl): Arg ASMSPEC now char *.
+ 	* toplev.c (rest_of_decl_compilation): Likewise.
+ 	* c-decl.c (finish_decl): Change call to rest_of_decl_compilation.
+ 
+ 	* tree.h (struct tree_decl): Pack machine_mode into 8 bits.
+ 
+ 	* explow.c (memory_address, copy_to_reg):
+ 	Use force_operand to copy arithmetic to register.
+ 
+ 	* tm-isi68-nfp.h: New file.
+ 	* tm-isi68.h: Allow overriding TARGET_DEFAULT, and let that
+ 	change CPP_SPEC and LINK_SPEC.
+ 	(ASM_FILE_START): No `.globl fltused' if soft-float.
+ 
+ Tue Aug  8 21:50:52 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* varasm.c (const_hash): For constructor, mask TREE_TYPE to HASHBITS
+ 	bits and take modulo, so we don't get negative numbers.
+ 
+ 	* varasm.c (record_constant_1, compare_constant_1):
+ 	Record and compare the width of an integer.
+ 
+ 	* varasm.c (assemble_function, assemble_variable, get_or_assign_label):
+ 	(force_const_mem): Don't call ASM_OUTPUT_ALIGN if boundary is 1.
+ 
+ 	* c-decl.c (duplicate_decls): Consider const and volatile as part of
+ 	type when checking for match and when installing new type into OLDDECL.
+ 
+ 	* expr.c (do_store_flag): Make sure target fits operand predicate.
+ 	Also, omit the AND insn when true-value is 1
+ 	and the mode we get is wider than the one we want.
+ 
+ 	* genrecog.c (main): Make insn-recog.c include real.h.
+ 
+ Mon Aug  7 16:58:56 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* genemit.c (main): Define `operands' as `emit_operands',
+ 	not `recog_operands'.
+ 
+ 	* reload1.c (emit_reload_insns): Don't copy back a dead output reg.
+ 
+ Sun Aug  6 13:56:53 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* sdbout.c (plain_type_1, sdbout_one_type): Use the main variant.
+ 	(sdbout_type_fields): No need to check TREE_ASM_WRITTEN here,
+ 	since sdbout_one_type does that.
+ 
+ 	* expr.c (do_store_flag): Ensure the CLOBBER doesn't clobber an input.
+ 
+ 	* fold-const.c (fold_convert): Attempt to avoid overflow
+ 	when converting real to integer.  Use unsigned conversion for
+ 	low part; always convert as positive and then change sign;
+ 	subtract high part before converting low part.
+ 	Also, check for real values out of range for chosen int type;
+ 	warn and do not convert.
+ 
+ 	* tm-hp9k320.h (CPP_SPEC) [not HPUX_ASM]: Don't define mc68000 here.
+ 	(CPP_PREDEFINES): Remove mc68k, add m68k and mc68000.
+ 	[HPUX_ASM]: Define CPP_SPEC here as in the other case,
+ 	but add __HPUX_ASM__ to each alternative.
+ 
+ 	* tm-m68k.h (FUNCTION_EPILOGUE): Call new hook FUNCTION_EXTRA_EPILOGUE.
+ 	* tm-altos3068.h (FUNCTION_EXTRA_EPILOGUE): Define it.
+ 
+ 	* Makefile: Use $< wherever appropriate.
+ 	Also put definitions of customization vars before the comments
+ 	saying how to override them.
+ 
+ Sat Aug  5 14:15:39 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* i386.md (sne): Typo in opcode name.
+ 
+ 	* tree.h (struct tree_identifier): Delete redundant/unused error_locus.
+ 
+ Fri Aug  4 00:04:10 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* varasm.c (const_hash, compare_constant_1, record_constant_1):
+ 	Compare types only for record constructors, not for array constructors.
+ 
+ 	* dbxout.c (dbxout_parms): When outputing parm from home in local slot,
+ 	with address from the RTL, don't do big-endian correction on it.
+ 
+ 	* c-typeck.c (build_unary_op): Do default conversion for unary +.
+ 
+ 	* cccp.c (rescan): Accept comments between macro and its args.
+ 
+ 	* c-decl.c (lang_decode_option): -traditional implies writable strings.
+ 
+ 	* cccp.c (trigraph_pcp): Make warning msg more accurate.
+ 
+ 	* c-typeck.c (c_expand_asm_operands): Delete the default promotion
+ 	which was inserted mysteriously since 1.35.
+ 
+ 	* global-alloc.c (global_conflicts): Allocate regs_set only once.
+ 	Make it twice as big since clobbers are stored twice.
+ 
+ 	* sparc.md (block move patterns): Record and use alignment operand.
+ 	* out-sparc.c (output_block_move): Get alignment from there.
+ 	(output_size_for_block_move): Greatly simplified.
+ 
+ 	* tm-i386v.h (PCC_BITFIELD_TYPE_MATTERS): Define it.
+ 
+ 	* stor-layout.c (layout_record): Anonymous bitfields don't affect
+ 	overall structure alignment, in PCC_BITFIELD_TYPE_MATTERS case.
+ 
+ 	* loop.c (strength_reduce): Prevent hard reg from becoming biv or giv.
+ 
+ 	* combine.c (subst): Simplify (eq (neg ...) (const_int 0)).
+ 
+ Thu Aug  3 13:08:05 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* cse.c (fold_rtx): For (op var const) special cases, also check 
+ 	for constant as first argument.
+ 
+ 	* c-decl.c (pushtag): For global_binding_level, make permanent nodes.
+ 
+ 	* expr.c (do_store_flag): Put the CLOBBER before the comparison.
+ 
+ 	* expr.c (emit_push_insn): Conditionalize recent changes
+ 	on no FIRST_PARM_CALLER_OFFSET, so they don't happen on sparc.
+ 
+ 	* out-sparc.c (gen_scc_insn):
+ 	Don't be confused by CLOBBER emitted by do_store_flag.
+ 	Skip past such insns looking for last_insn.
+ 	Don't alter last_insn; instead, patch it to a NOTE and emit new insn.
+ 
+ 	* varasm.c (const_hash, compare_constant_1, record_constant_1):
+ 	For a CONSTRUCTOR, hash/compare/record type as well as elts.
+ 
+ 	* cse.c (cse_insn): July 18 change was wrong.
+ 	Now, invalidate at the beginning any regs explicitly clobbered
+ 	so they will not be substituted for if they appear as inputs.
+ 	* sparc.md (movstrsi): Copy addresses to temp regs, then use them.
+ 
+ 	* loop.c (record_giv): When comparing life spans for setting
+ 	->forces, use luids consistently, not uids.
+ 
+ 	* sparc.md (ashlsi3, ashrsi3, lshrsi3): Truncate constants mod 32.
+ 
+ Wed Aug  2 17:50:30 1989  Richard Stallman  (rms at sugar-bombs)
+ 
+ 	* mips.md (patterns to move a subreg): Deleted.
+ 
+ Sun Jul 30 19:23:13 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* gcc.c (process_command): Skip `-b' like `-B', in 2nd scan.
+ 
+ 	* xm-sunos4.h: Deleted.
+ 	* tm-sparc.h, tm-sun3.h: Define LINK_SPEC here instead.
+ 	* tm-sun4os3.h: Undef it here.
+ 	* tm-sun3os3.h, tm-sun3os3nf.h: New files to undef LINK_SPEC.
+ 	* config.gcc: Use those new files where needed.
+ 
+ 	* config.gcc: Delete sun3-fpa and sun3-os4-fpa.
+ 	* tm-sun3-fpa.h: Deleted.
+ 
+ 	* cccp.c (do_include): Mention even non-ex files for -M.
+ 
+ 	* out-mips.c (addr_compensate): Handle HImode.
+ 	* mips.md (Set HI from subreg of SI rule):
+ 	Allow operand in memory.
+ 
+ 	* mips.md (cmpqi, cmphi): Patterns deleted.
+ 	(cmpsi, cmpsf, cmpdf): Change predicates to register_operand.
+ 
+ 	* cexp.y (rule for ?:): Result is unsigned if either operand is.
+ 
+ 	* expr.c (emit_push_insn): If PARTIAL > 0, load the partial regs
+ 	at the end, in case the rest of the push does a function call.
+ 
+ 	* reload1.c (alter_frame_pointer_addresses):
+ 	After altering a PLUS, re-fetch CODE before scanning subexps.
+ 
+ 	* stmt.c (assign_parms): Don't copy the arg pointer value
+ 	if it is also the frame pointer.  If we do copy it,
+ 	inhibit REG_EQUIV notes for parms copied into pseudo regs
+ 
+ 	* integrate.c (copy_for_inline, copy_rtx_and_substitute):
+ 	Set up filename and lineno fields of copy of ASM_OPERANDS.
+ 
+ Sat Jul 29 18:58:49 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* integrate.c (expand_inline_function): Handle struct-value-addr
+ 	passed in memory just like that passed in reg:
+ 	in either case, translate the pseudo-reg made in
+ 	expand_function_start.
+ 	(function_cannot_inline_p): Permit inlining in that case.
+ 	But reject it if using pcc-style return convention.
+ 
+ 	* stor-layout.c (layout_type): Consider STRICT_ALIGNMENT
+ 	for ARRAY_TYPE just as for RECORD_TYPE.
+ 
+ Wed Jul 26 12:54:59 1989  Richard M. Stallman  (rms at mipos3)
+ 
+ 	* cse.c (fold_rtx): If WIDTH is zero for binary operator,
+ 	look at the modes of the original operands.
+ 
+ 	* cse.c (cse_insn): Set prev_insn_explicit_cc0, for (set (cc0) INT).
+ 	(predecide_loop_entry): Likewise.
+ 	(fold_rtx): Look at it, for (if_then_else (cc0) ...).
+ 
+ 	* expr.c (expand_builtin): Pass back return value from
+ 	__builtin_saveregs.
+ 
+ 	* stmt.c (assign_parms): Allow arg pointer reg not to be fixed.
+ 	If it is not, copy it to a pseudo reg and use that later on.
+ 
+ Tue Jul 25 15:42:04 1989  Richard M. Stallman  (rms at mipos3)
+ 
+ 	* expr.c (expand_builtin): New builtin __builtin_classify_type.
+ 	* tree.h, c-decl.c: Additional support.
+ 
+ 	* flow.c (mark_used_regs): Treat arg pointer like stack pointer.
+ 
+ 	* expr.c (emit_library_call):
+ 	Pass (tree)0 as TYPE arg to FUNCTION_ARG, etc.
+ 
+ Mon Jul 24 11:18:10 1989  Richard M. Stallman  (rms at mipos3)
+ 
+ 	* loop.c (regs_match_p): Fix braino.
+ 
+ 	* integrate.c (copy_for_inline, copy_rtx_and_substitute):
+ 	Make ASM_OPERANDS constraint vector be shared like operand vector.
+ 
+ 	* xm-iris.h: New file.
+ 
+ 	* Makefile (stage4): New target.
+ 
+ 	* gnulib2.c (badd, bsub, bmul, bdiv): If want long value from
+ 	arithmetic, widen the operands first.
+ 	(__div_internal aka bdiv): Rename to __bdiv.
+ 
+ 	* sparc.md (seq combination patterns): Fully initialize cc_status.
+ 
+ 	* expr.c (emit_push_insn): Like July 19 change, for BLKmode.
+ 
+ 	* stmt.c (expand_function_end): Stack-restore for alloca
+ 	is now done after the return_label.
+ 
+ 	* loop.c (scan_loop): Set MAYBE_NEVER for conditional jump to loopbeg.
+ 
+ 	* integrate.c (copy_rtx_and_substitute): Allow mapping of hard regs.
+ 	(expand_inline_function): Always create parm_map.
+ 	Handle structure value that way if nec. even if no parms.
+ 	Otherwise, find the pseudo used in the function to hold the
+ 	structure address, and map it to a new pseudo.
+ 
+ 	* expr.c (expand_call):
+ 	Use mark_addressable to make FNDECL addressable.
+ 	* c-typeck.c (mark_addressable): No longer static.
+ 
+ 	* cse.c (cse_insn): Modify last change: don't canon_reg
+ 	for hard regs inside clobbers.
+ 
+ 	* expr.c (expand_assignment): ALIGN arg to store_field comes from
+ 	the structure, not from the value stored.
+ 
+ Fri Jul 21 16:23:45 1989  Richard M. Stallman  (rms at mipos3)
+ 
+ 	* stmt.c (warn_if_unused_value): Don't warn for a cast
+ 	around a MODIFY_EXPR.
+ 
+ 	* tm-hp9k320.h (PCC_STATIC_STRUCT_RETURN): Undefine it.
+ 	(CPP_PREDEFINES): Add some.
+ 
+ 	* combine.c (simplify_and_const_int):
+ 	Simplify (and (ashiftrt (zero_extend FOO) N) M).
+ 
+ 	* optabs.c (expand_binop): When widening,
+ 	for some operations we need not actually extend.
+ 
+ Thu Jul 20 16:16:35 1989  Richard M. Stallman  (rms at mipos3)
+ 
+ 	* Makefile (insn-emit.o): Depend on insn-codes.h.
+ 
+ 	* stmt.c (check_for_full_enumeration_handling): 
+ 	Handle all cases for TYPE_NAME of enum type.
+ 
+ Wed Jul 19 17:00:39 1989  Richard M. Stallman  (rms at mipos3)
+ 
+ 	* fold-const.c (fold_convert): Don't fail to force_fit_type.
+ 
+ 	* expr.c (emit_push_insn): When pushing only part of scalar on stack,
+ 	adjust stack offset not to count the words not pushed.
+ 
+ 	* stmt.c (expand_function_end): Always put return structure address
+ 	in return register.
+ 
+ 	* c-typeck.c (process_init_constructor): Assume 0 for nameless field.
+ 
+ 	* recog.c (general_operand, memory_operand):
+ 	Check validity of mem address using the mode of the MEM.
+ 
+ 	* fixincludes: When calling egrep, use redirect, not -s.
+ 
+ Tue Jul 18 11:18:55 1989  Richard M. Stallman  (rms at mipos3)
+ 
+ 	* Makefile (bootstrap*): Pass value of libdir down.
+ 
+ 	* cse.c (cse_insn): Do canon_reg on any CLOBBERs and USEs.
+ 
+ 	* cse.c (cse_insn): Don't use no_labels_between_p to check
+ 	for jump to following label; find following label and compare.
+ 
+ 	* combine.c (try_combine): Don't substitute into subreg(x)=y
+ 	if modes of x and y are not tieable.
+ 
+ 	* out-i386.c (call_top_dead_p): Don't fail to check
+ 	the rtx code of the insns themselves.
+ 
+ 	* i386.md (tstsf, tstdf): Don't discard TOS if not dead.
+ 
+ 	* stupid.c: Don't use regs with PRESERVE_DEATH_INFO_REGNO_P
+ 	for pseudos which live across jumps or labels.
+ 	(stupid_life_analysis): Update last_jump_suid, last_label_suid.
+ 	(stupid_mark_refs): Use those to set reg_crosses_blocks.
+ 	(stupid_find_reg): Check that data, passed from stupid_life_analysis.
+ 
+ 	* toplev.c (main): Avoid using caddr_t.
+ 
+ 	* mips.md (inverted bgeu peephole): Typo in opcode.
+ 
+ Mon Jul 17 12:29:45 1989  Richard M. Stallman  (rms at mipos3)
+ 
+ 	* i386.md (mulb patterns): Turned off due to assembler bug.
+ 
+ 	* rtl.c (read_name): Use 0, not NULL, for character.
+ 
+ 	* alliant.md (movqi): Typos in mov opcodes.
+ 
+ 	* tm-sparc.h, tm-spur.h (CONST_DOUBLE_OK_FOR_LETTER_P):
+ 	Use CONST_DOUBLE_LOW, etc. 
+ 
+ 	* stmt.c (expand_function_end): Check value of EXIT_IGNORE_STACK,
+ 	not just whether defined.
+ 
+ 	* i386.md (seq, etc.): New patterns.
+ 	* expr.c (do_store_flags): If result is wrong mode, 
+ 	ensure rest of bits are cleared.
+ 	Before storing low part of TARGET, emit a CLOBBER for it.
+ 
+ 	* i386.md (load address): Use an immediate add if possible.
+ 
+ 	* i386.md (ashlsi3): Don't generate leal; shift is faster.
+ 
+ 	* Now struct_value_rtx is 0 to treat it as a parm.
+ 	* expr.c (expand_call): Implement that.
+ 	* integrate.c (expand_inline_function): Don't freak out.
+ 	* tm-apollo68.h (STRUCT_VALUE): Make it 0.
+ 
+ 	* On 386, called function must pop the structure value address.
+ 	* tm-i386.h (STRUCT_VALUE): Don't change this.
+ 	Address is now pushed but not counted as a parm.
+ 	* out-i386.c (function_epilogue): Use ret $4 to pop that address.
+ 	* output.h: Declare the current_function_... variables.
+ 	* final.c: Include output.h.
+ 
+ 	* varasm.c (make_decl_rtl): Insert missing `else', validating reg decl.
+ 
+ Fri Jul 14 14:12:17 1989  Richard M. Stallman  (rms at mipos3)
+ 
+ 	* out-sparc.c, out-spur.c (output_move_double):
+ 	Fixed typo, addreg0 => addreg1.
+ 
+ 	* c-decl.c (lang_decode_option): Handle -fshort-enums.
+ 	(finish_enum): In that case, give enum minimum number of bytes.
+ 	* toplev.c (main): Default flag_short_enums.
+ 	* toplev.c, flags.h (flag_short_enums, flag_signed_char): 
+ 	Define those flags here, not in c-decl.c and c-tree.h.
+ 
+ 	* i386.md (mulqi3, umulqi3): New patterns.
+ 
+ 	* c-convert.c (convert_to_integer): Tighter restrictions on
+ 	distributing truncation through max, min, and multiplication.
+ 	If operands were extended from unsigned, make the operation
+ 	unsigned.
+ 
+ 	* cccp.c (main): Fix bug where #include <...>, when -I- was used,
+ 	failed to search standard dirs and/or searched some dirs
+ 	intended only for #include "...".
+ 
+ 	* tm-mips.h (FUNCTION_PROLOGUE,FUNCTION_EPILOGUE):
+ 	Increment push_loc after store or load, not before.
+ 
+ Thu Jul 13 11:24:30 1989  Richard M. Stallman  (rms at mipos3)
+ 
+ 	* emit-rtl.c (add_insn_after): Don't update last_insn
+ 	if insn is in a sequence.  Instead, update end of sequence.
+ 
+ 	* stmt.c (fixup_var_refs): Update end of stacked sequence.
+ 
+ 	* stmt.c (expand_function_start): Set result rtl before assign_parms.
+ 
+ 	* optabs.c (emit_unop_insn): Set PREV_INSN after preliminaries.
+ 
+ 	* stmt.c (warn_if_unused_value): Do CONVERT_EXPR like NOP_EXPR.
+ 
+ 	* stmt.c (expand_function_start): Make sure parm_birth_insn
+ 	is a NOTE.
+ 
+ 	* Makefile (clean): Delete tmp-insn-*.
+ 
+ Wed Jul 12 14:24:12 1989  Richard M. Stallman  (rms at mipos3)
+ 
+ 	* i386.md (mulqi3): Restrict operand 2 to `q' reg.
+ 
+ 	* reload1.c (choose_reload_regs): Check HARD_REGNO_MODE_OK
+ 	for regs to be inherited.
+ 	Also check HARD_REGNO_MODE_OK at end for modes of both
+ 	reload_in and reload_out as well as reload_mode.
+ 
+ 	* Makefile (maketest): Update for config subdir.
+ 
+ Tue Jul 11 16:29:57 1989  Richard M. Stallman  (rms at mipos3)
+ 
+ 	* integrate.c (copy_decl_tree): Copy TREE_USED of each LET_STMT.
+ 
+ 	* make-cc1.com: Changes by Angel Li.
+ 	Define variables CC, CFLAGS, LDFLAGS, LIBS.
+ 	Use LIBR library, not LIB.  Specify a /INC in CFLAGS.
+ 	Use MCR to run the gen* files.  Add some comments.
+ 	* make-cccp.com: Similar.
+ 	* config-gcc.com: New file.
+ 
+ 	* stmt.c (assign_parms): Compute parm alignment from passed type.
+ 
+ 	* c-typeck.c (actualparameterlist): Instead of truncating
+ 	and then promoting for PROMOTE_PROTOTYPES, go straight to int.
+ 
+ 	* c-parse.y (setspecs): Save old current_declspecs on a stack.
+ 	(decl, component_decl): Restore from that stack.
+ 
+ Wed Jul  5 15:01:00 1989  Richard Stallman  (tiemann at yahi)
+ 
+ 	* tm-aix386.h, xm-aix386.h: New files.
+ 
+ 	* loop.c (check_dbra_loop): Handle either test or compare
+ 	for insn two before loop end; detect and reject anything else.
+ 
+ 	* expr.c (expand_call, expand_builtin): If alloca is done,
+ 	set current_function_calls_alloca.
+ 	* stmt.c (expand_function_end): If so, generate code to save and
+ 	restore the stack pointer, if not EXIT_IGNORE_STACK.
+ 
+ 	* ns32k.md (movsi): Fixes for moving from fp or sp.
+ 
+ 	* tm-mips.h (ASM_OUTPUT_ASCII): Start new .ascii every 256 chars.
+ 
+ Tue Jul  4 11:01:00 1989  Richard Stallman  (tiemann at yahi)
+ 
+ 	* reload1.c (choose_reload_targets): Don't depend on
+ 	reload_spill_index when cancelling invalid inheritance.
+ 	Also, abort if trying to preserve death info
+ 	on a spill reg used in operand addressing.
+ 
+ 	* fold-const.c (fold): Don't fold "foo"[n] here.
+ 	* expr.c (expand_expr): Do it here.
+ 	Handle wide strings correctly.
+ 
+ 	* i386.md (movsf,movdf): Disallow mem-mem moves.
+ 	Enable mem-to-reg moves.
+ 
+ 	* c-decl.c (finish_{struct,enum}): Warn if inside parm decls.
+ 	(in_parm_level_p, declare_parm_level): Record when inside.
+ 	* c-parse.y (parmlist, parmlist_or_identifiers): Call
+ 	declare_parm_level.
+ 
+ 	* c-decl.c (parmlist_tags_warning): Revise warning message text.
+ 
+ 	* tm-hp9k320.h (ASM_SPEC): Pass -V switch to assembler.
+ 
+ 	* tm-sun386.h (ASM_START_FILE): Truncate filename to 14 chars.
+ 
+ 	* c-typeck.c (decl_constant_value): Use only literal values.
+ 
+ Sat Jul  1 17:29:54 1989  Richard Stallman  (tiemann at yahi)
+ 
+ 	* integrate.c (copy_rtx_and_substitute): Don't make nested SUBREGs.
+ 
+ 	* stmt.c (expand_function_start): Set new global
+ 	current_function_returns_pointer.
+ 
+ 	* stmt.c (get_frame_size): Return the size, not the offset.
+ 	* integrate.c (expand_inline_function): When setting FP_DELTA,
+ 	compensate for this change.
+ 	* tm-alliant.h,tm-mips.h,tm-sparc.h,tm-tahoe.h
+ 	(FUNCTION_PROLOGUE,FUNCTION_EPILOGUE): Compensate.
+ 
+ 	* out-mips.c (function_arg): Return 0 for BLKmode.
+ 
+ 	* tm-mips.h (FUNCTION_INCOMING_ARG): Delete; no register windows.
+ 	* out-mips.c (function_inarg): Delete; no longer used.
+ 
+ 	* mips.md (addsi3): Use register_operand for operands 0,1.
+ 	(load address): New pattern, following movsi.
+ 	(fix_trunc*): Use trunc insn, not cvt.
+ 	(cmpfs + bgt peephole): Operands were backwards in template.
+ 
+ 	* gcc.c (main): Record in explicit_link_files which input files go
+ 	straight to linker.  If linker is not run, complain about them.
+ 	(execute): Increment execution_count, to show we were called.
+ 
+ 	* gcc.c (validate_all_switches): Check ASM_SPEC, CC1_SPEC, etc.,
+ 	so we find all switches that could be valid.
+ 
+ 	* varasm.c (output_constructor): Position fields according to
+ 	DECL_OFFSET; don't try to compute alignment here.
+ 
+ 	* tm-sparc.h (PCC_BITFIELD_TYPE_MATTERS): Define this.
+ 
+ 	* reload1.c (emit_reload_insns): Fix stupid error in last change.
+ 
+ 	* c-decl.c (duplicate_decls): If redeclaring builtin, give error is
+ 	type mismatched; otherwise warn only if -W.
+ 
+ 	* jump.c (jump_back_p): Verify that PREV is not null.
+ 
+ Mon Jun 26 13:50:28 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* reload1.c (choose_reload_regs): If number of reloads needing
+ 	spill regs exceeds n_spills, don't inherit any reloads.
+ 
+ 	* sdbout.c (sdbout_record_type_name): Dumb error in last change.
+ 
+ 	* reload1.c (emit_reload_insns): Extend last change: don't use
+ 	equiv reg if reg is in use at same stage of insn, either.
+ 
+ Sun Jun 25 00:00:56 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* reload1.c (emit_reload_insns): Don't use an equivalent register
+ 	to reload from, if that register was used for reloading
+ 	earlier in this insn.
+ 
+ 	* sdbout.c (sdbout_record_type_name): Handle a TYPE_DECL as the
+ 	type name.  Get rid of TYPE_TAG_NAME as separate macro.
+ 
+ 	* optabs.c (emit_cmp_insn): Args to memcmp are addresses, not blocks.
+ 
+ 	* reload1.c (choose_reload_regs): Typo, clearing reload_override_in.
+ 
+ 	* tm-i386.h: Add register classes SIREG and DIREG.
+ 	(enum reg_class, REG_CLASS_NAMES): Define class names.
+ 	(REGNO_REG_CLASS, REG_CLASS_CONTENTS): Define their contents.
+ 	(REG_CLASS_FROM_LETTER): Define letters `S' and `D'.
+ 
+ Sat Jun 24 00:17:16 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* c-decl.c (keep_next_level): New function.
+ 	(struct binding): New slot `keep' says make a LET_STMT for this level.
+ 	(pushlevel, poplevel): Implement that.
+ 	* c-parse.y (stmt exprs): Call keep_next_level.
+ 
+ 	* sdbout.c (plain_type_1): Handle REFERENCE_TYPE, METHOD_TYPE.
+ 	Correct for size less than 0.
+ 	(plain_type): Correct for size less than 0.
+ 
+ 	* global-alloc.c (mark_reg_set): For CLOBBERs, call mark_reg_clobber.
+ 
+ 	* reload1.c (order_regs_for_reload): Among regs explicitly used,
+ 	prefer those used less often.
+ 
+ 	* reload1.c (choose_reload_regs): If we find alternate place
+ 	to reload from, verify it after all reloads assigned.
+ 	New variable reload_override_in used for this.
+ 
+ 	* combine.c (record_dead_and_set_regs): Look inside SIGN_EXTEND and
+ 	STRICT_LOW_PART for place being set.
+ 	(subst): When using reg_last_set to find what a register contains,
+ 	verify the entire register was set.
+ 
+ 	* toplev.c (rest_of_decl_compilation): Report invalid register name.
+ 
+ Fri Jun 23 13:19:41 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* tm-hp9k3bsd.h: New file.
+ 	* config.gcc: New target hp9k320-bsd.
+ 
+ 	* gcc.c (record_temp_file): Don't add a name twice to one queue.
+ 
+ 	* stmt.c (expand_expr_stmt): Call warn_if_unused_value.
+ 	(warn_if_unused_value): Code extracted from expand_expr_stmt.
+ 	Recurse to handle COMPOUND_EXPR.  Don't warn about COND_EXPR.
+ 
+ 	* tm-encore.h (DBX_REGISTER_NUMBER): Override tm-ns32k.h;
+ 	return operand unchanged.
+ 
+ 	* reload1.c (emit_reload_insns): Don't use recog_memoized
+ 	on an asm.
+ 
+ 	* jump.c (delete_insn): Update last_insn.
+ 	* emit-rtl.c (set_last_insn): New function.
+ 
+ 	* reload1.c (reload): Put a note at end of insn chain.
+ 
+ 	* gcc.c: Put cpp output of .S file into a .s file.
+ 
+ Thu Jun 22 22:14:35 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* optabs.c (expand_binop, expand_unop): Emit queue before library call.
+ 	It is done within emit_library_call, and cse screws up if there is a
+ 	queued insn in the middle of a cse-able sequence.
+ 
+ Wed Jun 21 11:57:22 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* tm-mips.h (CPP_PREDEFINES): Define -Dunix.
+ 
+ 	* reload.c (combine_reloads): Combined reload needed for entire insn.
+ 
+ 	* c-parse.y (yylex): Braino checking for out-of-range escape seq.
+ 
+ 	* stor-layout.c (layout_union): Handle PCC_BITFIELD_TYPE_MATTERS.
+ 	(layout_struct): Don't let a bitfield cross the storage unit
+ 	of its type, if PCC_BITFIELD_TYPE_MATTERS.
+ 
+ Tue Jun 20 00:03:48 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* varasm.c (get_or_assign_label): Let CONSTANT_ALIGNMENT specify
+ 	alignment of the constant.
+ 	CONSTANT_ALIGNMENT is a new optional macro.
+ 
+ 	* varasm.c (force_const_mem, get_or_assign_label):
+ 	Make buffer bigger.
+ 
+ 	* toplev.c (print_target_switch_defaults): New fn called for -version.
+ 
+ 	* toplev.c (compile_file): Detect error closing output file.
+ 
+ 	* stor-layout.c (fixup_unsigned_type): Don't shift by 32.
+ 
+ 	* stmt.c (emit_case_nodes): Pass UNSIGNEDP along to emit_cmp_insn.
+ 
+ 	* stmt.c (expand_end_case): If index is narrow and cannot be
+ 	directly compared, widen it just once.
+ 
+ 	* c-parse.y (yylex): Support multi-character constants.
+ 	Thorough rewrite of char constant parsing.
+ 
+ 	* c-decl.c (pushdecl): Replace local extern function decl with
+ 	previous global decl if latter is inline, or builtin, or has
+ 	more arg type info.
+ 
+ 	* hard-params.c (xmalloc): Define it, for alloca.c.
+ 
+ 	* tm-hp9k320.h (STANDARD_STARTFILE_PREFIX): Override -D in Makefile.
+ 
+ 	* expmed.c (store_fixed_bit_field): Avoid shift by 32.
+ 
+ 	* stmt.c (expand_function_start): Emit a NOTE_INSN_FUNCTION_BEG.
+ 	* final.c (final_scan_insn): For SDB output, do the
+ 	sdbout_begin_function at that note.
+ 
+ 	* reload1.c (choose_reload_regs): If a reload reg inherits
+ 	from a previous reload, verify safety after all reloads are assigned.
+ 
+ 	* c-decl.c (build_enumerator): Remove no-op casts.
+ 
+ 	* reload.c (find_reloads): If an earlyclobber operand matches
+ 	an input operand it is constrained to match, that's not a problem.
+ 	If an earlyclobber operand loses due to earlyclobber, its matching
+ 	input operand also loses.
+ 
+ 	* reload1.c (choose_reload_regs): Don't use result of find_equiv_reg
+ 	if that reg is used for reloading in an earlier part of the insn.
+ 
+ 	* cse.c (fold_rtx): If WIDTH is 0, don't try sign-extending ARG0, ARG1.
+ 
+ 	* Makefile (hard-params*): Use $(OLDCC).
+ 
+ 	* c-typeck.c (c_alignof): No warning for -pedantic.
+ 
+ 	* c-parse.y (readescape): Don't have both error and warning
+ 	on one hex escape.
+ 
+ 	* c-parse.y (yylex): Treat vertical tab as white space.
+ 	(skip_white_space): Likewise.
+ 
+ 	* c-parse.y (datadef): If pedantic, warn for stray semicolon.
+ 
+ 	* expr.c (expand_increment): Pass accurate unsignedp arg
+ 	to expand_binary_op.
+ 
+ Mon Jun 19 13:36:20 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* config.gcc (news, news-gas): Use xm-m68k.h.
+ 
+ 	* final.c (output_asm_label, output_addr_const): Make buf bigger.
+ 
+ 	* cexp.y (main): Handle EOF on input.
+ 	(lookup, warning): Provide as a dummy.
+ 	(is_idchar, is_idstart): Declare as unsigned char.
+ 
+ 	* cexp.y (parse_escape): Use TARGET_NEWLINE, etc., as values.
+ 	Support hex escapes.  Warn if octal or hex escape doesn't fit in char.
+ 
+ 	* cexp.y (yylex): Sign-extend char constants if appropriate.
+ 
+ 	* genemit.c: Make insn-emit.c include insn-flags.h.
+ 
+ 	* gcc.c: Move record_temp_file past page which declares vflag.
+ 
+ 	* integrate.c (expand_inline_function): If copying an insn with
+ 	a REG_EQUIV note, make a similar note.
+ 
+ 	* Allow reload regs to be reused for parts of an insn.
+ 	* reload.c (find_reloads): Classify each reload for which part
+ 	of the insn it is needed in.
+ 	(find_reloads_address, etc.): Pass down the overall operand
+ 	that this is part of, to record it on address reloads.
+ 	(push_reload): Record that for each reload.
+ 	* reload1.c (reload): Compute maximum needs of any part of the insn.
+ 	(choose_reload_regs): Part of old choose_reload_targets.
+ 	Hairier criteria for inheriting reloads and for which ones are
+ 	available for the next insn to inherit.
+ 	(emit_reload_insns): The rest of old choose_reload_targets.
+ 	Emit reload insns in proper order according to where they are needed.
+ 	* Record `reload_reg_in_use' separately for each part of the insn.
+ 	(mark_reload_reg_in_use): New function.
+ 	(reload_reg_free_p, reload_reg_free_before_p): New functions.
+ 	(reload_reg_reaches_end_p): New function.
+ 
+ 	* expr.c (expand_expr): Emit queue in X+=(Y?Z:A) optimization.
+ 
+ 	* rtlanal.c (rtx_equal_p): Check vectors have same length.
+ 
+ Sun Jun 18 12:16:14 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* stmt.c (expand_expr_stmt): Maybe warn if top-level operator
+ 	makes an unused result.
+ 
+ 	* gcc.c (delete_temp_files, delete_failure_queue):
+ 	If -v, report failures in unlink.
+ 
+ 	* Makefile (includes): New target to run fixincludes.
+ 	(install): Swap arms of if-statement.
+ 
+ Sat Jun 17 12:41:53 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* stor-layout.c (layout_union): Arg to error_with_decl was missing.
+ 
+ 	* ns32k.md (movsf): Use CONST_DOUBLE_LOW to extract from CONST_DOUBLE.
+ 
+ 	* loop.c (consec_sets_giv): Change type of force, force2.
+ 
+ 	* combine.c (dump*): Declare arg as FILE*.
+ 
+ 	* Makefile (clean): Delete hard-params.
+ 
+ 	* flow.c (life_analysis): Use a special obstack for the temporary
+ 	regsets.
+ 
+ 	* m68k.md (clr pattern): On 68000, use moveq to clear data reg.
+ 
+ 	* gvarargs.h: File varargs.h renamed.
+ 	The old name conflicted with <varargs.h>, now that -I. is used.
+ 	* tree.c, expr.c, emit-rtl.c: Change #include commands.
+ 	* Makefile (install): Install gvarargs.h under name varargs.h.
+ 	* gcc.c: Include gvarargs.h, not system's varargs.h.
+ 
+ 	* Makefile: Use -I$(srcdir) before -I$(srcdir)/config.
+ 	* config/tm.h: Deleted; didn't work if config was a symlink.
+ 
+ 	* cse.c (cse_insn): Record location of inner_dest
+ 	so it can be replaced properly if a new MEM rtx is made.
+ 
+ Fri Jun 16 14:17:20 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* make-cc1.com: Compile and link rtlanal.c.
+ 
+ 	* c-typeck.c (build_array_ref): Call fold on the array ref.
+ 	* fold-const.c (fold): Simplify array ref of string constant.
+ 
+ 	* stmt.c (expand_asm_operands): Fix error message.
+ 
+ 	* Makefile (gnulib2): Remove old members before compiling new.
+ 	Fix stupid errors.
+ 	* gnulib2.c (__cmpdi2, __ucmpdi2): Typos in names of interface unions.
+ 
+ 	* genconfig.c (main): Don't write MAX_CLOBBERS_PER_INSN; obsolete.
+ 	Add 3 to MAX_RECOG_OPERANDS.
+ 
+ 	* cse.c (fold_cc0): Extra arg specifies machine mode.
+ 	Callers changed.
+ 	(cse_insn): Record original mode of each src for this purpose.
+ 
+ Thu Jun 15 12:35:18 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* gnulib2.c (_cmpdi2, _ucmpdi2): Moved here from gnulib.c.
+ 	Use long long for argument type.
+ 
+ 	* rtlanal.c (may_trap_p): Moved here from loop.c.
+ 	Return 1 for division by explicit zero.
+ 
+ 	* reload1.c (eliminate_frame_pointer, alter_frame_pointer_addresses):
+ 	Rerecognize insns which are changed by this.
+ 
+ 	* i386.md (call_value): Don't return prematurely.
+ 
+ 	* alliant.md (movqi): Handle moving Aregs to mem and vice versa.
+ 	(bftst -> btst): Restrict to bitpos less than 8
+ 	so operand may be non-offsettable.
+ 	(nop): New pattern.
+ 	(return): Was disabled; now deleted.
+ 	* tm-alliant.h (PRINT_OPERAND_PUNCT_VALID_P): Define it.
+ 	* out-alliant.c (output_btst): Same change as in out-m68k.c
+ 
+ 	* alliant.md, out-alliant.c: Offsetable -> offsettable.
+ 
+ 	* c-parse.y (rule for stmt_exprs): Make the LET_STMT volatile. 
+ 
+ 	* c-decl.c (duplicate_decls): Don't save inline function data
+ 	from previous definition if a new *definition* is seen.
+ 
+ 	* integrate.c (access_parm_map): Handle subregs and constants.
+ 
+ 	* stmt.c (expand_return): Don't crash if DECL_RTL (DECL_RESULT()) is 0.
+ 
+ 	* tm-tahoe.h (LONGJMP_RESTORE_FROM_STACK): Define it.
+ 
+ 	* tm-mips.h (CONSTANT_P): Deleted; duplicates rtl.h.
+ 
+ Fri Jun  9 01:39:30 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* Makefile (float.h): Avoid using $(MAKE).
+ 
+ 	* Don't cram two things into STMT_BODY of a LET_STMT.
+ 	* tree.h (struct bind_stmt): New field, subblocks.
+ 	(STMT_SUBBLOCKS): New macro to access it.
+ 	* print-tree.c (walk): Print new field.
+ 	* tree.c (build_let_stmt): Store the old BODY arg into subblocks field.
+ 	* c-parse.y (stmt expr rule): Put rtl expr alone into body field.
+ 	* dbxout.c (dbxout_block): Recurse on subblocks, not body.
+ 	* sdbout.c, symout.c: Likewise.
+ 	* integrate.c (copy_decl_tree): Likewise.
+ 	* stmt.c (setjmp_protect, uninitialized_vars_warning): Likewise.
+ 	* expr.c (expand_expr): For LET_STMT, simply use its body.
+ 
+ 	* machmode.def: Add sixth arg to each entry.
+ 	* tree.h, rtl.h, rtl.c: Add arg to DEF_MACHMODE.
+ 	* rtl.h (GET_WIDER_MODE): New macro; table in rtl.c.
+ 	* expr.c (expand_expr): Use that for widening multiply.
+ 
+ 	* stmt.c (fixup_var_refs_1): When converting MEM to QImode for
+ 	bit field, adjust the address if possible to make bitpos
+ 	less than 8.
+ 	* m68k.md (bftst -> btst): Restrict to bitpos less than 8
+ 	so operand may be non-offsettable.
+ 
+ 	* cccp.c (do_line): Accept and pass on 3rd arg for enter or leave file.
+ 
+ 	* out-m68k.c (output_btst): Handle COUNT bigger than size of unit.
+ 
+ 	* cccp.c (CHECK_DEPTH): Macro to detect instack overflow.
+ 	(finclude, macroexpand, expand_to_temp_buffer): Use that.
+ 
+ 	* cccp.c (rescan): Don't check for disabled macro if traditional.
+ 	(macroexpand): Don't disable macro if traditional.
+ 
+ 	* sdbout.c (sdbout_one_type): Take out last change; assembler barfs.
+ 
+ 	* c-parse.y (maybe_attribute): Eliminate #-syntaxes.
+ 	Make ATTRIBUTE the name for __attribute.
+ 
+ 	* c-parse.gperf: Add __attribute{,__} and __signed{,__}.
+ 	* c-parse.y: Install results of that change.
+ 
+ 	* Fix bug in sizeof ({...}).
+ 	* c-decl.c (poplevel): Set TREE_USED.  Return the LET_STMT.
+ 	* c-parse.y (stmt-expr rule): Put the RTL_EXPR in the LET_STMT,
+ 	clear its TREE_USED, and use it as the result.
+ 	* expr.c (expand_expr): Allow LET_STMT as an expr.
+ 	Set its TREE_USED and expand the TREE_VALUE of its body.
+ 	* dbxout.c (dbxout_block): Ignore LET_STMT if TREE_USED not set.
+ 	* sdbout.c, symout.c: Likewise.
+ 
+ Thu Jun  8 00:06:36 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* c-parse.y (yylex): Extend ERANGE-inhibitor for 0.0
+ 	to 0.0e0 as well.
+ 
+ 	* flow.c (life_analysis): Prevent allocation of regs live at setjmp
+ 	on certain machines.  Controlled by LONGJMP_RESTORE_FROM_STACK.
+ 	Sets reg_live_length to -1.
+ 	* local-alloc.c (block_alloc): Be prepared for that.
+ 	* tm-vax.h (LONGJMP_RESTORE_FROM_STACK): Define it.
+ 
+ 	* gnulib2.c (all interfaces): Declare args and values as long long,
+ 	and split them using unions.
+ 
+ 	* loop.c (check_dbra_loop): Don't reverse loop if there are two
+ 	refs to varying addresses.  Consider foo[i] = foo[i-1].
+ 	(count_nonfixed_refs): Subroutine to count them.
+ 
+ 	* cexp.y: Distinguish signed and unsigned.
+ 	An integer value is now represented by a struct.
+ 	All rules for arithmetic changed.
+ 	(yylex): Adapt to change in yylval data type.
+ 
+ 	* limits.h (LONG_MIN): Make sure it's a signed long.
+ 
+ 	* sdbout.c (sdbout_one_type): Output types of fields first,
+ 	if they are structs.  Don't go through pointers.
+ 	(sdbout_field_types): Subroutine for that
+ 
+ Wed Jun  7 13:00:44 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* fixincludes: Switch to /usr/include before doing vuid_event.h.
+ 	Use $2 as output directory for sed.
+ 
+ 	* tm-i386.h (FUNCTION_PROFILER): Put counter address in %edx.
+ 	* tm-i386v.h (LIB_SPEC): Use -L/usr/lib/libp if profiling.
+ 
+ 	* expr.c (expand_increment): Typo testing for BImode component.
+ 
+ 	* convex changes from csmith:
+ 	* tm-convex.h: use EXTRA_SECTIONS to do .bss.
+ 	out-convex.c: set_section, align_section are now unused.
+ 	* convex.md: add pattern to pick an A-reg destination for sums
+ 	whose source involves a dedicated A reg (frame or arg pointer)
+ 	* convex.md: immediate and, or, xor instructions store a 32-bit
+ 	result.  Fix instructions that assumed it was 64.
+ 
+ 	* mips.md (probe): New pattern to create stack space.
+ 
+ 	* Makefile (float.h): Ignore errors from hard-params.
+ 	Specify ./ to run it.
+ 
+ Tue Jun  6 15:45:27 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* out-tahoe.c: Rename `offsetable' to `offsettable'.
+ 
+ 	* tahoe.md (nop): New pattern.
+ 
+ 	* i386.md (umul...): Constrain operand 1 as `0', not `a'.
+ 	`a' sometimes wanted two a-regs for operands 0 and 1.
+ 
+ 	* cccp.c: Forward-declare some structs.
+ 
+ 	* c-decl.c: Rearrange fcn fwd decls and struct decls.
+ 
+ 	* expr.c: Move some fcn fwd decls after structs their args use.
+ 	* genpeep.c, genextract.c: Likewise.
+ 
+ 	* loop.c: Forward-declare some structs.
+ 
+ 	* stmt.c: Move decls of structs before those of static functions.
+ 
+ 	* loop.c (strength_reduce): Delete extra arg to check_eliminate_biv.
+ 
+ 	* integrate.c (expand_inline_function): Supply missing arg
+ 	to convert_to_mode.
+ 
+ 	* gcc.c (handle_braces): Supply missing arg to do_spec_1.
+ 
+ 	* explow.c (lookup_static_chain): Accept a context arg.
+ 
+ 	* expmed.c (store_split_bit_field): Pass ALIGN arg
+ 	to extract_fixed_bit_field.
+ 
+ 	* expr.c (expand_assignment): Convert TYPE_ALIGN to bytes.
+ 	(store_constructor, expand_expr): Likewise.
+ 
+ 	* m68k.h: NO_ADDSUB_Q conditionals turn off all addq, subq insns.
+ 	(Fully supported only with MOTOROLA and HPUX_ASM flags.)
+ 
+ 	* jump.c (do_cross_jump): Don't die if LABEL is 0.
+ 
+ 	* tm-mips.h (PRINT_OPERAND_PUNCT_VALID_P): New macro.
+ 	* tm-iris.h: New file.  Unsplit lines accidentally split.
+ 
+ Mon Jun  5 15:39:30 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* integrate.c (output_inline_function): Call init_function_start,
+ 	not expand_function_start.
+ 	* emit-rtl.c (restore_reg_data): No need to init reg_rtx_no.
+ 
+ 	* stmt.c (init_function_start): Set current_function_returns_struct.
+ 
+ 	* rtlanal.c (reg_set_between_p): New fn analogous to reg_used_between_p
+ 	* loop.c (strength_reduce): Reject biv initial value which is altered
+ 	subsequently before actual loop start.
+ 
+ 	* rtlanal.c: New file split out from rtl.c.
+ 	Has things not used in the gen files.
+ 
+ 	* loop.c (strength_reduce): Reject biv initial value in a hard reg
+ 	clobbered by an intervening function call.
+ 
+ 	* tree.c (get_identifier): New flag needed to enable id-clash warnings.
+ 	(start_identifier_warnings): Set that flag.
+ 	* c-decl.c (init_decl_processing): Call that, after making built-ins.
+ 
+ Sat Jun  3 14:41:34 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* final.c (final_scan_insn): No basic block profiling at jump tables.
+ 
+ 	* stmt.c (expand_decl): Probe the stack to make pages exist.
+ 	* expr.c (expand_builtin): Likewise, for alloca.
+ 
+ 	* move-if-change: Specify /bin/sh.
+ 
+ 	* tm-ns32k.h (INDIRECTABLE_2_ADDRESS_P): Don't accept PLUS
+ 	with constant operands but not inside CONST.
+ 
+ 	* integrate.c (output_inline_function, save_for_inline):
+ 	Save stack_slot_list, and restore it for actual output.
+ 	* emit-rtl.c (gen_inline_header_rtx): New arg for this.
+ 
+ 	* emit-rtl.c (restore_reg_data): Initialize reg_rtx_no.
+ 	(restore_reg_data_1): Handle reg_rtx_no jumping past
+ 	reg_pointer_flag_length.
+ 
+ 	* reload1.c (alter_reg): Do nothing if regno_reg_rtx has 0.
+ 
+ 	* integrate.c (copy_rtx_and_substitute): Typos for stack parm
+ 	addresses in PLUS case.
+ 
+ 	* genoutput.c (gen_insn, gen_peephole): Make output_n fns static.
+ 	(output_prologue): Use new macro DEFAULT_MACHINE_INFO if defined.
+ 
+ 	* tree.h (enum machine_mode): Define MAX_MACHINE_MODE as in rtl.h.
+ 
+ Fri Jun  2 15:40:47 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* cccp.c (do_include): A file included via a system header file
+ 	counts as a system header file for -M.
+ 
+ 	* gnulib2.c: Support boolean ops and shifts.
+ 
+ 	* loop.c (emit_iv_inc): Use emit_iv_init_code.
+ 
+ 	* rtl.h (CONST0_RTX): Don't try to cast abort.
+ 
+     	* tm-news.h (PRINT_OPERAND_ADDRESS): Fix typo `reg_name'.
+ 	Delete two garbage lines.
+ 
+ 	* loop.c (eliminate_biv): Use emit_iv_init_code to compute comparison
+ 	value.  If value is constant, recognize the insn, and if that fails,
+ 	put the value in a register.  
+ 
+ Thu Jun  1 16:56:39 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* print-tree.c (dump): Don't die if rtx components are null.
+ 
+ 	* expmed.c (expand_mult_add): New fn to do A * X + B.
+ 	(make_tree): New subroutine.
+ 	* loop.c (emit_iv_init_code): Use that.  Much simpler now.
+ 
+ Tue May 30 17:20:40 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* fold-const.c (fold): Use TREE_SET_CODE to store in tree codes.
+ 
+ 	* tree.h (struct tree_common): Make `code' an unsigned int.
+ 	(TREE_CODE, TREE_SET_CODE): Put in casts.
+ 
+ 	* optabs.c (emit_cmp_insn): Supply all the args in recursive calls.
+ 
+ 	* toplev.c (report_error_function): Fix typo; METHOD_TYPE missing.
+ 
+ 	* fixincludes: Add code to make internal non-directory links.
+ 
+ Mon May 29 21:36:28 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* gcc.c (find_exec_file): Try both with and without machine_suffix.
+ 	(find_file): Use machine_suffix here too.
+ 
+ Sat May 27 00:02:26 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* reload.c (decompose): OFFSET wasn't initialized.
+ 
+ 	* cse.c (cse_main): Assign monotonic cuids.
+ 	(make_regs_eqv, CHEAPER): Use cuids, not uids.
+ 	(cse_end_of_basic_block): Return a cuid, not a uid.
+ 
+ 	* expr.c (expand_builtin): For BUILTIN_SAVEREGS, range of regs
+ 	moved included one extra previous insn.
+ 
+ 	* emit-rtl.c (emit_line_note): Don't check -g here.
+ 	(emit_note): For line number when no -g, increment cur_insn_uid anyway.
+ 	* stmt.c (expand_start_case): Always output a NOTE_INSN_DELETED.
+ 
+ 	* loop.c (loop_optimize): Don't count line-number NOTEs for luids.
+ 	Prevents -g from affecting optimization decisions.
+ 
+ Fri May 26 17:31:15 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* local-alloc.c (block_alloc): Don't count notes in insn_number.
+ 	Prevents -g from affecting order of allocation.
+ 
+ Thu May 25 14:12:19 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* local-alloc.c (block_alloc): Clear full length of regs_live_at.
+ 
+ 	* ns32k.md (cmpsi): Make this the first cmp pattern.
+ 
+ 	* jump.c (do_cross_jump): Skip NOTEs while checking for existing label.
+ 
+ 	* cse.c (cse_insn): When no-oping a jump, decrement use count of label.
+ 	(cse_basic_block): If label use count is 0, go past it.
+ 
+ 	* integrate.c (access_parm_map): New fn, broken out of
+ 	copy_rtx_and_substitute, handles case of mem ref to stack arg.
+ 	(copy_rtx_and_substitute): Call it.
+ 	Also use it for address of a stack arg.
+ 
+ 	* gen*.c (fatal): Declare 1st arg as string.
+ 
+ Wed May 24 00:13:36 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* optabs.c (init_optabs): Handle movdi and movdf insns.
+ 
+ 	* final.c (end_final): Realign locn ctr after outputting string.
+ 
+ 	* tm-sparc.h (LINK_SPEC): Link bb_link.o before standard lib.
+ 
+ 	* tm-sun386i.h (LINK_SPEC): Accept and ignore -sun386.
+ 
+ 	* gcc.c (find_exec_file): Use machine_suffix.
+ 	(process_command): Set that for -b option.
+ 
+ 	* integrate.c (function_cannot_inline_p): No size limit
+ 	for functions declared inline.
+ 
+ 	* loop.c (skip_consec_insns): New fn, skip several insns or libcalls.
+ 	(force_movables): New fn, part of scan_loop broken out.
+ 	(ignore_some_movables): New fn, ignore a movable whose insn
+ 	is within another movable's libcall.
+ 	(scan_loop): Call those three.
+ 	Don't handle m->consec for zero-extend movables, since always 0.
+ 
+ Tue May 23 12:58:24 1989  Joe Weening  (weening at gang-of-four.stanford.edu)
+ 
+ 	* config/alliant.md:
+ 	Removed operand classes 'x', 'y', 'G', 'H'.
+ 	Added "%." to many opcodes to simplify comparison with m68k.md.
+ 	Changed TARGET_68881 to TARGET_CE.
+ 	Changed floating-point insns to better describe the Alliant CE.
+ 	Most args to floating-point insns are now nonimmediate_operand.
+ 	Removed special insns for pushing doublewords onto stack.
+ 	Added non-CE versions of movsf and movdf to avoid using FP
+ 	registers in this case.
+ 	(float*i*f2): Don't allow immediate ops.
+ 	(sne): Fix typo, fsne => fsneq.
+ 	(call, call_value): Changed to always pop args from stack
+ 	upon return; this gives better code than before and conforms
+ 	to Alliant calling standard.
+ 	Incorporated some recent changes to m68k.md.
+ 
+ 	* config/out-alliant.c:
+ 	(regno_reg_class): Removed FPA reg classes.
+ 	(output_move_const_double): Function not needed, removed.
+ 
+ 	* config/tm-alliant.h:
+ 	Removed FPA registers and reg classes.
+ 	Target flags: changed TARGET_68881 to TARGET_CE, removed
+ 	TARGET_RTD, TARGET_REGPARM, TARGET_FPA.
+ 	Removed TARGET_CE test in several places since we need to
+ 	use FP regs even for non-CE programs.
+ 	(TARGET_VERSION, CPP_SPEC): Define for Alliant.
+ 	(CONDITIONAL_REGISTER_USAGE): Removed, not needed.
+ 	(FRAME_POINTER_REQUIRED): Defined.
+ 	(RETURN_POPS_ARGS): Defined.
+ 	(FUNCTION_VALUE, LIBCALL_VALUE, FUNCTION_VALUE_REGNO_P):
+ 	Use fp0 to return floating-point values.
+ 	(FUNCTION_ARG): Remove TARGET_REGPARM code.
+ 	(FUNCTION_ARG_PARTIAL_NREGS): Always 0.
+ 	(FUNCTION_PROFILER): Define for Alliant.
+ 	(FUNCTION_EPILOGUE): Remove use of rtd instruction.
+ 	Renamed CC_IN_68881 to CC_IN_FP.
+ 	(NOTICE_UPDATE_CC): Incorporate changes that were made
+ 	in tm-m68k.h.
+ 
+ 	* config/xm-alliant.h (LINK_SPEC): Pass -X to linker.
+ 
+ Tue May 23 12:58:24 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* sdbout.c: Don't include c-tree.h.
+ 
+ 	* tree.c (build_index_type): Use sizetype for min and max values.
+ 	Convert maxval rather than clobbering it.
+ 
+ 	* tm-hp9k320.h: Finish unterminated comment.
+ 
+ 	* sdbout.c (sdbout_parms): Use gen_fake_label for anonymous parm.
+ 
+ Sun May 21 12:58:06 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* stmt.c (aggregate_value_p): New fn says whether expression is a type
+ 	that functions cannot return as a scalar.
+ 	(assign_parms, expand_function_start): Use that.
+ 	* expr.c (expand_call): Likewise.
+ 
+ 	* gcc.c (delete_failure_queue): New subroutine.
+ 	(delete_temp_files): No longer delete the failure queue.
+ 	(main): Delete failure queue after each failing compilation.
+ 
+ Sat May 20 13:16:23 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* varasm.c (force_const_mem): New optional macro SELECT_RTX_SECTION.
+ 
+ 	* mips.md: Change %u0 to %:.
+ 	(movsi): Add constraint alternative accepting address arg.
+ 
+ 	* fold-const.c (mul_double): Special case for 2nd arg 2, 4, 8.
+ 	(combine): Special case shortcuts for plus, minus, mult, div.
+ 
+ 	* stmt.c (expand_function_start): Simplify hairy statement for 3B1.
+ 	* expr.c (expand_call): Likewise.
+ 
+ 	* math-68881.h: New file.
+ 
+ 	* m68k.md (movqi): Handle moving aregs to mem and vice versa.
+ 
+ 	* dbxout.c (dbxout_type): Don't test use_gdb_dbx_extensions
+ 	in cases that occur in C.
+ 
+ 	* stmt.c (expand_function_{start,end}): Make DECL_RESULT's rtl 0
+ 	when function returns no value.
+ 
+ 	* tree.c (build_decl): Initialize DECL_PRINT_NAME, DECL_ASSEMBLER_NAME.
+ 
+ 	* c-decl.c (store_parm_decls): Call init_function_start.
+ 
+ Thu May 18 00:41:37 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* stmt.c (expand_null_return_1): New arg USE_GOTO says jump to
+ 	return_label even if could otherwise use a return insn.
+ 	Make a return_label if we need one and don't have one already.
+ 	If have parm cleanups, always jump to cleanup_label.
+ 	(expand_null_return): Pass 1 for USE_GOTO if cleanups pending.
+ 	(expand_return): Set LAST_INSN if have local cleanups or parm cleanups.
+ 	Use that if jumping to tail-recursion label.
+ 	Optimization for returning a comparison is safe for local cleanups
+ 	but don't do it if there are parm cleanups.
+ 	Calling expand_null_return_1, pass 1 for USE_GOTO if local cleanups.
+ 	(this_contour_has_cleanups_p): New function.
+ 
+ 	* stmt.c (init_function_start): New function, beginning of
+ 	expand_function_start broken out.
+ 	Use DECL_PRINT_NAME to get function's name.
+ 	(expand_function_start): Now two args, function and PARMS_HAVE_CLEANUPS
+ 	Compute RETURN_LABEL sooner; make one if parm cleanups.
+ 	If parms have cleanups, put scalar return value in pseudo-reg.
+ 	Don't mark that pseudo with REG_FUNCTION_VALUE_P.
+ 	(expand_function_end): Simplify decisions about output of return_label
+ 	and return insn.
+ 	If DECL_RESULT is pseudo-reg, copy it to real return reg.
+ 
+ 	* stmt.c (expand_function_end): Handle ordinary struct values
+ 	like pcc, but only if unoptimized.
+ 	(expand_function_start): Make a return_label for ordinary struct value.
+ 
+ 	* stor-layout.c (layout_type): Handle METHOD_TYPE like FUNCTION_TYPE.
+ 	(layout_decl): Allow TYPE_DECL.
+ 
+ 	* stor-layout.c (layout_basetypes): Code for basetypes broken
+ 	out of layout_record.  Sets the type size tentatively.
+ 	(layout_record): Start with that tentative size.
+ 	Also, don't do anything with CONST_DECL members.
+ 
+ 	* stor-layout.c (layout_union): Simpler error report for static memb.
+ 
+ 	* reload1.c (eliminate_frame_pointer): Reduce PUSH_ROUNDING
+ 	conditional to apply only to push instructions.
+ 
+ 	* expr.c (expand_call): Fix stupid errors handling MAX_PARM_BOUNDARY.
+ 	* stmt.c (assign_parms): Likewise.
+ 
+ 	* toplev.c (announce_function, report_error_function):
+ 	(error_with_decl, warning_with_decl): Use DECL_PRINT_NAME.
+ 
+ 	* toplev.c (compile_file): Subtract integration_time from parse_time.
+ 
+ 	* toplev.c (compile_file): Don't output read-only static variables
+ 	at end of compilation if address was not used.
+ 
+ 	* toplev.c (rest_of_compilation): Handle flag_syntax_only.
+ 
+ 	* toplev.c (main): Handle -g0 and -G0 options.
+ 	For -g and -G, set use_gdb_dbx_extensions.
+ 
+ 	* toplev.c (main): Set `progname'.
+ 	(pfatal_with_name, fatal_io_error, {error,warning}_with_file_and_line):
+ 	(sorry): Print value of `progname', not "cc1".
+ 
+ 	* tree.def: Delete FRIEND_DECL.  Add PUSH_EXPR and POP_EXPR.
+ 
+ 	* tree.c (simple_cst_equal): Handle INDIRECT_REF.
+ 
+ 	* tree.c (lvalue_p): Handle METHOD_TYPE.  Handle NEW_EXPR.
+ 
+ 	* tree.c (copy_list): New function.
+ 
+ 	* tree.h (struct tree_decl): New fields print_name and assembler_name.
+ 	(DECL_PRINT_NAME, DECL_ASSEMBLER_NAME): New accessors.
+ 
+ 	* c-decl.c (LONG_DOUBLE_TYPE_SIZE): New compilation parameter.
+ 
+ Wed May 17 22:07:17 1989  Randall Smith  (randy at apple-gunkies.ai.mit.edu)
+ 
+ 	* dbranch.c (emit_delay_sequence): Reset insn code to -1 when
+ 	turning insn into a sequence so that it won't think that it matches
+ 	something in the md file.
+ 
+ 	* dbranch.c (insn_eligible_p): Call refers_to_regno_p with a
+ 	non-zero range.
+ 
+ 	* dbranch.c (pnote): Modified to make sure instruction clobbered
+ 	register is a set, rather than, say, a clobber.
+ 
+ Wed May 17 14:01:20 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* sdbout.c (sdbout_parms): Handle parm with no name.
+ 
+ 	* loop.c (combine_movables): Test for overlap of zero-extend regs
+ 	was screwed up.
+ 
+ 	* c-typeck.c (c_sizeof{,_nowarn}): Convert from bytes to chars,
+ 	since c defines sizeof (char) as 1.
+ 	(pointer_int_sum, pointer_diff): Use c_sizeof{,_nowarn}. 
+ 
+ Tue May 16 16:27:32 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* reload1.c (choose_reload_targets): Don't reuse regs
+ 	mentioned in reload_reg_rtx.
+ 
+ 	* tm-tahoe.h, tahoe.md, out-tahoe.c, xm-tahoe.h: New files.
+ 
+ Mon May 15 16:25:12 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* fixincludes: Exit with explicit status 0 at end.
+ 	cd to /usr/include before cd to subtree root in case of relative link.
+ 	Create dir $LIB earlier.
+ 	When checking for a link, treat .. like an absolute target.
+ 
+ 	* symout.c (symout_block_symbols): Give every local decl a typespec.
+ 	* cexp.y (parse_number):
+ 	* flow.c (life_analysis, dump_flow_info):
+ 
+ 	* loop.c (consec_sets_invariant_p): Logic error accepted consec sets
+ 	of which only one was invariant.
+ 
+ 	* expr.c (expand_expr): Use no subtargets inside loops.
+ 	* stmt.c (inside_loop): New function.
+ 
+ Sun May 14 00:11:07 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* tree.h: Declare long long types.
+ 
+ 	* c-parse.y (combine_strings): Make string contents saveable.
+ 
+ 	* tree.c (savealloc): New function.
+ 
+ 	* m68k.md (movdi): % missing in fmove%.d.
+ 
+ 	* c-parse.y (yylex): Detect overflow past 64-bits.
+ 	Detect specially numbers not fitting in signed long long.
+ 
+ Sat May 13 13:16:05 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* reload1.c (alter_frame_pointer_addresses): Preserve volatility.
+ 
+ 	* varasm.c (output_constructor): Die if BITS_PER_UNIT is too big
+ 	for this function to work.
+ 
+ 	* genpeep.c (match_rtx): For match_operator, match the operands, too.
+ 
+ 	* varasm.c (output_constant): Use ASM_OUTPUT_DOUBLE_INT for DImode.
+ 
+ 	* stor-layout.c (make_signed_type, make_unsigned_type):
+ 	(fixup_unsigned_type): Use HOST_BITS_PER_INT.
+ 
+ 	* stor-layout.c (layout_type): Use TFmode if appro.
+ 
+ 	* optabs.c (emit_cmp_insn): Use mode sizes to check cmpstrqi, cmpstrhi.
+ 
+ 	* c-typeck.c (get_floating_type): Compare MODE against modes of types.
+ 	(signed_type, unsigned_type, signed_or_unsigned_type, type_for_size):
+ 	Handle long long types.
+ 	(digest_init): Don't assume width of `char' is BITS_PER_UNIT.
+ 
+ 	* c-parse.y (yylex): For truncating chars, use width of `char' type.
+ 	Allow `ll' in int constants and make long long.
+ 	Also make long long if constant won't fit in an int.
+ 
+ 	* c-decl.c (SHORT_TYPE_SIZE): Round up when dividing.
+ 
+ Fri May 12 22:36:21 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* real.h: Allow multiple inclusion.
+ 
+ 	* tm-sun386i.h (DBX_REGISTER_NUMBER): Bizarre renumbering.
+ 
+ Thu May 11 00:36:21 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* fixincludes: Fix non-ansi declaration of sprintf in X11/Xmu.h
+ 
+ 	* c-parse.y (stmt from expr): Do default conversion if useful
+ 	for sake of ({...}).
+ 
+ 	* sparc.md (andcc recognizer): Operand missing in subreg.
+ 
+ Wed May 10 17:20:38 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* rtl.c (read_name): Error if name is missing.
+ 	(dump_and_abort): Don't print char args if -1.
+ 
+ 	* i386.md (umulqihi3): Operand numbers were missing.
+ 
+ 	* reload1.c (choose_reload_targets): Allow spill reg in find_equiv_reg
+ 	if it's free and correct class. 
+ 
+ 	* cse.c (canon_hash): Handle empty strings.
+ 
+ 	* cccp.c (macroexpand): Newline newline treated like real white space
+ 	when stringifying.
+ 
+ 	* Rename *offsetable* to *offsettable*.
+ 
+ Tue May  9 22:54:58 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* c-decl.c (finish_type): Layout any variants of the type.
+ 
+ Tue May  9 12:30:28 1989  Randall Smith  (randy at apple-gunkies.ai.mit.edu)
+ 
+ 	* final.c (final_scan_insn, final): Added an argument to
+ 	final_scan_insn to disallow peephole processing (to turn it off
+ 	during delayed branch scheduling).
+ 
+ 	* final.c (final_scan_insn): Made insn not matching any MD rtl a
+ 	criteria for delayed branch case.  Moved delayed branch case to just
+ 	before real insn recognition to reduce the number of insns on which
+ 	recog_memoized is called.
+ 
+ Mon May  8 15:02:42 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* fixincludes (LIB): Allow overriding.
+ 
+ 	* cccp.c: Don't search /usr/include/CC by default.
+ 
+ Mon May  8 13:09:21 1989  Randall Smith  (randy at apple-gunkies.ai.mit.edu)
+ 
+ 	* print-tree.c (dump): Fixed typo; IDENTIFIER ==> IDENTIFIER_NODE.
+ 
+ Sun May  7 12:44:53 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* print-tree.c (dump): TYPE_NAME may be IDENTIFIER or TYPE_DECL.
+ 
+ Sat May  6 00:13:47 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* tree.def: Define EXACT_DIV_EXPR, for when remainder known as 0.
+ 	* fold-const.c (combine, fold, div_and_round_double): Handle new code.
+ 	* expr.c (expand_expr): Likewise.
+ 	* c-typeck.c (pointer_diff): Use EXACT_DIV_EXPR.
+ 
+ 	* integrate.c (expand_inline_function): Use size of passed type
+ 	for allocating stack slot with that type.
+ 
+ 	* c-parse.y (maybe_attribute, attribute*): New syntax for Apollos.
+ 	These tokens currently not generated.
+ 
+ Fri May  5 18:43:01 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* toplev.c [USG]: Undefine FLOAT for sake of sys/param.h on hpux.
+ 
+ 	* optabs.c (expand_binop): If backtracking, don't delete insns made
+ 	for -fforce-mem.
+ 
+ Thu May  4 01:57:23 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* reload.c (find_reloads): Don't compare an earlyclobber operand
+ 	with itself.
+ 
+ 	* reload.c (immune_p): Constants and stack slots don't overlap.
+ 
+ 	* Put no-ops in front of loops and labels,
+ 	to prevent confusion in the debugger.
+ 	* c-parse.y (loops and labels): Call emit_nop.
+ 	* stmt.c (emit_nop): New function--sometimes emit a no-op.
+ 	* *.md (nop): New insn.
+ 
+ 	* expr.c (expand_call): Typo in arg to FIRST_PARM_CALLER_OFFSET.
+ 
+ Wed May  3 01:34:58 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* loop.c (scan_loop): Scanning around end of loop
+ 	should not set maybe_never.
+ 
+ 	* Rename SELECT_VARIABLE_SECTION to SELECT_SECTION.
+ 	* varasm.c (get_or_assign_label): Use SELECT_SECTION if defined.
+ 	* varasm.c: Use EXTRA_SECTION_FUNCTIONS if defined (new macro).
+ 
+ 	* mips.md: Change %u to %u0 to avoid error check.
+ 
+ 	* tm-mips.h (TARGET_VERSNUM): Inc. to 1 08.
+ 	(TARGET_VERSION): Change strings.
+ 	(AL_DEBUG): Don't define it.
+ 	(HARD_REGNO_MODE_OK): Add some casts to int.
+ 	(STACK_ARGS_ADJUST): Name was misspelled.
+ 	(PRINT_OPERAND_ADDRESS): Just abort for MEM, POST_INC, etc.
+ 	(EXTRA_SECTIONS, SELECT_VARIABLE_SECTION, SELECTORS_EXTRA_SECTIONS,
+ 	SELECT_VARIABLE_CONST_SECTION): New macros.
+ 	(ASM_FILE_END): Change function name.
+ 	* out-mips.c (function_arg_advance): Delete debugging printfs.
+ 	(function_inarg, function_arg): Likewise.
+ 	(compare_collect, compare_restore): Add some.
+ 
+ 	* reload1.c (reload): Fix handling of caller_save_needed.
+ 
+ 	* stmt.c (expand_function_start): Clear caller_save_needed.
+ 
+ 	* stmt.c (emit_case_nodes): Some compiler has trouble with calling
+ 	a function pointer.
+ 	* gnulib.c: likewise.
+ 
+ Tue May  2 15:32:25 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* loop.c (combine_movables): For zero extend,
+ 	do each from-mode separately.
+ 
+ Mon May  1 00:18:47 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* tm-apollo68.h: New file.
+ 
+ 	* c-parse.y (is_reserved_word, hash): Add keywords `__asm__', etc.
+ 	* c-parse.gperf: Corresponding changes.
+ 
+ 	* c-parse.y (check_newline): Set main_input_filename before
+ 	considering optional arguments.
+ 
+ 	* final.c (final_scan_function): Return next insn to process.
+ 	Usually that's the following insn; occasionally, previous compare.
+ 
+ 	* c-decl.c (DOUBLE_TYPE_SIZE): Wrong value.
+ 
+ 	* reload.c (decompose): Failed to return value.
+ 
+ 	* Support local specified-register variables.
+ 	* varasm.c (decode_reg_name): New function, cvt asmspec to regnum.
+ 	(make_decl_rtl): Call that.
+ 	* toplev.c (rest_of_decl_compilation): Handle local specified-register
+ 	declarations.
+ 
+ 	* i386.md (tstqi, trunc*qi): Constrain to `q' regs.
+ 
+ 	* loop.c (scan_loop, move_movables): ->global for zero-extend register
+ 	now means register is used outside range from where it is set
+ 	to the following label.  Non-global zero-extend regs
+ 	may be entirely cleared.
+ 
+ 	* loop.c (combine_movables): Loop that combines matching movables
+ 	broken out from scan_loop.
+ 	Now also combine non-global zero-extend registers with each other
+ 	if their lifespans don't overlap.
+ 
+ 	* c-typeck.c (build_unary_op, ADDR_EXPR of a COMPONENT_REF):
+ 	Always convert to desired result type.
+ 
+ Sun Apr 30 12:58:58 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* c-decl.c (init_decl_processing): New macros parameterize int types.
+ 	CHAR_TYPE_SIZE, SHORT_TYPE_SIZE, LONG_TYPE_SIZE, LONG_LONG_TYPE_SIZE,
+ 	FLOAT_TYPE_SIZE, DOUBLE_TYPE_SIZE.
+ 
+ 	* fixincludes: Use sed instead of ex.  No problem with split lines.
+ 
+ 	* print-tree.c (dump): Print type's name, if any.
+ 
+ 	* c-parse.y: Use __inline, not plain inline.
+ 
+ 	* toplev.c: New option -fdelayed-branch.
+ 	(compile_file): Open and close dbranch dump file.
+ 	Collect and print dbranch time.
+ 	(rest_of_compilation): Optionally do dbranch scheduling, 
+ 	only if HAVE_DELAYED_BRANCH.
+ 	(main): Handle -dd.
+ 
+ 	* rtl.c (copy_rtx): Handle null pointers as code `e'.
+ 
+ 	* final.c (dbr_sequence_length): New function.
+ 	(final_scan_insn): Most of `final' broken out.
+ 	Add support for SEQUENCE insns.
+ 	last_ignored_compare and new_block now top-level static.
+ 
+ 	* c-parse.y (MAX_WORD_LENGTH): Long enough for __volatile.
+ 
+ Sat Apr 29 13:03:20 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* c-parse.y (asm statements): Output line numbers.
+ 
+ 	* loop.c (emit_iv_init_code, emit_iv_inc, eliminate_biv): Copy
+ 	additive term rtx's to prevent sharing between insns.
+ 
+ 	* c-parse.y (check_newline): Increment input_file_stack_tick.
+ 	* toplev.c (report_error_function): Describe input stack only if
+ 	changed.
+ 
+ 	* c-decl.c (finish_struct): Reject zero width for named field.
+ 
+ 	* tm-sun3.h (CC1_SPEC): Prevent error on `-sun3'.
+ 	* tm-sparc.h (CC1_SPEC): Prevent error on `-sun4'.
+ 
+ 	* Makefile (cleanconfig): cleanlinks renamed; also delete gnulib.
+ 	(gnulib): Delete stamp-gnulib2 since gnulib2 should be redone after.
+ 
+ Fri Apr 28 00:38:32 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* config.gcc (genix): Correct xm file name.
+ 
+ 	* tm-genix.h: Undefine ASM_SPEC inherited from tm-encore.h.
+ 
+ 	* Makefile: Make float.h using hard-params.
+ 	(clean): Delete float.h.
+ 
+ 	* hard-params.c: New program.
+ 
+ 	* varasm.c (assemble_variable): Use SELECT_VARIABLE_SECTION if defined.
+ 	(in_section): Use EXTRA_SECTIONS if defined.
+ 
+ 	* toplev.c (compile_file): Call ASM_FILE_END if defined.
+ 
+ 	* gcc.c (SWITCH_TAKES_ARG, WORD_SWITCH_TAKES_ARG): Let config override.
+ 
+ 	* loop.c (emit_iv_init_code): Force A to a reg if it isn't.
+ 
+ Thu Apr 27 12:51:14 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* tm-mips.h (ASM_START_FILES): Don't call print_options.
+ 	Don't call the funny abort-functions.
+ 	* out-mips.c: Delete funny debugging functions and aborts.
+ 	(print_options): #if 0.
+ 	(compare_restore): Test for COMPARE, not MINUS.
+ 	(mips_section_get, mips_output_external, mips_asm_final): New fns.
+ 
+ 	* input.h: New file with *input_filename, lineno and input_file_stack.
+ 	Included in toplev.c and c-parse.y.
+ 	* c-decl.c (finish_function): LINENO is now arg.
+ 	* c-parse.y: Calls changed.
+ 
+ 	* c-parse.y (check_newline): Handle `1' or `2' from cpp
+ 	by pushing or popping input_file_stack.
+ 	* toplev.c (compile_file): Push main input file on input_file_stack.
+ 	(report_error_function): If in include file, print the chain
+ 	of include-locations.
+ 
+ 	* cccp.c (output_line_command): New arg says whether entering or
+ 	leaving a file.  Output `1' or `2' on #-line if so.  Callers changed.
+ 
+ 	* gnulib2.c: Little-endian fixes from csmith@convex.com.
+ 
+ 	* fixincludes: Wrong quoting in `echo' command.
+ 
+ 	* tm-mips.h (REG_P): Duplicate defn deleted.
+ 	(PRINT_OPERAND): `\' was missing.
+ 
  Wed Apr 26 02:44:59 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
+ 
+ 	* cccp.c (handle_directive): Preprocess even #pragma, but copy 
+ 	to output file afterward.
+ 	(do_pragma): Use standard calling convention.
+ 	(install_builtins, special_symbol): Define __INCLUDE_LEVEL__.
+ 
+ 	* cccp.c (do_include): Don't forget to close file.
+ 
+ 	* final.c (output_asm_insn): Use PRINT_OPERAND_PUNCT_VALID_P
+ 	to validate punctuation after percent.
+ 	* tm-m68k.h, tm-alliant.h, tm-ns32k.h, tm-vax.h, tm-i386.h:
+ 	Define PRINT_OPERAND_PUNCT_VALID_P.
  
  	* Version 1.35 released.
diff -rc2N gcc-1.35/INSTALL gcc-1.36/INSTALL
*** gcc-1.35/INSTALL	Mon Apr 24 02:48:16 1989
--- gcc-1.36/INSTALL	Sun Sep 24 08:52:29 1989
***************
*** 14,17 ****
--- 14,20 ----
  * Menu:
  
+ * Other Dir::     Compiling in a separate directory (not where the source is).
+ * Sun Install::   See below for installation on the Sun.
+ * 3B1 Install::   See below for installation on the 3B1.
  * VMS Install::   See below for installation on VMS.
  
***************
*** 23,28 ****
  
    3. Choose configuration files.  The easy way to do this is to run
!      the command file `config.gcc' with a single argument, which is
!      the name of the machine (and operating system, in some cases).
  
       Here is a list of the possible arguments:
--- 26,32 ----
  
    3. Choose configuration files.  The easy way to do this is to run
!      the command file `config.gcc' with a single argument, which
!      specifies the type of machine (and in some cases which operating
!      system).
  
       Here is a list of the possible arguments:
***************
*** 47,50 ****
--- 51,57 ----
            Sequent with Intel 386 processors.
  
+     `i386-aix'
+           Intel 386 PCs or PS/2s running AIX.
+ 
      `sun2'
            Sun 2 running system version 2 or 3.
***************
*** 51,60 ****
  
      `sun3'
!           Sun 3 running system version 2 or 3, with 68881.
! 
!           Note there we do not provide a configuration file to use an
!           FPA by default because programs that establish signal
!           handlers for floating point traps inherently cannot work
!           with the FPA.
  
      `sun3-nfp'
--- 58,65 ----
  
      `sun3'
!           Sun 3 running system version 2 or 3, with 68881.  Note
!           there we do not provide a configuration file to use an FPA
!           by default, because programs that establish signal handlers
!           for floating point traps inherently cannot work with the FPA.
  
      `sun3-nfp'
***************
*** 62,66 ****
  
      `sun4'
!           Sun 4 running system version 2 or 3.
  
      `sun2-os4'
--- 67,73 ----
  
      `sun4'
!           Sun 4 running system version 2 or 3.  *Note
!           Incompatibilities::, for calling convention
!           incompatibilities on the Sun 4 (sparc).
  
      `sun2-os4'
***************
*** 74,78 ****
  
      `sun4-os4'
!           Sun 4 running system version 4.
  
      `sun386'
--- 81,87 ----
  
      `sun4-os4'
!           Sun 4 running system version 4.  *Note Incompatibilities::,
!           for calling convention incompatibilities on the Sun 4
!           (sparc).
  
      `sun386'
***************
*** 80,94 ****
  
      `alliant'
!           Alliant FX/8 computer.  Currently, there are bugs in the
!           support for floating point.  Also note that Alliant's
!           version of dbx does not manage to work with the output from
!           GNU CC.
  
      `mips'
!           Some variant of MIPS computer (but not the one from DEC). 
!           Note that this machine description was written for GNU CC
!           version 1.32 and may require some updating to work with the
!           current version.
  
      `convex-c1'
            Convex C1 computer.
--- 89,138 ----
  
      `alliant'
!           Alliant FX/8 computer.  Note that the standard installed C
!           compiler in Concentrix 5.0 has a bug which prevent it from
!           compiling GNU CC correctly.  You can patch the compiler bug
!           as follows:
! 
!                cp /bin/pcc ./pcc
!                adb -w ./pcc - << 'EOF'
!                15f6?w 6610
!                EOF
! 
!           Then you must use the `-ip12' option when compiling GNU CC
!           with the patched compiler, as shown here:
! 
!                make CC="./pcc -ip12" CFLAGS=-w
! 
!           Note also that Alliant's version of DBX does not manage to
!           work with the output from GNU CC.
! 
!     `tahoe'
!           The tahoe computer (running BSD, and using DBX).
! 
!     `decstation'
!           The DEC 3100 Mips machine (``pmax'').  Note that GNU CC
!           cannot generate debugging information in the unusual format
!           used on the Mips.
! 
!     `mips-sysv'
!           The Mips computer, RS series, with the System V environment
!           as default.  Note that GNU CC cannot generate debugging
!           information in the unusual format used on the Mips.
! 
!     `mips-bsd43'
!           The Mips computer, RS series, with the BSD 4.3 environment
!           as default.  Note that GNU CC cannot generate debugging
!           information in the unusual format used on the Mips.
  
      `mips'
!           The Mips computer, M series.  Note that GNU CC cannot
!           generate debugging information in the unusual format used
!           on the Mips.
  
+     `iris'
+           The Mips computer, as delivered by Iris.  Note that GNU CC
+           cannot generate debugging information in the unusual format
+           used on the Mips.
+ 
      `convex-c1'
            Convex C1 computer.
***************
*** 97,100 ****
--- 141,147 ----
            Convex C2 computer.
  
+     `pyramid'
+           Pyramid computer.
+ 
      `hp9k320'
            HP 9000 series 300 using HPUX assembler.  Note there is no
***************
*** 102,106 ****
            available in this configuration.
  
!     `hp9k320g'
            HP 9000 series 300 using GNU assembler, linker and debugger.
            This requires the HP-adapt package, which is available
--- 149,153 ----
            available in this configuration.
  
!     `hp9k320-gas'
            HP 9000 series 300 using GNU assembler, linker and debugger.
            This requires the HP-adapt package, which is available
***************
*** 108,113 ****
            distribution.  This is on the GNU CC distribution tape.
  
      `isi68'
!           ISI 68000 or 68020 system.
  
      `news800'
--- 155,172 ----
            distribution.  This is on the GNU CC distribution tape.
  
+     `hp9k320-old'
+           HP 9000 series 300 using HPUX assembler, in operating
+           system versions older than 6.5.  Note there is no support
+           in GNU CC for HP's debugger; thus, `-g' is not available in
+           this configuration.
+ 
+     `hp9k320-bsd'
+           HP 9000 series 300 running BSD.
+ 
      `isi68'
!           ISI 68000 or 68020 system with a 68881.
! 
!     `isi68-nfp'
!           ISI 68000 or 68020 system without a 68881.
  
      `news800'
***************
*** 123,131 ****
  
      `3b1'
!           AT&T 3b1, a.k.a. 7300 PC.  Note that the current version of
!           GNU CC cannot be compiled with the Unix compiler on this
!           machine, due to bugs in the Unix comiler.  GNU CC does work
!           correctly, however, if you can compile it with older
!           version of GNU CC or cross-compile it.
  
      `sequent-ns32k'
--- 182,190 ----
  
      `3b1'
!           AT&T 3b1, a.k.a. 7300 PC.  Note that special procedures are
!           needed to compile GNU CC with this machine's standard C
!           compiler, due to bugs in that compiler.  *Note 3b1
!           Install::.  You can bootstrap it more easily with previous
!           versions of GNU CC if you have them.
  
      `sequent-ns32k'
***************
*** 160,168 ****
                 for Intel 80386's running system V.
  
-          `xm-sunos4.h'
-                for Suns (model 2, 3 or 4) running *operating system*
-                version 4.  (Use `xm-m68k.h' or `xm-sparc.h' for
-                version 3.)
- 
           `xm-sun386i.h'
                 for Sun roadrunner running any version of the
--- 219,222 ----
***************
*** 193,196 ****
--- 247,257 ----
                 for Sun 3 machines with no hardware floating point.
  
+          `tm-sun3os3.h'
+                for Sun 3 machines with 68881, running Sunos version 3.
+ 
+          `tm-sun3os3nf.h'
+                for Sun 3 machines with no hardware floating point,
+                running Sunos version 3.
+ 
           `tm-sun2.h'
                 for Sun 2 machines.
***************
*** 203,208 ****
                 you use the GNU assembler.
  
           `tm-news800.h'
!                for SONY News systems.
  
           `tm-hp9k320.h'
--- 264,273 ----
                 you use the GNU assembler.
  
+          `tm-isi68-nfp.h'
+                for Integrated Solutions systems without a 68881. 
+                This file assumes you use the GNU assembler.
+ 
           `tm-news800.h'
!                for Sony NEWS systems.
  
           `tm-hp9k320.h'
***************
*** 232,235 ****
--- 297,306 ----
            `tm-sun386i.h' for a Sun 386 system.
  
+           For the Mips computer, there are five choices: `tm-mips.h'
+           for the M series, `tm-mips-bsd.h' for the RS series with
+           BSD, `tm-mips-sysv.h' for the RS series with System V,
+           `tm-iris.h' for the Iris version of the machine, and
+           `tm-decstatn.h' for the Decstation.
+ 
            For the 32000, use `tm-sequent.h' if you are using a
            Sequent machine, or `tm-encore.h' for an Encore machine, or
***************
*** 264,274 ****
       output for `c-parse.tab.c'.
  
!   5. If you are using a Sun, make sure the environment variable
!      `FLOAT_OPTION' is not set.  If this option were set to `f68881'
!      when `gnulib' is compiled, the resulting code would demand to be
!      linked with a special startup file and will not link properly
!      without special pains.
! 
!   6. Build the compiler.  Just type `make' in the compiler directory.
  
       Ignore any warnings you may see about ``statement not reached''
--- 335,339 ----
       output for `c-parse.tab.c'.
  
!   5. Build the compiler.  Just type `make' in the compiler directory.
  
       Ignore any warnings you may see about ``statement not reached''
***************
*** 278,282 ****
       Bugs::.).
  
!   7. Optionally, install the library functions for 64-bit integer
       arithmetic.  You do this with the command `make gnulib2'.  In
       the future this will happen automatically; for now, it is
--- 343,347 ----
       Bugs::.).
  
!   6. Optionally, install the library functions for 64-bit integer
       arithmetic.  You do this with the command `make gnulib2'.  In
       the future this will happen automatically; for now, it is
***************
*** 283,287 ****
       optional, until we are sure it works on all machines.
  
!   8. If you are using COFF-encapsulation, you must convert `gnulib'
       to a GNU-format library at this point.  See the file
       `README-ENCAP' in the directory containing the GNU binary file
--- 348,352 ----
       optional, until we are sure it works on all machines.
  
!   7. If you are using COFF-encapsulation, you must convert `gnulib'
       to a GNU-format library at this point.  See the file
       `README-ENCAP' in the directory containing the GNU binary file
***************
*** 288,292 ****
       utilities, for directions.
  
!   9. Move the first-stage object files and executables into a
       subdirectory with this command:
  
--- 353,357 ----
       utilities, for directions.
  
!   8. Move the first-stage object files and executables into a
       subdirectory with this command:
  
***************
*** 297,301 ****
       with `rm -r stage1'.
  
!  10. Recompile the compiler with itself, with this command:
  
            make CC=stage1/gcc CFLAGS="-g -O -Bstage1/"
--- 362,366 ----
       with `rm -r stage1'.
  
!   9. Recompile the compiler with itself, with this command:
  
            make CC=stage1/gcc CFLAGS="-g -O -Bstage1/"
***************
*** 307,311 ****
            make CC=stage1/gcc CFLAGS="-g -O -Bstage1/ -msoft-float"
  
!  11. If you wish to test the compiler by compiling it with itself one
       more time, do this (in C shell):
  
--- 372,376 ----
            make CC=stage1/gcc CFLAGS="-g -O -Bstage1/ -msoft-float"
  
!  10. If you wish to test the compiler by compiling it with itself one
       more time, do this (in C shell):
  
***************
*** 337,341 ****
            done
  
!  12. Install the compiler driver, the compiler's passes and run-time
       support.  You can use the following command:
  
--- 402,406 ----
            done
  
!  11. Install the compiler driver, the compiler's passes and run-time
       support.  You can use the following command:
  
***************
*** 388,417 ****
  
  ▶1f◀
! File: gcc.info,  Node: VMS Install,  Prev: Installation,  Up: Installation
  
! Installing GNU CC on VMS
! ========================
  
! The VMS version of GNU CC is distributed in a backup saveset
! containing both source code and precompiled binaries.
  
- Sometimes the binaries will be from an older version that the
- sources, because we don't always have time to update them.  In this
- case, you should use the binaries you get to recompile the sources. 
- If you must recompile, here is how:
  
!   1. Copy the file `tm-vms.h' to `tm.h', `xm-vms.h' to `config.h',
!      `vax.md' to `md.' and `output-vax.c' to `aux-output.c'.
  
!   2. Type `@make' to do recompile everything.
  
!      If you are compiling with a version of GCC older than 1.33,
!      specify `/DEFINE=("inline=")' as an option in all the
!      compilations.  This requires editing all the `gcc' commands in
!      `make-cc1.com'.  (The older versions had problems supporting
!      `inline'.)  Once you have a working 1.33 or newer GCC, you can
!      change this file back.
  
! To install the `GCC' command so you can use the compiler easily, in
  the same manner as you use the VMS C compiler, you must install the
  VMS CLD file for GNU CC as follows:
--- 453,561 ----
  
  ▶1f◀
! File: gcc.info,  Node: Other Dir,  Next: Sun Install,  Prev: Installation,  Up: Installation
  
! Compilation in a Separate Directory
! ===================================
  
! If you wish to build the object files and executables in a directory
! other than the one containing the source files, here is what you must
! do differently:
! 
!   1. Go to that directory before running `config.gcc':
! 
!           mkdir gcc-sun3
!           cd gcc-sun3
! 
!      On systems that do not support symbolic links, this directory
!      must be on the same file system as the source code directory.
! 
!   2. Specify where to find `config.gcc' when you run it:
! 
!           ../gcc-1.36/config.gcc ...
! 
!   3. Specify where to find the sources, as an argument to `config.gcc':
! 
!           ../gcc-1.36/config.gcc -srcdir=../gcc-1.36 sun3
! 
!      The `-srcdir=DIR' option is not needed when the source directory
!      is the parent of the current directory, because `config.gcc'
!      detects that case automatically.
! 
! Now, you can run `make' in that directory.  You need not repeat the
! configuration steps shown above, when ordinary source files change. 
! You must, however, run `config.gcc' again when the configuration
! files change, if your system does not support symbolic links.
  
  
! ▶1f◀
! File: gcc.info,  Node: Sun Install,  Next: 3b1 Install,  Prev: Other Dir,  Up: Installation
  
! Installing GNU CC on the Sun
! ============================
  
! Make sure the environment variable `FLOAT_OPTION' is not set when you
! compile `gnulib'.  If this option were set to `f68881' when `gnulib'
! is compiled, the resulting code would demand to be linked with a
! special startup file and would not link properly without special
! pains.
! 
! There is a bug in `alloca' in certain versions of the Sun library. 
! To avoid this bug, install the binaries of GNU CC that were compiled
! by GNU CC.  They use `alloca' as a built-in function and never the
! one in the library.
! 
! Some versions of the Sun compiler crash when compiling GNU CC.  The
! problem is a segmentation fault in cpp.
! 
! This problem seems to be due to the bulk of data in the environment
! variables.  You may be able to avoid it by using the following
! command to compile GNU CC with Sun CC:
! 
!      make CC="TERMCAP=x OBJS=x LIBFUNCS=x STAGESTUFF=x cc"
  
! 
! ▶1f◀
! File: gcc.info,  Node: 3b1 Install,  Next: VMS Install,  Prev: Sun Install,  Up: Installation
! 
! Installing GNU CC on the 3b1
! ============================
! 
! Installing GNU CC on the 3b1 is difficult if you do not already have
! GNU CC running, due to bugs in the installed C compiler.  However,
! the following procedure might work.  We are unable to test it.
! 
!   1. Comment out the `#include "config.h"' line on line 37 of
!      `cccp.c' and do `make cpp'.  This makes a preliminary version of
!      GNU cpp.
! 
!   2. Save the old `/lib/cpp' and copy the preliminary GNU cpp to that
!      file name.
! 
!   3. Undo your change in `cccp.c', or reinstall the original version,
!      and do `make cpp' again.
! 
!   4. Copy this final version of GNU cpp into `/lib/cpp'.
! 
!   5. Replace every occurance of `obstack_free' in `tree.c' with
!      `_obstack_free'.
! 
!   6. Run `make' to get the first-stage GNU CC.
! 
!   7. Reinstall the original version of `/lib/cpp'.
! 
!   8. Now you can compile GNU CC with itself and install it in the
!      normal fashion.
! 
! 
! ▶1f◀
! File: gcc.info,  Node: VMS Install,  Prev: 3B1 Install,  Up: Installation
! 
! Installing GNU CC on VMS
! ========================
! 
! The VMS version of GNU CC is distributed in a backup saveset
! containing both source code and precompiled binaries.
! 
! To install the `gcc' command so you can use the compiler easily, in
  the same manner as you use the VMS C compiler, you must install the
  VMS CLD file for GNU CC as follows:
***************
*** 422,435 ****
       This should be done with the commands:
  
!           $ assign /super /system disk:[gcc] gnu_cc
!           $ assign /super /system disk:[gcc.include] gnu_cc_include
  
       with the appropriate disk and directory names.  These commands
       can be placed in your system startup file so they will be
!      executed whenever the machine is rebooted.
  
    2. Install the `GCC' command with the command line:
  
!           $ set command /table=sys$library:dcltables gnu_cc:gcc
  
    3. To install the help file, do the following:
--- 566,581 ----
       This should be done with the commands:
  
!           $ assign /super /system disk:[gcc.] gnu_cc
!           $ assign /super /system disk:[gcc.include.] gnu_cc_include
  
       with the appropriate disk and directory names.  These commands
       can be placed in your system startup file so they will be
!      executed whenever the machine is rebooted.  You may, if you
!      choose, do this via the `GCC_INSTALL.COM' script in the `[GCC]'
!      directory.
  
    2. Install the `GCC' command with the command line:
  
!           $ set command /table=sys$library:dcltables gnu_cc:[000000]gcc
  
    3. To install the help file, do the following:
***************
*** 440,443 ****
--- 586,625 ----
       /verbose file.c', which is equivalent to the command `gcc -v -c
       file.c' in Unix.
+ 
+ We try to put corresponding binaries and sources on the VMS
+ distribution tape.  But sometimes the binaries will be from an older
+ version that the sources, because we don't always have time to update
+ them.  (Use the `/verbose' option to determine the version number of
+ the binaries and compare it with the source file `version.c' to tell
+ whether this is so.)  In this case, you should use the binaries you
+ get to recompile the sources.  If you must recompile, here is how:
+ 
+   1. Copy the file `tm-vms.h' to `tm.h', `xm-vms.h' to `config.h',
+      `vax.md' to `md.' and `out-vax.c' to `aux-output.c'.  The files
+      to be copied are found in the subdirectory named `config'; they
+      should be copied to the main directory of GNU CC.
+ 
+   2. Setup the logical names and command tables as defined above.  In
+      addition, define the vms logical name `GNU_BISON' to point at
+      the to the directories where the Bison executable is kept.  This
+      should be done with the command:
+ 
+           $ assign /super /system disk:[bison.] gnu_bison
+ 
+      You may, if you choose, use the `INSTALL_BISON.COM' script in
+      the `[BISON]' directory.
+ 
+   3. Install the `BISON' command with the command line:
+ 
+           $ set command /table=sys$library:dcltables gnu_bison:[000000]bison
+ 
+   4. Type `@make' to do recompile everything.
+ 
+      If you are compiling with a version of GNU CC older than 1.33,
+      specify `/DEFINE=("inline=")' as an option in all the
+      compilations.  This requires editing all the `gcc' commands in
+      `make-cc1.com'.  (The older versions had problems supporting
+      `inline'.)  Once you have a working 1.33 or newer GNU CC, you
+      can change this file back.
  
  There is a known problem on VMS: `const' global variables don't work
diff -rc2N gcc-1.35/Makefile gcc-1.36/Makefile
*** gcc-1.35/Makefile	Mon Apr 24 02:01:14 1989
--- gcc-1.36/Makefile	Fri Sep 22 17:47:25 1989
***************
*** 19,56 ****
  
  
- # Variables you should change for certain systems:
- 
- # These are what you would need on HPUX:
- # CFLAGS = -Wc,-Ns2000 -Wc,-Ne700 -Wc,-Np300
- # If you are using the GNU assembler and linker on HPUX,
- # add -I../hp-include to CFLAGS.
- # -g is desirable in CFLAGS, but a compiler bug in HPUX version 5
- # bites whenever tree.def, rtl.def or machmode.def is included
- # (ie., on every source file).
- # CCLIBFLAGS = -Wc,-Ns2000 -Wc,-Ne700
- # For CCLIBFLAGS you might want to specify the switch that
- # forces only 68000 instructions to be used.
- 
- # If you are making gcc for the first time, and if you are compiling it with
- # a non-gcc compiler, and if your system doesn't have a working alloca() in any
- # of the standard libraries (as is true for HP/UX or Genix),
- # then get alloca.c from GNU Emacs and un-comment the following line:
- # ALLOCA = alloca.o
- 
- # If your system has alloca() in /lib/libPW.a, un-comment the following line:
- # CLIB= -lPW
- 
- # If your system's malloc() routine fails for any reason (as it does on
- # certain versions of Genix), try getting the files
- # malloc.c and getpagesize.h from GNU Emacs and un-comment the following line:
- # MALLOC = malloc.o
- 
- # If you are running GCC on an Apollo (SR10.x),
- # go into a Berkeley environment and use this:
- # CFLAGS = -g -A nansi -A cpu,3000 -A runtype,bsd4.3 -A systype,any -DSHORT_ENUM_BUG
- # (Says vasta@apollo.com.)
- 
- 
  # Variables that exist for you to override.
  
  CFLAGS = -g $(XCFLAGS)
--- 19,24 ----
  
  
  # Variables that exist for you to override.
+ # See below for how to change them for certain systems.
  
  CFLAGS = -g $(XCFLAGS)
***************
*** 68,71 ****
--- 36,41 ----
  
  # CFLAGS for use with OLDCC, for compiling gnulib.
+ # NOTE: -O does not work on some Unix systems!
+ # If you use it here, you are asking for trouble.
  CCLIBFLAGS=
  
***************
*** 88,91 ****
--- 58,105 ----
  OBSTACK=obstack.o
  
+ # Directory to link to, when using the target `maketest'.
+ DIR = ../gcc
+ 
+ # End of variables for you to override.
+ 
+ 
+ # Variables you should change for certain systems.
+ 
+ # These are what you would need on HPUX:
+ # CFLAGS = -Wc,-Ns2000 -Wc,-Ne700 -Wc,-Np300
+ # If you are using the GNU assembler and linker on HPUX,
+ # add -I../hp-include to CFLAGS.
+ # -g is desirable in CFLAGS, but a compiler bug in HPUX version 5
+ # bites whenever tree.def, rtl.def or machmode.def is included
+ # (ie., on every source file).
+ # If you have a floating point accelerator, you might want -lsetjmp as well.
+ # CCLIBFLAGS = -Wc,-Ns2000 -Wc,-Ne700
+ # For CCLIBFLAGS you might want to specify the switch that
+ # forces only 68000 instructions to be used.
+ 
+ # If you are making gcc for the first time, and if you are compiling it with
+ # a non-gcc compiler, and if your system doesn't have a working alloca() in any
+ # of the standard libraries (as is true for HP/UX or Genix),
+ # then get alloca.c from GNU Emacs and un-comment the following line:
+ # ALLOCA = alloca.o
+ # But don't do that if compiling using GCC.
+ 
+ # If your system has alloca() in /lib/libPW.a, un-comment the following line:
+ # CLIB= -lPW
+ 
+ # On a pyramid, you need to uncomment the following line:
+ # CLIB= -lalloca
+ 
+ # If your system's malloc() routine fails for any reason (as it does on
+ # certain versions of Genix), try getting the files
+ # malloc.c and getpagesize.h from GNU Emacs and un-comment the following line:
+ # MALLOC = malloc.o
+ 
+ # If you are running GCC on an Apollo (SR10.x),
+ # go into a Berkeley environment and use this:
+ # CFLAGS = -g -A nansi -A cpu,3000 -A runtype,bsd4.3 -A systype,any -DSHORT_ENUM_BUG
+ # (Says vasta@apollo.com.)
+ 
+ 
  # Dependency on obstack, alloca, malloc or whatever library facilities
  # are not installed in the system libraries.
***************
*** 96,106 ****
  LIBS = $(OBSTACK) $(ALLOCA) $(MALLOC) $(CLIB)
  
! DIR = ../gcc
! 
! # End of variables for you to override.
  
  # Always use -I$(srcdir)/config when compiling.
  .c.o:
! 	$(CC) -c $(CFLAGS) $(CPPFLAGS) -I$(srcdir)/config $<
  
  # Language-specific object files for C.
--- 110,123 ----
  LIBS = $(OBSTACK) $(ALLOCA) $(MALLOC) $(CLIB)
  
! # Specify the directories to be searched for header files.
! # Both . and srcdir are used, in that order,
! # so that tm.h and config.h will be found in the compilation
! # subdirectory rather than in the source directory.
! INCLUDES = -I. -I$(srcdir) -I$(srcdir)/config
! SUBDIR_INCLUDES = -I.. -I../$(srcdir) -I../$(srcdir)/config
  
  # Always use -I$(srcdir)/config when compiling.
  .c.o:
! 	$(CC) -c $(CFLAGS) $(CPPFLAGS) $(INCLUDES) $<
  
  # Language-specific object files for C.
***************
*** 115,119 ****
  # Language-independent object files.
  OBJS = toplev.o version.o tree.o print-tree.o stor-layout.o fold-const.o \
!  rtl.o expr.o stmt.o expmed.o explow.o optabs.o varasm.o \
   symout.o dbxout.o sdbout.o emit-rtl.o insn-emit.o \
   integrate.o jump.o cse.o loop.o flow.o stupid.o combine.o \
--- 132,136 ----
  # Language-independent object files.
  OBJS = toplev.o version.o tree.o print-tree.o stor-layout.o fold-const.o \
!  rtl.o rtlanal.o expr.o stmt.o expmed.o explow.o optabs.o varasm.o \
   symout.o dbxout.o sdbout.o emit-rtl.o insn-emit.o \
   integrate.o jump.o cse.o loop.o flow.o stupid.o combine.o \
***************
*** 125,128 ****
--- 142,147 ----
  STAGESTUFF = *.o insn-flags.h insn-config.h insn-codes.h \
   insn-output.c insn-recog.c insn-emit.c insn-extract.c insn-peep.c \
+  stamp-flags.h stamp-config.h stamp-codes.h \
+  stamp-output.c stamp-recog.c stamp-emit.c stamp-extract.c stamp-peep.c \
   genemit genoutput genrecog genextract genflags gencodes genconfig genpeep \
   cc1 cpp cccp # cc1plus
***************
*** 131,138 ****
  LIBFUNCS = _eprintf _builtin_new _builtin_New _builtin_del \
     _umulsi3 _mulsi3 _udivsi3 _divsi3 _umodsi3 _modsi3 \
!    _lshrsi3 _lshlsi3 _ashrsi3 _ashlsi3 _cmpdi2 _ucmpdi2 \
     _divdf3 _muldf3 _negdf2 _adddf3 _subdf3 _cmpdf2 \
!    _fixunsdfsi _fixunsdfdi _fixdfsi _fixdfdi \
!    _floatsidf _floatdidf _truncdfsf2 _extendsfdf2 \
     _addsf3 _negsf2 _subsf3 _cmpsf2 _mulsf3 _divsf3 _varargs
  
--- 150,156 ----
  LIBFUNCS = _eprintf _builtin_new _builtin_New _builtin_del \
     _umulsi3 _mulsi3 _udivsi3 _divsi3 _umodsi3 _modsi3 \
!    _lshrsi3 _lshlsi3 _ashrsi3 _ashlsi3 \
     _divdf3 _muldf3 _negdf2 _adddf3 _subdf3 _cmpdf2 \
!    _fixunsdfsi _fixdfsi _floatsidf _truncdfsf2 _extendsfdf2 \
     _addsf3 _negsf2 _subsf3 _cmpsf2 _mulsf3 _divsf3 _varargs
  
***************
*** 139,148 ****
  # Library members defined in gnulib2.c.
  LIB2FUNCS = _adddi3 _subdi3 _muldi3 _divdi3 _moddi3 _udivdi3 _umoddi3 _negdi2 \
!     _div_internal
  
  # Header files that are made available to programs compiled with gcc.
! USER_H = stddef.h stdarg.h assert.h varargs.h va-*.h limits.h
  
! # If you want to recompile everything, just do rm *.o.
  # CONFIG_H = config.h tm.h
  CONFIG_H =
--- 157,172 ----
  # Library members defined in gnulib2.c.
  LIB2FUNCS = _adddi3 _subdi3 _muldi3 _divdi3 _moddi3 _udivdi3 _umoddi3 _negdi2 \
!     _anddi3 _iordi3 _xordi3 _lshrdi3 _lshldi3 _ashldi3 _ashrdi3 _one_cmpldi2  \
!     _bdiv _cmpdi2 _ucmpdi2 _fixunsdfdi _fixdfdi _floatdidf
  
  # Header files that are made available to programs compiled with gcc.
! USER_H = stddef.h stdarg.h assert.h va-*.h limits.h
  
! # The files that "belong" in CONFIG_H are deliberately omitted
! # because having them there would not be useful in actual practice.
! # All they would do is cause complete recompilation every time
! # one of the machine description files is edited.
! # That may or may not be what one wants to do.
! # If it is, rm *.o is an easy way to do it.
  # CONFIG_H = config.h tm.h
  CONFIG_H =
***************
*** 151,162 ****
  CPLUS_TREE_H = $(TREE_H) cplus-tree.h c-tree.h
  
! all: gnulib gcc cc1 cpp # cc1plus gnulib2
! 
! # gnulib2 is commented out in 1.35 since it's too late for real testing.
! # Do `make gnulib2' explicitly if you want `long long' support.
! lang-c: gnulib gcc cc1 cpp # gnulib2
! # lang-cplus: gnulib gcc cc1plus cpp
  
! doc: cpp.info gplus.info gcc.info
  
  compilations: ${OBJS}
--- 175,194 ----
  CPLUS_TREE_H = $(TREE_H) cplus-tree.h c-tree.h
  
! # Note that dependencies on obstack.h are not written
! # because that file is not part of GCC.
! # Dependencies on gvarargs.h are not written
! # because all that file does, when not compiling with GCC,
! # is include the system varargs.h.
! 
! all: config.status gnulib gcc cc1 cpp float.h gnulib2 # cc1plus
! 
! lang-c: config.status gnulib gcc cc1 cpp gnulib2
! # lang-cplus: config.status gnulib gcc cc1plus cpp gnulib2
! 
! config.status:
! 	@echo You must configure gcc.  Look at the INSTALL file for details.
! 	@false
  
! doc: $(srcdir)/cpp.info $(srcdir)/gplus.info $(srcdir)/gcc.info
  
  compilations: ${OBJS}
***************
*** 167,175 ****
  	mv gccnew gcc
  
- gcc.o: gcc.c $(CONFIG_H)
- 	$(CC) $(CFLAGS) -I$(srcdir)/config \
-   -DSTANDARD_STARTFILE_PREFIX=\"$(libdir)/\" \
-   -DSTANDARD_EXEC_PREFIX=\"$(libdir)/gcc-\" -c gcc.c
- 
  cc1: $(C_OBJS) $(OBJS) $(LIBDEPS)
  	$(CC) $(CFLAGS) $(LDFLAGS) -o cc1 $(C_OBJS) $(OBJS) $(LIBS)
--- 199,202 ----
***************
*** 181,188 ****
  # Don't compile this with gcc!
  # (That would cause most arithmetic functions to call themselves.)
! gnulib: gnulib.c
! 	-mkdir libtemp
! 	cd libtemp; \
! 	rm -f gnulib; \
  	for name in $(LIBFUNCS); \
  	do \
--- 208,214 ----
  # Don't compile this with gcc!
  # (That would cause most arithmetic functions to call themselves.)
! gnulib: gnulib.c $(CONFIG_H)
! 	-rm -f stamp-gnulib2
! 	rm -f tmpgnulib gnulib; \
  	for name in $(LIBFUNCS); \
  	do \
***************
*** 189,199 ****
  	  echo $${name}; \
  	  rm -f $${name}.c; \
! 	  cp ../gnulib.c $${name}.c; \
! 	  $(OLDCC) $(CCLIBFLAGS) -O -I.. -I../config -c -DL$${name} $${name}.c; \
! 	  $(AR) qc gnulib $${name}.o; \
  	done
! 	mv libtemp/gnulib .
! 	rm -rf libtemp
! 	if [ -f /usr/bin/ranlib ] ; then  ranlib gnulib ;fi
  # On HPUX, if you are working with the GNU assembler and linker,
  # the previous line must be replaced with the following two lines.
--- 215,227 ----
  	  echo $${name}; \
  	  rm -f $${name}.c; \
! 	  cp $(srcdir)/gnulib.c $${name}.c; \
! 	  $(OLDCC) $(CCLIBFLAGS) -O $(INCLUDES) -c -DL$${name} $${name}.c; \
! 	  $(AR) qc tmpgnulib $${name}.o; \
! 	  rm -f $${name}.[co]; \
  	done
! 	if [ -f /usr/bin/ranlib -o -f /bin/ranlib ] ; then ranlib tmpgnulib ;fi
! # Actually build it in tmpgnulib above, then rename now,
! # so that gnulib itself remains nonexistent if compilation is aborted.
! 	mv tmpgnulib gnulib
  # On HPUX, if you are working with the GNU assembler and linker,
  # the previous line must be replaced with the following two lines.
***************
*** 202,229 ****
  #	../hp-bin/hpxt gnulib-hp gnulib
  
! gnulib2: stamp-gnulib2 ;
! stamp-gnulib2: gnulib2.c
! 	-mkdir libtemp
! 	cd libtemp; \
! 	cp ../gnulib .; \
  	for name in $(LIB2FUNCS); \
  	do \
  	  echo $${name}; \
! 	  rm -f $${name}.c; \
! 	  cp ../gnulib2.c $${name}.c; \
! 	  ../gcc -B../ -fstrength-reduce -O -I.. -I../config -c -DL$${name} $${name}.c; \
! 	  $(AR) qc gnulib $${name}.o; \
  	done
! 	mv libtemp/gnulib .
! 	rm -rf libtemp
! 	if [ -f /usr/bin/ranlib ] ; then  ranlib gnulib ;fi
  	touch stamp-gnulib2
! # On HPUX, this might require some change; no one has tried it.
  
  # C language specific files.
  
! c-parse.tab.o : c-parse.tab.c $(CONFIG_H) $(TREE_H) c-parse.h c-tree.h
! c-parse.tab.c : c-parse.y
! 	$(BISON) $(BISONFLAGS) c-parse.y
  
  c-decl.o : c-decl.c $(CONFIG_H) $(TREE_H) c-tree.h c-parse.h flags.h
--- 230,272 ----
  #	../hp-bin/hpxt gnulib-hp gnulib
  
! gnulib2: stamp-gnulib2;
! stamp-gnulib2: gnulib2.c gnulib cc1 gcc cpp $(CONFIG_H)
  	for name in $(LIB2FUNCS); \
  	do \
  	  echo $${name}; \
! 	  ./gcc -B./ -fstrength-reduce -O $(INCLUDES) $(GNULIB2_CFLAGS) -c -DL$${name} $(srcdir)/gnulib2.c -o $${name}.o; \
! 	  $(AR) rc gnulib $${name}.o; \
! 	  rm -f $${name}.o; \
  	done
! 	if [ -f /usr/bin/ranlib -o -f /bin/ranlib ] ; then  ranlib gnulib ;fi
! # On HPUX, if you are working with the GNU assembler and linker,
! # the previous line must be commented out.
! # No change is needed here if you are using the HPUX assembler and linker.
  	touch stamp-gnulib2
! 
! float.h:
! # Originally, we used `make' rather than $(MAKE), to avoid propagating
! # a CC=gcc command option.  However, since hard-params is now made
! # with $(OLDCC) explicitly, this is no longer important.
! # However, $(MAKE) fails on some systems where it isn't defined.
! # `make' has the disadvantage of sometimes running the system's make,
! # instead of GNU make.  And the system's make might not support VPATH.
! # However, the compilation of hard-params should not need to use VPATH,
! # due to the explicit use of `$(srcdir)'.
! 	make hard-params
! 	-./hard-params -f > float.h
! 
! # Compile hard-params with standard cc.  It avoids some headaches.
! hard-params: hard-params.o
! 	$(OLDCC) $(CCLIBFLAGS) $(LDFLAGS) hard-params.o -o $@
! hard-params.o: $(srcdir)/hard-params.c
! 	-cp $(srcdir)/hard-params.c . > /dev/null 2>&1
! 	$(OLDCC) $(CCLIBFLAGS) $(CPPFLAGS) -DNO_SC -c hard-params.c
  
  # C language specific files.
  
! c-parse.tab.o : $(srcdir)/c-parse.tab.c $(CONFIG_H) $(TREE_H) c-parse.h c-tree.h input.h
! $(srcdir)/c-parse.tab.c : $(srcdir)/c-parse.y
! 	$(BISON) $(BISONFLAGS) $(srcdir)/c-parse.y -o $@
  
  c-decl.o : c-decl.c $(CONFIG_H) $(TREE_H) c-tree.h c-parse.h flags.h
***************
*** 233,245 ****
  # C++ language specific files.
  
! cplus-parse.o : cplus-parse.c $(CONFIG_H) $(CPLUS_TREE_H) flags.h
! 	$(CC) -c $(CFLAGS) -I$(srcdir)/config \
!   -DPARSE_OUTPUT=\"$(PWD)/cplus-parse.output\" cplus-parse.c
  
! cplus-parse.h cplus-parse.c : cplus-parse.y
  	@echo expect 49 shift/reduce conflicts and 4 reduce/reduce conflicts
! 	$(BISON) $(BISONFLAGS) -d -o cplus-parse.c cplus-parse.y
  
! cplus-lex.o : cplus-lex.c $(CONFIG_H) $(CPLUS_TREE_H) cplus-parse.h
  cplus-decl.o : cplus-decl.c $(CONFIG_H) $(CPLUS_TREE_H) flags.h
  cplus-typeck.o : cplus-typeck.c $(CONFIG_H) $(CPLUS_TREE_H) flags.h
--- 276,289 ----
  # C++ language specific files.
  
! cplus-parse.o : $(srcdir)/cplus-parse.c $(CONFIG_H) $(CPLUS_TREE_H) flags.h
! 	$(CC) -c $(CFLAGS) $(INCLUDES) \
!   -DPARSE_OUTPUT=\"$(PWD)/cplus-parse.output\" \
!   `echo $(srcdir)/cplus-parse.c | sed 's,^\./,,'`
  
! $(srcdir)/cplus-parse.h $(srcdir)/cplus-parse.c : $(srcdir)/cplus-parse.y
  	@echo expect 49 shift/reduce conflicts and 4 reduce/reduce conflicts
! 	$(BISON) $(BISONFLAGS) -d -o $(srcdir)/cplus-parse.c $(srcdir)/cplus-parse.y
  
! cplus-lex.o : cplus-lex.c $(CONFIG_H) $(CPLUS_TREE_H) $(srcdir)/cplus-parse.h
  cplus-decl.o : cplus-decl.c $(CONFIG_H) $(CPLUS_TREE_H) flags.h
  cplus-typeck.o : cplus-typeck.c $(CONFIG_H) $(CPLUS_TREE_H) flags.h
***************
*** 253,268 ****
  # Language-independent files.
  
  tree.o : tree.c $(CONFIG_H) $(TREE_H) flags.h
  print-tree.o : print-tree.c $(CONFIG_H) $(TREE_H)
! stor-layout.o : stor-layout.c $(CONFIG_H) $(TREE_H)
  fold-const.o : fold-const.c $(CONFIG_H) $(TREE_H)
! toplev.o : toplev.c $(CONFIG_H) $(TREE_H) flags.h
  
  rtl.o : rtl.c $(CONFIG_H) $(RTL_H)
  
  varasm.o : varasm.c $(CONFIG_H) $(TREE_H) $(RTL_H) flags.h expr.h \
     insn-codes.h hard-reg-set.h
  stmt.o : stmt.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h  \
!    insn-flags.h expr.h insn-config.h regs.h insn-codes.h
  expr.o : expr.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h  \
     insn-flags.h insn-codes.h expr.h insn-config.h recog.h
--- 297,323 ----
  # Language-independent files.
  
+ gcc.o: gcc.c $(CONFIG_H)
+ 	$(CC) $(CFLAGS) $(INCLUDES) \
+   -DSTANDARD_STARTFILE_PREFIX=\"$(libdir)/\" \
+   -DSTANDARD_EXEC_PREFIX=\"$(libdir)/gcc-\" -c \
+   `echo $(srcdir)/gcc.c | sed 's,^\./,,'`
+ 
+ version.o: version.c
+ obstack.o: obstack.c
+ 
  tree.o : tree.c $(CONFIG_H) $(TREE_H) flags.h
  print-tree.o : print-tree.c $(CONFIG_H) $(TREE_H)
! stor-layout.o : stor-layout.c $(CONFIG_H) $(TREE_H) $(RTL_H)
  fold-const.o : fold-const.c $(CONFIG_H) $(TREE_H)
! toplev.o : toplev.c $(CONFIG_H) $(TREE_H) flags.h input.h
  
  rtl.o : rtl.c $(CONFIG_H) $(RTL_H)
  
+ rtlanal.o : rtlanal.c $(CONFIG_H) $(RTL_H)
+ 
  varasm.o : varasm.c $(CONFIG_H) $(TREE_H) $(RTL_H) flags.h expr.h \
     insn-codes.h hard-reg-set.h
  stmt.o : stmt.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h  \
!    insn-flags.h expr.h insn-config.h regs.h hard-reg-set.h insn-codes.h
  expr.o : expr.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h  \
     insn-flags.h insn-codes.h expr.h insn-config.h recog.h
***************
*** 274,278 ****
  symout.o : symout.c $(CONFIG_H) $(TREE_H) $(RTL_H) symseg.h gdbfiles.h
  dbxout.o : dbxout.c $(CONFIG_H) $(TREE_H) $(RTL_H) flags.h
! sdbout.o : sdbout.c $(CONFIG_H) $(TREE_H) $(RTL_H) c-tree.h
  
  emit-rtl.o : emit-rtl.c $(CONFIG_H) $(RTL_H) regs.h insn-config.h real.h
--- 329,333 ----
  symout.o : symout.c $(CONFIG_H) $(TREE_H) $(RTL_H) symseg.h gdbfiles.h
  dbxout.o : dbxout.c $(CONFIG_H) $(TREE_H) $(RTL_H) flags.h
! sdbout.o : sdbout.c $(CONFIG_H) $(TREE_H) $(RTL_H)
  
  emit-rtl.o : emit-rtl.c $(CONFIG_H) $(RTL_H) regs.h insn-config.h real.h
***************
*** 286,310 ****
  cse.o : cse.c $(CONFIG_H) $(RTL_H) regs.h hard-reg-set.h flags.h real.h
  loop.o : loop.c $(CONFIG_H) $(RTL_H) insn-config.h insn-codes.h \
!    regs.h recog.h flags.h expr.h
  flow.o : flow.c $(CONFIG_H) $(RTL_H) basic-block.h regs.h hard-reg-set.h
  combine.o : combine.c $(CONFIG_H) $(RTL_H) flags.h  \
     insn-config.h regs.h basic-block.h recog.h
! regclass.o : regclass.c $(CONFIG_H) $(RTL_H) flags.h regs.h \
!    insn-config.h recog.h hard-reg-set.h
! local-alloc.o : local-alloc.c $(CONFIG_H) $(RTL_H) basic-block.h regs.h \
!    insn-config.h recog.h hard-reg-set.h
  global-alloc.o : global-alloc.c $(CONFIG_H) $(RTL_H) flags.h  \
     basic-block.h regs.h hard-reg-set.h insn-config.h
  
! reload.o : reload.c $(CONFIG_H) $(RTL_H)  \
     reload.h recog.h hard-reg-set.h insn-config.h regs.h
  reload1.o : reload1.c $(CONFIG_H) $(RTL_H) flags.h  \
!    reload.h regs.h hard-reg-set.h insn-config.h basic-block.h
  caller-save.o : caller-save.c $(CONFIG_H) $(RTL_H) flags.h \
     reload.h regs.h hard-reg-set.h insn-config.h basic-block.h recog.h
! final.o : final.c $(CONFIG_H) $(RTL_H) regs.h recog.h conditions.h gdbfiles.h \
!    insn-config.h real.h
  recog.o : recog.c $(CONFIG_H) $(RTL_H)  \
!    regs.h recog.h hard-reg-set.h insn-config.h
  
  # Normally this target is not used; but it is used if you
--- 341,365 ----
  cse.o : cse.c $(CONFIG_H) $(RTL_H) regs.h hard-reg-set.h flags.h real.h
  loop.o : loop.c $(CONFIG_H) $(RTL_H) insn-config.h insn-codes.h \
!    regs.h hard-reg-set.h recog.h flags.h expr.h
  flow.o : flow.c $(CONFIG_H) $(RTL_H) basic-block.h regs.h hard-reg-set.h
  combine.o : combine.c $(CONFIG_H) $(RTL_H) flags.h  \
     insn-config.h regs.h basic-block.h recog.h
! regclass.o : regclass.c $(CONFIG_H) $(RTL_H) hard-reg-set.h flags.h \
!    basic-block.h regs.h insn-config.h recog.h 
! local-alloc.o : local-alloc.c $(CONFIG_H) $(RTL_H) flags.h basic-block.h regs.h \
!    hard-reg-set.h insn-config.h recog.h
  global-alloc.o : global-alloc.c $(CONFIG_H) $(RTL_H) flags.h  \
     basic-block.h regs.h hard-reg-set.h insn-config.h
  
! reload.o : reload.c $(CONFIG_H) $(RTL_H) flags.h \
     reload.h recog.h hard-reg-set.h insn-config.h regs.h
  reload1.o : reload1.c $(CONFIG_H) $(RTL_H) flags.h  \
!    reload.h regs.h hard-reg-set.h insn-config.h basic-block.h recog.h
  caller-save.o : caller-save.c $(CONFIG_H) $(RTL_H) flags.h \
     reload.h regs.h hard-reg-set.h insn-config.h basic-block.h recog.h
! final.o : final.c $(CONFIG_H) $(RTL_H) flags.h regs.h recog.h conditions.h \
!    gdbfiles.h insn-config.h real.h output.h
  recog.o : recog.c $(CONFIG_H) $(RTL_H)  \
!    regs.h recog.h hard-reg-set.h insn-config.h real.h
  
  # Normally this target is not used; but it is used if you
***************
*** 313,317 ****
  # Note some machines won't allow $(CC) without -S on this source file.
  alloca.o:	alloca.c
! 	$(CC) $(CFLAGS) -S alloca.c
  	as alloca.s -o alloca.o
  
--- 368,372 ----
  # Note some machines won't allow $(CC) without -S on this source file.
  alloca.o:	alloca.c
! 	$(CC) $(CFLAGS) -S `echo $(srcdir)/alloca.c | sed 's,^\./,,'`
  	as alloca.s -o alloca.o
  
***************
*** 330,334 ****
  stamp-config.h : md genconfig
  	./genconfig md > tmp-insn-config.h
! 	./move-if-change tmp-insn-config.h insn-config.h
  	touch stamp-config.h
  
--- 385,389 ----
  stamp-config.h : md genconfig
  	./genconfig md > tmp-insn-config.h
! 	$(srcdir)/move-if-change tmp-insn-config.h insn-config.h
  	touch stamp-config.h
  
***************
*** 336,340 ****
  stamp-flags.h : md genflags
  	./genflags md > tmp-insn-flags.h
! 	./move-if-change tmp-insn-flags.h insn-flags.h
  	touch stamp-flags.h
  
--- 391,395 ----
  stamp-flags.h : md genflags
  	./genflags md > tmp-insn-flags.h
! 	$(srcdir)/move-if-change tmp-insn-flags.h insn-flags.h
  	touch stamp-flags.h
  
***************
*** 342,350 ****
  stamp-codes.h : md gencodes
  	./gencodes md > tmp-insn-codes.h
! 	./move-if-change tmp-insn-codes.h insn-codes.h
  	touch stamp-codes.h
  
! insn-emit.o : insn-emit.c $(CONFIG_H) $(RTL_H) expr.h insn-config.h real.h
! 	$(CC) $(CFLAGS) -I$(srcdir)/config -c insn-emit.c
  
  insn-emit.c: stamp-emit.c ;
--- 397,406 ----
  stamp-codes.h : md gencodes
  	./gencodes md > tmp-insn-codes.h
! 	$(srcdir)/move-if-change tmp-insn-codes.h insn-codes.h
  	touch stamp-codes.h
  
! insn-emit.o : insn-emit.c $(CONFIG_H) $(RTL_H) expr.h real.h insn-codes.h \
!   insn-config.h insn-flags.h
! 	$(CC) $(CFLAGS) $(INCLUDES) -c insn-emit.c
  
  insn-emit.c: stamp-emit.c ;
***************
*** 351,359 ****
  stamp-emit.c : md genemit
  	./genemit md > tmp-insn-emit.c
! 	./move-if-change tmp-insn-emit.c insn-emit.c
  	touch stamp-emit.c
  
! insn-recog.o : insn-recog.c $(CONFIG_H) $(RTL_H) insn-config.h
! 	$(CC) $(CFLAGS) -I$(srcdir)/config -c insn-recog.c
  
  insn-recog.c: stamp-recog.c ;
--- 407,415 ----
  stamp-emit.c : md genemit
  	./genemit md > tmp-insn-emit.c
! 	$(srcdir)/move-if-change tmp-insn-emit.c insn-emit.c
  	touch stamp-emit.c
  
! insn-recog.o : insn-recog.c $(CONFIG_H) $(RTL_H) insn-config.h real.h recog.h
! 	$(CC) $(CFLAGS) $(INCLUDES) -c insn-recog.c
  
  insn-recog.c: stamp-recog.c ;
***************
*** 360,368 ****
  stamp-recog.c : md genrecog
  	./genrecog md > tmp-insn-recog.c
! 	./move-if-change tmp-insn-recog.c insn-recog.c
  	touch stamp-recog.c
  
! insn-extract.o : insn-extract.c $(RTL_H)
! 	$(CC) $(CFLAGS) -I$(srcdir)/config -c insn-extract.c
  
  insn-extract.c: stamp-extract.c ;
--- 416,424 ----
  stamp-recog.c : md genrecog
  	./genrecog md > tmp-insn-recog.c
! 	$(srcdir)/move-if-change tmp-insn-recog.c insn-recog.c
  	touch stamp-recog.c
  
! insn-extract.o : insn-extract.c $(CONFIG_H) $(RTL_H)
! 	$(CC) $(CFLAGS) $(INCLUDES) -c insn-extract.c
  
  insn-extract.c: stamp-extract.c ;
***************
*** 369,377 ****
  stamp-extract.c : md genextract
  	./genextract md > tmp-insn-extract.c
! 	./move-if-change tmp-insn-extract.c insn-extract.c
  	touch stamp-extract.c
  
  insn-peep.o : insn-peep.c $(CONFIG_H) $(RTL_H) regs.h real.h
! 	$(CC) $(CFLAGS) -I$(srcdir)/config -c insn-peep.c
  
  insn-peep.c: stamp-peep.c ;
--- 425,433 ----
  stamp-extract.c : md genextract
  	./genextract md > tmp-insn-extract.c
! 	$(srcdir)/move-if-change tmp-insn-extract.c insn-extract.c
  	touch stamp-extract.c
  
  insn-peep.o : insn-peep.c $(CONFIG_H) $(RTL_H) regs.h real.h
! 	$(CC) $(CFLAGS) $(INCLUDES) -c insn-peep.c
  
  insn-peep.c: stamp-peep.c ;
***************
*** 378,382 ****
  stamp-peep.c : md genpeep
  	./genpeep md > tmp-insn-peep.c
! 	./move-if-change tmp-insn-peep.c insn-peep.c
  	touch stamp-peep.c
  
--- 434,438 ----
  stamp-peep.c : md genpeep
  	./genpeep md > tmp-insn-peep.c
! 	$(srcdir)/move-if-change tmp-insn-peep.c insn-peep.c
  	touch stamp-peep.c
  
***************
*** 383,387 ****
  insn-output.o : insn-output.c $(CONFIG_H) $(RTL_H) regs.h real.h conditions.h \
      hard-reg-set.h insn-config.h insn-flags.h output.h aux-output.c
! 	$(CC) $(CFLAGS) -I$(srcdir)/config -c insn-output.c
  
  insn-output.c: stamp-output.c ;
--- 439,443 ----
  insn-output.o : insn-output.c $(CONFIG_H) $(RTL_H) regs.h real.h conditions.h \
      hard-reg-set.h insn-config.h insn-flags.h output.h aux-output.c
! 	$(CC) $(CFLAGS) $(INCLUDES) -c insn-output.c
  
  insn-output.c: stamp-output.c ;
***************
*** 388,395 ****
  stamp-output.c : md genoutput
  	./genoutput md > tmp-insn-output.c
! 	./move-if-change tmp-insn-output.c insn-output.c
  	touch stamp-output.c
  
  # Now the programs that generate those files.
  
  genconfig : genconfig.o rtl.o $(LIBDEPS)
--- 444,455 ----
  stamp-output.c : md genoutput
  	./genoutput md > tmp-insn-output.c
! 	$(srcdir)/move-if-change tmp-insn-output.c insn-output.c
  	touch stamp-output.c
  
  # Now the programs that generate those files.
+ # $(CONFIG_H) is omitted from the deps of the gen*.o
+ # because these programs don't really depend on anything 
+ # about the target machine.  They do depend on config.h itself,
+ # since that describes the host machine.
  
  genconfig : genconfig.o rtl.o $(LIBDEPS)
***************
*** 396,400 ****
  	$(CC) $(CFLAGS) $(LDFLAGS) -o genconfig genconfig.o rtl.o $(LIBS)
  
! genconfig.o : genconfig.c $(RTL_H)
  
  genflags : genflags.o rtl.o $(LIBDEPS)
--- 456,460 ----
  	$(CC) $(CFLAGS) $(LDFLAGS) -o genconfig genconfig.o rtl.o $(LIBS)
  
! genconfig.o : genconfig.c $(RTL_H) config.h
  
  genflags : genflags.o rtl.o $(LIBDEPS)
***************
*** 401,405 ****
  	$(CC) $(CFLAGS) $(LDFLAGS) -o genflags genflags.o rtl.o $(LIBS)
  
! genflags.o : genflags.c $(RTL_H)
  
  gencodes : gencodes.o rtl.o $(LIBDEPS)
--- 461,465 ----
  	$(CC) $(CFLAGS) $(LDFLAGS) -o genflags genflags.o rtl.o $(LIBS)
  
! genflags.o : genflags.c $(RTL_H) config.h
  
  gencodes : gencodes.o rtl.o $(LIBDEPS)
***************
*** 406,410 ****
  	$(CC) $(CFLAGS) $(LDFLAGS) -o gencodes gencodes.o rtl.o $(LIBS)
  
! gencodes.o : gencodes.c $(RTL_H)
  
  genemit : genemit.o rtl.o $(LIBDEPS)
--- 466,470 ----
  	$(CC) $(CFLAGS) $(LDFLAGS) -o gencodes gencodes.o rtl.o $(LIBS)
  
! gencodes.o : gencodes.c $(RTL_H) config.h
  
  genemit : genemit.o rtl.o $(LIBDEPS)
***************
*** 411,415 ****
  	$(CC) $(CFLAGS) $(LDFLAGS) -o genemit genemit.o rtl.o $(LIBS)
  
! genemit.o : genemit.c $(RTL_H)
  
  genrecog : genrecog.o rtl.o $(LIBDEPS)
--- 471,475 ----
  	$(CC) $(CFLAGS) $(LDFLAGS) -o genemit genemit.o rtl.o $(LIBS)
  
! genemit.o : genemit.c $(RTL_H) config.h
  
  genrecog : genrecog.o rtl.o $(LIBDEPS)
***************
*** 416,420 ****
  	$(CC) $(CFLAGS) $(LDFLAGS) -o genrecog genrecog.o rtl.o $(LIBS)
  
! genrecog.o : genrecog.c $(RTL_H)
  
  genextract : genextract.o rtl.o $(LIBDEPS)
--- 476,480 ----
  	$(CC) $(CFLAGS) $(LDFLAGS) -o genrecog genrecog.o rtl.o $(LIBS)
  
! genrecog.o : genrecog.c $(RTL_H) config.h
  
  genextract : genextract.o rtl.o $(LIBDEPS)
***************
*** 421,425 ****
  	$(CC) $(CFLAGS) $(LDFLAGS) -o genextract genextract.o rtl.o $(LIBS)
  
! genextract.o : genextract.c $(RTL_H)
  
  genpeep : genpeep.o rtl.o $(LIBDEPS)
--- 481,485 ----
  	$(CC) $(CFLAGS) $(LDFLAGS) -o genextract genextract.o rtl.o $(LIBS)
  
! genextract.o : genextract.c $(RTL_H) config.h
  
  genpeep : genpeep.o rtl.o $(LIBDEPS)
***************
*** 426,430 ****
  	$(CC) $(CFLAGS) $(LDFLAGS) -o genpeep genpeep.o rtl.o $(LIBS)
  
! genpeep.o : genpeep.c $(RTL_H)
  
  genoutput : genoutput.o rtl.o $(LIBDEPS)
--- 486,490 ----
  	$(CC) $(CFLAGS) $(LDFLAGS) -o genpeep genpeep.o rtl.o $(LIBS)
  
! genpeep.o : genpeep.c $(RTL_H) config.h
  
  genoutput : genoutput.o rtl.o $(LIBDEPS)
***************
*** 431,435 ****
  	$(CC) $(CFLAGS) $(LDFLAGS) -o genoutput genoutput.o rtl.o $(LIBS)
  
! genoutput.o : genoutput.c $(RTL_H)
  
  # Making the preprocessor
--- 491,495 ----
  	$(CC) $(CFLAGS) $(LDFLAGS) -o genoutput genoutput.o rtl.o $(LIBS)
  
! genoutput.o : genoutput.c $(RTL_H) config.h
  
  # Making the preprocessor
***************
*** 439,459 ****
  cccp: cccp.o cexp.o version.o $(LIBDEPS)
  	$(CC) $(CFLAGS) $(LDFLAGS) -o cccp cccp.o cexp.o version.o $(LIBS)
! cexp.o: cexp.c
! cexp.c: cexp.y
! 	$(BISON) cexp.y
! 	mv cexp.tab.c cexp.c
! cccp.o: cccp.c
! 	$(CC) $(CFLAGS) -I$(srcdir)/config \
            -DGCC_INCLUDE_DIR=\"$(libdir)/gcc-include\" \
!           -DGPLUSPLUS_INCLUDE_DIR=\"$(libdir)/g++-include\" -c cccp.c
! 
! cpp.info: cpp.texinfo
! 	makeinfo $<
  
! gplus.info: gplus.texinfo
! 	makeinfo $<
  
! gcc.info: gcc.texinfo
! 	makeinfo $<
  
  # gnulib is not deleted because deleting it would be inconvenient
--- 499,519 ----
  cccp: cccp.o cexp.o version.o $(LIBDEPS)
  	$(CC) $(CFLAGS) $(LDFLAGS) -o cccp cccp.o cexp.o version.o $(LIBS)
! cexp.o: $(srcdir)/cexp.c $(CONFIG_H)
! $(srcdir)/cexp.c: $(srcdir)/cexp.y
! 	$(BISON) -o $(srcdir)/cexp.c $(srcdir)/cexp.y
! cccp.o: cccp.c $(CONFIG_H)
! 	$(CC) $(CFLAGS) $(INCLUDES) \
            -DGCC_INCLUDE_DIR=\"$(libdir)/gcc-include\" \
!           -DGPLUSPLUS_INCLUDE_DIR=\"$(libdir)/g++-include\" \
! 	  -c `echo $(srcdir)/cccp.c | sed 's,^\./,,'`
  
! $(srcdir)/cpp.info: $(srcdir)/cpp.texinfo
! 	makeinfo `echo $(srcdir)/cpp.texinfo | sed 's,^\./,,'`
! 
! $(srcdir)/gplus.info: $(srcdir)/gplus.texinfo
! 	makeinfo `echo $(srcdir)/gplus.texinfo | sed 's,^\./,,'`
  
! $(srcdir)/gcc.info: $(srcdir)/gcc.texinfo
! 	makeinfo `echo $(srcdir)/gcc.texinfo | sed 's,^\./,,'`
  
  # gnulib is not deleted because deleting it would be inconvenient
***************
*** 461,477 ****
  clean:
  	-rm -f $(STAGESTUFF) $(STAGE_GCC)
! 	-rm -f stamp-*.[ch]
! 	-rm -f *.s *.s[0-9] *.co *.greg *.lreg *.combine *.flow *.cse *.jump *.rtl *.tree *.loop
! 	-rm -f core
  
  # Like clean but also delete the links made to configure gcc.
! cleanlinks: clean
! 	-rm -f tm.h aux-output.c config.h md config.status
  
  # Get rid of every file that's generated from some other file (except INSTALL).
! realclean: cleanlinks
  	-rm -f cpp.aux cpp.cps cpp.fns cpp.info cpp.kys cpp.pgs cpp.tps cpp.vrs
  #	-rm -f cplus-parse.tab.c cplus-parse.output
! 	-rm -f c-parse.tab.c c-parse.output
  	-rm -f gnulib cexp.c TAGS 
  	-rm -f cpp.info* cpp.?? cpp.??s cpp.log cpp.toc cpp.*aux
--- 521,541 ----
  clean:
  	-rm -f $(STAGESTUFF) $(STAGE_GCC)
! # Delete the temp files made in the course of building gnulib.
! 	-rm -f tmpgnulib
! 	for name in $(LIBFUNCS); do rm -f $${name}.c; done
! 	-rm -f stamp-*.[ch] tmp-insn-*
! 	-rm -f *.s *.s[0-9] *.co *.greg *.lreg *.combine *.flow *.cse *.jump *.rtl *.tree *.loop *.dbr *.jump2
! 	-rm -f core float.h hard-params
  
  # Like clean but also delete the links made to configure gcc.
! # Also removes gnulib, since that is desirable if you are changing cpus.
! cleanconfig: clean
! 	-rm -f tm.h aux-output.c config.h md config.status gnulib stamp-gnulib2
  
  # Get rid of every file that's generated from some other file (except INSTALL).
! realclean: cleanconfig
  	-rm -f cpp.aux cpp.cps cpp.fns cpp.info cpp.kys cpp.pgs cpp.tps cpp.vrs
  #	-rm -f cplus-parse.tab.c cplus-parse.output
! 	-rm -f c-parse.tab.c c-parse.output c-parse.tab.output
  	-rm -f gnulib cexp.c TAGS 
  	-rm -f cpp.info* cpp.?? cpp.??s cpp.log cpp.toc cpp.*aux
***************
*** 490,496 ****
  	$(INSTALL) gcc $(bindir)
  	-mkdir $(libdir)/gcc-include
! 	chmod ugo+rx $(libdir)/gcc-include
! 	for file in $(USER_H); do $(INSTALL) $${file} $(libdir)/gcc-include; done
! 	$(INSTALL) gcc.1 $(mandir)/gcc.$(manext)
  
  # do make -f ../gcc/Makefile maketest DIR=../gcc
--- 554,562 ----
  	$(INSTALL) gcc $(bindir)
  	-mkdir $(libdir)/gcc-include
! 	-chmod ugo+rx $(libdir)/gcc-include
! 	for file in $(USER_H); do $(INSTALL) $(srcdir)/$${file} $(libdir)/gcc-include; done
! 	$(INSTALL) float.h $(libdir)/gcc-include/float.h
! 	$(INSTALL) $(srcdir)/gvarargs.h $(libdir)/gcc-include/varargs.h
! 	$(INSTALL) $(srcdir)/gcc.1 $(mandir)/gcc.$(manext)
  
  # do make -f ../gcc/Makefile maketest DIR=../gcc
***************
*** 498,503 ****
  maketest:
  	ln -s $(DIR)/*.[chy] .
  	ln -s $(DIR)/*.def .
- 	ln -s $(DIR)/*.md .
  	-rm -f =*
  	ln -s $(DIR)/.gdbinit .
--- 564,569 ----
  maketest:
  	ln -s $(DIR)/*.[chy] .
+ 	ln -s $(DIR)/config .
  	ln -s $(DIR)/*.def .
  	-rm -f =*
  	ln -s $(DIR)/.gdbinit .
***************
*** 505,509 ****
  	ln -s $(DIR)/config.gcc .
  	ln -s $(DIR)/move-if-change .
! 	if [ -f Makefile ] ; then false; else ln -s $(DIR)/Makefile . ; fi
  	-rm tm.h aux-output.c config.h md
  	make clean
--- 571,576 ----
  	ln -s $(DIR)/config.gcc .
  	ln -s $(DIR)/move-if-change .
! # The then and else were swapped to avoid a problem on Ultrix.
! 	if [ ! -f Makefile ] ; then ln -s $(DIR)/Makefile . ; else false; fi
  	-rm tm.h aux-output.c config.h md
  	make clean
***************
*** 512,526 ****
  bootstrap: all force
  	$(MAKE) stage1
! 	$(MAKE) CC="stage1/gcc -Bstage1/" CFLAGS="-O $(CFLAGS)"
  	$(MAKE) stage2
! 	$(MAKE) CC="stage2/gcc -Bstage2/" CFLAGS="-O $(CFLAGS)"
  
  bootstrap2: force
! 	$(MAKE) CC="stage1/gcc -Bstage1/" CFLAGS="-O $(CFLAGS)"
  	$(MAKE) stage2
! 	$(MAKE) CC="stage2/gcc -Bstage2/" CFLAGS="-O $(CFLAGS)"
  
  bootstrap3: force
! 	$(MAKE) CC="stage2/gcc -Bstage2/" CFLAGS="-O $(CFLAGS)"
  
  # Copy the object files from a particular stage into a subdirectory.
--- 579,593 ----
  bootstrap: all force
  	$(MAKE) stage1
! 	$(MAKE) CC="stage1/gcc -Bstage1/" CFLAGS="-O $(CFLAGS)" libdir=$(libdir)
  	$(MAKE) stage2
! 	$(MAKE) CC="stage2/gcc -Bstage2/" CFLAGS="-O $(CFLAGS)" libdir=$(libdir)
  
  bootstrap2: force
! 	$(MAKE) CC="stage1/gcc -Bstage1/" CFLAGS="-O $(CFLAGS)" libdir=$(libdir)
  	$(MAKE) stage2
! 	$(MAKE) CC="stage2/gcc -Bstage2/" CFLAGS="-O $(CFLAGS)" libdir=$(libdir)
  
  bootstrap3: force
! 	$(MAKE) CC="stage2/gcc -Bstage2/" CFLAGS="-O $(CFLAGS)" libdir=$(libdir)
  
  # Copy the object files from a particular stage into a subdirectory.
***************
*** 543,546 ****
--- 610,619 ----
  	-ln gnulib stage3 || (cp gnulib stage3 && ranlib stage3/gnulib)
  
+ stage4: force
+ 	-mkdir stage4
+ 	-mv $(STAGESTUFF) $(STAGE_GCC) stage4
+ 	-rm -f stage4/gnulib
+ 	-ln gnulib stage4 || (cp gnulib stage4 && ranlib stage4/gnulib)
+ 
  TAGS: force
  	mkdir temp
***************
*** 550,555 ****
  	rmdir temp
  
  #In GNU Make, ignore whether `stage*' exists.
! .PHONY: stage1 stage2 stage3 clean realclean TAGS bootstrap
  
  force:
--- 623,631 ----
  	rmdir temp
  
+ includes: force
+ 	libdir=$(libdir) fixincludes
+ 
  #In GNU Make, ignore whether `stage*' exists.
! .PHONY: stage1 stage2 stage3 stage4 clean realclean TAGS bootstrap
  
  force:
diff -rc2N gcc-1.35/PROJECTS gcc-1.36/PROJECTS
*** gcc-1.35/PROJECTS	Tue Apr 18 13:32:13 1989
--- gcc-1.36/PROJECTS	Thu May 11 13:12:56 1989
***************
*** 20,26 ****
  * More cse
  
! The techniques for doing full global cse are described in the
! red dragon book.  It is likely to be slow and use a lot of memory,
! but it might be worth offering as an additional option.
  
  It is probably possible to extend cse to a few very frequent cases
--- 20,27 ----
  * More cse
  
! The techniques for doing full global cse are described in the red
! dragon book, or (a different version) in Frederick Chow's thesis from
! Stanford.  It is likely to be slow and use a lot of memory, but it
! might be worth offering as an additional option.
  
  It is probably possible to extend cse to a few very frequent cases
***************
*** 49,56 ****
  
  * Put short statics vars at low addresses and use short addressing mode?
  Useful on the 68000/68020 and perhaps on the 32000 series,
  provided one has a linker that works with the feature.
  This is said to make a 15% speedup on the 68000.
! This brings to mind Hayes' changes for Stanford MIPS.
  
  * Detect dead stores into memory?
--- 50,132 ----
  
  * Put short statics vars at low addresses and use short addressing mode?
+ 
  Useful on the 68000/68020 and perhaps on the 32000 series,
  provided one has a linker that works with the feature.
  This is said to make a 15% speedup on the 68000.
! 
! * Keep global variables in registers.
! 
! Here is a scheme for doing this.  A global variable, or a local variable
! whose address is taken, can be kept in a register for an entire function
! if it does not use non-constant memory addresses and (for globals only)
! does not call other functions.  If the entire function does not meet
! this criterion, a loop may.
! 
! The VAR_DECL for such a variable would have to have two RTL expressions:
! the true home in memory, and the pseudo-register used temporarily. 
! It is necessary to emit insns to copy the memory location into the
! pseudo-register at the beginning of the function or loop, and perhaps
! back out at the end.  These insns should have REG_EQUIV notes so that,
! if the pseudo-register does not get a hard register, it is spilled into
! the memory location which exists in any case.
! 
! The easiest way to set up these insns is to modify the routine
! put_var_into_stack so that it does not apply to the entire function
! (sparing any loops which contain nothing dangerous) and to call it at
! the end of the function regardless of where in the function the
! address of a local variable is taken.  It would be called
! unconditionally at the end of the function for all relevant global
! variables.
! 
! For debugger output, the thing to do is to invent a new binding level
! around the appropriate loop and define the variable name as a register
! variable with that scope.
! 
! * Live-range splitting.
! 
! Currently a variable is allocated a hard register either for the full
! extent of its use or not at all.  Sometimes it would be good to
! allocate a variable a hard register for just part of a function; for
! example, through a particular loop where the variable is mostly used,
! or outside of a particular loop where the variable is not used.  (The
! latter is nice because it might let the variable be in a register most
! of the time even though the loop needs all the registers.)
! 
! It might not be very hard to do this in global-alloc.c when a variable
! fails to get a hard register for its entire life span.
! 
! The first step is to find a loop in which the variable is live, but
! which is not the whole life span or nearly so.  It's probably best to
! use a loop in which the variable is heavily used.
! 
! Then create a new pseudo-register to represent the variable in that loop.
! Substitute this for the old pseudo-register there, and insert move insns
! to copy between the two at the loop entry and all exits.  (When several
! such moves are inserted at the same place, some new feature should be
! added to say that none of those registers conflict merely because of
! overlap between the new moves.  And the reload pass should reorder them
! so that a store precedes a load, for any given hard register.)
! 
! After doing this for all the reasonable candidates, run global-alloc
! over again.  With luck, one of the two pseudo-registers will be fit
! somewhere.  It may even have a much higher priority due to its reduced
! life span.
! 
! There will be no room in general for the new pseudo-registers in
! basic_block_live_at_start, so there will need to be a second such
! matrix exclusively for the new ones.  Various other vectors indexed by
! register number will have to be made bigger, or there will have to be
! secondary extender vectors just for global-alloc.
! 
! A simple new feature could arrange that both pseudo-registers get the
! same stack slot if they both fail to get hard registers.
! 
! Other compilers split live ranges when they are not connected, or
! try to split off pieces `at the edge'.  I think splitting around loops
! will provide more speedup.
! 
! Creating a fake binding block and a new like-named variable with
! shorter life span and different address might succeed in describing
! this technique for the debugger.
  
  * Detect dead stores into memory?
***************
*** 213,217 ****
  within functions.  Some of the mechanisms for this already exist.
  
! 4. Generalize the machine model.
  
  * Some new compiler features may be needed to do a good job on machines
--- 289,335 ----
  within functions.  Some of the mechanisms for this already exist.
  
! 4. More extensions.
! 
! * Label-addresses as expressions.
! 
! It would be nice to have access to the addresses of labels; to be able to
! store them in variables, or initialize vectors of them.
! 
! Alas, `&label0' is the address of the variable named label0, which is
! unrelated to the label with that name.  Some other syntax is needed.
! Perhaps colon as a unary operator?  That is ambiguous with `?:' with
! the middle operand omitted.  Perhaps ^ as a unary operator?  Perhaps
! `__label__ label0' could mean the value of label0?  Its type could be
! `void *'.  `goto *EXP' could be used to go to a value of type `void
! *'--no ambiguity there.
! 
! Jump optimization and flow analysis must know about computed jumps,
! but that is not hard.  Each basic block headed by a possible target of
! computed jumps must be considered a successor of each basic block
! ending in a computed jump.  Aside from this, I believe no other
! optimizer changes are needed.
! 
! Next question: stack levels.  In most functions, there is no problem,
! but it would be a shame to make a feature that doesn't work together
! with other features.  Here is an idea:
! 
! For each label that might need stack level restoration, construct a
! shadow-label which will restore the stack and jump to the user-label.
! Then use the address of the shadow label for label0 when someone asks
! for that of label0.  Jump optimization will delete all the shadow labels
! if the function has no computed gotos.
! 
! * Block structure for labels.
! 
! The ({...}) construct should serve as a lexical block for label names,
! so that the same label may be defined both inside and outside of it.
! Then macro definitions could use labels internally safely, by enclosing
! the label and the goto in one of these constructs.
! 
! * Generated unique labels.  Have some way of generating distinct labels
! for use in extended asm statements.  I don't know what a good syntax would
! be.
! 
! 5. Generalize the machine model.
  
  * Some new compiler features may be needed to do a good job on machines
***************
*** 222,226 ****
  now have a way to understand this.
  
! 5. Precompilation of header files.
  
  In the future, many programs will use thousands of lines of header files.
--- 340,344 ----
  now have a way to understand this.
  
! 6. Precompilation of header files.
  
  In the future, many programs will use thousands of lines of header files.
***************
*** 293,297 ****
  JNC@lcs.mit.edu has some ideas on this subject also.
  
! 6. Better documentation of how GCC works and how to port it.
  
  Here is an outline proposed by Allan Adler.
--- 411,415 ----
  JNC@lcs.mit.edu has some ideas on this subject also.
  
! 7. Better documentation of how GCC works and how to port it.
  
  Here is an outline proposed by Allan Adler.
diff -rc2N gcc-1.35/README gcc-1.36/README
*** gcc-1.35/README	Wed Apr 26 14:40:21 1989
--- gcc-1.36/README	Sun Sep 24 08:15:41 1989
***************
*** 1,3 ****
! This directory contains the version 1.35 test release of the GNU C compiler.
  All bugs reported for previous test releases have been fixed.
  Some bugs surely remain.
--- 1,3 ----
! This directory contains the version 1.36 test release of the GNU C compiler.
  All bugs reported for previous test releases have been fixed.
  Some bugs surely remain.
***************
*** 8,9 ****
--- 8,14 ----
  The GNU C compiler is free software.  See the file COPYING for copying
  permission.
+ 
+ The files print-self.c and print-self1.c are not part of GCC.
+ They are programs that print themselves on standard output.
+ They were written by Dario Dariol and Giovanni Cozzi, and are
+ included for your hacking pleasure.
diff -rc2N gcc-1.35/c-convert.c gcc-1.36/c-convert.c
*** gcc-1.35/c-convert.c	Tue Apr 11 13:43:45 1989
--- gcc-1.36/c-convert.c	Thu Sep 21 18:37:27 1989
***************
*** 102,106 ****
      register tree tem = make_node (REAL_CST);
      TREE_TYPE (tem) = type;
!     TREE_REAL_CST (tem) = 0;
      return tem;
    }
--- 102,106 ----
      register tree tem = make_node (REAL_CST);
      TREE_TYPE (tem) = type;
!     TREE_REAL_CST (tem) = REAL_VALUE_ATOF ("0.0");
      return tem;
    }
***************
*** 178,187 ****
  	    break;
  	  /* In this case, shifting is like multiplication.  */
  
- 	case PLUS_EXPR:
- 	case MINUS_EXPR:
- 	case MULT_EXPR:
  	case MAX_EXPR:
  	case MIN_EXPR:
  	case BIT_AND_EXPR:
  	case BIT_IOR_EXPR:
--- 178,205 ----
  	    break;
  	  /* In this case, shifting is like multiplication.  */
+ 	  goto trunc1;
  
  	case MAX_EXPR:
  	case MIN_EXPR:
+ 	case MULT_EXPR:
+ 	  {
+ 	    tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
+ 	    tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
+ 
+ 	    /* Don't distribute unless the output precision is at least as big
+ 	       as the actual inputs.  Otherwise, the comparison of the
+ 	       truncated values will be wrong.  */
+ 	    if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
+ 		&& outprec >= TYPE_PRECISION (TREE_TYPE (arg1))
+ 		/* If signedness of arg0 and arg1 don't match,
+ 		   we can't necessarily find a type to compare them in.  */
+ 		&& (TREE_UNSIGNED (TREE_TYPE (arg0))
+ 		    == TREE_UNSIGNED (TREE_TYPE (arg1))))
+ 	      goto trunc1;
+ 	    break;
+ 	  }
+ 
+ 	case PLUS_EXPR:
+ 	case MINUS_EXPR:
  	case BIT_AND_EXPR:
  	case BIT_IOR_EXPR:
***************
*** 214,219 ****
  		  {
  		    /* Don't do unsigned arithmetic where signed was wanted,
! 		       or vice versa.  */
! 		    typex = (TREE_UNSIGNED (TREE_TYPE (expr))
  			     ? unsigned_type (typex) : signed_type (typex));
  		    return convert (type,
--- 232,242 ----
  		  {
  		    /* Don't do unsigned arithmetic where signed was wanted,
! 		       or vice versa.
! 		       Exception: if the original operands were unsigned
! 		       then can safely do the work as unsigned.
! 		       And we may need to do it as unsigned
! 		       if we truncate to the original size.  */
! 		    typex = ((TREE_UNSIGNED (TREE_TYPE (expr))
! 			      || TREE_UNSIGNED (TREE_TYPE (arg0)))
  			     ? unsigned_type (typex) : signed_type (typex));
  		    return convert (type,
diff -rc2N gcc-1.35/c-decl.c gcc-1.36/c-decl.c
*** gcc-1.35/c-decl.c	Wed Apr 26 02:44:58 1989
--- gcc-1.36/c-decl.c	Wed Sep  6 16:32:06 1989
***************
*** 44,56 ****
  #define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
  
! static tree grokparms (), grokdeclarator ();
! tree pushdecl ();
! static void builtin_function ();
  
! static tree lookup_tag ();
! static tree lookup_tag_reverse ();
! static tree lookup_name_current_level ();
! static char *redeclaration_error_message ();
  
  /* a node which has tree code ERROR_MARK, and whose type is itself.
     All erroneous expressions are replaced with this node.  All functions
--- 44,79 ----
  #define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
  
! #ifndef CHAR_TYPE_SIZE
! #define CHAR_TYPE_SIZE BITS_PER_UNIT
! #endif
  
! #ifndef SHORT_TYPE_SIZE
! #define SHORT_TYPE_SIZE (BITS_PER_UNIT * MIN ((UNITS_PER_WORD + 1) / 2, 2))
! #endif
! 
! #ifndef INT_TYPE_SIZE
! #define INT_TYPE_SIZE BITS_PER_WORD
! #endif
! 
! #ifndef LONG_TYPE_SIZE
! #define LONG_TYPE_SIZE BITS_PER_WORD
! #endif
! 
! #ifndef LONG_LONG_TYPE_SIZE
! #define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2)
! #endif
! 
! #ifndef FLOAT_TYPE_SIZE
! #define FLOAT_TYPE_SIZE BITS_PER_WORD
! #endif
! 
! #ifndef DOUBLE_TYPE_SIZE
! #define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
! #endif
  
+ #ifndef LONG_DOUBLE_TYPE_SIZE
+ #define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
+ #endif
+ \f


  /* a node which has tree code ERROR_MARK, and whose type is itself.
     All erroneous expressions are replaced with this node.  All functions
***************
*** 179,188 ****
  
  static int warn_about_return_type;
  \f


! /* C-specific option variables.  */
  
! /* Nonzero means `char' should be signed.  */
  
! int flag_signed_char;
  
  /* Nonzero means allow type mismatches in conditional expressions;
--- 202,306 ----
  
  static int warn_about_return_type;
+ 
+ /* Nonzero when starting a function delcared `extern inline'.  */
+ 
+ static int current_extern_inline;
  \f


! /* For each binding contour we allocate a binding_level structure
!  * which records the names defined in that contour.
!  * Contours include:
!  *  0) the global one
!  *  1) one for each function definition,
!  *     where internal declarations of the parameters appear.
!  *  2) one for each compound statement,
!  *     to record its declarations.
!  *
!  * The current meaning of a name can be found by searching the levels from
!  * the current one out to the global one.
!  */
! 
! /* Note that the information in the `names' component of the global contour
!    is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers.  */
! 
! struct binding_level
!   {
!     /* A chain of _DECL nodes for all variables, constants, functions,
!        and typedef types.  These are in the reverse of the order supplied.
!      */
!     tree names;
! 
!     /* A list of structure, union and enum definitions,
!      * for looking up tag names.
!      * It is a chain of TREE_LIST nodes, each of whose TREE_PURPOSE is a name,
!      * or NULL_TREE; and whose TREE_VALUE is a RECORD_TYPE, UNION_TYPE,
!      * or ENUMERAL_TYPE node.
!      */
!     tree tags;
! 
!     /* For each level, a list of shadowed outer-level local definitions
!        to be restored when this level is popped.
!        Each link is a TREE_LIST whose TREE_PURPOSE is an identifier and
!        whose TREE_VALUE is its old definition (a kind of ..._DECL node).  */
!     tree shadowed;
! 
!     /* For each level (except not the global one),
!        a chain of LET_STMT nodes for all the levels
!        that were entered and exited one level down.  */
!     tree blocks;
! 
!     /* The binding level which this one is contained in (inherits from).  */
!     struct binding_level *level_chain;
! 
!     /* Nonzero for the level that holds the parameters of a function.  */
!     char parm_flag;
! 
!     /* Nonzero if this level "doesn't exist" for tags.  */
!     char tag_transparent;
! 
!     /* Nonzero means make a LET_STMT for this level regardless of all else.  */
!     char keep;
! 
!     /* Number of decls in `names' that have incomplete 
!        structure or union types.  */
!     int n_incomplete;
!   };
! 
! #define NULL_BINDING_LEVEL (struct binding_level *) NULL
!   
! /* The binding level currently in effect.  */
! 
! static struct binding_level *current_binding_level;
! 
! /* A chain of binding_level structures awaiting reuse.  */
! 
! static struct binding_level *free_binding_level;
! 
! /* The outermost binding level, for names of file scope.
!    This is created when the compiler is started and exists
!    through the entire run.  */
! 
! static struct binding_level *global_binding_level;
! 
! /* Binding level structures are initialized by copying this one.  */
! 
! static struct binding_level clear_binding_level
!   = {NULL, NULL, NULL, NULL, NULL, 0, 0, 0};
! 
! /* Nonzero means unconditionally make a LET_STMT for the next level pushed.  */
! 
! static int keep_next_level_flag;
! 
! /* Forward declarations.  */
  
! static tree grokparms (), grokdeclarator ();
! tree pushdecl ();
! static void builtin_function ();
  
! static tree lookup_tag ();
! static tree lookup_tag_reverse ();
! static tree lookup_name_current_level ();
! static char *redeclaration_error_message ();
! \f


! /* C-specific option variables.  */
  
  /* Nonzero means allow type mismatches in conditional expressions;
***************
*** 242,250 ****
     return 0 if not recognized.  */
     
  lang_decode_option (p)
       char *p;
  {
!   if (!strcmp (p, "-ftraditional"))
!     flag_traditional = 1, dollars_in_ident = 1;
    else if (!strcmp (p, "-fsigned-char"))
      flag_signed_char = 1;
--- 360,369 ----
     return 0 if not recognized.  */
     
+ int
  lang_decode_option (p)
       char *p;
  {
!   if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional"))
!     flag_traditional = 1, dollars_in_ident = 1, flag_writable_strings = 1;
    else if (!strcmp (p, "-fsigned-char"))
      flag_signed_char = 1;
***************
*** 255,258 ****
--- 374,381 ----
    else if (!strcmp (p, "-fno-unsigned-char"))
      flag_signed_char = 1;
+   else if (!strcmp (p, "-fshort-enums"))
+     flag_short_enums = 1;
+   else if (!strcmp (p, "-fno-short-enums"))
+     flag_short_enums = 0;
    else if (!strcmp (p, "-fcond-mismatch"))
      flag_cond_mismatch = 1;
***************
*** 263,268 ****
    else if (!strcmp (p, "-fno-asm"))
      flag_no_asm = 1;
-   else if (!strcmp (p, "-traditional"))
-     flag_traditional = 1, dollars_in_ident = 1;
    else if (!strcmp (p, "-ansi"))
      flag_no_asm = 1, dollars_in_ident = 0;
--- 386,389 ----
***************
*** 299,379 ****
  }
  \f


- /* For each binding contour we allocate a binding_level structure
-  * which records the names defined in that contour.
-  * Contours include:
-  *  0) the global one
-  *  1) one for each function definition,
-  *     where internal declarations of the parameters appear.
-  *  2) one for each compound statement,
-  *     to record its declarations.
-  *
-  * The current meaning of a name can be found by searching the levels from
-  * the current one out to the global one.
-  */
- 
- /* Note that the information in the `names' component of the global contour
-    is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers.  */
- 
- struct binding_level
-   {
-     /* A chain of _DECL nodes for all variables, constants, functions,
-        and typedef types.  These are in the reverse of the order supplied.
-      */
-     tree names;
- 
-     /* A list of structure, union and enum definitions,
-      * for looking up tag names.
-      * It is a chain of TREE_LIST nodes, each of whose TREE_PURPOSE is a name,
-      * or NULL_TREE; and whose TREE_VALUE is a RECORD_TYPE, UNION_TYPE,
-      * or ENUMERAL_TYPE node.
-      */
-     tree tags;
- 
-     /* For each level, a list of shadowed outer-level local definitions
-        to be restored when this level is popped.
-        Each link is a TREE_LIST whose TREE_PURPOSE is an identifier and
-        whose TREE_VALUE is its old definition (a kind of ..._DECL node).  */
-     tree shadowed;
- 
-     /* For each level (except not the global one),
-        a chain of LET_STMT nodes for all the levels
-        that were entered and exited one level down.  */
-     tree blocks;
- 
-     /* The binding level which this one is contained in (inherits from).  */
-     struct binding_level *level_chain;
- 
-     /* Nonzero for the level that holds the parameters of a function.  */
-     char parm_flag;
- 
-     /* Nonzero if this level "doesn't exist" for tags.  */
-     char tag_transparent;
- 
-     /* Number of decls in `names' that have incomplete 
-        structure or union types.  */
-     int n_incomplete;
-   };
- 
- #define NULL_BINDING_LEVEL (struct binding_level *) NULL
-   
- /* The binding level currently in effect.  */
- 
- static struct binding_level *current_binding_level;
- 
- /* A chain of binding_level structures awaiting reuse.  */
- 
- static struct binding_level *free_binding_level;
- 
- /* The outermost binding level, for names of file scope.
-    This is created when the compiler is started and exists
-    through the entire run.  */
- 
- static struct binding_level *global_binding_level;
- 
- /* Binding level structures are initialized by copying this one.  */
- 
- static struct binding_level clear_binding_level
-   = {NULL, NULL, NULL, NULL, NULL, 0, 0, 0};
- \f


  /* Create a new `struct binding_level'.  */
  
--- 420,423 ----
***************
*** 394,397 ****
--- 438,462 ----
  }
  
+ void
+ keep_next_level ()
+ {
+   keep_next_level_flag = 1;
+ }
+ 
+ /* Identify this binding level as a level of parameters.  */
+ 
+ void
+ declare_parm_level ()
+ {
+   current_binding_level->parm_flag = 1;
+ }
+ 
+ /* Nonzero if currently making parm declarations.  */
+ 
+ in_parm_level_p ()
+ {
+   return current_binding_level->parm_flag;
+ }
+ 
  /* Enter a new binding level.
     If TAG_TRANSPARENT is nonzero, do so only for the name space of variables,
***************
*** 433,436 ****
--- 498,503 ----
    current_binding_level = newlevel;
    newlevel->tag_transparent = tag_transparent;
+   newlevel->keep = keep_next_level_flag;
+   keep_next_level_flag = 0;
  }
  
***************
*** 450,454 ****
     them into the LET_STMT.  */
  
! void
  poplevel (keep, reverse, functionbody)
       int keep;
--- 517,521 ----
     them into the LET_STMT.  */
  
! tree
  poplevel (keep, reverse, functionbody)
       int keep;
***************
*** 464,467 ****
--- 531,536 ----
    tree block = 0;
  
+   keep |= current_binding_level->keep;
+ 
    /* This warning is turned off because it causes warnings for
       declarations like `extern struct foo *x'.  */
***************
*** 588,592 ****
      current_binding_level->blocks
        = chainon (current_binding_level->blocks, subblocks);
!     
  }
  \f


--- 657,664 ----
      current_binding_level->blocks
        = chainon (current_binding_level->blocks, subblocks);
! 
!   if (block)
!     TREE_USED (block) = 1;
!   return block;
  }
  \f


***************
*** 612,616 ****
  	TYPE_NAME (type) = name;
  
!       b->tags = saveable_tree_cons (name, type, b->tags);
      }
  }
--- 684,691 ----
  	TYPE_NAME (type) = name;
  
!       if (b == global_binding_level)
! 	b->tags = perm_tree_cons (name, type, b->tags);
!       else
! 	b->tags = saveable_tree_cons (name, type, b->tags);
      }
  }
***************
*** 645,649 ****
        else if (TREE_CODE (olddecl) == FUNCTION_DECL
  	       && DECL_FUNCTION_CODE (olddecl) != NOT_BUILT_IN)
! 	warning_with_decl (newdecl, "built-in function `%s' redeclared");
        else if (!types_match)
  	{
--- 720,729 ----
        else if (TREE_CODE (olddecl) == FUNCTION_DECL
  	       && DECL_FUNCTION_CODE (olddecl) != NOT_BUILT_IN)
!  	{
!  	  if (!types_match)
!  	    error_with_decl (newdecl, "conflicting types for built-in function `%s'");
!  	  else if (extra_warnings)
!  	    warning_with_decl (newdecl, "built-in function `%s' redeclared");
!  	}
        else if (!types_match)
  	{
***************
*** 707,710 ****
--- 787,796 ----
  				 "follows non-prototype definition here");
  	    }
+ 
+ 	  /* These bits are logically part of the type.  */
+ 	  if (pedantic
+ 	      && (TREE_READONLY (newdecl) != TREE_READONLY (olddecl)
+ 		  || TREE_THIS_VOLATILE (newdecl) != TREE_THIS_VOLATILE (olddecl)))
+ 	    warning_with_decl (newdecl, "type qualifiers for `%s' conflict with previous decl");
  	}
      }
***************
*** 712,715 ****
--- 798,804 ----
    if (TREE_CODE (olddecl) == TREE_CODE (newdecl))
      {
+       int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
+ 			       && DECL_INITIAL (newdecl) != 0);
+ 
        /* Copy all the DECL_... slots specified in the new decl
  	 except for any that we copy here from the old type.  */
***************
*** 740,743 ****
--- 829,838 ----
  	    }
  
+ 	  /* Merge the type qualifiers.  */
+ 	  if (TREE_READONLY (newdecl))
+ 	    TREE_READONLY (olddecl) = 1;
+ 	  if (TREE_THIS_VOLATILE (newdecl))
+ 	    TREE_THIS_VOLATILE (olddecl) = 1;
+ 
  	  /* Merge the initialization information.  */
  	  if (DECL_INITIAL (newdecl) == 0)
***************
*** 746,753 ****
  	  DECL_RTL (newdecl) = DECL_RTL (olddecl);
  	}
!       /* If cannot merge, then use the new type
! 	 and discard the old rtl.  */
        else
! 	TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
  
        /* Merge the storage class information.  */
--- 841,853 ----
  	  DECL_RTL (newdecl) = DECL_RTL (olddecl);
  	}
!       /* If cannot merge, then use the new type and qualifiers,
! 	 and don't preserve the old rtl.  */
        else
! 	{
! 	  TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
! 	  TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
! 	  TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
! 	  TREE_VOLATILE (olddecl) = TREE_VOLATILE (newdecl);
! 	}
  
        /* Merge the storage class information.  */
***************
*** 783,804 ****
  
        /* If redeclaring a builtin function, and not a definition,
! 	 it stays built in.  */
!       if (TREE_CODE (newdecl) == FUNCTION_DECL
! 	  && DECL_INITIAL (newdecl) == 0)
! 	DECL_SET_FUNCTION_CODE (newdecl, DECL_FUNCTION_CODE (olddecl));
! 
!       /* Don't lose track of having output OLDDECL as GDB symbol.  */
!       DECL_BLOCK_SYMTAB_ADDRESS (newdecl)
! 	= DECL_BLOCK_SYMTAB_ADDRESS (olddecl);
! 
!       /* If fn was already defined, don't lose its DECL_RESULT.  */
!       if (TREE_CODE (newdecl) == FUNCTION_DECL
!           && DECL_RESULT (newdecl) == 0)
! 	DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
! 
!       /* If fn was already defined, don't lose its DECL_SAVED_INSNS.  */
!       if (TREE_CODE (newdecl) == FUNCTION_DECL
!           && DECL_SAVED_INSNS (newdecl) == 0)
  	{
  	  DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
  	  DECL_RESULT_TYPE (newdecl) = DECL_RESULT_TYPE (olddecl);
--- 883,892 ----
  
        /* If redeclaring a builtin function, and not a definition,
! 	 it stays built in.
! 	 Also preserve various other info from the definition.  */
!       if (TREE_CODE (newdecl) == FUNCTION_DECL && !new_is_definition)
  	{
+ 	  DECL_SET_FUNCTION_CODE (newdecl, DECL_FUNCTION_CODE (olddecl));
+ 	  DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
  	  DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
  	  DECL_RESULT_TYPE (newdecl) = DECL_RESULT_TYPE (olddecl);
***************
*** 806,809 ****
--- 894,901 ----
  	}
  
+       /* Don't lose track of having output OLDDECL as GDB symbol.  */
+       DECL_BLOCK_SYMTAB_ADDRESS (newdecl)
+ 	= DECL_BLOCK_SYMTAB_ADDRESS (olddecl);
+ 
        bcopy ((char *) newdecl + sizeof (struct tree_common),
  	     (char *) olddecl + sizeof (struct tree_common),
***************
*** 915,918 ****
--- 1007,1021 ----
  	  IDENTIFIER_GLOBAL_VALUE (name) = x;
  
+ 	  /* Don't forget if the function was used via an implicit decl.  */
+ 	  if (IDENTIFIER_IMPLICIT_DECL (name)
+ 	      && TREE_USED (IDENTIFIER_IMPLICIT_DECL (name)))
+ 	    TREE_USED (x) = 1;
+ 
+ 	  /* Don't forget if its address was taken in that way.  */
+ 	  if (IDENTIFIER_IMPLICIT_DECL (name)
+ 	      && TREE_ADDRESSABLE (IDENTIFIER_IMPLICIT_DECL (name)))
+ 	    TREE_ADDRESSABLE (x) = 1;
+ 
+ 	  /* Warn about mismatches against previous implicit decl.  */
  	  if (IDENTIFIER_IMPLICIT_DECL (name) != 0
  	      /* If this real decl matches the implicit, don't complain.  */
***************
*** 939,942 ****
--- 1042,1046 ----
  	  /* Here to install a non-global value.  */
  	  tree oldlocal = IDENTIFIER_LOCAL_VALUE (name);
+ 	  tree oldglobal = IDENTIFIER_GLOBAL_VALUE (name);
  	  IDENTIFIER_LOCAL_VALUE (name) = x;
  
***************
*** 944,951 ****
  	     have a global definition for the function.  */
  	  if (oldlocal == 0
! 	      && IDENTIFIER_GLOBAL_VALUE (name)
  	      && TREE_CODE (x) == FUNCTION_DECL
! 	      && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == FUNCTION_DECL
! 	      && TREE_INLINE (IDENTIFIER_GLOBAL_VALUE (name)))
  	    {
  	      /* We have one.  Their types must agree.  */
--- 1048,1054 ----
  	     have a global definition for the function.  */
  	  if (oldlocal == 0
! 	      && oldglobal != 0
  	      && TREE_CODE (x) == FUNCTION_DECL
! 	      && TREE_CODE (oldglobal) == FUNCTION_DECL)
  	    {
  	      /* We have one.  Their types must agree.  */
***************
*** 954,959 ****
  		warning_with_decl (x, "local declaration of `%s' doesn't match global one");
  	      /* If the global one is inline, make the local one inline.  */
! 	      else if (TREE_INLINE (IDENTIFIER_GLOBAL_VALUE (name)))
! 		IDENTIFIER_LOCAL_VALUE (name) = IDENTIFIER_GLOBAL_VALUE (name);
  	    }
  	  /* If we have a local external declaration,
--- 1057,1065 ----
  		warning_with_decl (x, "local declaration of `%s' doesn't match global one");
  	      /* If the global one is inline, make the local one inline.  */
! 	      else if (TREE_INLINE (oldglobal)
! 		       || DECL_FUNCTION_CODE (oldglobal) != NOT_BUILT_IN
! 		       || (TYPE_ARG_TYPES (TREE_TYPE (oldglobal)) != 0
! 			   && TYPE_ARG_TYPES (TREE_TYPE (x)) == 0))
! 		IDENTIFIER_LOCAL_VALUE (name) = oldglobal;
  	    }
  	  /* If we have a local external declaration,
***************
*** 961,965 ****
  	     then if we later have a file-scope decl it must not be static.  */
  	  if (oldlocal == 0
! 	      && IDENTIFIER_GLOBAL_VALUE (name) == 0
  	      && TREE_EXTERNAL (x)
  	      && TREE_PUBLIC (x))
--- 1067,1071 ----
  	     then if we later have a file-scope decl it must not be static.  */
  	  if (oldlocal == 0
! 	      && oldglobal == 0
  	      && TREE_EXTERNAL (x)
  	      && TREE_PUBLIC (x))
***************
*** 1079,1083 ****
  	 so there can be no error on that account.
  	 However defining the same name twice is no good.  */
!       if (DECL_INITIAL (olddecl) != 0 && DECL_INITIAL (newdecl) != 0)
  	return "redefinition of `%s'";
        return 0;
--- 1185,1193 ----
  	 so there can be no error on that account.
  	 However defining the same name twice is no good.  */
!       if (DECL_INITIAL (olddecl) != 0 && DECL_INITIAL (newdecl) != 0
! 	  /* However, defining once as extern inline and a second
! 	     time in another way is ok.  */
! 	  && !(TREE_INLINE (olddecl) && TREE_EXTERNAL (olddecl)
! 	       && !(TREE_INLINE (newdecl) && TREE_EXTERNAL (newdecl))))
  	return "redefinition of `%s'";
        return 0;
***************
*** 1313,1316 ****
--- 1423,1429 ----
    register tree endlink;
  
+   /* Make identifier nodes long enough for the language-specific slots.  */
+   set_identifier_size (sizeof (struct lang_identifier));
+ 
    current_function_decl = NULL;
    named_labels = NULL;
***************
*** 1324,1332 ****
    /* Define `int' and `char' first so that dbx will output them first.  */
  
- #ifdef INT_TYPE_SIZE
    integer_type_node = make_signed_type (INT_TYPE_SIZE);
- #else
-   integer_type_node = make_signed_type (BITS_PER_WORD);
- #endif
    pushdecl (build_decl (TYPE_DECL, ridpointers[(int) RID_INT],
  			integer_type_node));
--- 1437,1441 ----
***************
*** 1337,1358 ****
    char_type_node =
      (flag_signed_char
!      ? make_signed_type (BITS_PER_UNIT)
!      : make_unsigned_type (BITS_PER_UNIT));
    pushdecl (build_decl (TYPE_DECL, get_identifier ("char"),
  			char_type_node));
  
!   long_integer_type_node = make_signed_type (BITS_PER_WORD);
    pushdecl (build_decl (TYPE_DECL, get_identifier ("long int"),
  			long_integer_type_node));
  
- #ifdef INT_TYPE_SIZE
    unsigned_type_node = make_unsigned_type (INT_TYPE_SIZE);
- #else
-   unsigned_type_node = make_unsigned_type (BITS_PER_WORD);
- #endif
    pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"),
  			unsigned_type_node));
  
!   long_unsigned_type_node = make_unsigned_type (BITS_PER_WORD);
    pushdecl (build_decl (TYPE_DECL, get_identifier ("long unsigned int"),
  			long_unsigned_type_node));
--- 1446,1463 ----
    char_type_node =
      (flag_signed_char
!      ? make_signed_type (CHAR_TYPE_SIZE)
!      : make_unsigned_type (CHAR_TYPE_SIZE));
    pushdecl (build_decl (TYPE_DECL, get_identifier ("char"),
  			char_type_node));
  
!   long_integer_type_node = make_signed_type (LONG_TYPE_SIZE);
    pushdecl (build_decl (TYPE_DECL, get_identifier ("long int"),
  			long_integer_type_node));
  
    unsigned_type_node = make_unsigned_type (INT_TYPE_SIZE);
    pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"),
  			unsigned_type_node));
  
!   long_unsigned_type_node = make_unsigned_type (LONG_TYPE_SIZE);
    pushdecl (build_decl (TYPE_DECL, get_identifier ("long unsigned int"),
  			long_unsigned_type_node));
***************
*** 1360,1371 ****
    /* `unsigned long' or `unsigned int' is the standard type for sizeof.
       Traditionally, use a signed type.  */
! #ifdef INT_TYPE_SIZE
!   if (INT_TYPE_SIZE != BITS_PER_WORD)
      sizetype = flag_traditional ? long_integer_type_node : long_unsigned_type_node;
    else
      sizetype = flag_traditional ? integer_type_node : unsigned_type_node;
- #else
-   sizetype = flag_traditional ? integer_type_node : unsigned_type_node;
- #endif
  
    TREE_TYPE (TYPE_SIZE (integer_type_node)) = sizetype;
--- 1465,1472 ----
    /* `unsigned long' or `unsigned int' is the standard type for sizeof.
       Traditionally, use a signed type.  */
!   if (INT_TYPE_SIZE != LONG_TYPE_SIZE)
      sizetype = flag_traditional ? long_integer_type_node : long_unsigned_type_node;
    else
      sizetype = flag_traditional ? integer_type_node : unsigned_type_node;
  
    TREE_TYPE (TYPE_SIZE (integer_type_node)) = sizetype;
***************
*** 1378,1394 ****
    TREE_TYPE (error_mark_node) = error_mark_node;
  
!   short_integer_type_node = make_signed_type (BITS_PER_UNIT * MIN (UNITS_PER_WORD / 2, 2));
    pushdecl (build_decl (TYPE_DECL, get_identifier ("short int"),
  			short_integer_type_node));
  
!   long_long_integer_type_node = make_signed_type (2 * BITS_PER_WORD);
    pushdecl (build_decl (TYPE_DECL, get_identifier ("long long int"),
  			long_long_integer_type_node));
  
!   short_unsigned_type_node = make_unsigned_type (BITS_PER_UNIT * MIN (UNITS_PER_WORD / 2, 2));
    pushdecl (build_decl (TYPE_DECL, get_identifier ("short unsigned int"),
  			short_unsigned_type_node));
  
!   long_long_unsigned_type_node = make_unsigned_type (2 * BITS_PER_WORD);
    pushdecl (build_decl (TYPE_DECL, get_identifier ("long long unsigned int"),
  			long_long_unsigned_type_node));
--- 1479,1495 ----
    TREE_TYPE (error_mark_node) = error_mark_node;
  
!   short_integer_type_node = make_signed_type (SHORT_TYPE_SIZE);
    pushdecl (build_decl (TYPE_DECL, get_identifier ("short int"),
  			short_integer_type_node));
  
!   long_long_integer_type_node = make_signed_type (LONG_LONG_TYPE_SIZE);
    pushdecl (build_decl (TYPE_DECL, get_identifier ("long long int"),
  			long_long_integer_type_node));
  
!   short_unsigned_type_node = make_unsigned_type (SHORT_TYPE_SIZE);
    pushdecl (build_decl (TYPE_DECL, get_identifier ("short unsigned int"),
  			short_unsigned_type_node));
  
!   long_long_unsigned_type_node = make_unsigned_type (LONG_LONG_TYPE_SIZE);
    pushdecl (build_decl (TYPE_DECL, get_identifier ("long long unsigned int"),
  			long_long_unsigned_type_node));
***************
*** 1395,1403 ****
  
    /* Define both `signed char' and `unsigned char'.  */
!   signed_char_type_node = make_signed_type (BITS_PER_UNIT);
    pushdecl (build_decl (TYPE_DECL, get_identifier ("signed char"),
  			signed_char_type_node));
  
!   unsigned_char_type_node = make_unsigned_type (BITS_PER_UNIT);
    pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned char"),
  			unsigned_char_type_node));
--- 1496,1504 ----
  
    /* Define both `signed char' and `unsigned char'.  */
!   signed_char_type_node = make_signed_type (CHAR_TYPE_SIZE);
    pushdecl (build_decl (TYPE_DECL, get_identifier ("signed char"),
  			signed_char_type_node));
  
!   unsigned_char_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
    pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned char"),
  			unsigned_char_type_node));
***************
*** 1404,1408 ****
  
    float_type_node = make_node (REAL_TYPE);
!   TYPE_PRECISION (float_type_node) = BITS_PER_WORD;
    pushdecl (build_decl (TYPE_DECL, ridpointers[(int) RID_FLOAT],
  			float_type_node));
--- 1505,1509 ----
  
    float_type_node = make_node (REAL_TYPE);
!   TYPE_PRECISION (float_type_node) = FLOAT_TYPE_SIZE;
    pushdecl (build_decl (TYPE_DECL, ridpointers[(int) RID_FLOAT],
  			float_type_node));
***************
*** 1410,1414 ****
  
    double_type_node = make_node (REAL_TYPE);
!   TYPE_PRECISION (double_type_node) = 2 * BITS_PER_WORD;
    pushdecl (build_decl (TYPE_DECL, ridpointers[(int) RID_DOUBLE],
  			double_type_node));
--- 1511,1515 ----
  
    double_type_node = make_node (REAL_TYPE);
!   TYPE_PRECISION (double_type_node) = DOUBLE_TYPE_SIZE;
    pushdecl (build_decl (TYPE_DECL, ridpointers[(int) RID_DOUBLE],
  			double_type_node));
***************
*** 1416,1420 ****
  
    long_double_type_node = make_node (REAL_TYPE);
!   TYPE_PRECISION (long_double_type_node) = 2 * BITS_PER_WORD;
    pushdecl (build_decl (TYPE_DECL, get_identifier ("long double"),
  			long_double_type_node));
--- 1517,1521 ----
  
    long_double_type_node = make_node (REAL_TYPE);
!   TYPE_PRECISION (long_double_type_node) = LONG_DOUBLE_TYPE_SIZE;
    pushdecl (build_decl (TYPE_DECL, get_identifier ("long double"),
  			long_double_type_node));
***************
*** 1512,1516 ****
    builtin_function ("__builtin_labs", long_ftype_long, BUILT_IN_LABS);
    builtin_function ("__builtin_ffs", int_ftype_int, BUILT_IN_FFS);
!   builtin_function ("__builtin_saveregs", default_function_type, BUILT_IN_SAVEREGS);
  #if 0
    /* Support for these has not been written in either expand_builtin
--- 1613,1620 ----
    builtin_function ("__builtin_labs", long_ftype_long, BUILT_IN_LABS);
    builtin_function ("__builtin_ffs", int_ftype_int, BUILT_IN_FFS);
!   builtin_function ("__builtin_saveregs", default_function_type,
! 		    BUILT_IN_SAVEREGS);
!   builtin_function ("__builtin_classify_type", default_function_type,
! 		    BUILT_IN_CLASSIFY_TYPE);
  #if 0
    /* Support for these has not been written in either expand_builtin
***************
*** 1529,1532 ****
--- 1633,1638 ----
    builtin_function ("__builtin_getman", double_ftype_double, BUILT_IN_GETMAN);
  #endif
+ 
+   start_identifier_warnings ();
  }
  
***************
*** 1744,1750 ****
  
  void
! finish_decl (decl, init, asmspec)
       tree decl, init;
!      tree asmspec;
  {
    register tree type = TREE_TYPE (decl);
--- 1850,1856 ----
  
  void
! finish_decl (decl, init, asmspec_tree)
       tree decl, init;
!      tree asmspec_tree;
  {
    register tree type = TREE_TYPE (decl);
***************
*** 1751,1755 ****
--- 1857,1865 ----
    int was_incomplete = (DECL_SIZE (decl) == 0);
    int temporary = allocation_temporary_p ();
+   char *asmspec = 0;
  
+   if (asmspec_tree)
+     asmspec = TREE_STRING_POINTER (asmspec_tree);
+ 
    /* If `start_decl' didn't like having an initialization, ignore it now.  */
  
***************
*** 2570,2573 ****
--- 2680,2686 ----
  	      /* Assume that otherwise the function can be inlined.  */
  	      TREE_INLINE (decl) = 1;
+ 
+ 	    if (specbits & (1 << (int) RID_EXTERN))
+ 	      current_extern_inline = 1;
  	  }
        }
***************
*** 2808,2812 ****
        if (! already)
  	{
! 	  warning ("such a name is accessible only within its parameter list,");
  	  warning ("which is probably not what you want.");
  	  already = 1;
--- 2921,2925 ----
        if (! already)
  	{
! 	  warning ("its scope is only this definition or declaration,");
  	  warning ("which is probably not what you want.");
  	  already = 1;
***************
*** 2925,2928 ****
--- 3038,3045 ----
    TYPE_SIZE (t) = 0;
  
+   if (in_parm_level_p ())
+     warning ((TREE_CODE (t) == UNION_TYPE ? "union defined inside parms"
+ 	      : "structure defined inside parms"));
+ 
    old_momentary = suspend_momentary ();
  
***************
*** 2987,2990 ****
--- 3104,3112 ----
  	      warning_with_decl (x, "negative width in bit-field `%s'");
  	    }
+ 	  else if (width == 0 && DECL_NAME (x) != 0)
+ 	    {
+ 	      error_with_decl (x, "zero width for bit-field `%s'");
+ 	      DECL_INITIAL (x) = NULL;
+ 	    }
  	  else if (width > TYPE_PRECISION (TREE_TYPE (x)))
  	    {
***************
*** 3074,3078 ****
       EMPTY_FIELD_BOUNDARY.  */
    TYPE_ALIGN (t) = round_up_size;
!   
    layout_type (t);
  
--- 3196,3206 ----
       EMPTY_FIELD_BOUNDARY.  */
    TYPE_ALIGN (t) = round_up_size;
! 
!   for (x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
!     {
!       TYPE_FIELDS (x) = TYPE_FIELDS (t);
!       TYPE_ALIGN (x) = TYPE_ALIGN (t);
!     }
! 
    layout_type (t);
  
***************
*** 3172,3175 ****
--- 3300,3306 ----
    register int i;
  
+   if (in_parm_level_p ())
+     warning ("enum defined inside parms");
+ 
    TYPE_VALUES (enumtype) = values;
  
***************
*** 3190,3208 ****
      }
  
! #if 0
!   /* Determine the precision this type needs, lay it out, and define it.  */
! 
!   for (i = maxvalue; i; i >>= 1)
!     TYPE_PRECISION (enumtype)++;
! 
!   if (!TYPE_PRECISION (enumtype))
!     TYPE_PRECISION (enumtype) = 1;
  
!   /* Cancel the laying out previously done for the enum type,
!      so that fixup_unsigned_type will do it over.  */
!   TYPE_SIZE (enumtype) = 0;
  
!   fixup_unsigned_type (enumtype);
! #endif
  
    TREE_INT_CST_LOW (TYPE_MAX_VALUE (enumtype)) = maxvalue;
--- 3321,3340 ----
      }
  
!   if (flag_short_enums)
!     {
!       /* Determine the precision this type needs, lay it out, and define it.  */
  
!       for (i = maxvalue; i; i >>= 1)
! 	TYPE_PRECISION (enumtype)++;
! 
!       if (!TYPE_PRECISION (enumtype))
! 	TYPE_PRECISION (enumtype) = 1;
! 
!       /* Cancel the laying out previously done for the enum type,
! 	 so that fixup_unsigned_type will do it over.  */
!       TYPE_SIZE (enumtype) = 0;
  
!       fixup_unsigned_type (enumtype);
!     }
  
    TREE_INT_CST_LOW (TYPE_MAX_VALUE (enumtype)) = maxvalue;
***************
*** 3231,3234 ****
--- 3363,3370 ----
    /* Validate and default VALUE.  */
  
+   /* Remove no-op casts from the value.  */
+   while (value != 0 && TREE_CODE (value) == NOP_EXPR)
+     value = TREE_OPERAND (value, 0);
+ 
    if (value != 0 && TREE_CODE (value) != INTEGER_CST)
      {
***************
*** 3278,3281 ****
--- 3414,3418 ----
    current_function_returns_null = 0;
    warn_about_return_type = 0;
+   current_extern_inline = 0;
  
    decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1);
***************
*** 3319,3324 ****
      TREE_TYPE (current_function_decl) = TREE_TYPE (old_decl);
  
!   /* This is a definition, not a reference.  */
!   TREE_EXTERNAL (current_function_decl) = 0;
    /* This function exists in static storage.
       (This does not mean `static' in the C sense!)  */
--- 3456,3465 ----
      TREE_TYPE (current_function_decl) = TREE_TYPE (old_decl);
  
!   /* This is a definition, not a reference.
!      So normally clear TREE_EXTERNAL.
!      However, `extern inline' acts like a declaration
!      except for defining how to inline.  So set TREE_EXTERNAL in that case.  */
!   TREE_EXTERNAL (current_function_decl) = current_extern_inline;
! 
    /* This function exists in static storage.
       (This does not mean `static' in the C sense!)  */
***************
*** 3332,3336 ****
  
    pushlevel (0);
!   current_binding_level->parm_flag = 1;
  
    make_function_rtl (current_function_decl);
--- 3473,3477 ----
  
    pushlevel (0);
!   declare_parm_level ();
  
    make_function_rtl (current_function_decl);
***************
*** 3609,3613 ****
    /* Initialize the RTL code for the function.  */
  
!   expand_function_start (fndecl);
  }
  \f


--- 3750,3758 ----
    /* Initialize the RTL code for the function.  */
  
!   init_function_start (fndecl);
! 
!   /* Set up parameters and prepare for return, for the function.  */
! 
!   expand_function_start (fndecl, 0);
  }
  \f


***************
*** 3617,3624 ****
  
     This is called after parsing the body of the function definition.
!    STMTS is the chain of statements that makes up the function body.  */
  
  void
! finish_function ()
  {
    register tree fndecl = current_function_decl;
--- 3762,3770 ----
  
     This is called after parsing the body of the function definition.
!    LINENO is the current line number.  */
  
  void
! finish_function (lineno)
!      int lineno;
  {
    register tree fndecl = current_function_decl;
diff -rc2N gcc-1.35/c-parse.gperf gcc-1.36/c-parse.gperf
*** gcc-1.35/c-parse.gperf	Wed Mar 29 23:47:30 1989
--- gcc-1.36/c-parse.gperf	Fri Jun  9 22:09:03 1989
***************
*** 1,4 ****
  %{
! /* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word c-parse.gperf  */
  %}
  struct resword { char *name; short token; enum rid rid; };
--- 1,4 ----
  %{
! /* Command-line: gperf -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ c-parse.gperf  */ 
  %}
  struct resword { char *name; short token; enum rid rid; };
***************
*** 5,13 ****
--- 5,23 ----
  %%
  __alignof, ALIGNOF, NORID
+ __alignof__, ALIGNOF, NORID
  __asm, ASM, NORID
+ __asm__, ASM, NORID
+ __attribute, ATTRIBUTE, NORID
+ __attribute__, ATTRIBUTE, NORID
  __const, TYPE_QUAL, RID_CONST
+ __const__, TYPE_QUAL, RID_CONST
  __inline, SCSPEC, RID_INLINE
+ __inline__, SCSPEC, RID_INLINE
+ __signed, TYPESPEC, RID_SIGNED
+ __signed__, TYPESPEC, RID_SIGNED
  __typeof, TYPEOF, NORID
+ __typeof__, TYPEOF, NORID
  __volatile, TYPE_QUAL, RID_VOLATILE
+ __volatile__, TYPE_QUAL, RID_VOLATILE
  asm, ASM, NORID
  auto, SCSPEC, RID_AUTO
diff -rc2N gcc-1.35/c-parse.y gcc-1.36/c-parse.y
*** gcc-1.35/c-parse.y	Mon Apr 10 06:20:19 1989
--- gcc-1.36/c-parse.y	Wed Sep 20 01:11:01 1989
***************
*** 24,46 ****
  %expect 8
  
! /* These are the 23 conflicts you should get in parse.output;
     the state numbers may vary if minor changes in the grammar are made.
  
  State 41 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
! State 90 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
! State 97 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
! State 101 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
! State 117 contains 1 shift/reduce conflict.  (See comment at component_decl.)
! State 169 contains 2 shift/reduce conflicts.  (make notype_declarator longer.)
! State 181 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
! State 191 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
! State 197 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
! State 239 contains 2 shift/reduce conflicts.  (make absdcl1 longer if poss.)
! State 269 contains 2 shift/reduce conflicts.  (same for after_type_declarator).
! State 299 contains 2 shift/reduce conflicts.  (similar for absdcl1 again.)
! State 362 contains 1 shift/reduce conflict.  (dangling else.)
! State 370 contains 2 shift/reduce conflicts.  (like 241, other context.)
! State 373 contains 2 shift/reduce conflicts.  (like 241, other context.)
! State 411 contains 2 shift/reduce conflicts.  (like 166 for parm_declarator)?
  */
  
--- 24,38 ----
  %expect 8
  
! /* These are the 8 conflicts you should get in parse.output;
     the state numbers may vary if minor changes in the grammar are made.
  
  State 41 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
! State 92 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
! State 99 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
! State 103 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
! State 119 contains 1 shift/reduce conflict.  (See comment at component_decl.)
! State 183 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
! State 193 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
! State 199 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
  */
  
***************
*** 48,51 ****
--- 40,44 ----
  #include "config.h"
  #include "tree.h"
+ #include "input.h"
  #include "c-parse.h"
  #include "c-tree.h"
***************
*** 103,106 ****
--- 96,100 ----
  %token SIZEOF ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
  %token BREAK CONTINUE RETURN GOTO ASM TYPEOF ALIGNOF
+ %token ATTRIBUTE
  
  /* Add precedence rules to solve dangling else s/r conflict */
***************
*** 139,143 ****
--- 133,140 ----
  %type <ttype> init initlist maybeasm
  %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
+ %type <ttype> maybe_attribute attribute_list attrib
  
+ %type <ttype> compstmt
+ 
  %type <ttype> declarator
  %type <ttype> notype_declarator after_type_declarator
***************
*** 165,175 ****
  static void reinit_parse_for_function ();
  
! /* List of types and structure classes of the current declaration */
  tree current_declspecs;
  
! char *input_filename;		/* source file current line is coming from */
! char *main_input_filename;	/* top-level source file */
  
! int undeclared_variable_notice;	/* 1 if we explained undeclared var errors. */
  
  static int yylex ();
--- 162,172 ----
  static void reinit_parse_for_function ();
  
! /* List of types and structure classes of the current declaration.  */
  tree current_declspecs;
  
! /* Stack of saved values of current_declspecs.  */
! tree declspec_stack;
  
! int undeclared_variable_notice;	/* 1 if we explained undeclared var errors.  */
  
  static int yylex ();
***************
*** 217,220 ****
--- 214,219 ----
  	| error '}'
  	| ';'
+ 		{ if (pedantic)
+ 		    warning ("ANSI C does not allow extra `;' outside of a function"); }
  	;
  
***************
*** 227,231 ****
  		{ store_parm_decls (); }
  	  compstmt_or_error
! 		{ finish_function (); }
  	| typed_declspecs setspecs declarator error
  		{ }
--- 226,230 ----
  		{ store_parm_decls (); }
  	  compstmt_or_error
! 		{ finish_function (lineno); }
  	| typed_declspecs setspecs declarator error
  		{ }
***************
*** 237,241 ****
  		{ store_parm_decls (); }
  	  compstmt_or_error
! 		{ finish_function (); }
  	| declmods setspecs notype_declarator error
  		{ }
--- 236,240 ----
  		{ store_parm_decls (); }
  	  compstmt_or_error
! 		{ finish_function (lineno); }
  	| declmods setspecs notype_declarator error
  		{ }
***************
*** 247,251 ****
  		{ store_parm_decls (); }
  	  compstmt_or_error
! 		{ finish_function (); }
  	| setspecs notype_declarator error
  		{ }
--- 246,250 ----
  		{ store_parm_decls (); }
  	  compstmt_or_error
! 		{ finish_function (lineno); }
  	| setspecs notype_declarator error
  		{ }
***************
*** 307,311 ****
  		      && TREE_PACKED (TREE_OPERAND ($2, 1)))
  		    error ("`__alignof' applied to a bit-field");
! 		  $$ = c_alignof (TREE_TYPE ($2)); }
  	| ALIGNOF '(' typename ')'  %prec HYPERUNARY
  		{ $$ = c_alignof (groktypename ($3)); }
--- 306,327 ----
  		      && TREE_PACKED (TREE_OPERAND ($2, 1)))
  		    error ("`__alignof' applied to a bit-field");
! 		  if (TREE_CODE ($2) == INDIRECT_REF)
! 		    {
! 		      tree t = TREE_OPERAND ($2, 0);
! 		      tree best = t;
! 		      int bestalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));
! 		      while (TREE_CODE (t) == NOP_EXPR
! 			     && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == POINTER_TYPE)
! 			{
! 			  int thisalign;
! 			  t = TREE_OPERAND (t, 0);
! 			  thisalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));
! 			  if (thisalign > bestalign)
! 			    best = t, bestalign = thisalign;
! 			}
! 		      $$ = c_alignof (TREE_TYPE (TREE_TYPE (best)));
! 		    }
! 		  else
! 		    $$ = c_alignof (TREE_TYPE ($2)); }
  	| ALIGNOF '(' typename ')'  %prec HYPERUNARY
  		{ $$ = c_alignof (groktypename ($3)); }
***************
*** 425,429 ****
  	| '(' error ')'
  		{ $$ = error_mark_node; }
! 	| '(' 
  		{ if (current_function_decl == 0)
  		    {
--- 441,445 ----
  	| '(' error ')'
  		{ $$ = error_mark_node; }
! 	| '('
  		{ if (current_function_decl == 0)
  		    {
***************
*** 431,439 ****
  		      YYERROR;
  		    }
  		  $<ttype>$ = expand_start_stmt_expr (); }
  	  compstmt ')'
! 		{ if (pedantic)
  		    warning ("ANSI C forbids braced-groups within expressions");
! 		  $$ = expand_end_stmt_expr ($<ttype>2); }
  	| primary '(' exprlist ')'   %prec '.'
  		{ $$ = build_function_call ($1, $3); }
--- 447,464 ----
  		      YYERROR;
  		    }
+ 		  keep_next_level ();
  		  $<ttype>$ = expand_start_stmt_expr (); }
  	  compstmt ')'
! 		{ tree rtl_exp;
! 		  if (pedantic)
  		    warning ("ANSI C forbids braced-groups within expressions");
! 		  rtl_exp = expand_end_stmt_expr ($<ttype>2);
! 		  $$ = $3;
! 		  TREE_USED ($$) = 0;
! 		  /* Since the statements have side effects,
! 		     consider this volatile.  */
! 		  TREE_VOLATILE ($$) = 1;
! 		  TREE_TYPE ($$) = TREE_TYPE (rtl_exp);
! 		  STMT_BODY ($$) = rtl_exp; }
  	| primary '(' exprlist ')'   %prec '.'
  		{ $$ = build_function_call ($1, $3); }
***************
*** 470,477 ****
  
  /* records the type and storage class specs to use for processing
!    the declarators that follow */
  setspecs: /* empty */
! 		{ current_declspecs = $<ttype>0;
! 		  $$ = suspend_momentary (); }
  	;
  
--- 495,506 ----
  
  /* records the type and storage class specs to use for processing
!    the declarators that follow.
!    Maintains a stack of outer-level values of current_declspecs,
!    for the sake of parm declarations nested in function declarators.  */
  setspecs: /* empty */
! 		{ $$ = suspend_momentary ();
! 		  declspec_stack = tree_cons (0, current_declspecs,
! 					      declspec_stack);
! 		  current_declspecs = $<ttype>0; }
  	;
  
***************
*** 478,484 ****
  decl:
  	typed_declspecs setspecs initdecls ';'
! 		{ resume_momentary ($2); }
  	| declmods setspecs notype_initdecls ';'
! 		{ resume_momentary ($2); }
  	| typed_declspecs ';'
  		{ shadow_tag ($1); }
--- 507,517 ----
  decl:
  	typed_declspecs setspecs initdecls ';'
! 		{ current_declspecs = TREE_VALUE (declspec_stack);
! 		  declspec_stack = TREE_CHAIN (declspec_stack);
! 		  resume_momentary ($2); }
  	| declmods setspecs notype_initdecls ';'
! 		{ current_declspecs = TREE_VALUE (declspec_stack);
! 		  declspec_stack = TREE_CHAIN (declspec_stack);
! 		  resume_momentary ($2); }
  	| typed_declspecs ';'
  		{ shadow_tag ($1); }
***************
*** 585,594 ****
  
  initdcl:
! 	  declarator maybeasm '='
  		{ $<ttype>$ = start_decl ($1, current_declspecs, 1); }
  	  init
  /* Note how the declaration of the variable is in effect while its init is parsed! */
! 		{ finish_decl ($<ttype>4, $5, $2); }
! 	| declarator maybeasm
  		{ tree d = start_decl ($1, current_declspecs, 0);
  		  finish_decl (d, NULL_TREE, $2); }
--- 618,627 ----
  
  initdcl:
! 	  declarator maybeasm maybe_attribute '='
  		{ $<ttype>$ = start_decl ($1, current_declspecs, 1); }
  	  init
  /* Note how the declaration of the variable is in effect while its init is parsed! */
! 		{ finish_decl ($<ttype>5, $6, $2); }
! 	| declarator maybeasm maybe_attribute
  		{ tree d = start_decl ($1, current_declspecs, 0);
  		  finish_decl (d, NULL_TREE, $2); }
***************
*** 596,608 ****
  
  notype_initdcl:
! 	  notype_declarator maybeasm '='
  		{ $<ttype>$ = start_decl ($1, current_declspecs, 1); }
  	  init
  /* Note how the declaration of the variable is in effect while its init is parsed! */
! 		{ finish_decl ($<ttype>4, $5, $2); }
! 	| notype_declarator maybeasm
  		{ tree d = start_decl ($1, current_declspecs, 0);
  		  finish_decl (d, NULL_TREE, $2); }
  	;
  
  init:
--- 629,672 ----
  
  notype_initdcl:
! 	  notype_declarator maybeasm maybe_attribute '='
  		{ $<ttype>$ = start_decl ($1, current_declspecs, 1); }
  	  init
  /* Note how the declaration of the variable is in effect while its init is parsed! */
! 		{ finish_decl ($<ttype>5, $6, $2); }
! 	| notype_declarator maybeasm maybe_attribute
  		{ tree d = start_decl ($1, current_declspecs, 0);
  		  finish_decl (d, NULL_TREE, $2); }
  	;
+ /* the * rules are dummies to accept the Apollo extended syntax
+    so that the header files compile. */
+ maybe_attribute:
+     /* empty */
+     | ATTRIBUTE '(' '(' attribute_list ')' ')'
+         { $$ = $4; }
+     ;
+ 
+ attribute_list
+     : attrib
+     | attribute_list ',' attrib
+     ;
+ 
+ attrib
+     : IDENTIFIER
+ 	{ warning ("`%s' attribute directive ignored",
+ 		   IDENTIFIER_POINTER ($1));
+ 	  $$ = $1; }
+     | IDENTIFIER '(' CONSTANT ')'
+ 	{ /* if not "aligned(1)", then issue warning */
+ 	  if (strcmp (IDENTIFIER_POINTER ($1), "aligned") != 0
+ 	      || TREE_CODE ($3) != INTEGER_CST
+ 	      || TREE_INT_CST_LOW ($3) != 1)
+ 	    warning ("`%s' attribute directive ignored",
+ 		     IDENTIFIER_POINTER ($1));
+ 	  $$ = $1; }
+     | IDENTIFIER '(' identifiers ')'
+ 	{ warning ("`%s' attribute directive ignored",
+ 		   IDENTIFIER_POINTER ($1));
+ 	  $$ = $1; }
+     ;
  
  init:
***************
*** 751,755 ****
  		{ $$ = chainon ($1, $2); }
  	| component_decl_list ';'
! 		{ if (pedantic) 
  		    warning ("extra semicolon in struct or union specified"); }
  	;
--- 815,819 ----
  		{ $$ = chainon ($1, $2); }
  	| component_decl_list ';'
! 		{ if (pedantic)
  		    warning ("extra semicolon in struct or union specified"); }
  	;
***************
*** 767,773 ****
--- 831,841 ----
  	typed_typespecs setspecs components
  		{ $$ = $3;
+ 		  current_declspecs = TREE_VALUE (declspec_stack);
+ 		  declspec_stack = TREE_CHAIN (declspec_stack);
  		  resume_momentary ($2); }
  	| nonempty_type_quals setspecs components
  		{ $$ = $3;
+ 		  current_declspecs = TREE_VALUE (declspec_stack);
+ 		  declspec_stack = TREE_CHAIN (declspec_stack);
  		  resume_momentary ($2); }
  	| error
***************
*** 786,792 ****
  
  component_declarator:
! 	declarator
  		{ $$ = grokfield (input_filename, lineno, $1, current_declspecs, NULL_TREE); }
! 	| declarator ':' expr_no_commas
  		{ $$ = grokfield (input_filename, lineno, $1, current_declspecs, $3); }
  	| ':' expr_no_commas
--- 854,860 ----
  
  component_declarator:
! 	declarator maybe_attribute
  		{ $$ = grokfield (input_filename, lineno, $1, current_declspecs, NULL_TREE); }
! 	| declarator ':' expr_no_commas maybe_attribute
  		{ $$ = grokfield (input_filename, lineno, $1, current_declspecs, $3); }
  	| ':' expr_no_commas
***************
*** 819,823 ****
  		{ $$ = build_tree_list ($1, $2); }
  	;
! 	
  absdcl:   /* an absolute declarator */
  	/* empty */
--- 887,891 ----
  		{ $$ = build_tree_list ($1, $2); }
  	;
! 
  absdcl:   /* an absolute declarator */
  	/* empty */
***************
*** 891,894 ****
--- 959,963 ----
  compstmt_or_error:
  	  compstmt
+ 		{}
  	| error compstmt
  	;
***************
*** 895,909 ****
  
  compstmt: '{' '}'
  	| '{' pushlevel decls xstmts '}'
  		{ expand_end_bindings (getdecls (), 1, 0);
! 		  poplevel (1, 1, 0);
  		  pop_momentary (); }
  	| '{' pushlevel error '}'
  		{ expand_end_bindings (getdecls (), 0, 0);
! 		  poplevel (0, 0, 0);
  		  pop_momentary (); }
  	| '{' pushlevel stmts '}'
  		{ expand_end_bindings (getdecls (), 0, 0);
! 		  poplevel (0, 0, 0);
  		  pop_momentary (); }
  	;
--- 964,979 ----
  
  compstmt: '{' '}'
+ 		{ $$ = 0; }
  	| '{' pushlevel decls xstmts '}'
  		{ expand_end_bindings (getdecls (), 1, 0);
! 		  $$ = poplevel (1, 1, 0);
  		  pop_momentary (); }
  	| '{' pushlevel error '}'
  		{ expand_end_bindings (getdecls (), 0, 0);
! 		  $$ = poplevel (0, 0, 0);
  		  pop_momentary (); }
  	| '{' pushlevel stmts '}'
  		{ expand_end_bindings (getdecls (), 0, 0);
! 		  $$ = poplevel (0, 0, 0);
  		  pop_momentary (); }
  	;
***************
*** 917,923 ****
  
  stmt:
! 	  compstmt
  	| expr ';'
  		{ emit_line_note (input_filename, lineno);
  		  expand_expr_stmt ($1);
  		  clear_momentary (); }
--- 987,999 ----
  
  stmt:
! 	  compstmt	{}
  	| expr ';'
  		{ emit_line_note (input_filename, lineno);
+ 		  /* Do default conversion if safe and possibly important,
+ 		     in case within ({...}).  */
+ 		  if ((TREE_CODE (TREE_TYPE ($1)) == ARRAY_TYPE
+ 		       && lvalue_p ($1))
+ 		      || TREE_CODE (TREE_TYPE ($1)) == FUNCTION_TYPE)
+ 		    $1 = default_conversion ($1);
  		  expand_expr_stmt ($1);
  		  clear_momentary (); }
***************
*** 929,933 ****
  		{ expand_end_cond (); }
  	| WHILE
! 		{ emit_line_note (input_filename, lineno);
  		  expand_start_loop (1); }
  	  '(' expr ')'
--- 1005,1010 ----
  		{ expand_end_cond (); }
  	| WHILE
! 		{ emit_nop ();
! 		  emit_line_note (input_filename, lineno);
  		  expand_start_loop (1); }
  	  '(' expr ')'
***************
*** 937,941 ****
  		{ expand_end_loop (); }
  	| DO
! 		{ emit_line_note (input_filename, lineno);
  		  expand_start_loop_continue_elsewhere (1); }
  	  stmt WHILE
--- 1014,1019 ----
  		{ expand_end_loop (); }
  	| DO
! 		{ emit_nop ();
! 		  emit_line_note (input_filename, lineno);
  		  expand_start_loop_continue_elsewhere (1); }
  	  stmt WHILE
***************
*** 946,952 ****
  		  expand_end_loop ();
  		  clear_momentary (); }
! 	| FOR 
  	  '(' xexpr ';'
! 		{ emit_line_note (input_filename, lineno);
  		  if ($3) expand_expr_stmt ($3);
  		  expand_start_loop_continue_elsewhere (1); }
--- 1024,1031 ----
  		  expand_end_loop ();
  		  clear_momentary (); }
! 	| FOR
  	  '(' xexpr ';'
! 		{ emit_nop ();
! 		  emit_line_note (input_filename, lineno);
  		  if ($3) expand_expr_stmt ($3);
  		  expand_start_loop_continue_elsewhere (1); }
***************
*** 1023,1027 ****
  		  if ( ! expand_exit_something ())
  		    error ("break statement not within loop or switch"); }
! 	| CONTINUE ';'	
  		{ emit_line_note (input_filename, lineno);
  		  if (! expand_continue_loop ())
--- 1102,1106 ----
  		  if ( ! expand_exit_something ())
  		    error ("break statement not within loop or switch"); }
! 	| CONTINUE ';'
  		{ emit_line_note (input_filename, lineno);
  		  if (! expand_continue_loop ())
***************
*** 1035,1038 ****
--- 1114,1118 ----
  	| ASM maybe_type_qual '(' string ')' ';'
  		{ if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
+ 		  emit_line_note (input_filename, lineno);
  		  expand_asm ($4); }
  	/* This is the case with just output operands.  */
***************
*** 1039,1042 ****
--- 1119,1123 ----
  	| ASM maybe_type_qual '(' string ':' asm_operands ')' ';'
  		{ if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
+ 		  emit_line_note (input_filename, lineno);
  		  c_expand_asm_operands ($4, $6, NULL_TREE, NULL_TREE,
  					 $2 == ridpointers[(int)RID_VOLATILE],
***************
*** 1045,1048 ****
--- 1126,1130 ----
  	| ASM maybe_type_qual '(' string ':' asm_operands ':' asm_operands ')' ';'
  		{ if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
+ 		  emit_line_note (input_filename, lineno);
  		  c_expand_asm_operands ($4, $6, $8, NULL_TREE,
  					 $2 == ridpointers[(int)RID_VOLATILE],
***************
*** 1052,1055 ****
--- 1134,1138 ----
    	  asm_operands ':' asm_clobbers ')' ';'
  		{ if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
+ 		  emit_line_note (input_filename, lineno);
  		  c_expand_asm_operands ($4, $6, $8, $10,
  					 $2 == ridpointers[(int)RID_VOLATILE],
***************
*** 1063,1066 ****
--- 1146,1150 ----
  	| identifier ':'
  		{ tree label = define_label (input_filename, lineno, $1);
+ 		  emit_nop ();
  		  if (label)
  		    expand_label (label); }
***************
*** 1107,1114 ****
  
  asm_clobbers:
! 	  STRING
! 		{ $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
! 	| asm_clobbers ',' STRING
! 		{ $$ = tree_cons (NULL_TREE, $3, $1); }
  	;
  
--- 1191,1198 ----
  
  asm_clobbers:
! 	  string
! 		{ $$ = tree_cons (NULL_TREE, combine_strings ($1), NULL_TREE); }
! 	| asm_clobbers ',' string
! 		{ $$ = tree_cons (NULL_TREE, combine_strings ($3), $1); }
  	;
  
***************
*** 1116,1120 ****
     Its value is a list of ..._TYPE nodes.  */
  parmlist:
! 		{ pushlevel (0); }
  	  parmlist_1
  		{ $$ = $2;
--- 1200,1205 ----
     Its value is a list of ..._TYPE nodes.  */
  parmlist:
! 		{ pushlevel (0);
! 		  declare_parm_level (); }
  	  parmlist_1
  		{ $$ = $2;
***************
*** 1126,1130 ****
     Its value is a list of ..._TYPE nodes or a list of identifiers.  */
  parmlist_or_identifiers:
! 		{ pushlevel (0); }
  	  parmlist_or_identifiers_1
  		{ $$ = $2;
--- 1211,1216 ----
     Its value is a list of ..._TYPE nodes or a list of identifiers.  */
  parmlist_or_identifiers:
! 		{ pushlevel (0);
! 		  declare_parm_level (); }
  	  parmlist_or_identifiers_1
  		{ $$ = $2;
***************
*** 1157,1161 ****
  	;
  
! parms:	
  	parm
  		{ push_parm_decl ($1); }
--- 1243,1247 ----
  	;
  
! parms:
  	parm
  		{ push_parm_decl ($1); }
***************
*** 1180,1184 ****
  
  /* A nonempty list of identifiers.  */
! identifiers:	
  	IDENTIFIER
  		{ $$ = build_tree_list (NULL_TREE, $1); }
--- 1266,1270 ----
  
  /* A nonempty list of identifiers.  */
! identifiers:
  	IDENTIFIER
  		{ $$ = build_tree_list (NULL_TREE, $1); }
***************
*** 1195,1199 ****
     We return an INDIRECT_REF whose "contents" are TARGET
     and whose type is the modifier list.  */
!    
  static tree
  make_pointer_declarator (type_quals, target)
--- 1281,1285 ----
     We return an INDIRECT_REF whose "contents" are TARGET
     and whose type is the modifier list.  */
! 
  static tree
  make_pointer_declarator (type_quals, target)
***************
*** 1240,1244 ****
  	length = length * UNITS_PER_WORD + wide_length;
  
!       p = (char *) oballoc (length);
  
        /* Copy the individual strings into the new combined string.
--- 1326,1330 ----
  	length = length * UNITS_PER_WORD + wide_length;
  
!       p = (char *) savealloc (length);
  
        /* Copy the individual strings into the new combined string.
***************
*** 1320,1331 ****
  
  #define MIN_WORD_LENGTH     2      /* minimum size for C keyword */
! #define MAX_WORD_LENGTH     9      /* maximum size for C keyword */
! #define MIN_HASH_VALUE      4      /* range of the hash keys values  */
! #define MAX_HASH_VALUE      52     /* for the perfect hash generator */
  #define NORID RID_UNUSED
  
  /* This function performs the minimum-perfect hash mapping from input
!    string to reswords table index.  It only looks at the first and 
!    last characters in the string, thus assuring the O(1) lookup time 
     (this keeps our constant down to an insignificant amount!).  Compiling
     the following 2 functions as inline removes all overhead of the
--- 1406,1417 ----
  
  #define MIN_WORD_LENGTH     2      /* minimum size for C keyword */
! #define MAX_WORD_LENGTH     13     /* maximum size for C keyword */
! #define MIN_HASH_VALUE      7      /* range of the hash keys values  */
! #define MAX_HASH_VALUE      91     /* for the perfect hash generator */
  #define NORID RID_UNUSED
  
  /* This function performs the minimum-perfect hash mapping from input
!    string to reswords table index.  It only looks at the first and
!    last characters in the string, thus assuring the O(1) lookup time
     (this keeps our constant down to an insignificant amount!).  Compiling
     the following 2 functions as inline removes all overhead of the
***************
*** 1333,1339 ****
  
  #ifdef __GNUC__
! inline 
  #endif
! static int 
  hash (str, len)
       register char *str;
--- 1419,1425 ----
  
  #ifdef __GNUC__
! __inline
  #endif
! static int
  hash (str, len)
       register char *str;
***************
*** 1341,1386 ****
  {
  /* This table is used to build the hash table index that recognizes
!    reserved words in 0(1) steps.  It is larger than strictly necessary, 
!    but I'm trading off the space for the time-saving luxury of avoiding 
!    subtraction of an offset.  All those ``52's'' (actually just a
!    short-hand for MAX_HASH_VALUE #defined above) are used to speed up 
!    the search when the string found on the input stream doesn't have a 
!    first or last character that is part of the set of alphabetic 
!    characters that comprise the first or last characters in C 
     reserved words. */
  
!   static int hash_table[] = 
      {
!       52,  52,  52,  52,  52,  52,  52,  52,  52,  52,
!       52,  52,  52,  52,  52,  52,  52,  52,  52,  52,
!       52,  52,  52,  52,  52,  52,  52,  52,  52,  52,
!       52,  52,  52,  52,  52,  52,  52,  52,  52,  52,
!       52,  52,  52,  52,  52,  52,  52,  52,  52,  52,
!       52,  52,  52,  52,  52,  52,  52,  52,  52,  52,
!       52,  52,  52,  52,  52,  52,  52,  52,  52,  52,
!       52,  52,  52,  52,  52,  52,  52,  52,  52,  52,
!       52,  52,  52,  52,  52,  52,  52,  52,  52,  52,
!       52,  52,  52,  52,  52,   7,  52,  12,   0,  18,
!        5,   0,  13,   2,   2,  29,  52,   0,   7,  37,
!       25,   0,  52,  52,  17,  19,   0,  21,   1,   3,
!       52,  52,  52,  52,  52,  52,  52,  52,
      };
! 
!   /* The hash function is very simple: add the length of STR
!      to the hash_table value of its first and last character. 
!      Putting LEN near LEN - 1 generates slightly better 
!      code... */
  
!   return len + hash_table[str[len - 1]] + hash_table[str[0]];
  }
  
  /* This routine attempts to match the string found in the reswords table
!    with the one from the input stream.  If all the relevant details 
     match then an actual strcmp comparison is performed and the address of
!    correct struct resword entry is returned.  Otherwise, a NULL 
     pointer is returned. */
  
  #ifdef __GNUC__
! inline 
  #endif
  struct resword *
--- 1427,1476 ----
  {
  /* This table is used to build the hash table index that recognizes
!    reserved words in 0(1) steps.  It is larger than strictly necessary,
!    but I'm trading off the space for the time-saving luxury of avoiding
!    subtraction of an offset.  All those ``91's'' (actually just a
!    short-hand for MAX_HASH_VALUE #defined above) are used to speed up
!    the search when the string found on the input stream doesn't have a
!    first or last character that is part of the set of alphabetic
!    characters that comprise the first or last characters in C
     reserved words. */
  
!   static int hash_table[] =
      {
!      91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
!      91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
!      91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
!      91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
!      91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
!      91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
!      91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
!      91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
!      91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
!      91, 91, 91, 91, 91,  1, 91,  2,  1, 32,
!       7,  5, 18, 20,  1, 17, 91,  1, 18,  1,
!      28,  1, 23, 91, 12, 20,  1, 41,  7, 15,
!      91, 91, 10, 91, 91, 91, 91, 91,
      };
!   register int hval = len ;
  
!   switch (hval)
!     {
!       default:
!       case 3:
!         hval += hash_table[str[2]];
!       case 2:
!       case 1:
!         return hval + hash_table[str[0]] + hash_table[str[len - 1]];
!     }
  }
  
  /* This routine attempts to match the string found in the reswords table
!    with the one from the input stream.  If all the relevant details
     match then an actual strcmp comparison is performed and the address of
!    correct struct resword entry is returned.  Otherwise, a NULL
     pointer is returned. */
  
  #ifdef __GNUC__
! __inline
  #endif
  struct resword *
***************
*** 1392,1459 ****
       The order of keywords has been chosen for perfect hashing.
       Therefore, this table cannot be updated by hand.
!      Use the program ``gperf,'' available with the latest libg++ 
!      distribution, to generate an updated table.  The command-line
!      arguments to build this table were: gperf -g -o -j1 -t gnuc.input  */
  
!   static struct resword reswords[] = 
!     {
!       { "",},{ "",},{ "",},{ "",},
!       { "else", ELSE, NORID },
!       { "break", BREAK, NORID },
!       { "goto", GOTO, NORID },
!       { "do", DO, NORID },
!       { "while", WHILE, NORID },
!       { "volatile", TYPE_QUAL, RID_VOLATILE },
!       { "void", TYPESPEC, RID_VOID },
!       { "double", TYPESPEC, RID_DOUBLE },
!       { "default", DEFAULT, NORID },
!       { "long", TYPESPEC, RID_LONG },
!       { "__const", TYPE_QUAL, RID_CONST },
!       { "__inline", SCSPEC, RID_INLINE },
!       { "auto", SCSPEC, RID_AUTO },
!       { "__volatile", TYPE_QUAL, RID_VOLATILE },
!       { "float", TYPESPEC, RID_FLOAT },
!       { "typeof", TYPEOF, NORID },
!       { "typedef", SCSPEC, RID_TYPEDEF },
!       { "",},
!       { "case", CASE, NORID },
!       { "const", TYPE_QUAL, RID_CONST },
!       { "short", TYPESPEC, RID_SHORT },
!       { "struct", STRUCT, NORID },
!       { "continue", CONTINUE, NORID },
!       { "switch", SWITCH, NORID },
!       { "__typeof", TYPEOF, NORID },
!       { "__alignof", ALIGNOF, NORID },
!       { "signed", TYPESPEC, RID_SIGNED },
!       { "extern", SCSPEC, RID_EXTERN },
!       { "int", TYPESPEC, RID_INT },
!       { "for", FOR, NORID },
!       { "unsigned", TYPESPEC, RID_UNSIGNED },
!       { "inline", SCSPEC, RID_INLINE },
!       { "",},{ "",},
!       { "sizeof", SIZEOF, NORID },
!       { "char", TYPESPEC, RID_CHAR },
!       { "",},
!       { "enum", ENUM, NORID },
!       { "register", SCSPEC, RID_REGISTER },
!       { "static", SCSPEC, RID_STATIC },
!       { "if", IF, NORID },
!       { "",},{ "",},{ "",},
!       { "return", RETURN, NORID },
!       { "__asm", ASM, NORID },
!       { "",},
!       { "union", UNION, NORID },
!       { "asm", ASM, NORID },
      };
  
!   if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) 
      {
        register int key = hash (str, len);
  
!       if (key <= MAX_HASH_VALUE) 
          {
            register char *s = reswords[key].name;
  
!           if (*s == *str && !strcmp (str + 1, s + 1)) 
              return &reswords[key];
          }
--- 1482,1566 ----
       The order of keywords has been chosen for perfect hashing.
       Therefore, this table cannot be updated by hand.
!      Use the program ``gperf,'' available with the latest libg++
!      distribution, to generate an updated table.  A file called
!      c-parse.gperf, distributed with GNU C, contains the keyword file.  */
  
!   static struct resword reswords[] =
!     {
!       { "", }, { "", }, { "", }, { "", }, { "", }, { "", }, { "", }, 
!       {"asm",  ASM, NORID },
!       {"auto",  SCSPEC, RID_AUTO },
!       {"__asm",  ASM, NORID },
!       {"do",  DO, NORID },
!       {"__asm__",  ASM, NORID },
!       {"break",  BREAK, NORID },
!       {"__typeof__",  TYPEOF, NORID },
!       { "", }, 
!       {"__alignof__",  ALIGNOF, NORID },
!       { "", }, 
!       {"__attribute__",  ATTRIBUTE, NORID },
!       { "", }, 
!       {"__attribute",  ATTRIBUTE, NORID },
!       { "", }, 
!       {"__volatile__",  TYPE_QUAL, RID_VOLATILE },
!       {"int",  TYPESPEC, RID_INT },
!       {"__volatile",  TYPE_QUAL, RID_VOLATILE },
!       { "", }, 
!       {"float",  TYPESPEC, RID_FLOAT },
!       {"goto",  GOTO, NORID },
!       {"short",  TYPESPEC, RID_SHORT },
!       {"__typeof",  TYPEOF, NORID },
!       {"__inline__",  SCSPEC, RID_INLINE },
!       {"__alignof",  ALIGNOF, NORID },
!       {"__inline",  SCSPEC, RID_INLINE },
!       {"__signed__",  TYPESPEC, RID_SIGNED },
!       {"default",  DEFAULT, NORID },
!       {"else",  ELSE, NORID },
!       {"void",  TYPESPEC, RID_VOID },
!       {"__signed",  TYPESPEC, RID_SIGNED },
!       {"if",  IF, NORID },
!       {"volatile",  TYPE_QUAL, RID_VOLATILE },
!       {"struct",  STRUCT, NORID },
!       {"extern",  SCSPEC, RID_EXTERN },
!       {"__const",  TYPE_QUAL, RID_CONST },
!       {"while",  WHILE, NORID },
!       {"__const__",  TYPE_QUAL, RID_CONST },
!       {"switch",  SWITCH, NORID },
!       {"for",  FOR, NORID },
!       {"inline",  SCSPEC, RID_INLINE },
!       {"return",  RETURN, NORID },
!       {"typeof",  TYPEOF, NORID },
!       {"typedef",  SCSPEC, RID_TYPEDEF },
!       {"char",  TYPESPEC, RID_CHAR },
!       {"enum",  ENUM, NORID },
!       {"register",  SCSPEC, RID_REGISTER },
!       {"signed",  TYPESPEC, RID_SIGNED },
!       {"sizeof",  SIZEOF, NORID },
!       { "", }, { "", }, { "", }, { "", }, 
!       {"double",  TYPESPEC, RID_DOUBLE },
!       {"static",  SCSPEC, RID_STATIC },
!       {"case",  CASE, NORID },
!       { "", }, { "", }, { "", }, { "", }, 
!       {"const",  TYPE_QUAL, RID_CONST },
!       { "", }, { "", }, { "", }, 
!       {"long",  TYPESPEC, RID_LONG },
!       { "", }, { "", }, 
!       {"continue",  CONTINUE, NORID },
!       { "", }, { "", }, 
!       {"unsigned",  TYPESPEC, RID_UNSIGNED },
!       { "", }, { "", }, { "", }, { "", }, { "", }, { "", }, { "", }, { "", }, { "", }, 
!       { "", }, { "", }, { "", }, { "", }, { "", }, 
!       {"union",  UNION, NORID },
      };
  
!   if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
      {
        register int key = hash (str, len);
  
!       if (key <= MAX_HASH_VALUE)
          {
            register char *s = reswords[key].name;
  
!           if (*s == *str && !strcmp (str + 1, s + 1))
              return &reswords[key];
          }
***************
*** 1573,1576 ****
--- 1680,1684 ----
  	case '\f':
  	case '\r':
+ 	case '\v':
  	case '\b':
  	  c = getc (finput);
***************
*** 1732,1735 ****
--- 1840,1844 ----
        && TREE_CODE (yylval.ttype) == INTEGER_CST)
      {
+       int old_lineno = lineno;
        /* subtract one, because it is the following line that
  	 gets the specified number */
***************
*** 1765,1771 ****
        if (main_input_filename == 0)
  	main_input_filename = input_filename;
      }
    else
!     error ("invalid #line");
  
    /* skip the rest of this line.  */
--- 1874,1917 ----
        if (main_input_filename == 0)
  	main_input_filename = input_filename;
+ 
+       /* Is this the last nonwhite stuff on the line?  */
+       c = getc (finput);
+       while (c == ' ' || c == '\t')
+ 	c = getc (finput);
+       if (c == '\n')
+ 	return c;
+       ungetc (c, finput);
+ 
+       token = yylex ();
+ 
+       /* `1' after file name means entering new file.
+ 	 `2' after file name means just left a file.  */
+ 
+       if (token == CONSTANT
+ 	  && TREE_CODE (yylval.ttype) == INTEGER_CST)
+ 	{
+ 	  if (TREE_INT_CST_LOW (yylval.ttype) == 1)
+ 	    {
+ 	      struct file_stack *p
+ 		= (struct file_stack *) xmalloc (sizeof (struct file_stack));
+ 	      input_file_stack->line = old_lineno;
+ 	      p->next = input_file_stack;
+ 	      p->name = input_filename;
+ 	      input_file_stack = p;
+ 	      input_file_stack_tick++;
+ 	    }
+ 	  else if (input_file_stack->next)
+ 	    {
+ 	      struct file_stack *p = input_file_stack;
+ 	      input_file_stack = p->next;
+ 	      free (p);
+ 	      input_file_stack_tick++;
+ 	    }
+ 	  else
+ 	    error ("#-lines for entering and leaving files don't match");
+ 	}
      }
    else
!     error ("invalid #-line");
  
    /* skip the rest of this line.  */
***************
*** 1817,1823 ****
        if (count == 0)
  	error ("\\x used with no following hex digits");
!       if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)
! 	  || ((1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4))
! 	      <= firstdig))
  	warning ("hex escape out of range");
        return code;
--- 1963,1969 ----
        if (count == 0)
  	error ("\\x used with no following hex digits");
!       else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)
! 	       || ((1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4))
! 		   <= firstdig))
  	warning ("hex escape out of range");
        return code;
***************
*** 1930,1933 ****
--- 2076,2080 ----
        case '\f':
        case '\r':
+       case '\v':
        case '\b':
  	c = getc (finput);
***************
*** 2011,2015 ****
  
        /* Try to recognize a keyword.  Uses minimum-perfect hash function */
!   
        {
  	register struct resword *ptr;
--- 2158,2162 ----
  
        /* Try to recognize a keyword.  Uses minimum-perfect hash function */
! 
        {
  	register struct resword *ptr;
***************
*** 2065,2068 ****
--- 2212,2216 ----
  	   giving us 64 bits of reliable precision */
  	short shorts[8];
+ 	int overflow = 0;
  
  	enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag
***************
*** 2165,2172 ****
  		  largest_digit = c;
  		numdigits++;
! 	    
  		for (count = 0; count < 8; count++)
  		  {
! 		    (shorts[count] *= base);
  		    if (count)
  		      {
--- 2313,2320 ----
  		  largest_digit = c;
  		numdigits++;
! 
  		for (count = 0; count < 8; count++)
  		  {
! 		    shorts[count] *= base;
  		    if (count)
  		      {
***************
*** 2176,2180 ****
  		    else shorts[0] += c;
  		  }
!     
  		if (p >= token_buffer + maxtoken - 3)
  		  p = extend_token_buffer (p);
--- 2324,2332 ----
  		    else shorts[0] += c;
  		  }
! 
! 		if (shorts[7] >= 1<<8
! 		    || shorts[7] < - (1 << 8))
! 		  overflow = TRUE;
! 
  		if (p >= token_buffer + maxtoken - 3)
  		  p = extend_token_buffer (p);
***************
*** 2233,2238 ****
  		   Sunos 4 spuriously returns ERANGE for them.  */
  		while (*p1 == '0') p1++;
! 		if (*p1 == '.') p1++;
! 		while (*p1 == '0') p1++;
  		if (*p1 != 0)
  		  warning ("floating point number exceeds range of `double'");
--- 2385,2399 ----
  		   Sunos 4 spuriously returns ERANGE for them.  */
  		while (*p1 == '0') p1++;
! 		if (*p1 == '.')
! 		  {
! 		    p1++;
! 		    while (*p1 == '0') p1++;
! 		  }
! 		if (*p1 == 'e' || *p1 == 'E')
! 		  {
! 		    /* with significand==0, ignore the exponent */
! 		    p1++;
! 		    while (*p1 != 0) p1++;
! 		  }
  		if (*p1 != 0)
  		  warning ("floating point number exceeds range of `double'");
***************
*** 2245,2248 ****
--- 2406,2410 ----
  		if (c == 'f' || c == 'F')
  		  {
+ 		    float floater;
  		    if (f_seen)
  		      error ("two `f's in floating constant");
***************
*** 2249,2252 ****
--- 2411,2416 ----
  		    f_seen = 1;
  		    type = float_type_node;
+ 		    floater = value;
+ 		    value = floater;
  		  }
  		else if (c == 'l' || c == 'L')
***************
*** 2289,2292 ****
--- 2453,2457 ----
  	    int spec_unsigned = 0;
  	    int spec_long = 0;
+ 	    int spec_long_long = 0;
  
  	    while (1)
***************
*** 2301,2305 ****
  		  {
  		    if (spec_long)
! 		      error ("two `l's in integer constant");
  		    spec_long = 1;
  		  }
--- 2466,2476 ----
  		  {
  		    if (spec_long)
! 		      {
! 			if (spec_long_long)
! 			  error ("three `l's in integer constant");
! 			else if (pedantic)
! 			  warning ("ANSI C forbids long long integer constants");
! 			spec_long_long = 1;
! 		      }
  		    spec_long = 1;
  		  }
***************
*** 2327,2339 ****
  	    ungetc (c, finput);
  
! 	    if (shorts[7] | shorts[6] | shorts[5] | shorts[4])
  	      warning ("integer constant out of range");
  
  	    /* This is simplified by the fact that our constant
  	       is always positive.  */
  	    yylval.ttype
! 	      = build_int_2 ((shorts[3]<<24) + (shorts[2]<<16) + (shorts[1]<<8) + shorts[0],
! 			     0);
!     
  	    if (!spec_long && !spec_unsigned
  		&& int_fits_type_p (yylval.ttype, integer_type_node))
--- 2498,2520 ----
  	    ungetc (c, finput);
  
! 	    if ((overflow || shorts[7] || shorts[6] || shorts[5] || shorts[4])
! 		&& !spec_long_long)
  	      warning ("integer constant out of range");
  
+ 	    /* If it won't fit in a signed long long, make it unsigned.
+ 	       We can't distinguish based on the tree node because
+ 	       any integer constant fits any long long type.  */
+ 	    if (shorts[7] >= (1<<8))
+ 	      spec_unsigned = 1;
+ 
  	    /* This is simplified by the fact that our constant
  	       is always positive.  */
  	    yylval.ttype
! 	      = (build_int_2
! 		 ((shorts[3]<<24) + (shorts[2]<<16) + (shorts[1]<<8) + shorts[0],
! 		  (spec_long_long
! 		   ? (shorts[7]<<24) + (shorts[6]<<16) + (shorts[5]<<8) + shorts[4]
! 		   : 0)));
! 
  	    if (!spec_long && !spec_unsigned
  		&& int_fits_type_p (yylval.ttype, integer_type_node))
***************
*** 2341,2357 ****
  
  	    else if (!spec_long && base != 10
! 		&& int_fits_type_p (yylval.ttype, unsigned_type_node))
  	      type = unsigned_type_node;
  
! 	    else if (!spec_unsigned
! 		&& int_fits_type_p (yylval.ttype, long_integer_type_node))
  	      type = long_integer_type_node;
  
  	    else
  	      {
! 		type = long_unsigned_type_node;
! 		if (! int_fits_type_p (yylval.ttype, long_unsigned_type_node))
! 		  warning ("integer constant out of range");
  	      }
  	    TREE_TYPE (yylval.ttype) = type;
  	  }
--- 2522,2552 ----
  
  	    else if (!spec_long && base != 10
! 		     && int_fits_type_p (yylval.ttype, unsigned_type_node))
  	      type = unsigned_type_node;
  
! 	    else if (!spec_unsigned && !spec_long_long
! 		     && int_fits_type_p (yylval.ttype, long_integer_type_node))
  	      type = long_integer_type_node;
  
+ 	    else if (! spec_long_long
+ 		     && int_fits_type_p (yylval.ttype,
+ 					 long_unsigned_type_node))
+ 	      type = long_unsigned_type_node;
+ 
+ 	    else if (! spec_unsigned
+ 		     && int_fits_type_p (yylval.ttype,
+ 					 long_long_integer_type_node))
+ 	      type = long_long_integer_type_node;
+ 
+ 	    else if (int_fits_type_p (yylval.ttype,
+ 				      long_long_unsigned_type_node))
+ 	      type = long_long_unsigned_type_node;
+ 
  	    else
  	      {
! 		type = long_long_integer_type_node;
! 		warning ("integer constant out of range");
  	      }
+ 
  	    TREE_TYPE (yylval.ttype) = type;
  	  }
***************
*** 2362,2394 ****
      case '\'':
      char_constant:
-       c = getc (finput);
        {
! 	register int code = 0;
  
!       tryagain:
  
! 	if (c == '\\')
! 	  {
! 	    c = readescape ();
! 	    if (c < 0)
! 	      goto tryagain;
! 	    if (!wide_flag && c >= (1 << BITS_PER_UNIT))
! 	      warning ("escape sequence out of range for character");
! 	  }
! 	else if (c == '\n')
  	  {
! 	    if (pedantic)
! 	      warning ("ANSI C forbids newline in character constant");
! 	    lineno++;
  	  }
  
! 	code = c;
! 	token_buffer[1] = c;
! 	token_buffer[2] = '\'';
! 	token_buffer[3] = 0;
  
- 	c = getc (finput);
  	if (c != '\'')
  	  error ("malformatted character constant");
  
  	/* If char type is signed, sign-extend the constant.  */
--- 2557,2625 ----
      case '\'':
      char_constant:
        {
! 	register int result = 0;
! 	register num_chars = 0;
! 	int width = TYPE_PRECISION (char_type_node);
! 	int max_chars;
  
! 	if (wide_flag) width = TYPE_PRECISION (integer_type_node);
! 
! 	max_chars = TYPE_PRECISION (integer_type_node) / width;
  
! 	while (1)
  	  {
! 	  tryagain:
! 
! 	    c = getc (finput);
! 
! 	    if (c == '\'' || c == EOF)
! 	      break;
! 
! 	    if (c == '\\')
! 	      {
! 		c = readescape ();
! 		if (c < 0)
! 		  goto tryagain;
! 		if (width < HOST_BITS_PER_INT
! 		    && (unsigned) c >= (1 << width))
! 		  warning ("escape sequence out of range for character");
! 	      }
! 	    else if (c == '\n')
! 	      {
! 		if (pedantic)
! 		  warning ("ANSI C forbids newline in character constant");
! 		lineno++;
! 	      }
! 
! 	    num_chars++;
! 	    if (num_chars > maxtoken - 4)
! 	      extend_token_buffer (token_buffer);
! 
! 	    token_buffer[num_chars] = c;
! 
! 	    /* Merge character into result; ignore excess chars.  */
! 	    if (num_chars < max_chars + 1)
! 	      {
! 		if (width < HOST_BITS_PER_INT)
! 		  result = (result << width) | (c & ((1 << width) - 1));
! 		else
! 		  result = c;
! 	      }
  	  }
  
! 	token_buffer[num_chars + 1] = '\'';
! 	token_buffer[num_chars + 2] = 0;
  
  	if (c != '\'')
  	  error ("malformatted character constant");
+ 	else if (num_chars == 0)
+ 	  error ("empty character constant");
+ 	else if (num_chars > max_chars)
+ 	  {
+ 	    num_chars = max_chars;
+ 	    error ("character constant too long");
+ 	  }
+ 	else if (num_chars != 1 && ! flag_traditional)
+ 	  warning ("multi-character character constant");
  
  	/* If char type is signed, sign-extend the constant.  */
***************
*** 2395,2406 ****
  	if (! wide_flag)
  	  {
  	    if (TREE_UNSIGNED (char_type_node)
! 		|| ((code >> (BITS_PER_UNIT - 1)) & 1) == 0)
! 	      yylval.ttype = build_int_2 (code & ((1 << BITS_PER_UNIT) - 1), 0);
  	    else
! 	      yylval.ttype = build_int_2 (code | ((-1) << BITS_PER_UNIT), -1);
  	  }
  	else
! 	  yylval.ttype = build_int_2 (code, 0);
  
  	TREE_TYPE (yylval.ttype) = integer_type_node;
--- 2626,2644 ----
  	if (! wide_flag)
  	  {
+ 	    int num_bits = num_chars * width;
  	    if (TREE_UNSIGNED (char_type_node)
! 		|| ((result >> (num_bits - 1)) & 1) == 0)
! 	      yylval.ttype
! 		= build_int_2 (result & ((unsigned) ~0
! 					 >> (HOST_BITS_PER_INT - num_bits)),
! 			       0);
  	    else
! 	      yylval.ttype
! 		= build_int_2 (result | ~((unsigned) ~0
! 					  >> (HOST_BITS_PER_INT - num_bits)),
! 			       -1);
  	  }
  	else
! 	  yylval.ttype = build_int_2 (result, 0);
  
  	TREE_TYPE (yylval.ttype) = integer_type_node;
***************
*** 2426,2430 ****
  		if (c < 0)
  		  goto skipnewline;
! 		if (!wide_flag && c >= (1 << BITS_PER_UNIT))
  		  warning ("escape sequence out of range for character");
  	      }
--- 2664,2668 ----
  		if (c < 0)
  		  goto skipnewline;
! 		if (!wide_flag && c >= (1 << TYPE_PRECISION (char_type_node)))
  		  warning ("escape sequence out of range for character");
  	      }
***************
*** 2489,2493 ****
  	value = STRING; break;
        }
!       
      case '+':
      case '-':
--- 2727,2731 ----
  	value = STRING; break;
        }
! 
      case '+':
      case '-':
***************
*** 2533,2537 ****
  	  case '>':
  	    yylval.code = GT_EXPR; break;
! 	  }	
  
  	token_buffer[1] = c1 = getc (finput);
--- 2771,2775 ----
  	  case '>':
  	    yylval.code = GT_EXPR; break;
! 	  }
  
  	token_buffer[1] = c1 = getc (finput);
***************
*** 2550,2554 ****
  	      case '=':
  		value = EQCOMPARE; yylval.code = EQ_EXPR; goto done;
! 	      }	
  	    value = ASSIGN; goto done;
  	  }
--- 2788,2792 ----
  	      case '=':
  		value = EQCOMPARE; yylval.code = EQ_EXPR; goto done;
! 	      }
  	    value = ASSIGN; goto done;
  	  }
diff -rc2N gcc-1.35/c-tree.h gcc-1.36/c-tree.h
*** gcc-1.35/c-tree.h	Wed Mar 29 18:58:39 1989
--- gcc-1.36/c-tree.h	Fri Jul 14 21:11:07 1989
***************
*** 18,21 ****
--- 18,43 ----
  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  
+ /* Language-dependent contents of an identifier.  */
+ 
+ struct lang_identifier
+ {
+   struct tree_identifier ignore;
+   tree global_value, local_value, label_value, implicit_decl;
+   tree error_locus;
+ };
+ 
+ /* Macros for access to language-specific slots in an identifier.  */
+ 
+ #define IDENTIFIER_GLOBAL_VALUE(NODE)	\
+   (((struct lang_identifier *)(NODE))->global_value)
+ #define IDENTIFIER_LOCAL_VALUE(NODE)	\
+   (((struct lang_identifier *)(NODE))->local_value)
+ #define IDENTIFIER_LABEL_VALUE(NODE)	\
+   (((struct lang_identifier *)(NODE))->label_value)
+ #define IDENTIFIER_IMPLICIT_DECL(NODE)	\
+   (((struct lang_identifier *)(NODE))->implicit_decl)
+ #define IDENTIFIER_ERROR_LOCUS(NODE)	\
+   (((struct lang_identifier *)(NODE))->error_locus)
+ 
  /* Nonzero means reject anything that ANSI standard C forbids.  */
  extern int pedantic;
***************
*** 49,53 ****
  extern tree get_parm_info ();
  
! extern void pushlevel(), poplevel();
  
  extern tree groktypename(), lookup_name();
--- 71,76 ----
  extern tree get_parm_info ();
  
! extern void pushlevel ();
! extern tree poplevel ();
  
  extern tree groktypename(), lookup_name();
***************
*** 73,76 ****
--- 96,100 ----
  extern tree short_integer_type_node, short_unsigned_type_node;
  extern tree long_integer_type_node, long_unsigned_type_node;
+ extern tree long_long_integer_type_node, long_long_unsigned_type_node;
  extern tree unsigned_type_node;
  extern tree string_type_node, char_array_type_node, int_array_type_node;
***************
*** 79,96 ****
  extern int current_function_returns_null;
  
- extern int lineno;
- 
  extern tree ridpointers[];
  
- /* Points to the FUNCTION_DECL of the function whose body we are reading. */
- extern tree current_function_decl;
- 
  /* Nonzero means `$' can be in an identifier.  */
  
  extern int dollars_in_ident;
- 
- /* Nonzero means `char' should be signed.  */
- 
- extern int flag_signed_char;
  
  /* Nonzero means allow type mismatches in conditional expressions;
--- 103,111 ----
diff -rc2N gcc-1.35/c-typeck.c gcc-1.36/c-typeck.c
*** gcc-1.35/c-typeck.c	Mon Apr 24 15:30:27 1989
--- gcc-1.36/c-typeck.c	Thu Aug 24 17:44:57 1989
***************
*** 36,40 ****
  
  
! static int mark_addressable ();
  static tree convert_for_assignment ();
  static int compparms ();
--- 36,40 ----
  
  
! int mark_addressable ();
  static tree convert_for_assignment ();
  static int compparms ();
***************
*** 341,344 ****
--- 341,351 ----
    if (TREE_CODE (t1) != TREE_CODE (t2)) return 0;
  
+   /* Qualifiers must match.  */
+ 
+   if (TREE_READONLY (t1) != TREE_READONLY (t2))
+     return 0;
+   if (TREE_THIS_VOLATILE (t1) != TREE_THIS_VOLATILE (t2))
+     return 0;
+ 
    switch (TREE_CODE (t1))
      {
***************
*** 353,360 ****
  
      case ARRAY_TYPE:
!       /* Target types must match.  */
        if (!(TREE_TYPE (t1) == TREE_TYPE (t2)
! 	    || comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (t1)),
! 			  TYPE_MAIN_VARIANT (TREE_TYPE (t2)))))
  	return 0;
        {
--- 360,366 ----
  
      case ARRAY_TYPE:
!       /* Target types must match incl. qualifiers.  */
        if (!(TREE_TYPE (t1) == TREE_TYPE (t2)
! 	    || comptypes (TREE_TYPE (t1), TREE_TYPE (t2))))
  	return 0;
        {
***************
*** 470,473 ****
--- 476,481 ----
    if (type == long_integer_type_node)
      return long_unsigned_type_node;
+   if (type == long_long_integer_type_node)
+     return long_long_unsigned_type_node;
    return type;
  }
***************
*** 487,490 ****
--- 495,500 ----
    if (type == long_unsigned_type_node)
      return long_integer_type_node;
+   if (type == long_long_unsigned_type_node)
+     return long_long_integer_type_node;
    return type;
  }
***************
*** 508,511 ****
--- 518,524 ----
    if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node)) 
      return unsignedp ? long_unsigned_type_node : long_integer_type_node;
+   if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node)) 
+     return (unsignedp ? long_long_unsigned_type_node
+ 	    : long_long_integer_type_node);
    return type;
  }
***************
*** 531,534 ****
--- 544,551 ----
      return unsignedp ? long_unsigned_type_node : long_integer_type_node;
  
+   if (bits <= TYPE_PRECISION (long_long_integer_type_node))
+     return (unsignedp ? long_long_unsigned_type_node
+ 	    : long_long_integer_type_node);
+ 
    return 0;
  }
***************
*** 538,545 ****
       enum machine_mode mode;
  {
!   if (mode == SFmode)
      return float_type_node;
!   if (mode == DFmode)
      return double_type_node;
    abort ();
  }
--- 555,564 ----
       enum machine_mode mode;
  {
!   if (mode == TYPE_MODE (float_type_node))
      return float_type_node;
!   if (mode == TYPE_MODE (double_type_node))
      return double_type_node;
+   if (mode == TYPE_MODE (long_double_type_node))
+     return long_double_type_node;
    abort ();
  }
***************
*** 564,568 ****
      }
  
!   return size_in_bytes (type);
  }
  
--- 583,589 ----
      }
  
!   /* Convert in case a char is more than one unit.  */
!   return convert_units (size_in_bytes (type), BITS_PER_UNIT,
! 			TYPE_PRECISION (char_type_node));
  }
  
***************
*** 577,581 ****
      return build_int (1);
  
!   return size_in_bytes (type);
  }
  
--- 598,604 ----
      return build_int (1);
  
!   /* Convert in case a char is more than one unit.  */
!   return convert_units (size_in_bytes (type), BITS_PER_UNIT,
! 			TYPE_PRECISION (char_type_node));
  }
  
***************
*** 589,595 ****
    enum tree_code code = TREE_CODE (type);
  
-   if (pedantic)
-     warning ("ANSI C does not allow `__alignof'");
- 
    if (code == FUNCTION_TYPE)
      return build_int (FUNCTION_BOUNDARY / BITS_PER_UNIT);
--- 612,615 ----
***************
*** 614,620 ****
        && ! TREE_THIS_VOLATILE (decl)
        && DECL_INITIAL (decl) != 0
-       && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR
        && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK
!       && ! TREE_VOLATILE (DECL_INITIAL (decl))
        && DECL_MODE (decl) != BLKmode)
      return DECL_INITIAL (decl);
--- 634,644 ----
        && ! TREE_THIS_VOLATILE (decl)
        && DECL_INITIAL (decl) != 0
        && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK
!       /* This is invalid if initial value is not constant.
! 	 If it has either a function call, a memory reference,
! 	 or a variable, then re-evaluating it could give different results.  */
!       && TREE_LITERAL (DECL_INITIAL (decl))
!       /* Check for cases where this is sub-optimal, even though valid.  */
!       && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR
        && DECL_MODE (decl) != BLKmode)
      return DECL_INITIAL (decl);
***************
*** 872,876 ****
        TREE_VOLATILE (rval) |= TREE_VOLATILE (TREE_TYPE (TREE_TYPE (array)));
        TREE_THIS_VOLATILE (rval) |= TREE_VOLATILE (TREE_TYPE (TREE_TYPE (array)));
!       return require_complete_type (rval);
      }
  
--- 896,900 ----
        TREE_VOLATILE (rval) |= TREE_VOLATILE (TREE_TYPE (TREE_TYPE (array)));
        TREE_THIS_VOLATILE (rval) |= TREE_VOLATILE (TREE_TYPE (TREE_TYPE (array)));
!       return require_complete_type (fold (rval));
      }
  
***************
*** 917,920 ****
--- 941,945 ----
    if (TREE_CODE (function) == FUNCTION_DECL)
      {
+       name = DECL_NAME (function);
        /* Differs from default_conversion by not setting TREE_ADDRESSABLE
  	 (because calling an inline function does not mean the function
***************
*** 1038,1041 ****
--- 1063,1074 ----
  	  else
  	    {
+ #ifdef PROMOTE_PROTOTYPES
+ 	      /* Rather than truncating and then reextending,
+ 		 convert directly to int, if that's the type we will want.  */
+ 	      if (! flag_traditional
+ 		  && TREE_CODE (type) == INTEGER_TYPE
+ 		  && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
+ 		type = integer_type_node;
+ #endif
  	      parmval = convert_for_assignment (type, val, "argument passing");
  #ifdef PROMOTE_PROTOTYPES
***************
*** 1190,1193 ****
--- 1223,1230 ----
  
      case TRUNC_DIV_EXPR:
+     case CEIL_DIV_EXPR:
+     case FLOOR_DIV_EXPR:
+     case ROUND_DIV_EXPR:
+     case EXACT_DIV_EXPR:
        if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
  	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
***************
*** 1613,1617 ****
      }
    else
!     size_exp = size_in_bytes (TREE_TYPE (result_type));
  
    /* If what we are about to multiply by the size of the elements
--- 1650,1654 ----
      }
    else
!     size_exp = c_sizeof (TREE_TYPE (result_type));
  
    /* If what we are about to multiply by the size of the elements
***************
*** 1678,1701 ****
    op0 = build_binary_op (MINUS_EXPR,
  			 convert (restype, op0), convert (restype, op1));
!   op1 = ((TREE_CODE (TREE_TYPE (dt0)) == VOID_TYPE
! 	  || TREE_CODE (TREE_TYPE (dt0)) == FUNCTION_TYPE)
! 	 ? integer_one_node
! 	 : size_in_bytes (TREE_TYPE (dt0)));
  
-   /* By altering RESULTCODE, we direct this function to build
-      the division operation.  If dividing by a power of 2,
-      use floor-division (rounding down) since that is what
-      a shift insn does.  Otherwise, since we can't use a shift anyway,
-      use whichever kind of rounding this machine does most easily.  */
- 
-   if (TREE_CODE (op1) == INTEGER_CST
-       && -1 == exact_log2 (TREE_INT_CST_LOW (op1)))
-     resultcode = FLOOR_DIV_EXPR;
-   else
-     resultcode = EASY_DIV_EXPR;
- 
    /* Create the sum or difference.  */
  
!   result = build (resultcode, restype, op0, op1);
  
    folded = fold (result);
--- 1715,1723 ----
    op0 = build_binary_op (MINUS_EXPR,
  			 convert (restype, op0), convert (restype, op1));
!   op1 = c_sizeof_nowarn (TREE_TYPE (dt0));
  
    /* Create the sum or difference.  */
  
!   result = build (EXACT_DIV_EXPR, restype, op0, op1);
  
    folded = fold (result);
***************
*** 2067,2076 ****
      {
      case CONVERT_EXPR:
-       if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE))
-         errstring = "wrong type argument to unary plus";
        /* This is used for unary plus, because a CONVERT_EXPR
  	 is enough to prevent anybody from looking inside for
! 	 associativity, but won't generate any code.
! 	 Any argument is ok.  */
        break;
  
--- 2089,2099 ----
      {
      case CONVERT_EXPR:
        /* This is used for unary plus, because a CONVERT_EXPR
  	 is enough to prevent anybody from looking inside for
! 	 associativity, but won't generate any code.  */
!       if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE))
!         errstring = "wrong type argument to unary plus";
!       else if (!noconvert)
! 	arg = default_conversion (arg);
        break;
  
***************
*** 2286,2289 ****
--- 2309,2314 ----
  	      }
  
+ 	    addr = convert (argtype, addr);
+ 
  	    if (DECL_OFFSET (field) != 0)
  	      {
***************
*** 2294,2299 ****
  		addr = fold (build (PLUS_EXPR, argtype, addr, offset));
  	      }
- 	    else
- 	      addr = convert (argtype, addr);
  	  }
  	else
--- 2319,2322 ----
***************
*** 2544,2548 ****
     Value is 1 if successful.  */
  
! static int
  mark_addressable (exp)
       tree exp;
--- 2567,2571 ----
     Value is 1 if successful.  */
  
! int
  mark_addressable (exp)
       tree exp;
***************
*** 3340,3344 ****
  	  if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string)))
  	       != char_type_node)
! 	      && TYPE_PRECISION (typ1) == BITS_PER_UNIT)
  	    {
  	      error ("char-array initialized from wide string");
--- 3363,3367 ----
  	  if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string)))
  	       != char_type_node)
! 	      && TYPE_PRECISION (typ1) == TYPE_PRECISION (char_type_node))
  	    {
  	      error ("char-array initialized from wide string");
***************
*** 3347,3351 ****
  	  if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string)))
  	       == char_type_node)
! 	      && TYPE_PRECISION (typ1) != BITS_PER_UNIT)
  	    {
  	      error ("int-array initialized from non-wide string");
--- 3370,3374 ----
  	  if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string)))
  	       == char_type_node)
! 	      && TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node))
  	    {
  	      error ("int-array initialized from non-wide string");
***************
*** 3386,3389 ****
--- 3409,3418 ----
  	}
  
+       if (TREE_CODE (init) == CONSTRUCTOR)
+ 	{
+ 	  error ("initializer for scalar has extra braces");
+ 	  return error_mark_node;
+ 	}
+ 
        return convert_for_assignment (type, default_conversion (init),
  				     "initialization");
***************
*** 3509,3512 ****
--- 3538,3547 ----
  	  register tree next1;
  
+ 	  if (! DECL_NAME (field))
+ 	    {
+ 	      members = tree_cons (field, integer_zero_node, members);
+ 	      continue;
+ 	    }
+ 
  	  if (TREE_VALUE (tail) != 0)
  	    {
***************
*** 3573,3576 ****
--- 3608,3617 ----
    for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
      o[i] = TREE_VALUE (tail);
+ 
+ #if 0  /* Don't do this--it screws up operands expected to be in memory.  */
+   /* Perform default conversions on all inputs.  */
+   for (i = 0, tail = inputs; tail; tail = TREE_CHAIN (tail), i++)
+     TREE_VALUE (tail) = default_conversion (TREE_VALUE (tail));
+ #endif
  
    /* Generate the ASM_OPERANDS insn;
diff -rc2N gcc-1.35/cccp.c gcc-1.36/cccp.c
*** gcc-1.35/cccp.c	Fri Apr 21 23:52:24 1989
--- gcc-1.36/cccp.c	Mon Sep 11 23:43:13 1989
***************
*** 87,90 ****
--- 87,95 ----
  /* Forward declarations.  */
  
+ struct directive;
+ struct file_buf;
+ struct arglist;
+ struct argdata;
+ 
  int do_define (), do_line (), do_include (), do_undef (), do_error (),
    do_pragma (), do_if (), do_xifdef (), do_else (),
***************
*** 95,103 ****
  
  char *xmalloc (), *xrealloc (), *xcalloc (), *savestring ();
! void fatal (), pfatal_with_name (), perror_with_name ();
  
  void conditional_skip ();
  void skip_if_group ();
  void output_line_command ();
  
  int grow_outbuf ();
--- 100,112 ----
  
  char *xmalloc (), *xrealloc (), *xcalloc (), *savestring ();
! void fatal (), fancy_abort (), pfatal_with_name (), perror_with_name ();
  
+ void macroexpand ();
+ void dump_all_macros ();
  void conditional_skip ();
  void skip_if_group ();
  void output_line_command ();
+ /* Last arg to output_line_command.  */
+ enum file_change_code {same_file, enter_file, leave_file};
  
  int grow_outbuf ();
***************
*** 205,208 ****
--- 214,227 ----
     `instack[indepth]' is the level currently being read.  */
  int indepth = -1;
+ #define CHECK_DEPTH(code) \
+   if (indepth >= (INPUT_STACK_MAX - 1))					\
+     {									\
+       error_with_line (line_for_error (instack[indepth].lineno),	\
+ 		       "macro or #include recursion too deep");		\
+       code;								\
+     }
+ 
+ /* Current depth in #include directives that use <...>.  */
+ int system_include_depth = 0;
  
  typedef struct file_buf FILE_BUF;
***************
*** 250,262 ****
      /* Pick up GNU C++ specific include files.  */
      { &cplusplus_include_defaults[1], GPLUSPLUS_INCLUDE_DIR },
-     /* Borrow AT&T C++ head files, if available.  */
-     { &cplusplus_include_defaults[2], "/usr/include/CC" },
      /* Use GNU CC specific header files.  */
!     { &cplusplus_include_defaults[3], GCC_INCLUDE_DIR },
      { 0, "/usr/include" }
  #else
!     { &cplusplus_include_defaults[1], "GNU_CC_INCLUDE:" },
      /* VAX-11 C includes */
!     { &cplusplus_include_defaults[2], "SYS$SYSROOT:[SYSLIB.]" },
      { 0, "" },	/* This makes normal VMS filespecs work OK */
  #endif /* VMS */
--- 269,280 ----
      /* Pick up GNU C++ specific include files.  */
      { &cplusplus_include_defaults[1], GPLUSPLUS_INCLUDE_DIR },
      /* Use GNU CC specific header files.  */
!     { &cplusplus_include_defaults[2], GCC_INCLUDE_DIR },
      { 0, "/usr/include" }
  #else
!     { &cplusplus_include_defaults[1], "GNU_GXX_INCLUDE:" },
!     { &cplusplus_include_defaults[2], "GNU_CC_INCLUDE:" },
      /* VAX-11 C includes */
!     { &cplusplus_include_defaults[3], "SYS$SYSROOT:[SYSLIB.]" },
      { 0, "" },	/* This makes normal VMS filespecs work OK */
  #endif /* VMS */
***************
*** 353,356 ****
--- 371,375 ----
   T_FILE,	/* `__FILE__' */
   T_BASE_FILE,	/* `__BASE_FILE__' */
+  T_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */
   T_VERSION,	/* `__VERSION__' */
   T_TIME,	/* `__TIME__' */
***************
*** 405,409 ****
    char angle_brackets;		/* Nonzero => <...> is special.  */
    char traditional_comments;	/* Nonzero: keep comments if -traditional.  */
!   char noscan;			/* Don't scan argument-line, just peek.  */
  };
  
--- 424,428 ----
    char angle_brackets;		/* Nonzero => <...> is special.  */
    char traditional_comments;	/* Nonzero: keep comments if -traditional.  */
!   char pass_thru;		/* Copy preprocessed directive to output file.  */
  };
  
***************
*** 536,539 ****
--- 555,575 ----
  
    progname = argv[0];
+ #ifdef VMS
+   {
+     /* Remove directories from PROGNAME.  */
+     char *s;
+     extern char *rindex ();
+ 
+     progname = savestring (argv[0]);
+ 
+     if (!(s = rindex (progname, ']')))
+       s = rindex (progname, ':');
+     if (s)
+       strcpy (progname, s+1);
+     if (s = rindex (progname, '.'))
+       *s = '\0';
+   }
+ #endif
+ 
    in_fname = NULL;
    out_fname = NULL;
***************
*** 574,578 ****
      if (argv[i][0] != '-') {
        if (out_fname != NULL)
! 	fatal ("Usage: %s [switches] input output\n", argv[0]);
        else if (in_fname != NULL)
  	out_fname = argv[i];
--- 610,614 ----
      if (argv[i][0] != '-') {
        if (out_fname != NULL)
! 	fatal ("Usage: %s [switches] input output", argv[0]);
        else if (in_fname != NULL)
  	out_fname = argv[i];
***************
*** 585,588 ****
--- 621,626 ----
  	if (argv[i][2] != 0)
  	  pend_files[i] = argv[i] + 2;
+ 	else if (i + 1 == argc)
+ 	  fatal ("Filename missing after -i option");
  	else
  	  pend_files[i] = argv[i+1], i++;
***************
*** 591,595 ****
        case 'o':
  	if (out_fname != NULL)
! 	  fatal ("Output filename specified twice\n");
  	out_fname = argv[++i];
  	if (!strcmp (out_fname, "-"))
--- 629,635 ----
        case 'o':
  	if (out_fname != NULL)
! 	  fatal ("Output filename specified twice");
! 	if (i + 1 == argc)
! 	  fatal ("Filename missing after -o option");
  	out_fname = argv[++i];
  	if (!strcmp (out_fname, "-"))
***************
*** 651,654 ****
--- 691,696 ----
  	  if (argv[i][2] != 0)
  	    p = argv[i] + 2;
+ 	  else if (i + 1 == argc)
+ 	    fatal ("Macro name missing after -D option");
  	  else
  	    p = argv[++i];
***************
*** 663,666 ****
--- 705,710 ----
  	if (argv[i][2] != 0)
  	  pend_undefs[i] = argv[i] + 2;
+ 	else if (i + 1 == argc)
+ 	  fatal ("Macro name missing after -U option");
  	else
  	  pend_undefs[i] = argv[i+1], i++;
***************
*** 699,702 ****
--- 743,748 ----
  	    if (argv[i][2] != 0)
  	      dirtmp->fname = argv[i] + 2;
+ 	    else if (i + 1 == argc)
+ 	      fatal ("Directory name missing after -I option");
  	    else
  	      dirtmp->fname = argv[++i];
***************
*** 731,735 ****
  
        default:
! 	fatal ("Invalid option `%s'\n", argv[i]);
        }
      }
--- 777,781 ----
  
        default:
! 	fatal ("Invalid option `%s'", argv[i]);
        }
      }
***************
*** 778,781 ****
--- 824,831 ----
        last_include->next
  	= (cplusplus ? cplusplus_include_defaults : include_defaults);
+     /* Make sure the list for #include <...> also has the standard dirs.  */
+     if (ignore_srcdir && first_bracket_include == 0)
+       first_bracket_include
+ 	= (cplusplus ? cplusplus_include_defaults : include_defaults);
    }
  
***************
*** 969,973 ****
      pfatal_with_name (out_fname);
  
!   output_line_command (fp, &outbuf, 0);
  
    /* Scan the input, processing macros and directives.  */
--- 1019,1023 ----
      pfatal_with_name (out_fname);
  
!   output_line_command (fp, &outbuf, 0, same_file);
  
    /* Scan the input, processing macros and directives.  */
***************
*** 1075,1079 ****
    buf->buf[buf->length] = '\0';
    if (warn_trigraphs && fptr != bptr)
!     warning("file contains %d trigraph(s)", (fptr - bptr) / 2);
  }
  \f


--- 1125,1129 ----
    buf->buf[buf->length] = '\0';
    if (warn_trigraphs && fptr != bptr)
!     warning ("%d trigraph(s) encountered", (fptr - bptr) / 2);
  }
  \f


***************
*** 1448,1452 ****
  	else {
  	  /* must fake up a comment here */
! 	  *obp++ = '/';
  	  *obp++ = '/';
  	}
--- 1498,1502 ----
  	else {
  	  /* must fake up a comment here */
! 	  *obp++ = '/';
  	  *obp++ = '/';
  	}
***************
*** 1586,1590 ****
  	/* Newline White is a "funny space" to separate tokens that are
  	   supposed to be separate but without space between.
! 	   Here While means any horizontal whitespace character.
  	   Newline - marks a recursive macro use that is not
  	   supposed to be expandable.  */
--- 1636,1640 ----
  	/* Newline White is a "funny space" to separate tokens that are
  	   supposed to be separate but without space between.
! 	   Here White means any horizontal whitespace character.
  	   Newline - marks a recursive macro use that is not
  	   supposed to be expandable.  */
***************
*** 1637,1641 ****
        if (ip->lineno != op->lineno) {
  	op->bufp = obp;
! 	output_line_command (ip, op, 1);
  	check_expand (op, ip->length - (ip->bufp - ip->buf));
  	obp = op->bufp;
--- 1687,1691 ----
        if (ip->lineno != op->lineno) {
  	op->bufp = obp;
! 	output_line_command (ip, op, 1, same_file);
  	check_expand (op, ip->length - (ip->bufp - ip->buf));
  	obp = op->bufp;
***************
*** 1754,1759 ****
--- 1804,1814 ----
  
  	    if (disabled) {
+ #if 0
+ 	      /* This error check caught useful cases such as
+ 		 #define foo(x,y) bar(x(y,0), y)
+ 		 foo(foo, baz)  */
  	      if (traditional)
  		error ("recursive use of macro `%s'", hp->name);
+ #endif
  
  	      if (output_marks) {
***************
*** 1778,1781 ****
--- 1833,1856 ----
  		    RECACHE;
  		  }
+ 		  /* A comment: copy it to the output unchanged.  */
+ 		  else if (*ibp == '/' && ibp+1 != limit && ibp[1] == '*') {
+ 		    *obp++ = '/';
+ 		    *obp++ = '*';
+ 		    ibp += 2;
+ 		    while (ibp + 1 != limit
+ 			   && !(ibp[0] == '*' && ibp[1] == '/')) {
+ 		      /* We need not worry about newline-marks,
+ 			 since they are never found in comments.  */
+ 		      if (*ibp == '\n') {
+ 			/* Newline in a file.  Count it.  */
+ 			++ip->lineno;
+ 			++op->lineno;
+ 		      }
+ 		      *obp++ = *ibp++;
+ 		    }
+ 		    ibp += 2;
+ 		    *obp++ = '*';
+ 		    *obp++ = '/';
+ 		  }
  		  else if (is_space[*ibp]) {
  		    *obp++ = *ibp++;
***************
*** 1901,1904 ****
--- 1976,1989 ----
    buf1[length] = 0;
  
+   /* Set up to receive the output.  */
+ 
+   obuf.length = length * 2 + 100; /* Usually enough.  Why be stingy?  */
+   obuf.bufp = obuf.buf = (U_CHAR *) xmalloc (obuf.length);
+   obuf.fname = 0;
+   obuf.macro = 0;
+   obuf.free_ptr = 0;
+ 
+   CHECK_DEPTH ({return obuf;});
+ 
    ++indepth;
  
***************
*** 1911,1922 ****
    ip->if_stack = if_stack;
  
-   /* Set up to receive the output.  */
- 
-   obuf.length = length * 2 + 100; /* Usually enough.  Why be stingy?  */
-   obuf.bufp = obuf.buf = (U_CHAR *) xmalloc (obuf.length);
-   obuf.fname = 0;
-   obuf.macro = 0;
-   obuf.free_ptr = 0;
- 
    ip->lineno = obuf.lineno = 1;
  
--- 1996,1999 ----
***************
*** 2021,2031 ****
        int keep_comments = traditional && kt->traditional_comments;
  
-       /* For #pragma, check whether `once' follows
- 	 without really scanning anything.  */
-       if (kt->noscan) {
- 	(*kt->func) (after_ident, after_ident, op, kt);
- 	return 0;
-       }
- 
        /* Find the end of this command (first newline not backslashed
  	 and not in a string or comment).
--- 2098,2101 ----
***************
*** 2186,2189 ****
--- 2256,2278 ----
        ip->bufp = resume_p;
  
+       /* Some directives should be written out for cc1 to process,
+ 	 just as if they were not defined.  */
+ 
+       if (kt->pass_thru) {
+         int len;
+ 
+ 	/* Output directive name.  */
+         check_expand (op, kt->length+1);
+         *op->bufp++ = '#';
+         bcopy (kt->name, op->bufp, kt->length);
+         op->bufp += kt->length;
+ 
+ 	/* Output arguments.  */
+         len = (cp - buf);
+         check_expand (op, len);
+         bcopy (buf, op->bufp, len);
+         op->bufp += len;
+       }
+ 
        /* Call the appropriate command handler.  buf now points to
  	 either the appropriate place in the input buffer, or to
***************
*** 2216,2219 ****
--- 2305,2309 ----
    long t;
    int i, len;
+   int true_indepth;
    FILE_BUF *ip = NULL;
    static struct tm *timebuf = NULL;
***************
*** 2253,2256 ****
--- 2343,2356 ----
      }
  
+   case T_INCLUDE_LEVEL:
+     true_indepth = 0;
+     for (i = indepth; i >= 0; i--)
+       if (instack[i].fname != NULL)
+         true_indepth++;
+ 
+     buf = (char *) alloca (8);	/* Eigth bytes ought to be more than enough */
+     sprintf (buf, "%d", true_indepth - 1);
+     break;
+ 
    case T_VERSION:
      buf = (char *) alloca (3 + strlen (version_string));
***************
*** 2482,2485 ****
--- 2582,2597 ----
      fname[flen] = 0;
      error_from_errno (fname);
+ 
+     /* For -M, add this file to the dependencies.  */
+     if (print_deps > (system_header_p || (system_include_depth > 0))) {
+       if (system_header_p)
+ 	warning ("nonexistent file <%.*s> omitted from dependency output",
+ 		 fend - fbeg, fbeg);
+       else
+ 	{
+ 	  deps_output (fbeg, fend - fbeg);
+ 	  deps_output (" ", 0);
+ 	}
+     }
    } else {
  
***************
*** 2490,2495 ****
  
      for (ptr = dont_repeat_files; ptr; ptr = ptr->next) {
!       if (!strcmp (ptr->fname, fname))
          return;				/* This file was once'd. */
      }
  
--- 2602,2609 ----
  
      for (ptr = dont_repeat_files; ptr; ptr = ptr->next) {
!       if (!strcmp (ptr->fname, fname)) {
! 	close (f);
          return;				/* This file was once'd. */
+       }
      }
  
***************
*** 2509,2513 ****
  
        /* For -M, add this file to the dependencies.  */
!       if (print_deps > system_header_p) {
  	deps_output (fname, strlen (fname));
  	deps_output (" ", 0);
--- 2623,2627 ----
  
        /* For -M, add this file to the dependencies.  */
!       if (print_deps > (system_header_p || (system_include_depth > 0))) {
  	deps_output (fname, strlen (fname));
  	deps_output (" ", 0);
***************
*** 2515,2520 ****
--- 2629,2641 ----
      }   
  
+     if (system_header_p)
+       system_include_depth++;
+ 
      /* Actually process the file.  */
      finclude (f, fname, op);
+ 
+     if (system_header_p)
+       system_include_depth--;
+ 
      close (f);
    }
***************
*** 2535,2538 ****
--- 2656,2661 ----
    int success = 0;
  
+   CHECK_DEPTH (return;);
+ 
    if (file_size_and_mode (f, &st_mode, &st_size) < 0)
      goto nope;		/* Impossible? */
***************
*** 2605,2612 ****
    indepth++;
  
!   output_line_command (fp, op, 0);
    rescan (op, 0);
    indepth--;
!   output_line_command (&instack[indepth], op, 0);
  
  nope:
--- 2728,2735 ----
    indepth++;
  
!   output_line_command (fp, op, 0, enter_file);
    rescan (op, 0);
    indepth--;
!   output_line_command (&instack[indepth], op, 0, leave_file);
  
  nope:
***************
*** 2755,2759 ****
  	msg = (U_CHAR *) alloca (sym_length + 20);
  	bcopy (symname, msg, sym_length);
! 	strcpy (msg + sym_length, " redefined");
  	warning (msg);
        }
--- 2878,2882 ----
  	msg = (U_CHAR *) alloca (sym_length + 20);
  	bcopy (symname, msg, sym_length);
! 	strcpy ((char *) (msg + sym_length), " redefined");
  	warning (msg);
        }
***************
*** 2786,2790 ****
    if (d1->nargs != d2->nargs)
      return 1;
!   if (strcmp (d1->argnames, d2->argnames))
      return 1;
    for (a1 = d1->pattern, a2 = d2->pattern; a1 && a2;
--- 2909,2913 ----
    if (d1->nargs != d2->nargs)
      return 1;
!   if (strcmp ((char *)d1->argnames, (char *)d2->argnames))
      return 1;
    for (a1 = d1->pattern, a2 = d2->pattern; a1 && a2;
***************
*** 3123,3126 ****
--- 3246,3250 ----
    FILE_BUF tem;
    int new_lineno;
+   enum file_change_code file_change = same_file;
  
    /* Expand any macros.  */
***************
*** 3171,3176 ****
      SKIP_WHITE_SPACE (bp);
      if (*bp) {
!       error ("invalid format #line command");
!       return;
      }
  
--- 3295,3313 ----
      SKIP_WHITE_SPACE (bp);
      if (*bp) {
!       if (*bp == '1')
! 	file_change = enter_file;
!       else if (*bp == '2')
! 	file_change = leave_file;
!       else {
! 	error ("invalid format #line command");
! 	return;
!       }
! 
!       bp++;
!       SKIP_WHITE_SPACE (bp);
!       if (*bp) {
! 	error ("invalid format #line command");
! 	return;
!       }
      }
  
***************
*** 3199,3203 ****
  
    ip->lineno = new_lineno;
!   output_line_command (ip, op, 0);
    check_expand (op, ip->length - (ip->bufp - ip->buf));
  }
--- 3336,3340 ----
  
    ip->lineno = new_lineno;
!   output_line_command (ip, op, 0, file_change);
    check_expand (op, ip->length - (ip->bufp - ip->buf));
  }
***************
*** 3268,3288 ****
  }
  
! /* #pragma receives as an argument the start of the rest of the line.
!    We use that to peek at what lies ahead without skipping any of it.
!    Thus, every #pragma is passed on to cc1, with macros expanded.
!    However, we also do something special here if the #pragma looks like
!    `#pragma once'.  */
! 
! do_pragma (ptr)
!      U_CHAR *ptr;
! {
!   U_CHAR *bp = ptr;
!   while (*bp == ' ' || *bp == '\t') bp++;
!   if (!strncmp (bp, "once", 4)) {
!     bp += 4;
!     while (*bp == ' ' || *bp == '\t') bp++;
!     if (*bp == '\n')
!       do_once ();
!   }
  }
  
--- 3405,3418 ----
  }
  
! /* #pragma and its argument line have already been copied to the output file.
!    Here just check for recognized pragmas.  */
! 
! do_pragma (buf, limit)
!      U_CHAR *buf, *limit;
! {
!   while (*buf == ' ' || *buf == '\t')
!     buf++;
!   if (!strncmp (buf, "once", 4))
!     do_once ();
  }
  
***************
*** 3380,3384 ****
      else {
        ++if_stack->if_succeeded;	/* continue processing input */
!       output_line_command (ip, op, 1);
      }
    }
--- 3510,3514 ----
      else {
        ++if_stack->if_succeeded;	/* continue processing input */
!       output_line_command (ip, op, 1, same_file);
      }
    }
***************
*** 3472,3476 ****
    } else {
      ++if_stack->if_succeeded;
!     output_line_command (ip, &outbuf, 1);
    }
  }
--- 3602,3606 ----
    } else {
      ++if_stack->if_succeeded;
!     output_line_command (ip, &outbuf, 1, same_file);
    }
  }
***************
*** 3674,3678 ****
    else {
      ++if_stack->if_succeeded;	/* continue processing input */
!     output_line_command (ip, op, 1);
    }
  }
--- 3804,3808 ----
    else {
      ++if_stack->if_succeeded;	/* continue processing input */
!     output_line_command (ip, op, 1, same_file);
    }
  }
***************
*** 3698,3702 ****
      if_stack = if_stack->next;
      free (temp);
!     output_line_command (&instack[indepth], op, 1);
    }
  }
--- 3828,3832 ----
      if_stack = if_stack->next;
      free (temp);
!     output_line_command (&instack[indepth], op, 1, same_file);
    }
  }
***************
*** 3891,3900 ****
   * appear to be a no-op, and we can output a few newlines instead
   * if we want to increase the line number by a small amount.
   */
  
  void
! output_line_command (ip, op, conditional)
       FILE_BUF *ip, *op;
       int conditional;
  {
    int len;
--- 4021,4032 ----
   * appear to be a no-op, and we can output a few newlines instead
   * if we want to increase the line number by a small amount.
+  * FILE_CHANGE says whether we are entering a file, leaving, or neither.
   */
  
  void
! output_line_command (ip, op, conditional, file_change)
       FILE_BUF *ip, *op;
       int conditional;
+      enum file_change_code file_change;
  {
    int len;
***************
*** 3925,3933 ****
  
  #ifdef OUTPUT_LINE_COMMANDS
!   sprintf (line_cmd_buf, "#line %d \"%s\"\n", ip->lineno, ip->fname);
  #else
!   sprintf (line_cmd_buf, "# %d \"%s\"\n", ip->lineno, ip->fname);
  #endif
    len = strlen (line_cmd_buf);
    check_expand (op, len + 1);
    if (op->bufp > op->buf && op->bufp[-1] != '\n')
--- 4057,4068 ----
  
  #ifdef OUTPUT_LINE_COMMANDS
!   sprintf (line_cmd_buf, "#line %d \"%s\"", ip->lineno, ip->fname);
  #else
!   sprintf (line_cmd_buf, "# %d \"%s\"", ip->lineno, ip->fname);
  #endif
+   if (file_change != same_file)
+     strcat (line_cmd_buf, file_change == enter_file ? " 1" : " 2");
    len = strlen (line_cmd_buf);
+   line_cmd_buf[len++] = '\n';
    check_expand (op, len + 1);
    if (op->bufp > op->buf && op->bufp[-1] != '\n')
***************
*** 3964,3967 ****
--- 4099,4103 ----
     an argument list follows; arguments come from the input stack.  */
  
+ void
  macroexpand (hp, op)
       HASHNODE *hp;
***************
*** 3974,3977 ****
--- 4110,4115 ----
    int start_line = instack[indepth].lineno;
  
+   CHECK_DEPTH (return;);
+ 
    /* it might not actually be a macro.  */
    if (hp->type != T_MACRO) {
***************
*** 4003,4007 ****
        /* Discard the open-parenthesis or comma before the next arg.  */
        ++instack[indepth].bufp;
!       if (parse_error = macarg ((i < nargs || (nargs == 0 && i == 0)) ? &args[i] : 0))
  	{
  	  error_with_line (line_for_error (start_line), parse_error);
--- 4141,4147 ----
        /* Discard the open-parenthesis or comma before the next arg.  */
        ++instack[indepth].bufp;
!       parse_error
! 	= macarg ((i < nargs || (nargs == 0 && i == 0)) ? &args[i] : 0);
!       if (parse_error)
  	{
  	  error_with_line (line_for_error (start_line), parse_error);
***************
*** 4011,4023 ****
      } while (*instack[indepth].bufp != ')');
  
!     if (nargs == 0 && i == 1) {
        register U_CHAR *bp = args[0].raw;
        register U_CHAR *lim = bp + args[0].raw_length;
        while (bp != lim && is_space[*bp]) bp++;
!       if (bp != lim)
! 	error ("arguments given to macro `%s'", hp->name);
!     } else if (i < nargs)
!       error ("only %d args to macro `%s'", i, hp->name);
!     else if (i > nargs)
        error ("too many (%d) args to macro `%s'", i, hp->name);
  
--- 4151,4176 ----
      } while (*instack[indepth].bufp != ')');
  
!     /* If we got one arg but it was just whitespace, call that 0 args.  */
!     if (i == 1) {
        register U_CHAR *bp = args[0].raw;
        register U_CHAR *lim = bp + args[0].raw_length;
        while (bp != lim && is_space[*bp]) bp++;
!       if (bp == lim)
! 	i = 0;
!     }
! 
!     if (nargs == 0 && i > 0)
!       error ("arguments given to macro `%s'", hp->name);
!     else if (i < nargs) {
!       /* traditional C allows foo() if foo wants one argument.  */
!       if (nargs == 1 && i == 0 && traditional)
! 	;
!       else if (i == 0)
! 	error ("no args to macro `%s'", hp->name);
!       else if (i == 1)
! 	error ("only 1 arg to macro `%s'", hp->name);
!       else
! 	error ("only %d args to macro `%s'", i, hp->name);
!     } else if (i > nargs)
        error ("too many (%d) args to macro `%s'", i, hp->name);
  
***************
*** 4082,4088 ****
  	    c = arg->raw[i];
  
! 	    /* Special markers Newline Space and Newline Newline
  	       generate nothing for a stringified argument.  */
! 	    if (c == '\n') {
  	      i++;
  	      continue;
--- 4235,4241 ----
  	    c = arg->raw[i];
  
! 	    /* Special markers Newline Space
  	       generate nothing for a stringified argument.  */
! 	    if (c == '\n' && arg->raw[i+1] != '\n') {
  	      i++;
  	      continue;
***************
*** 4090,4095 ****
  
  	    /* Internal sequences of whitespace are replaced by one space.  */
! 	    if (is_space[c]) {
! 	      while (c = arg->raw[i+1], is_space[c]) i++;
  	      c = ' ';
  	    }
--- 4243,4256 ----
  
  	    /* Internal sequences of whitespace are replaced by one space.  */
! 	    if (c == '\n' ? arg->raw[i+1] == '\n' : is_space[c]) {
! 	      while (1) {
! 		if (c == '\n' && arg->raw[i+1] == '\n')
! 		  i += 2;
! 		else if (c != '\n' && is_space[c])
! 		  i++;
! 		else break;
! 		c = arg->raw[i];
! 	      }
! 	      i--;
  	      c = ' ';
  	    }
***************
*** 4112,4116 ****
  	      xbuf[totlen++] = c;
  	    else {
! 	      sprintf (&xbuf[totlen], "\\%03o", (unsigned int) c);
  	      totlen += 4;
  	    }
--- 4273,4277 ----
  	      xbuf[totlen++] = c;
  	    else {
! 	      sprintf ((char *) &xbuf[totlen], "\\%03o", (unsigned int) c);
  	      totlen += 4;
  	    }
***************
*** 4197,4201 ****
      ip2->if_stack = if_stack;
  
!     hp->type = T_DISABLED;
    }
  }
--- 4358,4367 ----
      ip2->if_stack = if_stack;
  
!     /* Recursive macro use sometimes works traditionally.
!        #define foo(x,y) bar(x(y,0), y)
!        foo(foo, baz)  */
! 
!     if (!traditional)
!       hp->type = T_DISABLED;
    }
  }
***************
*** 4522,4526 ****
   */
  error (msg, arg1, arg2, arg3)
!      U_CHAR *msg;
  {
    int i;
--- 4688,4692 ----
   */
  error (msg, arg1, arg2, arg3)
!      char *msg;
  {
    int i;
***************
*** 4572,4576 ****
  
  warning (msg, arg1, arg2, arg3)
!      U_CHAR *msg;
  {
    int i;
--- 4738,4742 ----
  
  warning (msg, arg1, arg2, arg3)
!      char *msg;
  {
    int i;
***************
*** 4593,4597 ****
  error_with_line (line, msg, arg1, arg2, arg3)
       int line;
!      U_CHAR *msg;
  {
    int i;
--- 4759,4763 ----
  error_with_line (line, msg, arg1, arg2, arg3)
       int line;
!      char *msg;
  {
    int i;
***************
*** 4829,4832 ****
--- 4995,4999 ----
  /* Dump all macro definitions as #defines to stdout.  */
  
+ void
  dump_all_macros ()
  {
***************
*** 4884,4888 ****
      }
    }
-   return NULL;
  }
  
--- 5051,5054 ----
***************
*** 4979,4982 ****
--- 5145,5149 ----
    install ("__FILE__", -1, T_FILE, 0, -1);
    install ("__BASE_FILE__", -1, T_BASE_FILE, 0, -1);
+   install ("__INCLUDE_LEVEL__", -1, T_INCLUDE_LEVEL, 0, -1);
    install ("__VERSION__", -1, T_VERSION, 0, -1);
    install ("__TIME__", -1, T_TIME, 0, -1);
***************
*** 5006,5011 ****
    if (*p == 0) {
      buf = (U_CHAR *) alloca (p - buf + 4);
!     strcpy (buf, str);
!     strcat (buf, " 1");
    }
    
--- 5173,5178 ----
    if (*p == 0) {
      buf = (U_CHAR *) alloca (p - buf + 4);
!     strcpy ((char *)buf, str);
!     strcat ((char *)buf, " 1");
    }
    
***************
*** 5164,5167 ****
--- 5331,5343 ----
  }
  
+ /* More 'friendly' abort that prints the line and file.
+    config.h can #define abort fancy_abort if you like that sort of thing.  */
+ 
+ void
+ fancy_abort ()
+ {
+   fatal ("Internal gcc abort.");
+ }
+ 
  void
  perror_with_name (name)
***************
*** 5184,5188 ****
--- 5360,5368 ----
  {
    perror_with_name (name);
+ #ifdef VMS
+   exit (vaxc$errno);
+ #else
    exit (FATAL_EXIT_CODE);
+ #endif
  }
  
diff -rc2N gcc-1.35/cexp.y gcc-1.36/cexp.y
*** gcc-1.35/cexp.y	Wed Feb 22 11:46:11 1989
--- gcc-1.36/cexp.y	Thu Sep 21 00:37:42 1989
***************
*** 38,45 ****
    extern unsigned char is_idstart[], is_idchar[];
  
  %}
  
  %union {
!   long lval;
    int voidval;
    char *sval;
--- 38,48 ----
    extern unsigned char is_idstart[], is_idchar[];
  
+ #ifndef CHAR_TYPE_SIZE
+ #define CHAR_TYPE_SIZE BITS_PER_UNIT
+ #endif
  %}
  
  %union {
!   struct constant {long value; int unsignedp;} integer;
    int voidval;
    char *sval;
***************
*** 46,53 ****
  }
  
! %type <lval> exp exp1 start
! %token <lval> INT CHAR
  %token <sval> NAME
! %token <lval> ERROR
  
  %right '?' ':'
--- 49,56 ----
  }
  
! %type <integer> exp exp1 start
! %token <integer> INT CHAR
  %token <sval> NAME
! %token <integer> ERROR
  
  %right '?' ':'
***************
*** 70,74 ****
  
  start   :	exp1
! 		{ expression_value = $1; }
  	;
  
--- 73,77 ----
  
  start   :	exp1
! 		{ expression_value = $1.value; }
  	;
  
***************
*** 81,89 ****
  /* Expressions, not including the comma operator.  */
  exp	:	'-' exp    %prec UNARY
! 			{ $$ = - $2; }
  	|	'!' exp    %prec UNARY
! 			{ $$ = ! $2; }
  	|	'~' exp    %prec UNARY
! 			{ $$ = ~ $2; }
  	|	'(' exp1 ')'
  			{ $$ = $2; }
--- 84,95 ----
  /* Expressions, not including the comma operator.  */
  exp	:	'-' exp    %prec UNARY
! 			{ $$.value = - $2.value;
! 			  $$.unsignedp = $2.unsignedp; }
  	|	'!' exp    %prec UNARY
! 			{ $$.value = ! $2.value;
! 			  $$.unsignedp = 0; }
  	|	'~' exp    %prec UNARY
! 			{ $$.value = ~ $2.value;
! 			  $$.unsignedp = $2.unsignedp; }
  	|	'(' exp1 ')'
  			{ $$ = $2; }
***************
*** 92,148 ****
  /* Binary operators in order of decreasing precedence.  */
  exp	:	exp '*' exp
! 			{ $$ = $1 * $3; }
  	|	exp '/' exp
! 			{ if ($3 == 0)
  			    {
  			      error ("division by zero in #if");
! 			      $3 = 1;
  			    }
! 			  $$ = $1 / $3; }
  	|	exp '%' exp
! 			{ if ($3 == 0)
  			    {
  			      error ("division by zero in #if");
! 			      $3 = 1;
  			    }
! 			  $$ = $1 % $3; }
  	|	exp '+' exp
! 			{ $$ = $1 + $3; }
  	|	exp '-' exp
! 			{ $$ = $1 - $3; }
  	|	exp LSH exp
! 			{ $$ = $1 << $3; }
  	|	exp RSH exp
! 			{ $$ = $1 >> $3; }
  	|	exp EQUAL exp
! 			{ $$ = ($1 == $3); }
  	|	exp NOTEQUAL exp
! 			{ $$ = ($1 != $3); }
  	|	exp LEQ exp
! 			{ $$ = ($1 <= $3); }
  	|	exp GEQ exp
! 			{ $$ = ($1 >= $3); }
  	|	exp '<' exp
! 			{ $$ = ($1 < $3); }
  	|	exp '>' exp
! 			{ $$ = ($1 > $3); }
  	|	exp '&' exp
! 			{ $$ = ($1 & $3); }
  	|	exp '^' exp
! 			{ $$ = ($1 ^ $3); }
  	|	exp '|' exp
! 			{ $$ = ($1 | $3); }
  	|	exp AND exp
! 			{ $$ = ($1 && $3); }
  	|	exp OR exp
! 			{ $$ = ($1 || $3); }
  	|	exp '?' exp ':' exp
! 			{ $$ = $1 ? $3 : $5; }
  	|	INT
! 			{ $$ = yylval.lval; }
  	|	CHAR
! 			{ $$ = yylval.lval; }
  	|	NAME
! 			{ $$ = 0; }
  	;
  %%
--- 98,201 ----
  /* Binary operators in order of decreasing precedence.  */
  exp	:	exp '*' exp
! 			{ $$.unsignedp = $1.unsignedp || $3.unsignedp;
! 			  if ($$.unsignedp)
! 			    $$.value = (unsigned) $1.value * $3.value;
! 			  else
! 			    $$.value = $1.value * $3.value; }
  	|	exp '/' exp
! 			{ if ($3.value == 0)
  			    {
  			      error ("division by zero in #if");
! 			      $3.value = 1;
  			    }
! 			  $$.unsignedp = $1.unsignedp || $3.unsignedp;
! 			  if ($$.unsignedp)
! 			    $$.value = (unsigned) $1.value / $3.value;
! 			  else
! 			    $$.value = $1.value / $3.value; }
  	|	exp '%' exp
! 			{ if ($3.value == 0)
  			    {
  			      error ("division by zero in #if");
! 			      $3.value = 1;
  			    }
! 			  $$.unsignedp = $1.unsignedp || $3.unsignedp;
! 			  if ($$.unsignedp)
! 			    $$.value = (unsigned) $1.value % $3.value;
! 			  else
! 			    $$.value = $1.value % $3.value; }
  	|	exp '+' exp
! 			{ $$.value = $1.value + $3.value;
! 			  $$.unsignedp = $1.unsignedp || $3.unsignedp; }
  	|	exp '-' exp
! 			{ $$.value = $1.value - $3.value;
! 			  $$.unsignedp = $1.unsignedp || $3.unsignedp; }
  	|	exp LSH exp
! 			{ $$.unsignedp = $1.unsignedp;
! 			  if ($$.unsignedp)
! 			    $$.value = (unsigned) $1.value << $3.value;
! 			  else
! 			    $$.value = $1.value << $3.value; }
  	|	exp RSH exp
! 			{ $$.unsignedp = $1.unsignedp;
! 			  if ($$.unsignedp)
! 			    $$.value = (unsigned) $1.value >> $3.value;
! 			  else
! 			    $$.value = $1.value >> $3.value; }
  	|	exp EQUAL exp
! 			{ $$.value = ($1.value == $3.value);
! 			  $$.unsignedp = 0; }
  	|	exp NOTEQUAL exp
! 			{ $$.value = ($1.value != $3.value);
! 			  $$.unsignedp = 0; }
  	|	exp LEQ exp
! 			{ $$.unsignedp = 0;
! 			  if ($1.unsignedp || $3.unsignedp)
! 			    $$.value = (unsigned) $1.value <= $3.value;
! 			  else
! 			    $$.value = $1.value <= $3.value; }
  	|	exp GEQ exp
! 			{ $$.unsignedp = 0;
! 			  if ($1.unsignedp || $3.unsignedp)
! 			    $$.value = (unsigned) $1.value >= $3.value;
! 			  else
! 			    $$.value = $1.value >= $3.value; }
  	|	exp '<' exp
! 			{ $$.unsignedp = 0;
! 			  if ($1.unsignedp || $3.unsignedp)
! 			    $$.value = (unsigned) $1.value < $3.value;
! 			  else
! 			    $$.value = $1.value < $3.value; }
  	|	exp '>' exp
! 			{ $$.unsignedp = 0;
! 			  if ($1.unsignedp || $3.unsignedp)
! 			    $$.value = (unsigned) $1.value > $3.value;
! 			  else
! 			    $$.value = $1.value > $3.value; }
  	|	exp '&' exp
! 			{ $$.value = $1.value & $3.value;
! 			  $$.unsignedp = $1.unsignedp || $3.unsignedp; }
  	|	exp '^' exp
! 			{ $$.value = $1.value ^ $3.value;
! 			  $$.unsignedp = $1.unsignedp || $3.unsignedp; }
  	|	exp '|' exp
! 			{ $$.value = $1.value | $3.value;
! 			  $$.unsignedp = $1.unsignedp || $3.unsignedp; }
  	|	exp AND exp
! 			{ $$.value = ($1.value && $3.value);
! 			  $$.unsignedp = 0; }
  	|	exp OR exp
! 			{ $$.value = ($1.value || $3.value);
! 			  $$.unsignedp = 0; }
  	|	exp '?' exp ':' exp
! 			{ $$.value = $1.value ? $3.value : $5.value;
! 			  $$.unsignedp = $3.unsignedp || $5.unsignedp; }
  	|	INT
! 			{ $$ = yylval.integer; }
  	|	CHAR
! 			{ $$ = yylval.integer; }
  	|	NAME
! 			{ $$.value = 0;
! 			  $$.unsignedp = 0; }
  	;
  %%
***************
*** 167,173 ****
    register int c;
    register int base = 10;
!   register len = olen;
! 
!   extern double atof ();
  
    for (c = 0; c < len; c++)
--- 220,224 ----
    register int c;
    register int base = 10;
!   register int len = olen;
  
    for (c = 0; c < len; c++)
***************
*** 176,187 ****
        yyerror ("floating point numbers not allowed in #if expressions");
        return ERROR;
-       
- /* ****************
- 	 yylval.dval = atof (p);
- 	 lexptr += len;
- 	 return FLOAT;
- 		 ****************  */
      }
!   
    if (len >= 3 && (!strncmp (p, "0x", 2) || !strncmp (p, "0X", 2))) {
      p += 2;
--- 227,234 ----
        yyerror ("floating point numbers not allowed in #if expressions");
        return ERROR;
      }
! 
!   yylval.integer.unsignedp = 0;
! 
    if (len >= 3 && (!strncmp (p, "0x", 2) || !strncmp (p, "0X", 2))) {
      p += 2;
***************
*** 191,215 ****
    else if (*p == '0')
      base = 8;
!   
!   while (len-- > 0) {
      c = *p++;
!     n *= base;
!     if (c >= '0' && c <= '9')
        n += c - '0';
!     else {
!       if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
!       if (base == 16 && c >= 'a' && c <= 'f')
! 	n += c - 'a' + 10;
!       else if (len == 0 && c == 'l')
! 	;
!       else {
! 	yyerror ("Invalid number in #if expression");
! 	return ERROR;
        }
      }
    }
  
    lexptr = p;
!   yylval.lval = n;
    return INT;
  }
--- 238,284 ----
    else if (*p == '0')
      base = 8;
! 
!   while (len > 0) {
      c = *p++;
!     len--;
!     if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
! 
!     if (c >= '0' && c <= '9') {
!       n *= base;
        n += c - '0';
!     } else if (base == 16 && c >= 'a' && c <= 'f') {
!       n *= base;
!       n += c - 'a' + 10;
!     } else {
!       /* `l' means long, and `u' means unsigned.  */
!       while (1) {
! 	if (c == 'l' || c == 'L')
! 	  ;
! 	else if (c == 'u' || c == 'U')
! 	  yylval.integer.unsignedp = 1;
! 	else
! 	  break;
! 
! 	if (len == 0)
! 	  break;
! 	c = *p++;
! 	len--;
        }
+       /* Don't look for any more digits after the suffixes.  */
+       break;
      }
    }
  
+   if (len != 0) {
+     yyerror ("Invalid number in #if expression");
+     return ERROR;
+   }
+ 
+   /* If too big to be signed, consider it unsigned.  */
+   if (n < 0)
+     yylval.integer.unsignedp = 1;
+ 
    lexptr = p;
!   yylval.integer.value = n;
    return INT;
  }
***************
*** 220,224 ****
--- 289,295 ----
  };
  
+ #ifndef NULL
  #define NULL 0
+ #endif
  
  static struct token tokentab2[] = {
***************
*** 270,274 ****
      if (c == '\\')
        c = parse_escape (&lexptr);
!     yylval.lval = c;
      c = *lexptr++;
      if (c != '\'') {
--- 341,355 ----
      if (c == '\\')
        c = parse_escape (&lexptr);
! 
!     /* Sign-extend the constant if chars are signed on target machine.  */
!     {
!       if (lookup ("__CHAR_UNSIGNED__", sizeof ("__CHAR_UNSIGNED__")-1, -1)
! 	  || ((c >> (CHAR_TYPE_SIZE - 1)) & 1) == 0)
! 	yylval.integer.value = c & ((1 << CHAR_TYPE_SIZE) - 1);
!       else
! 	yylval.integer.value = c | ~((1 << CHAR_TYPE_SIZE) - 1);
!     }
! 
!     yylval.integer.unsignedp = 0;
      c = *lexptr++;
      if (c != '\'') {
***************
*** 358,376 ****
      {
      case 'a':
!       return '\a';
      case 'b':
!       return '\b';
      case 'e':
        return 033;
      case 'f':
!       return '\f';
      case 'n':
!       return '\n';
      case 'r':
!       return '\r';
      case 't':
!       return '\t';
      case 'v':
!       return '\v';
      case '\n':
        return -2;
--- 439,457 ----
      {
      case 'a':
!       return TARGET_BELL;
      case 'b':
!       return TARGET_BS;
      case 'e':
        return 033;
      case 'f':
!       return TARGET_FF;
      case 'n':
!       return TARGET_NEWLINE;
      case 'r':
!       return TARGET_CR;
      case 't':
!       return TARGET_TAB;
      case 'v':
!       return TARGET_VT;
      case '\n':
        return -2;
***************
*** 399,407 ****
  	while (++count < 3)
  	  {
! 	    if ((c = *(*string_ptr)++) >= '0' && c <= '7')
  	      {
! 		i *= 8;
! 		i += c - '0';
  	      }
  	    else
  	      {
--- 480,512 ----
  	while (++count < 3)
  	  {
! 	    c = *(*string_ptr)++;
! 	    if (c >= '0' && c <= '7')
! 	      i = (i << 3) + c - '0';
! 	    else
  	      {
! 		(*string_ptr)--;
! 		break;
  	      }
+ 	  }
+ 	if ((i & ~((1 << CHAR_TYPE_SIZE) - 1)) != 0)
+ 	  {
+ 	    i &= (1 << CHAR_TYPE_SIZE) - 1;
+ 	    warning ("octal character constant does not fit in a byte");
+ 	  }
+ 	return i;
+       }
+     case 'x':
+       {
+ 	register int i = 0;
+ 	register int count = 0;
+ 	for (;;)
+ 	  {
+ 	    c = *(*string_ptr)++;
+ 	    if (c >= '0' && c <= '9')
+ 	      i = (i << 4) + c - '0';
+ 	    else if (c >= 'a' && c <= 'f')
+ 	      i = (i << 4) + c - 'a' + 10;
+ 	    else if (c >= 'A' && c <= 'F')
+ 	      i = (i << 4) + c - 'A' + 10;
  	    else
  	      {
***************
*** 410,413 ****
--- 515,523 ----
  	      }
  	  }
+ 	if ((i & ~((1 << BITS_PER_UNIT) - 1)) != 0)
+ 	  {
+ 	    i &= (1 << BITS_PER_UNIT) - 1;
+ 	    warning ("hex character constant does not fit in a byte");
+ 	  }
  	return i;
        }
***************
*** 446,450 ****
       the parsing routine has printed an error message somewhere.
       there is surely a better thing to do than this.     */
!   if (setjmp(parse_return_error))
      return 0;
  
--- 556,560 ----
       the parsing routine has printed an error message somewhere.
       there is surely a better thing to do than this.     */
!   if (setjmp (parse_return_error))
      return 0;
  
***************
*** 455,459 ****
      error ("Junk after end of expression.");
  
!   return expression_value;	/* set by yyparse() */
  }
  \f


--- 565,569 ----
      error ("Junk after end of expression.");
  
!   return expression_value;	/* set by yyparse () */
  }
  \f


***************
*** 460,466 ****
  #ifdef TEST_EXP_READER
  /* main program, for testing purposes. */
! main()
  {
!   int n;
    char buf[1024];
    extern int yydebug;
--- 570,576 ----
  #ifdef TEST_EXP_READER
  /* main program, for testing purposes. */
! main ()
  {
!   int n, c;
    char buf[1024];
    extern int yydebug;
***************
*** 471,480 ****
  
    for (;;) {
!     printf("enter expression: ");
      n = 0;
!     while ((buf[n] = getchar()) != '\n')
        n++;
      buf[n] = '\0';
!     printf("parser returned %d\n", parse_c_expression(buf));
    }
  }
--- 581,592 ----
  
    for (;;) {
!     printf ("enter expression: ");
      n = 0;
!     while ((buf[n] = getchar ()) != '\n' && buf[n] != EOF)
        n++;
+     if (buf[n] == EOF)
+       break;
      buf[n] = '\0';
!     printf ("parser returned %d\n", parse_c_expression (buf));
    }
  }
***************
*** 481,488 ****
  
  /* table to tell if char can be part of a C identifier. */
! char is_idchar[256];
  /* table to tell if char can be first char of a c identifier. */
! char is_idstart[256];
! /* table to tell if c is horizontal space.  isspace() thinks that
     newline is space; this is not a good idea for this program. */
  char is_hor_space[256];
--- 593,600 ----
  
  /* table to tell if char can be part of a C identifier. */
! unsigned char is_idchar[256];
  /* table to tell if char can be first char of a c identifier. */
! unsigned char is_idstart[256];
! /* table to tell if c is horizontal space.  isspace () thinks that
     newline is space; this is not a good idea for this program. */
  char is_hor_space[256];
***************
*** 491,495 ****
   * initialize random junk in the hash table and maybe other places
   */
! initialize_random_junk()
  {
    register int i;
--- 603,607 ----
   * initialize random junk in the hash table and maybe other places
   */
! initialize_random_junk ()
  {
    register int i;
***************
*** 497,501 ****
    /*
     * Set up is_idchar and is_idstart tables.  These should be
!    * faster than saying (is_alpha(c) || c == '_'), etc.
     * Must do set up these things before calling any routines tthat
     * refer to them.
--- 609,613 ----
    /*
     * Set up is_idchar and is_idstart tables.  These should be
!    * faster than saying (is_alpha (c) || c == '_'), etc.
     * Must do set up these things before calling any routines tthat
     * refer to them.
***************
*** 523,527 ****
  error (msg)
  {
!   printf("error: %s\n", msg);
  }
  #endif
--- 635,653 ----
  error (msg)
  {
!   printf ("error: %s\n", msg);
! }
! 
! warning (msg)
! {
!   printf ("warning: %s\n", msg);
! }
! 
! struct hashnode *
! lookup (name, len, hash)
!      char *name;
!      int len;
!      int hash;
! {
!   return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
  }
  #endif
diff -rc2N gcc-1.35/combine.c gcc-1.36/combine.c
*** gcc-1.35/combine.c	Tue Apr 11 19:18:48 1989
--- gcc-1.36/combine.c	Fri Sep 15 00:40:17 1989
***************
*** 61,64 ****
--- 61,66 ----
     combine anyway.  */
  
+ #include <stdio.h>
+ 
  #include "config.h"
  #include "rtl.h"
***************
*** 336,340 ****
  	    }
  #endif
! 	  record_dead_and_set_regs (insn);
  	  prev = insn;
  	}
--- 338,343 ----
  	    }
  #endif
! 	  if (GET_CODE (insn) != NOTE)
! 	    record_dead_and_set_regs (insn);
  	  prev = insn;
  	}
***************
*** 371,374 ****
--- 374,378 ----
    int maxreg;
    rtx temp;
+   int i;
  
    combine_attempts++;
***************
*** 428,431 ****
--- 432,441 ----
  	  || use_crosses_set_p (i2src, INSN_CUID (i2))))
      return 0;
+   /* Don't substitute for a register intended as a clobberable operand.  */
+   if (GET_CODE (PATTERN (i3)) == PARALLEL)
+     for (i = 0; i < XVECLEN (PATTERN (i3), 0); i++)
+       if (GET_CODE (XVECEXP (PATTERN (i3), 0, i)) == CLOBBER
+ 	  && XEXP (XVECEXP (PATTERN (i3), 0, i), 0) == i2dest)
+ 	return 0;
  
    if (i1 != 0)
***************
*** 452,455 ****
--- 462,488 ----
  	      || use_crosses_set_p (i1src, INSN_CUID (i1))))
  	return 0;
+       /* Don't substitute for a register intended as a clobberable operand.  */
+       if (GET_CODE (PATTERN (i3)) == PARALLEL)
+ 	for (i = 0; i < XVECLEN (PATTERN (i3), 0); i++)
+ 	  if (GET_CODE (XVECEXP (PATTERN (i3), 0, i)) == CLOBBER
+ 	      && XEXP (XVECEXP (PATTERN (i3), 0, i), 0) == i1dest)
+ 	    return 0;
+     }
+ 
+   /* If it is better that two different modes keep two different pseudos,
+      avoid combining them.  */
+   if (GET_CODE (PATTERN (i3)) == SET)
+     {
+       rtx i3dest = SET_DEST (PATTERN (i3));
+       while (GET_CODE (i3dest) == SUBREG
+ 	     || GET_CODE (i3dest) == STRICT_LOW_PART
+ 	     || GET_CODE (i3dest) == SIGN_EXTRACT
+ 	     || GET_CODE (i3dest) == ZERO_EXTRACT)
+ 	i3dest = SUBREG_REG (i3dest);
+ 
+       if (SET_SRC (PATTERN (i3)) == i2dest
+ 	  && GET_CODE (i3dest) == REG
+ 	  && ! MODES_TIEABLE_P (GET_MODE (i2dest), GET_MODE (i3dest)))
+ 	return 0;
      }
  
***************
*** 935,938 ****
--- 968,973 ----
  	}
        /* (subreg:A (mem:B X) N) becomes a modified MEM.
+ 	 If we can't do that safely, then it becomes something nonsensical
+ 	 so that this combination won't take place.
  	 This avoids producing any (subreg (mem))s except in the special
  	 paradoxical case where gen_lowpart_for_combine makes them.  */
***************
*** 941,944 ****
--- 976,986 ----
  	{
  	  int endian_offset = 0;
+ 	  /* Don't combine this if mode A is wider than B.  */
+ 	  if (GET_MODE_SIZE (GET_MODE (x)) > GET_MODE_SIZE (GET_MODE (to)))
+ 	    return gen_rtx (CLOBBER, VOIDmode, const0_rtx);
+ 	  /* Don't change the mode of the MEM
+ 	     if that would change the meaning of the address.  */
+ 	  if (mode_dependent_address_p (XEXP (to, 0)))
+ 	    return gen_rtx (CLOBBER, VOIDmode, const0_rtx);
  #ifdef BYTES_BIG_ENDIAN
  	  if (GET_MODE_SIZE (GET_MODE (x)) < UNITS_PER_WORD)
***************
*** 997,1001 ****
--- 1039,1070 ----
        break;
  
+ #if 0
+     case COMPARE:
+       /* -x>0 if 0>x.  */
+       if (GET_CODE (XEXP (x, 0)) == NEG && XEXP (x, 1) == const0_rtx)
+ 	{
+ 	  SUBST (XEXP (x, 1), XEXP (XEXP (x, 0), 0));
+ 	  SUBST (XEXP (x, 0), const0_rtx);
+ 	}
+       if (GET_CODE (XEXP (x, 1)) == NEG && XEXP (x, 0) == const0_rtx)
+ 	{
+ 	  SUBST (XEXP (x, 0), XEXP (XEXP (x, 1), 0));
+ 	  SUBST (XEXP (x, 1), const0_rtx);
+ 	}
+       break;
+ #endif
+ 
      case PLUS:
+ #if 0  /* Turned off for caution: turn it on after 1.36.  */
+       /* Identify constant sums as such.  */
+       if ((was_replaced[0] || was_replaced[1])
+ 	  && CONSTANT_P (XEXP (x, 0))
+ 	  && CONSTANT_P (XEXP (x, 1)))
+ 	{
+ 	  if (!undobuf.storage)
+ 	    undobuf.storage = (char *) oballoc (0);
+ 	  return gen_rtx (CONST, GET_MODE (x), x);
+ 	}
+ #endif
        /* In (plus <foo> (ashift <bar> <n>))
  	 change the shift to a multiply so we can recognize
***************
*** 1143,1147 ****
  			  const1_rtx, XEXP (to, 1)));
  	}
! 
        break;
  
--- 1212,1224 ----
  			  const1_rtx, XEXP (to, 1)));
  	}
!       /* Negation is a no-op before equality test against zero.  */
!       if (GET_CODE (XEXP (x, 0)) == NEG && XEXP (x, 1) == const0_rtx)
! 	{
! 	  SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0));
! 	}
!       if (GET_CODE (XEXP (x, 1)) == NEG && XEXP (x, 0) == const0_rtx)
! 	{
! 	  SUBST (XEXP (x, 1), XEXP (XEXP (x, 1), 0));
! 	}
        break;
  
***************
*** 1208,1212 ****
  			  XEXP (to, 1));
  	}
!       /* In (zero_extend:M (subreg:N (lshiftrt:M (zero_extend:M (any:N ...)))))
  	 remove the outer zero extension.  */
        if (GET_CODE (XEXP (x, 0)) == SUBREG
--- 1285,1290 ----
  			  XEXP (to, 1));
  	}
!       /* In (zero_extend:M (subreg:N (lshiftrt:M REG))),
! 	 where REG was assigned from (zero_extend:M (any:N ...)),
  	 remove the outer zero extension.  */
        if (GET_CODE (XEXP (x, 0)) == SUBREG
***************
*** 1217,1222 ****
  	  rtx tmp = XEXP (to, 0);
  
  	  if (GET_CODE (tmp) == REG)
! 	    if (reg_n_sets[REGNO (tmp)] == 1)
  	      tmp = SET_SRC (PATTERN (reg_last_set[REGNO (tmp)]));
  	    else
--- 1295,1302 ----
  	  rtx tmp = XEXP (to, 0);
  
+ 	  /* See if arg of LSHIFTRT is a register whose value we can find.  */
  	  if (GET_CODE (tmp) == REG)
! 	    if (reg_n_sets[REGNO (tmp)] == 1
! 		&& SET_DEST (PATTERN (reg_last_set[REGNO (tmp)])) == tmp)
  	      tmp = SET_SRC (PATTERN (reg_last_set[REGNO (tmp)]));
  	    else
***************
*** 1285,1289 ****
  			  XEXP (to, 1));
  	} 
!       /* In (sign_extend:M (subreg:N (ashiftrt:M (sign_extend:M (any:N ...)))))
  	 remove the outer sign extension.  */
        if (GET_CODE (XEXP (x, 0)) == SUBREG
--- 1365,1370 ----
  			  XEXP (to, 1));
  	} 
!       /* In (sign_extend:M (subreg:N (ashiftrt:M REG))),
! 	 where REG was assigned from (sign_extend:M (any:N ...)),
  	 remove the outer sign extension.  */
        if (GET_CODE (XEXP (x, 0)) == SUBREG
***************
*** 1294,1299 ****
  	  rtx tmp = XEXP (to, 0);
  
  	  if (GET_CODE (tmp) == REG)
! 	    if (reg_n_sets[REGNO (tmp)] == 1)
  	      tmp = SET_SRC (PATTERN (reg_last_set[REGNO (tmp)]));
  	    else
--- 1375,1382 ----
  	  rtx tmp = XEXP (to, 0);
  
+ 	  /* See if arg of LSHIFTRT is a register whose value we can find.  */
  	  if (GET_CODE (tmp) == REG)
! 	    if (reg_n_sets[REGNO (tmp)] == 1
! 		&& SET_DEST (PATTERN (reg_last_set[REGNO (tmp)])) == tmp)
  	      tmp = SET_SRC (PATTERN (reg_last_set[REGNO (tmp)]));
  	    else
***************
*** 1355,1358 ****
--- 1438,1442 ----
  	{
  	  int shiftcount;
+ 	  int newmask;
  #ifdef BITS_BIG_ENDIAN
  	  shiftcount
***************
*** 1363,1366 ****
--- 1447,1457 ----
  	    = INTVAL (XEXP (XEXP (x, 0), 2));
  #endif
+ 	  newmask = ((INTVAL (XEXP (XEXP (x, 1), 1)) << shiftcount)
+ 		     + (GET_CODE (XEXP (x, 1)) == AND
+ 			? (1 << shiftcount) - 1
+ 			: 0));
+ 	  if (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (x, 0), 0)))
+ 	      < HOST_BITS_PER_INT)
+ 	    newmask &= (1 << GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (x, 0), 0)))) - 1;
  	  if (!undobuf.storage)
  	    undobuf.storage = (char *) oballoc (0);
***************
*** 1371,1380 ****
  			      GET_MODE (XEXP (XEXP (x, 0), 0)),
  			      XEXP (XEXP (XEXP (x, 1), 0), 0),
! 			      gen_rtx (CONST_INT, VOIDmode,
! 				       (INTVAL (XEXP (XEXP (x, 1), 1))
! 					<< shiftcount)
! 				       + (GET_CODE (XEXP (x, 1)) == AND
! 					  ? (1 << shiftcount) - 1
! 					  : 0))));
  	}
        /* Can simplify (set (cc0) (compare (zero/sign_extend FOO) CONST))
--- 1462,1466 ----
  			      GET_MODE (XEXP (XEXP (x, 0), 0)),
  			      XEXP (XEXP (XEXP (x, 1), 0), 0),
! 			      gen_rtx (CONST_INT, VOIDmode, newmask)));
  	}
        /* Can simplify (set (cc0) (compare (zero/sign_extend FOO) CONST))
***************
*** 1746,1749 ****
--- 1832,1853 ----
  		      XEXP (to, 0), XEXP (x, 1));
      }
+   /* (and (ashiftrt (zero_extend FOO) N) CONST)
+      may be simplified to (and (ashiftrt (subreg FOO) N) CONST)
+      if CONST masks off the bits changed by extension.  */
+   if ((GET_CODE (varop) == ASHIFTRT || GET_CODE (varop) == LSHIFTRT)
+       && GET_CODE (XEXP (varop, 1)) == CONST_INT
+       && XEXP (varop, 0) == to
+       && (GET_CODE (to) == ZERO_EXTEND || GET_CODE (to) == SIGN_EXTEND)
+       /* Verify the and discards all the extended bits.  */
+       && (((unsigned) constop << INTVAL (XEXP (varop, 1)))
+ 	  >> GET_MODE_BITSIZE (GET_MODE (XEXP (to, 0)))) == 0
+       && FAKE_EXTEND_SAFE_P (GET_MODE (x), XEXP (to, 0)))
+     {
+       if (!undobuf.storage)
+ 	undobuf.storage = (char *) oballoc (0);
+       SUBST (XEXP (varop, 0),
+ 	     gen_lowpart_for_combine (GET_MODE (x), XEXP (to, 0)));
+       return x;
+     }
    /* (and x const) may be converted to (zero_extend (subreg x 0)).  */
    if (constop == GET_MODE_MASK (QImode)
***************
*** 1985,1994 ****
  	  if (code == SET || code == CLOBBER)
  	    {
! 	      if (GET_CODE (XEXP (elt, 0)) == REG)
! 		reg_last_set[REGNO (XEXP (elt, 0))] = insn;
! 	      if (GET_CODE (XEXP (elt, 0)) == SUBREG
! 		  && GET_CODE (SUBREG_REG (XEXP (elt, 0))) == REG)
! 		reg_last_set[REGNO (SUBREG_REG (XEXP (elt, 0)))] = insn;
! 	      else if (GET_CODE (XEXP (elt, 0)) == MEM)
  		mem_last_set = INSN_CUID (insn);
  	    }
--- 2089,2102 ----
  	  if (code == SET || code == CLOBBER)
  	    {
! 	      rtx dest = XEXP (elt, 0);
! 	      while (GET_CODE (dest) == SUBREG
! 		     || GET_CODE (dest) == STRICT_LOW_PART
! 		     || GET_CODE (dest) == SIGN_EXTRACT
! 		     || GET_CODE (dest) == ZERO_EXTRACT)
! 		dest = XEXP (dest, 0);
! 	      
! 	      if (GET_CODE (dest) == REG)
! 		reg_last_set[REGNO (dest)] = insn;
! 	      else if (GET_CODE (dest) == MEM)
  		mem_last_set = INSN_CUID (insn);
  	    }
***************
*** 1998,2008 ****
  	   || GET_CODE (PATTERN (insn)) == CLOBBER)
      {
!       register rtx x = XEXP (PATTERN (insn), 0);
!       if (GET_CODE (x) == REG)
! 	reg_last_set[REGNO (x)] = insn;
!       if (GET_CODE (x) == SUBREG
! 	  && GET_CODE (SUBREG_REG (x)) == REG)
! 	reg_last_set[REGNO (SUBREG_REG (x))] = insn;
!       else if (GET_CODE (x) == MEM)
  	mem_last_set = INSN_CUID (insn);
      }
--- 2106,2120 ----
  	   || GET_CODE (PATTERN (insn)) == CLOBBER)
      {
!       register rtx dest = XEXP (PATTERN (insn), 0);
! 
!       while (GET_CODE (dest) == SUBREG
! 	     || GET_CODE (dest) == STRICT_LOW_PART
! 	     || GET_CODE (dest) == SIGN_EXTRACT
! 	     || GET_CODE (dest) == ZERO_EXTRACT)
! 	dest = XEXP (dest, 0);
! 
!       if (GET_CODE (dest) == REG)
! 	reg_last_set[REGNO (dest)] = insn;
!       else if (GET_CODE (dest) == MEM)
  	mem_last_set = INSN_CUID (insn);
      }
***************
*** 2604,2608 ****
  void
  dump_combine_stats (file)
!      char *file;
  {
    fprintf
--- 2716,2720 ----
  void
  dump_combine_stats (file)
!      FILE *file;
  {
    fprintf
***************
*** 2619,2623 ****
  void
  dump_combine_total_stats (file)
!      char *file;
  {
    fprintf
--- 2731,2735 ----
  void
  dump_combine_total_stats (file)
!      FILE *file;
  {
    fprintf
diff -rc2N gcc-1.35/config/alliant.md gcc-1.36/config/alliant.md
*** gcc-1.35/config/alliant.md	Thu Mar 23 04:38:00 1989
--- gcc-1.36/config/alliant.md	Sun Aug 27 14:14:57 1989
***************
*** 1,5 ****
! ;;- Machine description for GNU compiler
! ;;- Alliant FX Version (Based on Motorola 68000)
  ;;   Copyright (C) 1989 Free Software Foundation, Inc.
  
  ;; This file is part of GNU CC.
--- 1,6 ----
! ;;- Machine description for GNU C compiler for Alliant FX systems
  ;;   Copyright (C) 1989 Free Software Foundation, Inc.
+ ;;   Adapted from m68k.md by Paul Petersen (petersen@uicsrd.csrd.uiuc.edu)
+ ;;   and Joe Weening (weening@gang-of-four.stanford.edu).
  
  ;; This file is part of GNU CC.
***************
*** 36,54 ****
  ;;- 'a' one of the address registers can be used.
  ;;- 'd' one of the data registers can be used.
! ;;- 'f' one of the m68881 registers can be used
  ;;- 'r' either a data or an address register can be used.
- ;;- 'x' if one of the Sun FPA registers                    
- ;;- 'y' if one of the Low Sun FPA registers (fpa0-fpa15).
  
! ;;- Immediate Floating point operator constraints
! ;;- 'G' a floating point constant that is *NOT* one of the standard
! ;;   68881 constant values (to force calling output_move_const_double
! ;;   to get it from rom if it is a 68881 constant).
! ;;- 'H' one of the standard FPA constant values
! ;;
! ;;   See the functions standard_XXX_constant_p in output-m68k.c for more
! ;; info.
! 
! ;;- Immedidate integer operands Constrains:
  ;;- 'I'  1 .. 8
  ;;- 'J'  -32768 .. 32767
--- 37,44 ----
  ;;- 'a' one of the address registers can be used.
  ;;- 'd' one of the data registers can be used.
! ;;- 'f' one of the CE floating point registers can be used
  ;;- 'r' either a data or an address register can be used.
  
! ;;- Immediate integer operand constraints:
  ;;- 'I'  1 .. 8
  ;;- 'J'  -32768 .. 32767
***************
*** 56,84 ****
  ;;- 'L'  -8 .. -1
  
! ;;- Some of these insn's are composites of several m68000 op codes.
  ;;- The assembler (or final @@??) insures that the appropriate one is
  ;;- selected.
- 
  \f


! (define_insn ""
!   [(set (match_operand:DF 0 "push_operand" "=m")
! 	(match_operand:DF 1 "general_operand" "ro<>fyF"))]
!   ""
!   "*
! {
!   if (FP_REG_P (operands[1]))
!     return \"fmoved %1,%0\";
!   return output_move_double (operands);
! }")
  
- (define_insn ""
-   [(set (match_operand:DI 0 "push_operand" "=m")
- 	(match_operand:DI 1 "general_operand" "ro<>Fy"))]
-   ""
-   "*
- {
-   return output_move_double (operands);
- }")
- \f


  (define_insn "tstsi"
    [(set (cc0)
--- 46,58 ----
  ;;- 'L'  -8 .. -1
  
! ;;- Some remnants of constraint codes for the m68k ('x','y','G','H')
! ;;- may remain in the insn definitions.
! 
! ;;- Some of these insn's are composites of several Alliant op codes.
  ;;- The assembler (or final @@??) insures that the appropriate one is
  ;;- selected.
  \f


! ;; Put tstsi first among test insns so it matches a CONST_INT operand.
  
  (define_insn "tstsi"
    [(set (cc0)
***************
*** 88,96 ****
  {
    if (TARGET_68020 || ! ADDRESS_REG_P (operands[0]))
!     return \"tstl %0\";
    /* If you think that the 68020 does not support tstl a0,
       reread page B-167 of the 68020 manual more carefully.  */
    /* On an address reg, cmpw may replace cmpl.  */
!   return \"cmpw %#0,%0\";
  }")
  
--- 62,70 ----
  {
    if (TARGET_68020 || ! ADDRESS_REG_P (operands[0]))
!     return \"tst%.l %0\";
    /* If you think that the 68020 does not support tstl a0,
       reread page B-167 of the 68020 manual more carefully.  */
    /* On an address reg, cmpw may replace cmpl.  */
!   return \"cmp%.w %#0,%0\";
  }")
  
***************
*** 102,107 ****
  {
    if (TARGET_68020 || ! ADDRESS_REG_P (operands[0]))
!     return \"tstw %0\";
!   return \"cmpw %#0,%0\";
  }")
  
--- 76,81 ----
  {
    if (TARGET_68020 || ! ADDRESS_REG_P (operands[0]))
!     return \"tst%.w %0\";
!   return \"cmp%.w %#0,%0\";
  }")
  
***************
*** 110,150 ****
  	(match_operand:QI 0 "general_operand" "dm"))]
    ""
!   "tstb %0")
!   
! (define_expand "tstsf"
!   [(set (cc0)
! 	(match_operand:SF 0 "general_operand" ""))]
!   "TARGET_68881"
!   "")
! 
! 
! (define_insn ""
!   [(set (cc0)
! 	(match_operand:SF 0 "general_operand" "fdm"))]
!   "TARGET_68881"
!   "*
! {
!   cc_status.flags = CC_IN_68881;
!   if (FP_REG_P (operands[0]))
!     return \"ftests %0\";
!   return \"ftests %0\";
! }")
! 
! (define_expand "tstdf"
!   [(set (cc0)
! 	(match_operand:DF 0 "general_operand" ""))]
!   "TARGET_68881"
!   "")
  
! (define_insn ""
    [(set (cc0)
! 	(match_operand:DF 0 "general_operand" "fm"))]
!   "TARGET_68881"
!   "*
  {
!   cc_status.flags = CC_IN_68881;
!   if (FP_REG_P (operands[0]))
!     return \"ftestd %0\";
!   return \"ftestd %0\";
  }")
  \f


--- 84,107 ----
  	(match_operand:QI 0 "general_operand" "dm"))]
    ""
!   "tst%.b %0")
  
! (define_insn "tstsf"
    [(set (cc0)
! 	(match_operand:SF 0 "nonimmediate_operand" "fm"))]
!   "TARGET_CE"
!   "*
! {
!   cc_status.flags = CC_IN_FP;
!   return \"ftest%.s %0\";
! }")
! 
! (define_insn "tstdf"
!   [(set (cc0)
! 	(match_operand:DF 0 "nonimmediate_operand" "fm"))]
!   "TARGET_CE"
!   "*
  {
!   cc_status.flags = CC_IN_FP;
!   return \"ftest%.d %0\";
  }")
  \f


***************
*** 151,162 ****
  ;; compare instructions.
  
  ;; A composite of the cmp, cmpa, & cmpi m68000 op codes.
  (define_insn "cmpsi"
    [(set (cc0)
! 	(compare (match_operand:SI 0 "general_operand" "rKs,mr")
! 		 (match_operand:SI 1 "general_operand" "mr,Ksr")))]
    ""
    "*
  {
    if (REG_P (operands[1])
        || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
--- 108,123 ----
  ;; compare instructions.
  
+ ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
+ 
  ;; A composite of the cmp, cmpa, & cmpi m68000 op codes.
  (define_insn "cmpsi"
    [(set (cc0)
! 	(compare (match_operand:SI 0 "general_operand" "rKs,mr,>")
! 		 (match_operand:SI 1 "general_operand" "mr,Ksr,>")))]
    ""
    "*
  {
+   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
+     return \"cmpm%.l %1,%0\";
    if (REG_P (operands[1])
        || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
***************
*** 163,169 ****
      {
        cc_status.flags |= CC_REVERSED;
!       return \"cmpl %0,%1\"; 
      }
!   return \"cmpl %1,%0\";
  }")
  
--- 124,130 ----
      {
        cc_status.flags |= CC_REVERSED;
!       return \"cmp%.l %d0,%d1\"; 
      }
!   return \"cmp%.l %d1,%d0\";
  }")
  
***************
*** 170,205 ****
  (define_insn "cmphi"
    [(set (cc0)
! 	(compare (match_operand:HI 0 "general_operand" "rn,mr")
! 		 (match_operand:HI 1 "general_operand" "mr,nr")))]
    ""
    "*
  {
!   if (REG_P (operands[1])
        || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
!     {
!       cc_status.flags |= CC_REVERSED;
!       return \"cmpw %0,%1\"; 
      }
!   return \"cmpw %1,%0\";
  }")
  
- ;;
- ;;	This seems to cause problems -- PMP
- ;;
- ;;(define_insn ""
- ;;  [(set (cc0)
- ;;	(compare (match_operand:QI 0 "memory_operand" ">")
- ;;	         (match_operand:QI 1 "memory_operand" ">")))]
- ;;  "GET_CODE (XEXP (operands[0], 0)) == POST_INC
- ;;   && GET_CODE (XEXP (operands[1], 0)) == POST_INC"
- ;;  "cmpmb %1,%0")
- 
  (define_insn "cmpqi"
    [(set (cc0)
! 	(compare (match_operand:QI 0 "general_operand" "dn,md")
! 		 (match_operand:QI 1 "general_operand" "dm,nd")))]
    ""
    "*
  {
    if (REG_P (operands[1])
        || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
--- 131,158 ----
  (define_insn "cmphi"
    [(set (cc0)
! 	(compare (match_operand:HI 0 "general_operand" "rnm,d,n,m")
! 		 (match_operand:HI 1 "general_operand" "d,rnm,m,n")))]
    ""
    "*
  {
!   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
!     return \"cmpm%.w %1,%0\";
!   if ((REG_P (operands[1]) && !ADDRESS_REG_P (operands[1]))
        || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
!     { cc_status.flags |= CC_REVERSED;
!       return \"cmp%.w %d0,%d1\"; 
      }
!   return \"cmp%.w %d1,%d0\";
  }")
  
  (define_insn "cmpqi"
    [(set (cc0)
! 	(compare (match_operand:QI 0 "general_operand" "dn,md,>")
! 		 (match_operand:QI 1 "general_operand" "dm,nd,>")))]
    ""
    "*
  {
+   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
+     return \"cmpm%.b %1,%0\";
    if (REG_P (operands[1])
        || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
***************
*** 206,264 ****
      {
        cc_status.flags |= CC_REVERSED;
!       return \"cmpb %0,%1\";
      }
!   return \"cmpb %1,%0\";
  }")
  
! (define_expand "cmpdf"
!   [(set (cc0)
! 	(compare (match_operand:DF 0 "general_operand" "")
! 		 (match_operand:DF 1 "general_operand" "")))]
!   "TARGET_68881"
!   "")
! 
! (define_insn ""
!   [(set (cc0)
! 	(compare (match_operand:DF 0 "general_operand" "f,m")
! 		 (match_operand:DF 1 "general_operand" "fm,f")))]
!   "TARGET_68881"
    "*
  {
!   cc_status.flags = CC_IN_68881;
!   if (REG_P (operands[0]))
!     {
!       if (REG_P (operands[1]))
! 	return \"fcmpd %1,%0\";
!       else
!         return \"fcmpd %1,%0\";
!     }
    cc_status.flags |= CC_REVERSED;
!   return \"fcmpd %0,%1\";
  }")
  
! (define_expand "cmpsf"
!  [(set (cc0)
!        (compare (match_operand:SF 0 "general_operand" "")
! 		(match_operand:SF 1 "general_operand" "")))]
!  "TARGET_68881"
!  "")
! 
! (define_insn ""
!   [(set (cc0)
! 	(compare (match_operand:SF 0 "general_operand" "f,md")
! 		 (match_operand:SF 1 "general_operand" "fmd,f")))]
!   "TARGET_68881"
    "*
  {
!   cc_status.flags = CC_IN_68881;
    if (FP_REG_P (operands[0]))
!     {
!       if (FP_REG_P (operands[1]))
! 	return \"fcmps %1,%0\";
!       else
!         return \"fcmps %1,%0\";
!     }
    cc_status.flags |= CC_REVERSED;
!   return \"fcmps %0,%1\";
  }")
  \f


--- 159,193 ----
      {
        cc_status.flags |= CC_REVERSED;
!       return \"cmp%.b %d0,%d1\";
      }
!   return \"cmp%.b %d1,%d0\";
  }")
  
! (define_insn "cmpdf"
!   [(set (cc0)
! 	(compare (match_operand:DF 0 "nonimmediate_operand" "f,m")
! 		 (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
!   "TARGET_CE"
    "*
  {
!   cc_status.flags = CC_IN_FP;
!   if (FP_REG_P (operands[0]))
!     return \"fcmp%.d %1,%0\";
    cc_status.flags |= CC_REVERSED;
!   return \"fcmp%.d %0,%1\";
  }")
  
! (define_insn "cmpsf"
!   [(set (cc0)
! 	(compare (match_operand:SF 0 "nonimmediate_operand" "f,m")
! 		 (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
!   "TARGET_CE"
    "*
  {
!   cc_status.flags = CC_IN_FP;
    if (FP_REG_P (operands[0]))
!     return \"fcmp%.s %1,%0\";
    cc_status.flags |= CC_REVERSED;
!   return \"fcmp%.s %0,%1\";
  }")
  \f


***************
*** 305,322 ****
    "* { return output_btst (operands, operands[1], operands[0], insn, 31); }")
  
  (define_insn ""
!   ;; The constraint "o,d" here means that a nonoffsetable memref
!   ;; will match the first alternative, and its address will be reloaded.
!   ;; Copying the memory contents into a reg would be incorrect if the
!   ;; bit position is over 7.
!   [(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "o,d")
  			    (const_int 1)
! 			    (match_operand:SI 1 "general_operand" "i,i")))]
!   "GET_CODE (operands[1]) == CONST_INT"
    "*
! { operands[1] = gen_rtx (CONST_INT, VOIDmode, 7 - INTVAL (operands[1]));
!   return output_btst (operands, operands[1], operands[0], insn, 7); }")
  
  (define_insn ""
    [(set (cc0) (zero_extract (match_operand:HI 0 "nonimmediate_operand" "o,d")
  			    (const_int 1)
--- 234,256 ----
    "* { return output_btst (operands, operands[1], operands[0], insn, 31); }")
  
+ ;; Nonoffsettable mem refs are ok in this one pattern
+ ;; since we don't try to adjust them.
  (define_insn ""
!   [(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "md")
  			    (const_int 1)
! 			    (match_operand:SI 1 "general_operand" "i")))]
!   "GET_CODE (operands[1]) == CONST_INT
!    && (unsigned) INTVAL (operands[1]) < 8"
    "*
! {
!   operands[1] = gen_rtx (CONST_INT, VOIDmode, 7 - INTVAL (operands[1]));
!   return output_btst (operands, operands[1], operands[0], insn, 7);
! }")
  
  (define_insn ""
+   ;; The constraint "o,d" here means that a nonoffsettable memref
+   ;; will match the first alternative, and its address will be reloaded.
+   ;; Copying the memory contents into a reg would be incorrect if the
+   ;; bit position is over 7.
    [(set (cc0) (zero_extract (match_operand:HI 0 "nonimmediate_operand" "o,d")
  			    (const_int 1)
***************
*** 327,332 ****
    if (GET_CODE (operands[0]) == MEM)
      {
!       operands[0] = adj_offsetable_operand (operands[0],
! 					    INTVAL (operands[1]) / 8);
        operands[1] = gen_rtx (CONST_INT, VOIDmode, 
  			     7 - INTVAL (operands[1]) % 8);
--- 261,266 ----
    if (GET_CODE (operands[0]) == MEM)
      {
!       operands[0] = adj_offsettable_operand (operands[0],
! 					     INTVAL (operands[1]) / 8);
        operands[1] = gen_rtx (CONST_INT, VOIDmode, 
  			     7 - INTVAL (operands[1]) % 8);
***************
*** 347,352 ****
    if (GET_CODE (operands[0]) == MEM)
      {
!       operands[0] = adj_offsetable_operand (operands[0],
! 					    INTVAL (operands[1]) / 8);
        operands[1] = gen_rtx (CONST_INT, VOIDmode, 
  			     7 - INTVAL (operands[1]) % 8);
--- 281,286 ----
    if (GET_CODE (operands[0]) == MEM)
      {
!       operands[0] = adj_offsettable_operand (operands[0],
! 					     INTVAL (operands[1]) / 8);
        operands[1] = gen_rtx (CONST_INT, VOIDmode, 
  			     7 - INTVAL (operands[1]) % 8);
***************
*** 366,370 ****
  {
    cc_status.flags = CC_Z_IN_NOT_N | CC_NOT_NEGATIVE;
!   return \"tstb %0\";
  }")
  
--- 300,304 ----
  {
    cc_status.flags = CC_Z_IN_NOT_N | CC_NOT_NEGATIVE;
!   return \"tst%.b %0\";
  }")
  
***************
*** 382,391 ****
  \f


  ;; move instructions
! (define_insn "swapsi"
!   [(set (match_operand:SI 0 "general_operand" "r")
! 	(match_operand:SI 1 "general_operand" "r"))
!    (set (match_dup 1) (match_dup 0))]
!   ""
!   "exg %1,%0")
  
  ;; Special case of fullword move when source is zero.
--- 316,342 ----
  \f


  ;; move instructions
! 
! ;; A special case in which it is not desirable
! ;; to reload the constant into a data register.
! (define_insn ""
!   [(set (match_operand:SI 0 "push_operand" "=m")
! 	(match_operand:SI 1 "general_operand" "J"))]
!   "GET_CODE (operands[1]) == CONST_INT
!    && INTVAL (operands[1]) >= -0x8000
!    && INTVAL (operands[1]) < 0x8000"
!   "*
! {
!   if (operands[1] == const0_rtx)
!     return \"clr%.l %0\";
!   return \"pea %a1\";
! }")
! 
! ;This is never used.
! ;(define_insn "swapsi"
! ;  [(set (match_operand:SI 0 "general_operand" "r")
! ;	(match_operand:SI 1 "general_operand" "r"))
! ;   (set (match_dup 1) (match_dup 0))]
! ;  ""
! ;  "exg %1,%0")
  
  ;; Special case of fullword move when source is zero.
***************
*** 400,417 ****
  {
    if (ADDRESS_REG_P (operands[0]))
!     return \"subl %0,%0\";
!   return \"clrl %0\";
  }")
  
- ;; Another special case in which it is not desirable
- ;; to reload the constant into a data register.
- (define_insn ""
-   [(set (match_operand:SI 0 "push_operand" "=m")
- 	(match_operand:SI 1 "general_operand" "J"))]
-   "GET_CODE (operands[1]) == CONST_INT
-    && INTVAL (operands[1]) >= -0x8000
-    && INTVAL (operands[1]) < 0x8000"
-   "pea %a1")
- 
  ;; General case of fullword move.  The register constraints
  ;; force integer constants in range for a moveq to be reloaded
--- 351,358 ----
  {
    if (ADDRESS_REG_P (operands[0]))
!     return \"sub%.l %0,%0\";
!   return \"clr%.l %0\";
  }")
  
  ;; General case of fullword move.  The register constraints
  ;; force integer constants in range for a moveq to be reloaded
***************
*** 431,435 ****
  	  && (DATA_REG_P (operands[0])
  	      || GET_CODE (operands[0]) == MEM))
! 	return \"clrl %0\";
        else if (DATA_REG_P (operands[0])
  	       && INTVAL (operands[1]) < 128
--- 372,376 ----
  	  && (DATA_REG_P (operands[0])
  	      || GET_CODE (operands[0]) == MEM))
! 	return \"clr%.l %0\";
        else if (DATA_REG_P (operands[0])
  	       && INTVAL (operands[1]) < 128
***************
*** 439,443 ****
  	       && INTVAL (operands[1]) < 0x8000
  	       && INTVAL (operands[1]) >= -0x8000)
! 	return \"movw %1,%0\";
        else if (push_operand (operands[0], SImode)
  	       && INTVAL (operands[1]) < 0x8000
--- 380,384 ----
  	       && INTVAL (operands[1]) < 0x8000
  	       && INTVAL (operands[1]) >= -0x8000)
! 	return \"mov%.w %1,%0\";
        else if (push_operand (operands[0], SImode)
  	       && INTVAL (operands[1]) < 0x8000
***************
*** 453,457 ****
  	   && ADDRESS_REG_P (operands[0]))
      return \"lea %a1,%0\";
!   return \"movl %1,%0\";
  }")
  
--- 394,398 ----
  	   && ADDRESS_REG_P (operands[0]))
      return \"lea %a1,%0\";
!   return \"mov%.l %1,%0\";
  }")
  
***************
*** 467,471 ****
  	  && (DATA_REG_P (operands[0])
  	      || GET_CODE (operands[0]) == MEM))
! 	return \"clrw %0\";
        else if (DATA_REG_P (operands[0])
  	       && INTVAL (operands[1]) < 128
--- 408,412 ----
  	  && (DATA_REG_P (operands[0])
  	      || GET_CODE (operands[0]) == MEM))
! 	return \"clr%.w %0\";
        else if (DATA_REG_P (operands[0])
  	       && INTVAL (operands[1]) < 128
***************
*** 476,483 ****
        else if (INTVAL (operands[1]) < 0x8000
  	       && INTVAL (operands[1]) >= -0x8000)
! 	return \"movw %1,%0\";
      }
    else if (CONSTANT_P (operands[1]))
!     return \"movl %1,%0\";
    /* Recognize the insn before a tablejump, one that refers
       to a table of offsets.  Such an insn will need to refer
--- 417,424 ----
        else if (INTVAL (operands[1]) < 0x8000
  	       && INTVAL (operands[1]) >= -0x8000)
! 	return \"mov%.w %1,%0\";
      }
    else if (CONSTANT_P (operands[1]))
!     return \"mov%.l %1,%0\";
    /* Recognize the insn before a tablejump, one that refers
       to a table of offsets.  Such an insn will need to refer
***************
*** 499,503 ****
  				 CODE_LABEL_NUMBER (XEXP (labelref, 0)));
      }
!   return \"movw %1,%0\";
  }")
  
--- 440,444 ----
  				 CODE_LABEL_NUMBER (XEXP (labelref, 0)));
      }
!   return \"mov%.w %1,%0\";
  }")
  
***************
*** 513,529 ****
  	  && (DATA_REG_P (operands[0])
  	      || GET_CODE (operands[0]) == MEM))
! 	return \"clrw %0\";
      }
!   return \"movw %1,%0\";
  }")
  
  (define_insn "movqi"
!   [(set (match_operand:QI 0 "general_operand" "=d,*a,m")
! 	(match_operand:QI 1 "general_operand" "dmi*a,d*a,dmi"))]
    ""
    "*
  {
    if (operands[1] == const0_rtx)
!     return \"clrb %0\";
    if (GET_CODE (operands[1]) == CONST_INT
        && INTVAL (operands[1]) == -1)
--- 454,494 ----
  	  && (DATA_REG_P (operands[0])
  	      || GET_CODE (operands[0]) == MEM))
! 	return \"clr%.w %0\";
      }
!   return \"mov%.w %1,%0\";
  }")
  
  (define_insn "movqi"
!   [(set (match_operand:QI 0 "general_operand" "=d,*a,m,m,?*a")
! 	(match_operand:QI 1 "general_operand" "dmi*a,d*a,dmi,?*a,m"))]
    ""
    "*
  {
+   rtx xoperands[4];
+   if (ADDRESS_REG_P (operands[0]) && GET_CODE (operands[1]) == MEM)
+     {
+       xoperands[1] = operands[1];
+       xoperands[2]
+         = gen_rtx (MEM, QImode,
+ 		   gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, const1_rtx));
+       xoperands[3] = stack_pointer_rtx;
+       /* Just pushing a byte puts it in the high byte of the halfword.  */
+       /* We must put it in the low half, the second byte.  */
+       output_asm_insn (\"subq%.w %#2,%3\;mov%.b %1,%2\", xoperands);
+       return \"mov%.w %+,%0\";
+     }
+   if (ADDRESS_REG_P (operands[1]) && GET_CODE (operands[0]) == MEM)
+     {
+       xoperands[0] = operands[0];
+       xoperands[1] = operands[1];
+       xoperands[2]
+         = gen_rtx (MEM, QImode,
+ 		   gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, const1_rtx));
+       xoperands[3] = stack_pointer_rtx;
+       output_asm_insn (\"mov%.w %1,%-\;mov%.b %2,%0\;addq%.w %#2,%3\", xoperands);
+       return \"\";
+     }
    if (operands[1] == const0_rtx)
!     return \"clr%.b %0\";
    if (GET_CODE (operands[1]) == CONST_INT
        && INTVAL (operands[1]) == -1)
***************
*** 530,537 ****
      return \"st %0\";
    if (GET_CODE (operands[1]) != CONST_INT && CONSTANT_P (operands[1]))
!     return \"movl %1,%0\";
    if (ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1]))
!     return \"movw %1,%0\";
!   return \"movb %1,%0\";
  }")
  
--- 495,502 ----
      return \"st %0\";
    if (GET_CODE (operands[1]) != CONST_INT && CONSTANT_P (operands[1]))
!     return \"mov%.l %1,%0\";
    if (ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1]))
!     return \"mov%.w %1,%0\";
!   return \"mov%.b %1,%0\";
  }")
  
***************
*** 543,554 ****
  {
    if (operands[1] == const0_rtx)
!     return \"clrb %0\";
!   return \"movb %1,%0\";
  }")
  
! (define_insn "movsf"
!   [(set (match_operand:SF 0 "general_operand" "=rmf,x,y,rm,!x,!rm")
! 	(match_operand:SF 1 "general_operand" "rmfF,x,rmF,y,rm,x"))]
!   ""
    "*
  {
--- 508,534 ----
  {
    if (operands[1] == const0_rtx)
!     return \"clr%.b %0\";
!   return \"mov%.b %1,%0\";
  }")
  
! ;; Floating-point moves on a CE are faster using an FP register than
! ;; with movl instructions.  (Especially for double floats, but also
! ;; for single floats, even though it takes an extra instruction.)  But
! ;; on an IP, the FP registers are simulated and so should be avoided.
! ;; We do this by using define_expand for movsf and movdf, and using
! ;; different constraints for each target type.  The constraints for
! ;; TARGET_CE allow general registers because they sometimes need to
! ;; hold floats, but they are not preferable.
! 
! (define_expand "movsf"
!   [(set (match_operand:SF 0 "general_operand" "")
! 	(match_operand:SF 1 "nonimmediate_operand" ""))]
!   ""
!   "")
! 
! (define_insn ""
!   [(set (match_operand:SF 0 "general_operand" "=f,m,!*r,!f*m")
! 	(match_operand:SF 1 "nonimmediate_operand" "fm,f,f*r*m,*r"))]
!   "TARGET_CE"
    "*
  {
***************
*** 556,609 ****
      {
        if (FP_REG_P (operands[1]))
! 	return \"fmoves %1,%0\";
!       else if (ADDRESS_REG_P (operands[1]) || DATA_REG_P (operands[1]))
! 	return \"movl %1,%-\;fmoves %+,%0\";
!       else if (GET_CODE (operands[1]) == CONST_DOUBLE)
! 	{
! 	  rtx xoperands[2];
! 	  xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
! 				  CONST_DOUBLE_HIGH (operands[1]));
! 	  output_asm_insn (\"movl %1,%-\", xoperands);
! 	  xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
! 				  CONST_DOUBLE_LOW (operands[1]));
! 	  output_asm_insn (\"movl %1,%-\", xoperands);
! 	  return \"fmoveds %+,%0\";
! 	}
!       return \"fmoves %1,%0\";
!     }
!   if (FP_REG_P (operands[1]))
!     {
!       if (ADDRESS_REG_P (operands[0]) || DATA_REG_P (operands[0]))
! 	return \"fmoves %1,%-\;movl %+,%0\";
!       return \"fmoves %1,%0\";
!     }
!   return \"movl %1,%0\";
! }")
! 
! ;; This pattern forces (set (reg:DF ...) (const_double ...))
! ;; to be reloaded by putting the constant into memory.
! ;; It must come before the more general movdf pattern.
! 
! (define_insn ""
!   [(set (match_operand:DF 0 "general_operand" "=f,f,f")
!         (match_operand:DF 1 "" "mF,m,F"))]
!   "GET_CODE (operands[1]) == CONST_DOUBLE"
    "*
  {
!   rtx xoperands[2];
!   xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
! 			  CONST_DOUBLE_HIGH (operands[1]));
!   output_asm_insn (\"movl %1,%-\", xoperands);
!   xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
! 			  CONST_DOUBLE_LOW (operands[1]));
!   output_asm_insn (\"movl %1,%-\", xoperands);
!   return \"fmoved %+,%0\";
! }
! ")
  
! (define_insn "movdf"
!   [(set (match_operand:DF 0 "general_operand" "=rm,&rf,&rof<>,y,rm,x,!x,!rm")
! 	(match_operand:DF 1 "general_operand" "rf,m,rof<>,rm,y,x,rm,x"))]
    ""
    "*
  {
--- 536,586 ----
      {
        if (FP_REG_P (operands[1]))
! 	return \"fmove%.s %1,%0\";
!       if (REG_P (operands[1]))
! 	return \"mov%.l %1,%-\;fmove%.s %+,%0\";
!       return \"fmove%.s %1,%0\";
!     }
!   if (FP_REG_P (operands[1]))
!     {
!       if (REG_P (operands[0]))
! 	return \"fmove%.s %1,%-\;mov%.l %+,%0\";
!       return \"fmove%.s %1,%0\";
!     }
!   return \"mov%.l %1,%0\";
! }")
! 
! (define_insn ""
!   [(set (match_operand:SF 0 "general_operand" "=frm")
! 	(match_operand:SF 1 "nonimmediate_operand" "frm"))]
!   "!TARGET_CE"
    "*
  {
!   if (FP_REG_P (operands[0]))
!     {
!       if (FP_REG_P (operands[1]))
! 	return \"fmove%.s %1,%0\";
!       if (REG_P (operands[1]))
! 	return \"mov%.l %1,%-\;fmove%.s %+,%0\";
!       return \"fmove%.s %1,%0\";
!     }
!   if (FP_REG_P (operands[1]))
!     {
!       if (REG_P (operands[0]))
! 	return \"fmove%.s %1,%-\;mov%.l %+,%0\";
!       return \"fmove%.s %1,%0\";
!     }
!   return \"mov%.l %1,%0\";
! }")
  
! (define_expand "movdf"
!   [(set (match_operand:DF 0 "general_operand" "")
! 	(match_operand:DF 1 "nonimmediate_operand" ""))]
    ""
+   "")
+ 
+ (define_insn ""
+   [(set (match_operand:DF 0 "general_operand" "=f,m,!*r,!f*m")
+ 	(match_operand:DF 1 "nonimmediate_operand" "fm,f,f*r*m,*r"))]
+   "TARGET_CE"
    "*
  {
***************
*** 611,615 ****
      {
        if (FP_REG_P (operands[1]))
! 	return \"fmoved %1,%0\";
        if (REG_P (operands[1]))
  	{
--- 588,592 ----
      {
        if (FP_REG_P (operands[1]))
! 	return \"fmove%.d %1,%0\";
        if (REG_P (operands[1]))
  	{
***************
*** 616,635 ****
  	  rtx xoperands[2];
  	  xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
! 	  output_asm_insn (\"movl %1,%-\", xoperands);
! 	  output_asm_insn (\"movl %1,%-\", operands);
! 	  return \"fmoved %+,%0\";
! 	}
!       if (GET_CODE (operands[1]) == CONST_DOUBLE)
! 	{
! 	  rtx xoperands[2];
! 	  xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
! 				  CONST_DOUBLE_HIGH (operands[1]));
! 	  output_asm_insn (\"movl %1,%-\", xoperands);
! 	  xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
! 				  CONST_DOUBLE_LOW (operands[1]));
! 	  output_asm_insn (\"movl %1,%-\", xoperands);
! 	  return \"fmoved %+,%0\";
  	}
!       return \"fmoved %1,%0\";
      }
    else if (FP_REG_P (operands[1]))
--- 593,601 ----
  	  rtx xoperands[2];
  	  xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
! 	  output_asm_insn (\"mov%.l %1,%-\", xoperands);
! 	  output_asm_insn (\"mov%.l %1,%-\", operands);
! 	  return \"fmove%.d %+,%0\";
  	}
!       return \"fmove%.d %1,%0\";
      }
    else if (FP_REG_P (operands[1]))
***************
*** 637,657 ****
        if (REG_P (operands[0]))
  	{
! 	  output_asm_insn (\"fmoved %1,%-\;movl %+,%0\", operands);
  	  operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
! 	  return \"movl %+,%0\";
  	}
!       else
!         return \"fmoved %1,%0\";
      }
    return output_move_double (operands);
! }
! ")
  
! ;; movdi can apply to fp regs in some cases
! (define_insn "movdi"
!   ;; Let's see if it really still needs to handle fp regs, and, if so, why.
!   [(set (match_operand:DI 0 "general_operand" "=rm,&r,&ro<>,y,rm,!*x,!rm")
! 	(match_operand:DI 1 "general_operand" "rF,m,roi<>F,rmiF,y,rmF,*x"))]
!   ""
    "*
  {
--- 603,619 ----
        if (REG_P (operands[0]))
  	{
! 	  output_asm_insn (\"fmove%.d %1,%-\;mov%.l %+,%0\", operands);
  	  operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
! 	  return \"mov%.l %+,%0\";
  	}
!       return \"fmove%.d %1,%0\";
      }
    return output_move_double (operands);
! }")
  
! (define_insn ""
!   [(set (match_operand:DF 0 "general_operand" "=frm")
! 	(match_operand:DF 1 "nonimmediate_operand" "frm"))]
!   "!TARGET_CE"
    "*
  {
***************
*** 659,663 ****
      {
        if (FP_REG_P (operands[1]))
! 	return \"fmoved %1,%0\";
        if (REG_P (operands[1]))
  	{
--- 621,625 ----
      {
        if (FP_REG_P (operands[1]))
! 	return \"fmove%.d %1,%0\";
        if (REG_P (operands[1]))
  	{
***************
*** 664,674 ****
  	  rtx xoperands[2];
  	  xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
! 	  output_asm_insn (\"movl %1,%-\", xoperands);
! 	  output_asm_insn (\"movl %1,%-\", operands);
! 	  return \"fmoved %+,%0\";
  	}
!       if (GET_CODE (operands[1]) == CONST_DOUBLE)
! 	return output_move_const_double (operands);
!       return \"fmoved %1,%0\";
      }
    else if (FP_REG_P (operands[1]))
--- 626,634 ----
  	  rtx xoperands[2];
  	  xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
! 	  output_asm_insn (\"mov%.l %1,%-\", xoperands);
! 	  output_asm_insn (\"mov%.l %1,%-\", operands);
! 	  return \"fmove%.d %+,%0\";
  	}
!       return \"fmove%.d %1,%0\";
      }
    else if (FP_REG_P (operands[1]))
***************
*** 676,694 ****
        if (REG_P (operands[0]))
  	{
! 	  output_asm_insn (\"fmoved %1,%-\;movl %+,%0\", operands);
  	  operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
! 	  return \"movl %+,%0\";
  	}
!       else
!         return \"fmoved %1,%0\";
      }
    return output_move_double (operands);
  }
  ")
  
! ;; These go after the move instructions
  ;; because the move instructions are better (require no spilling)
! ;; when they can apply.  But these go before the add and subtract insns
! ;; because it is often shorter to use these when both apply.
  (define_insn "pushasi"
    [(set (match_operand:SI 0 "push_operand" "=m")
--- 636,663 ----
        if (REG_P (operands[0]))
  	{
! 	  output_asm_insn (\"fmove%.d %1,%-\;mov%.l %+,%0\", operands);
  	  operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
! 	  return \"mov%.l %+,%0\";
  	}
!       return \"fmove%.d %1,%0\";
      }
    return output_move_double (operands);
+ }")
+ 
+ (define_insn "movdi"
+   [(set (match_operand:DI 0 "general_operand" "=rm,&r,&ro<>")
+ 	(match_operand:DI 1 "general_operand" "r,m,roi<>"))]
+   ""
+   "*
+ {
+   return output_move_double (operands);
  }
  ")
  
! ;; This goes after the move instructions
  ;; because the move instructions are better (require no spilling)
! ;; when they can apply.  It goes before the add/sub insns
! ;; so we will prefer it to them.
! 
  (define_insn "pushasi"
    [(set (match_operand:SI 0 "push_operand" "=m")
***************
*** 696,706 ****
    ""
    "pea %a1")
- 
- 
- (define_insn ""
-   [(set (match_operand:SI 0 "general_operand" "=a")
- 	(match_operand:QI 1 "address_operand" "p"))]
-   ""
-   "lea %a1,%0")
  \f


  ;; truncation instructions
--- 665,668 ----
***************
*** 713,720 ****
  {
    if (GET_CODE (operands[0]) == REG)
!     return \"movl %1,%0\";
    if (GET_CODE (operands[1]) == MEM)
!     operands[1] = adj_offsetable_operand (operands[1], 3);
!   return \"movb %1,%0\";
  }")
  
--- 675,682 ----
  {
    if (GET_CODE (operands[0]) == REG)
!     return \"mov%.l %1,%0\";
    if (GET_CODE (operands[1]) == MEM)
!     operands[1] = adj_offsettable_operand (operands[1], 3);
!   return \"mov%.b %1,%0\";
  }")
  
***************
*** 726,734 ****
    "*
  {
    if (GET_CODE (operands[0]) == REG)
!     return \"movl %1,%0\";
    if (GET_CODE (operands[1]) == MEM)
!     operands[1] = adj_offsetable_operand (operands[1], 1);
!   return \"movb %1,%0\";
  }")
  
--- 688,700 ----
    "*
  {
+   if (GET_CODE (operands[0]) == REG
+       && (GET_CODE (operands[1]) == MEM
+ 	  || GET_CODE (operands[1]) == CONST_INT))
+     return \"mov%.w %1,%0\";
    if (GET_CODE (operands[0]) == REG)
!     return \"mov%.l %1,%0\";
    if (GET_CODE (operands[1]) == MEM)
!     operands[1] = adj_offsettable_operand (operands[1], 1);
!   return \"mov%.b %1,%0\";
  }")
  
***************
*** 741,748 ****
  {
    if (GET_CODE (operands[0]) == REG)
!     return \"movl %1,%0\";
    if (GET_CODE (operands[1]) == MEM)
!     operands[1] = adj_offsetable_operand (operands[1], 2);
!   return \"movw %1,%0\";
  }")
  \f


--- 707,714 ----
  {
    if (GET_CODE (operands[0]) == REG)
!     return \"mov%.l %1,%0\";
    if (GET_CODE (operands[1]) == MEM)
!     operands[1] = adj_offsettable_operand (operands[1], 2);
!   return \"mov%.w %1,%0\";
  }")
  \f


***************
*** 788,807 ****
        if (GET_CODE (operands[1]) == REG
  	  && REGNO (operands[0]) == REGNO (operands[1]))
! 	return \"andl %#0xFFFF,%0\";
        if (reg_mentioned_p (operands[0], operands[1]))
!         return \"movw %1,%0\;andl %#0xFFFF,%0\";
!       return \"clrl %0\;movw %1,%0\";
      }
    else if (GET_CODE (operands[0]) == MEM
  	   && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
!     return \"movw %1,%0\;clrw %0\";
    else if (GET_CODE (operands[0]) == MEM
  	   && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
!     return \"clrw %0\;movw %1,%0\";
    else
      {
!       output_asm_insn (\"clrw %0\", operands);
!       operands[0] = adj_offsetable_operand (operands[0], 2);
!       return \"movw %1,%0\";
      }
  }")
--- 754,773 ----
        if (GET_CODE (operands[1]) == REG
  	  && REGNO (operands[0]) == REGNO (operands[1]))
! 	return \"and%.l %#0xFFFF,%0\";
        if (reg_mentioned_p (operands[0], operands[1]))
!         return \"mov%.w %1,%0\;and%.l %#0xFFFF,%0\";
!       return \"clr%.l %0\;mov%.w %1,%0\";
      }
    else if (GET_CODE (operands[0]) == MEM
  	   && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
!     return \"mov%.w %1,%0\;clr%.w %0\";
    else if (GET_CODE (operands[0]) == MEM
  	   && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
!     return \"clr%.w %0\;mov%.w %1,%0\";
    else
      {
!       output_asm_insn (\"clr%.w %0\", operands);
!       operands[0] = adj_offsettable_operand (operands[0], 2);
!       return \"mov%.w %1,%0\";
      }
  }")
***************
*** 818,825 ****
        if (GET_CODE (operands[1]) == REG
  	  && REGNO (operands[0]) == REGNO (operands[1]))
! 	return \"andw %#0xFF,%0\";
        if (reg_mentioned_p (operands[0], operands[1]))
!         return \"movb %1,%0\;andw %#0xFF,%0\";
!       return \"clrw %0\;movb %1,%0\";
      }
    else if (GET_CODE (operands[0]) == MEM
--- 784,791 ----
        if (GET_CODE (operands[1]) == REG
  	  && REGNO (operands[0]) == REGNO (operands[1]))
! 	return \"and%.w %#0xFF,%0\";
        if (reg_mentioned_p (operands[0], operands[1]))
!         return \"mov%.b %1,%0\;and%.w %#0xFF,%0\";
!       return \"clr%.w %0\;mov%.b %1,%0\";
      }
    else if (GET_CODE (operands[0]) == MEM
***************
*** 828,843 ****
        if (REGNO (XEXP (XEXP (operands[0], 0), 0))
  	  == STACK_POINTER_REGNUM)
! 	return \"clrw %-\;movb %1,%0\";
        else
! 	return \"movb %1,%0\;clrb %0\";
      }
    else if (GET_CODE (operands[0]) == MEM
  	   && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
!     return \"clrb %0\;movb %1,%0\";
    else
      {
!       output_asm_insn (\"clrb %0\", operands);
!       operands[0] = adj_offsetable_operand (operands[0], 1);
!       return \"movb %1,%0\";
      }
  }")
--- 794,809 ----
        if (REGNO (XEXP (XEXP (operands[0], 0), 0))
  	  == STACK_POINTER_REGNUM)
! 	return \"clr%.w %-\;mov%.b %1,%0\";
        else
! 	return \"mov%.b %1,%0\;clr%.b %0\";
      }
    else if (GET_CODE (operands[0]) == MEM
  	   && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
!     return \"clr%.b %0\;mov%.b %1,%0\";
    else
      {
!       output_asm_insn (\"clr%.b %0\", operands);
!       operands[0] = adj_offsettable_operand (operands[0], 1);
!       return \"mov%.b %1,%0\";
      }
  }")
***************
*** 854,861 ****
        if (GET_CODE (operands[1]) == REG
  	  && REGNO (operands[0]) == REGNO (operands[1]))
! 	return \"andl %#0xFF,%0\";
        if (reg_mentioned_p (operands[0], operands[1]))
!         return \"movb %1,%0\;andl %#0xFF,%0\";
!       return \"clrl %0\;movb %1,%0\";
      }
    else if (GET_CODE (operands[0]) == MEM
--- 820,827 ----
        if (GET_CODE (operands[1]) == REG
  	  && REGNO (operands[0]) == REGNO (operands[1]))
! 	return \"and%.l %#0xFF,%0\";
        if (reg_mentioned_p (operands[0], operands[1]))
!         return \"mov%.b %1,%0\;and%.l %#0xFF,%0\";
!       return \"clr%.l %0\;mov%.b %1,%0\";
      }
    else if (GET_CODE (operands[0]) == MEM
***************
*** 863,867 ****
      {
        operands[0] = XEXP (XEXP (operands[0], 0), 0);
!       return \"clrl %0@-\;movb %1,%0@(3)\";
      }
    else if (GET_CODE (operands[0]) == MEM
--- 829,833 ----
      {
        operands[0] = XEXP (XEXP (operands[0], 0), 0);
!       return \"clr%.l %0@-\;mov%.b %1,%0@(3)\";
      }
    else if (GET_CODE (operands[0]) == MEM
***************
*** 869,879 ****
      {
        operands[0] = XEXP (XEXP (operands[0], 0), 0);
!       return \"clrl %0@+\;movb %1,%0@(-1)\";
      }
    else
      {
!       output_asm_insn (\"clrl %0\", operands);
!       operands[0] = adj_offsetable_operand (operands[0], 3);
!       return \"movb %1,%0\";
      }
  }")
--- 835,845 ----
      {
        operands[0] = XEXP (XEXP (operands[0], 0), 0);
!       return \"clr%.l %0@+\;mov%.b %1,%0@(-1)\";
      }
    else
      {
!       output_asm_insn (\"clr%.l %0\", operands);
!       operands[0] = adj_offsettable_operand (operands[0], 3);
!       return \"mov%.b %1,%0\";
      }
  }")
***************
*** 891,896 ****
  {
    if (ADDRESS_REG_P (operands[0]))
!     return \"movw %1,%0\";
!   return \"extl %0\";
  }")
  
--- 857,862 ----
  {
    if (ADDRESS_REG_P (operands[0]))
!     return \"mov%.w %1,%0\";
!   return \"ext%.l %0\";
  }")
  
***************
*** 900,904 ****
  	 (match_operand:QI 1 "general_operand" "0")))]
    ""
!   "extw %0")
  
  (define_insn "extendqisi2"
--- 866,870 ----
  	 (match_operand:QI 1 "general_operand" "0")))]
    ""
!   "ext%.w %0")
  
  (define_insn "extendqisi2"
***************
*** 907,973 ****
  	 (match_operand:QI 1 "general_operand" "0")))]
    "TARGET_68020"
!   "extbl %0")
  \f


  ;; Conversions between float and double.
  
! (define_expand "extendsfdf2"
!   [(set (match_operand:DF 0 "general_operand" "")
! 	(float_extend:DF
! 	 (match_operand:SF 1 "general_operand" "")))]
!   "TARGET_68881"
!   "")
! 
! (define_insn ""
!   [(set (match_operand:DF 0 "general_operand" "=f")
  	(float_extend:DF
! 	  (match_operand:SF 1 "general_operand" "fm")))]
!   "TARGET_68881"
!   "*
! {
!   if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
!     return \"fmovesd %1,%0\";
!   if (FP_REG_P (operands[0]))
!     return \"fmovesd %1,%0\";
!   if (DATA_REG_P (operands[0]) && FP_REG_P (operands[1]))
!     {
!       output_asm_insn (\"fmovesd %1,%-\;movl %+,%0\", operands);
!       operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
!       return \"movl %+,%0\";
!     }
!   return \"fmovesd %1,%0\";
! }")
  
! ;; This cannot output into an f-reg because there is no way to be
! ;; sure of truncating in that case.
! 
! (define_expand "truncdfsf2"
!   [(set (match_operand:SF 0 "general_operand" "")
! 	(float_truncate:SF
! 	  (match_operand:DF 1 "general_operand" "")))]
!   "TARGET_68881"
!   "")
! 
! (define_insn ""
!   [(set (match_operand:SF 0 "general_operand" "=fm")
  	(float_truncate:SF
! 	  (match_operand:DF 1 "general_operand" "f")))]
!   "TARGET_68881"
!   "*
! {
!   if (FP_REG_P (operands[1]))
!     {
!       if (FP_REG_P (operands[0])) 
! 	return \"fmoveds %1,%0\";
!       else
! 	{
! 	  output_asm_insn (\"fmoveds %1,%-\", operands);
! 	  return \"movl %+,%0\";
! 	}
!     }
!   if (FP_REG_P (operands[0])) 
!     return \"fmoveds %1,%0\";
!   return \"fmoveds %1,%0\";
! }")
! 
  \f


  ;; Conversion between fixed point and floating point.
--- 873,893 ----
  	 (match_operand:QI 1 "general_operand" "0")))]
    "TARGET_68020"
!   "extb%.l %0")
  \f


  ;; Conversions between float and double.
  
! (define_insn "extendsfdf2"
!   [(set (match_operand:DF 0 "general_operand" "=f,m")
  	(float_extend:DF
! 	  (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
!   "TARGET_CE"
!   "fmovesd %1,%0")
  
! (define_insn "truncdfsf2"
!   [(set (match_operand:SF 0 "general_operand" "=f,m")
  	(float_truncate:SF
! 	  (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
!   "TARGET_CE"
!   "fmoveds %1,%0")
  \f


  ;; Conversion between fixed point and floating point.
***************
*** 979,1196 ****
  ;; rather than as QImode or HImode.
  
! (define_expand "floatsisf2"
!   [(set (match_operand:SF 0 "general_operand" "")
! 	(float:SF (match_operand:SI 1 "general_operand" "")))]
!   "TARGET_68881"
!   "")
! 
! (define_insn ""
!   [(set (match_operand:SF 0 "general_operand" "=f")
! 	(float:SF (match_operand:SI 1 "general_operand" "dm")))]
!   "TARGET_68881"
    "fmovels %1,%0")
  
! (define_expand "floatsidf2"
!   [(set (match_operand:DF 0 "general_operand" "")
! 	(float:DF (match_operand:SI 1 "general_operand" "")))]
!   "TARGET_68881"
!   "")
! 
! (define_insn ""
!   [(set (match_operand:DF 0 "general_operand" "=f")
! 	(float:DF (match_operand:SI 1 "general_operand" "dm")))]
!   "TARGET_68881"
    "fmoveld %1,%0")
  
  (define_insn "floathisf2"
!   [(set (match_operand:SF 0 "general_operand" "=f")
! 	(float:SF (match_operand:HI 1 "general_operand" "dm")))]
!   "TARGET_68881"
    "fmovews %1,%0")
  
  (define_insn "floathidf2"
!   [(set (match_operand:DF 0 "general_operand" "=f")
! 	(float:DF (match_operand:HI 1 "general_operand" "dm")))]
!   "TARGET_68881"
    "fmovewd %1,%0")
  
  (define_insn "floatqisf2"
!   [(set (match_operand:SF 0 "general_operand" "=f")
! 	(float:SF (match_operand:QI 1 "general_operand" "dm")))]
!   "TARGET_68881"
    "fmovebs %1,%0")
  
  (define_insn "floatqidf2"
!   [(set (match_operand:DF 0 "general_operand" "=f")
! 	(float:DF (match_operand:QI 1 "general_operand" "dm")))]
!   "TARGET_68881"
    "fmovebd %1,%0")
! 
! ;; Convert a float to a float whose value is an integer.
! ;; This is the first stage of converting it to an integer type.
! 
! (define_insn "ftruncdf2"
!   [(set (match_operand:DF 0 "general_operand" "=fm")
! 	(fix:DF (match_operand:DF 1 "general_operand" "fm")))]
!   "TARGET_68881"
!   "*
! {
!   if (FP_REG_P (operands[1]))
!     {
!       if (FP_REG_P (operands[0]))
! 	{
! 	  output_asm_insn (\"fmovedl %1,%-\", operands);
! 	  return \"fmoveld %+,%0\";
!         }
!       return \"fmovedl %1,%0\";
!     }
!   if (FP_REG_P (operands[0]))
!     {
!       output_asm_insn (\"fmoved %1,%0\", operands);
!       output_asm_insn (\"fmovedl %0,%-\", operands);
!       return \"fmoveld %+,%0\";
!     }
!   return \"fmovedl %1,%0\";
! }")
! 
! (define_insn "ftruncsf2"
!   [(set (match_operand:SF 0 "general_operand" "=fm")
! 	(fix:SF (match_operand:SF 1 "general_operand" "fm")))]
!   "TARGET_68881"
!   "*
! {
!   if (FP_REG_P (operands[1]))
!     {
!       if (FP_REG_P (operands[0]))
!         {
! 	  output_asm_insn (\"fmovesl %1,%-\", operands);
! 	  return \"fmovels %+,%0\";
! 	}
!       return \"fmovesl %1,%0\";
!     }
!   if (FP_REG_P (operands[0]))
!     {
!       output_asm_insn (\"fmovesl %1,%-\", operands);
!       return \"fmovels %+,%0\";
!     }
!   return \"fmovesl %1,%0\";
! }")
! 
! ;; Convert a float whose value is an integer
! ;; to an actual integer.  Second stage of converting float to integer type.
! (define_insn "fixsfqi2"
!   [(set (match_operand:QI 0 "general_operand" "=m")
! 	(fix:QI (match_operand:SF 1 "general_operand" "f")))]
!   "TARGET_68881"
!   "*
! {
!   if (FP_REG_P (operands[0]))
!     {
!       output_asm_insn (\"fmovesb %1,%-\", operands);
!       return \"fmovebs %+,%0\";
!     }
!   if (DATA_REG_P (operands[0]))
!     {
!       output_asm_insn (\"fmovesb %1,%-\", operands);
!       return \"movb% %+,%0\";
!     }
!   return \"fmovesb %1,%0\";
! }")
  
! (define_insn "fixsfhi2"
!   [(set (match_operand:HI 0 "general_operand" "=m")
! 	(fix:HI (match_operand:SF 1 "general_operand" "f")))]
!   "TARGET_68881"
!   "*
! {
!   if (FP_REG_P (operands[0]))
!     {
!       output_asm_insn (\"fmovesw %1,%-\", operands);
!       return \"fmovews %+,%0\";
!     }
!   if (DATA_REG_P (operands[0]))
!     {
!       output_asm_insn (\"fmovesw %1,%-\", operands);
!       return \"movw% %+,%0\";
!     }
!   return \"fmovesw %1,%0\";
! }")
  
! (define_insn "fixsfsi2"
!   [(set (match_operand:SI 0 "general_operand" "=fdm")
! 	(fix:SI (match_operand:SF 1 "general_operand" "f")))]
!   "TARGET_68881"
!   "*
! {
!   if (FP_REG_P (operands[0]))
!     {
!       output_asm_insn (\"fmovesl %1,%-\", operands);
!       return \"fmovels %+,%0\";
!     }
!   if (DATA_REG_P (operands[0]))
!     {
!       output_asm_insn (\"fmovesl %1,%-\", operands);
!       return \"movl %+,%0\";
!     }
!   return \"fmovesl %1,%0\";
! }")
  
! (define_insn "fixdfqi2"
!   [(set (match_operand:QI 0 "general_operand" "=fdm")
! 	(fix:QI (match_operand:DF 1 "general_operand" "f")))]
!   "TARGET_68881"
!   "*
! {
!   if (FP_REG_P (operands[0]))
!     {
!       output_asm_insn (\"fmovedb %1,%-\", operands);
!       return \"fmovebd %+,%0\";
!     }
!   if (DATA_REG_P (operands[0]))
!     {
!       output_asm_insn (\"fmovedb %1,%-\", operands);
!       return \"movb% %+,%0\";
!     }
!   return \"fmovedb %1,%0\";
! }")
  
! (define_insn "fixdfhi2"
!   [(set (match_operand:HI 0 "general_operand" "=fdm")
! 	(fix:HI (match_operand:DF 1 "general_operand" "f")))]
!   "TARGET_68881"
!   "*
! {
!   if (FP_REG_P (operands[0]))
!     {
!       output_asm_insn (\"fmovedw %1,%-\", operands);
!       return \"fmovewd %+,%0\";
!     }
!   if (DATA_REG_P (operands[0]))
!     {
!       output_asm_insn (\"fmovedw %1,%-\", operands);
!       return \"movw% %+,%0\";
!     }
!   return \"fmovedw %1,%0\";
! }")
  
! (define_insn "fixdfsi2"
!   [(set (match_operand:SI 0 "general_operand" "=fdm")
! 	(fix:SI (match_operand:DF 1 "general_operand" "f")))]
!   "TARGET_68881"
!   "*
! {
!   if (FP_REG_P (operands[0]))
!     {
!       output_asm_insn (\"fmovedl %1,%-\", operands);
!       return \"fmoveld %+,%0\";
!     }
!   if (DATA_REG_P (operands[0]))
!     {
!       output_asm_insn (\"fmovedl %1,%-\", operands);
!       return \"movl %+,%0\";
!     }
!   return \"fmovedl %1,%0\";
! }")
  
  \f


  ;; add instructions
--- 899,975 ----
  ;; rather than as QImode or HImode.
  
! (define_insn "floatsisf2"
!   [(set (match_operand:SF 0 "register_operand" "=f")
! 	(float:SF (match_operand:SI 1 "nonimmediate_operand" "dm")))]
!   "TARGET_CE"
    "fmovels %1,%0")
  
! (define_insn "floatsidf2"
!   [(set (match_operand:DF 0 "register_operand" "=f")
! 	(float:DF (match_operand:SI 1 "nonimmediate_operand" "dm")))]
!   "TARGET_CE"
    "fmoveld %1,%0")
  
  (define_insn "floathisf2"
!   [(set (match_operand:SF 0 "register_operand" "=f")
! 	(float:SF (match_operand:HI 1 "nonimmediate_operand" "dm")))]
!   "TARGET_CE"
    "fmovews %1,%0")
  
  (define_insn "floathidf2"
!   [(set (match_operand:DF 0 "register_operand" "=f")
! 	(float:DF (match_operand:HI 1 "nonimmediate_operand" "dm")))]
!   "TARGET_CE"
    "fmovewd %1,%0")
  
  (define_insn "floatqisf2"
!   [(set (match_operand:SF 0 "register_operand" "=f")
! 	(float:SF (match_operand:QI 1 "nonimmediate_operand" "dm")))]
!   "TARGET_CE"
    "fmovebs %1,%0")
  
  (define_insn "floatqidf2"
!   [(set (match_operand:DF 0 "register_operand" "=f")
! 	(float:DF (match_operand:QI 1 "nonimmediate_operand" "dm")))]
!   "TARGET_CE"
    "fmovebd %1,%0")
! \f


! ;; Float-to-fix conversion insns.
  
! (define_insn "fix_truncsfqi2"
!   [(set (match_operand:QI 0 "general_operand" "=dm")
! 	(fix:QI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
!   "TARGET_CE"
!   "fmovesb %1,%0")
  
! (define_insn "fix_truncsfhi2"
!   [(set (match_operand:HI 0 "general_operand" "=dm")
! 	(fix:HI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
!   "TARGET_CE"
!   "fmovesw %1,%0")
  
! (define_insn "fix_truncsfsi2"
!   [(set (match_operand:SI 0 "general_operand" "=dm")
! 	(fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
!   "TARGET_CE"
!   "fmovesl %1,%0")
  
! (define_insn "fix_truncdfqi2"
!   [(set (match_operand:QI 0 "general_operand" "=dm")
! 	(fix:QI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
!   "TARGET_CE"
!   "fmovedb %1,%0")
  
! (define_insn "fix_truncdfhi2"
!   [(set (match_operand:HI 0 "general_operand" "=dm")
! 	(fix:HI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
!   "TARGET_CE"
!   "fmovedw %1,%0")
  
+ (define_insn "fix_truncdfsi2"
+   [(set (match_operand:SI 0 "general_operand" "=dm")
+ 	(fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
+   "TARGET_CE"
+   "fmovedl %1,%0")
  \f


  ;; add instructions
***************
*** 1217,1221 ****
        if (GET_CODE (operands[2]) == CONST_INT
  	  && INTVAL (operands[2]) + 0x8000 >= (unsigned) 0x10000)
!         return \"movl %2,%0\;addl %1,%0\";
        if (GET_CODE (operands[2]) == REG)
  	return \"lea %1@[%2:L:B],%0\";
--- 996,1000 ----
        if (GET_CODE (operands[2]) == CONST_INT
  	  && INTVAL (operands[2]) + 0x8000 >= (unsigned) 0x10000)
!         return \"mov%.l %2,%0\;add%.l %1,%0\";
        if (GET_CODE (operands[2]) == REG)
  	return \"lea %1@[%2:L:B],%0\";
***************
*** 1228,1233 ****
  	  && INTVAL (operands[2]) <= 8)
  	return (ADDRESS_REG_P (operands[0])
! 		? \"addqw %2,%0\"
! 		: \"addql %2,%0\");
        if (INTVAL (operands[2]) < 0
  	  && INTVAL (operands[2]) >= -8)
--- 1007,1012 ----
  	  && INTVAL (operands[2]) <= 8)
  	return (ADDRESS_REG_P (operands[0])
! 		? \"addq%.w %2,%0\"
! 		: \"addq%.l %2,%0\");
        if (INTVAL (operands[2]) < 0
  	  && INTVAL (operands[2]) >= -8)
***************
*** 1236,1241 ****
  			         - INTVAL (operands[2]));
  	  return (ADDRESS_REG_P (operands[0])
! 		  ? \"subqw %2,%0\"
! 		  : \"subql %2,%0\");
  	}
        if (ADDRESS_REG_P (operands[0])
--- 1015,1020 ----
  			         - INTVAL (operands[2]));
  	  return (ADDRESS_REG_P (operands[0])
! 		  ? \"subq%.w %2,%0\"
! 		  : \"subq%.l %2,%0\");
  	}
        if (ADDRESS_REG_P (operands[0])
***************
*** 1242,1248 ****
  	  && INTVAL (operands[2]) >= -0x8000
  	  && INTVAL (operands[2]) < 0x8000)
! 	return \"addw %2,%0\";
      }
!   return \"addl %2,%0\";
  }")
  
--- 1021,1027 ----
  	  && INTVAL (operands[2]) >= -0x8000
  	  && INTVAL (operands[2]) < 0x8000)
! 	return \"add%.w %2,%0\";
      }
!   return \"add%.l %2,%0\";
  }")
  
***************
*** 1252,1256 ****
  		 (sign_extend:SI (match_operand:HI 2 "general_operand" "rmn"))))]
    ""
!   "addw %2,%0")
  
  (define_insn "addhi3"
--- 1031,1035 ----
  		 (sign_extend:SI (match_operand:HI 2 "general_operand" "rmn"))))]
    ""
!   "add%.w %2,%0")
  
  (define_insn "addhi3"
***************
*** 1265,1269 ****
        if (INTVAL (operands[2]) > 0
  	  && INTVAL (operands[2]) <= 8)
! 	return \"addqw %2,%0\";
      }
    if (GET_CODE (operands[2]) == CONST_INT)
--- 1044,1048 ----
        if (INTVAL (operands[2]) > 0
  	  && INTVAL (operands[2]) <= 8)
! 	return \"addq%.w %2,%0\";
      }
    if (GET_CODE (operands[2]) == CONST_INT)
***************
*** 1274,1281 ****
  	  operands[2] = gen_rtx (CONST_INT, VOIDmode,
  			         - INTVAL (operands[2]));
! 	  return \"subqw %2,%0\";
  	}
      }
!   return \"addw %2,%0\";
  }")
  
--- 1053,1060 ----
  	  operands[2] = gen_rtx (CONST_INT, VOIDmode,
  			         - INTVAL (operands[2]));
! 	  return \"subq%.w %2,%0\";
  	}
      }
!   return \"add%.w %2,%0\";
  }")
  
***************
*** 1285,1289 ****
  		 (match_operand:HI 1 "general_operand" "dn,rmn")))]
    ""
!   "addw %1,%0")
  
  (define_insn "addqi3"
--- 1064,1068 ----
  		 (match_operand:HI 1 "general_operand" "dn,rmn")))]
    ""
!   "add%.w %1,%0")
  
  (define_insn "addqi3"
***************
*** 1298,1302 ****
        if (INTVAL (operands[2]) > 0
  	  && INTVAL (operands[2]) <= 8)
! 	return \"addqb %2,%0\";
      }
    if (GET_CODE (operands[2]) == CONST_INT)
--- 1077,1081 ----
        if (INTVAL (operands[2]) > 0
  	  && INTVAL (operands[2]) <= 8)
! 	return \"addq%.b %2,%0\";
      }
    if (GET_CODE (operands[2]) == CONST_INT)
***************
*** 1305,1312 ****
         {
  	 operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]));
! 	 return \"subqb %2,%0\";
         }
      }
!   return \"addb %2,%0\";
  }")
  
--- 1084,1091 ----
         {
  	 operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]));
! 	 return \"subq%.b %2,%0\";
         }
      }
!   return \"add%.b %2,%0\";
  }")
  
***************
*** 1316,1348 ****
  		 (match_operand:QI 1 "general_operand" "dn,dmn")))]
    ""
!   "addb %1,%0")
! 
! (define_expand "adddf3"
!   [(set (match_operand:DF 0 "general_operand" "")
! 	(plus:DF (match_operand:DF 1 "general_operand" "")
! 		 (match_operand:DF 2 "general_operand" "")))]
!   "TARGET_68881"
!   "")
! 
! (define_insn ""
!   [(set (match_operand:DF 0 "general_operand" "=f")
! 	(plus:DF (match_operand:DF 1 "general_operand" "%f")
! 		 (match_operand:DF 2 "general_operand" "fm")))]
!   "TARGET_68881"
!   "faddd %2,%1,%0")
! 
! (define_expand "addsf3"
!   [(set (match_operand:SF 0 "general_operand" "")
! 	(plus:SF (match_operand:SF 1 "general_operand" "")
! 		 (match_operand:SF 2 "general_operand" "")))]
!   "TARGET_68881"
!   "")
  
! (define_insn ""
!   [(set (match_operand:SF 0 "general_operand" "=f")
! 	(plus:SF (match_operand:SF 1 "general_operand" "%f")
! 		 (match_operand:SF 2 "general_operand" "fm")))]
!   "TARGET_68881"
!   "fadds %2,%1,%0")
  \f


  ;; subtract instructions
--- 1095,1113 ----
  		 (match_operand:QI 1 "general_operand" "dn,dmn")))]
    ""
!   "add%.b %1,%0")
  
! (define_insn "adddf3"
!   [(set (match_operand:DF 0 "register_operand" "=f")
! 	(plus:DF (match_operand:DF 1 "nonimmediate_operand" "%f")
! 		 (match_operand:DF 2 "nonimmediate_operand" "fm")))]
!   "TARGET_CE"
!   "fadd%.d %2,%1,%0")
! 
! (define_insn "addsf3"
!   [(set (match_operand:SF 0 "register_operand" "=f")
! 	(plus:SF (match_operand:SF 1 "nonimmediate_operand" "%f")
! 		 (match_operand:SF 2 "nonimmediate_operand" "fm")))]
!   "TARGET_CE"
!   "fadd%.s %2,%1,%0")
  \f


  ;; subtract instructions
***************
*** 1363,1369 ****
  	      if (INTVAL (operands[1]) > 0
  		  && INTVAL (operands[1]) <= 8)
! 		return \"subql %1,%0\;negl %0\";
  	    }
! 	  return \"subl %1,%0\;negl %0\";
  	}
        /* This case is matched by J, but negating -0x8000
--- 1128,1134 ----
  	      if (INTVAL (operands[1]) > 0
  		  && INTVAL (operands[1]) <= 8)
! 		return \"subq%.l %1,%0\;neg%.l %0\";
  	    }
! 	  return \"sub%.l %1,%0\;neg%.l %0\";
  	}
        /* This case is matched by J, but negating -0x8000
***************
*** 1371,1375 ****
  	 So do this specially.  */
        if (INTVAL (operands[2]) == -0x8000)
! 	return \"movl %1,%0\;subl %2,%0\";
        return \"lea %1@(%n2),%0\";
      }
--- 1136,1140 ----
  	 So do this specially.  */
        if (INTVAL (operands[2]) == -0x8000)
! 	return \"mov%.l %1,%0\;sub%.l %2,%0\";
        return \"lea %1@(%n2),%0\";
      }
***************
*** 1378,1388 ****
        if (INTVAL (operands[2]) > 0
  	  && INTVAL (operands[2]) <= 8)
! 	return \"subql %2,%0\";
        if (ADDRESS_REG_P (operands[0])
  	  && INTVAL (operands[2]) >= -0x8000
  	  && INTVAL (operands[2]) < 0x8000)
! 	return \"subw %2,%0\";
      }
!   return \"subl %2,%0\";
  }")
  
--- 1143,1153 ----
        if (INTVAL (operands[2]) > 0
  	  && INTVAL (operands[2]) <= 8)
! 	return \"subq%.l %2,%0\";
        if (ADDRESS_REG_P (operands[0])
  	  && INTVAL (operands[2]) >= -0x8000
  	  && INTVAL (operands[2]) < 0x8000)
! 	return \"sub%.w %2,%0\";
      }
!   return \"sub%.l %2,%0\";
  }")
  
***************
*** 1392,1396 ****
  		  (sign_extend:SI (match_operand:HI 2 "general_operand" "rmn"))))]
    ""
!   "subw %2,%0")
  
  (define_insn "subhi3"
--- 1157,1161 ----
  		  (sign_extend:SI (match_operand:HI 2 "general_operand" "rmn"))))]
    ""
!   "sub%.w %2,%0")
  
  (define_insn "subhi3"
***************
*** 1399,1403 ****
  		  (match_operand:HI 2 "general_operand" "dn,rmn")))]
    ""
!   "subw %2,%0")
  
  (define_insn ""
--- 1164,1168 ----
  		  (match_operand:HI 2 "general_operand" "dn,rmn")))]
    ""
!   "sub%.w %2,%0")
  
  (define_insn ""
***************
*** 1406,1410 ****
  		  (match_operand:HI 1 "general_operand" "dn,rmn")))]
    ""
!   "subw %1,%0")
  
  (define_insn "subqi3"
--- 1171,1175 ----
  		  (match_operand:HI 1 "general_operand" "dn,rmn")))]
    ""
!   "sub%.w %1,%0")
  
  (define_insn "subqi3"
***************
*** 1413,1417 ****
  		  (match_operand:QI 2 "general_operand" "dn,dmn")))]
    ""
!   "subb %2,%0")
  
  (define_insn ""
--- 1178,1182 ----
  		  (match_operand:QI 2 "general_operand" "dn,dmn")))]
    ""
!   "sub%.b %2,%0")
  
  (define_insn ""
***************
*** 1420,1452 ****
  		  (match_operand:QI 1 "general_operand" "dn,dmn")))]
    ""
!   "subb %1,%0")
! 
! (define_expand "subdf3"
!   [(set (match_operand:DF 0 "general_operand" "")
! 	(minus:DF (match_operand:DF 1 "general_operand" "")
! 		  (match_operand:DF 2 "general_operand" "")))]
!   "TARGET_68881"
!   "")
! 
! (define_insn ""
!   [(set (match_operand:DF 0 "general_operand" "=f")
! 	(minus:DF (match_operand:DF 1 "general_operand" "f")
! 		  (match_operand:DF 2 "general_operand" "fm")))]
!   "TARGET_68881"
!   "fsubd %2,%1,%0")
  
! (define_expand "subsf3"
!   [(set (match_operand:SF 0 "general_operand" "")
! 	(minus:SF (match_operand:SF 1 "general_operand" "")
! 		  (match_operand:SF 2 "general_operand" "")))]
!   "TARGET_68881"
!   "")
  
! (define_insn ""
!   [(set (match_operand:SF 0 "general_operand" "=f")
! 	(minus:SF (match_operand:SF 1 "general_operand" "f")
! 		  (match_operand:SF 2 "general_operand" "fm")))]
!   "TARGET_68881"
!   "fsubs %2,%1,%0")
  \f


  ;; multiply instructions
--- 1185,1213 ----
  		  (match_operand:QI 1 "general_operand" "dn,dmn")))]
    ""
!   "sub%.b %1,%0")
  
! (define_insn "subdf3"
!   [(set (match_operand:DF 0 "register_operand" "=f,f")
! 	(minus:DF (match_operand:DF 1 "nonimmediate_operand" "f,fm")
! 		  (match_operand:DF 2 "nonimmediate_operand" "fm,f")))]
!   "TARGET_CE"
!   "*
! {
!   if (FP_REG_P (operands[1]))
!     return \"fsub%.d %2,%1,%0\";
!   return \"frsub%.d %1,%2,%0\";
! }")
  
! (define_insn "subsf3"
!   [(set (match_operand:SF 0 "register_operand" "=f,f")
! 	(minus:SF (match_operand:SF 1 "nonimmediate_operand" "f,fm")
! 		  (match_operand:SF 2 "nonimmediate_operand" "fm,f")))]
!   "TARGET_CE"
!   "*
! {
!   if (FP_REG_P (operands[1]))
!     return \"fsub%.s %2,%1,%0\";
!   return \"frsub%.s %1,%2,%0\";
! }")
  \f


  ;; multiply instructions
***************
*** 1471,1475 ****
  		 (match_operand:SI 2 "general_operand" "dmsK")))]
    "TARGET_68020"
!   "mulsl %2,%0")
  
  (define_insn "umulhi3"
--- 1232,1236 ----
  		 (match_operand:SI 2 "general_operand" "dmsK")))]
    "TARGET_68020"
!   "muls%.l %2,%0")
  
  (define_insn "umulhi3"
***************
*** 1492,1524 ****
  		  (match_operand:SI 2 "general_operand" "dmsK")))]
    "TARGET_68020"
!   "mulul %2,%0")
! 
! (define_expand "muldf3"
!   [(set (match_operand:DF 0 "general_operand" "")
! 	(mult:DF (match_operand:DF 1 "general_operand" "")
! 		 (match_operand:DF 2 "general_operand" "")))]
!   "TARGET_68881"
!   "")
! 
! (define_insn ""
!   [(set (match_operand:DF 0 "general_operand" "=f")
! 	(mult:DF (match_operand:DF 1 "general_operand" "%f")
! 		 (match_operand:DF 2 "general_operand" "fm")))]
!   "TARGET_68881"
!   "fmuld %2,%1,%0")
! 
! (define_expand "mulsf3"
!   [(set (match_operand:SF 0 "general_operand" "")
! 	(mult:SF (match_operand:SF 1 "general_operand" "")
! 		 (match_operand:SF 2 "general_operand" "")))]
!   "TARGET_68881"
!   "")
  
! (define_insn ""
!   [(set (match_operand:SF 0 "general_operand" "=f")
! 	(mult:SF (match_operand:SF 1 "general_operand" "%f")
! 		 (match_operand:SF 2 "general_operand" "fm")))]
!   "TARGET_68881"
!   "fmuls %2,%1,%0")
  \f


  ;; divide instructions
--- 1253,1271 ----
  		  (match_operand:SI 2 "general_operand" "dmsK")))]
    "TARGET_68020"
!   "mulu%.l %2,%0")
  
! (define_insn "muldf3"
!   [(set (match_operand:DF 0 "register_operand" "=f")
! 	(mult:DF (match_operand:DF 1 "nonimmediate_operand" "%f")
! 		 (match_operand:DF 2 "nonimmediate_operand" "fm")))]
!   "TARGET_CE"
!   "fmul%.d %2,%1,%0")
! 
! (define_insn "mulsf3"
!   [(set (match_operand:SF 0 "register_operand" "=f")
! 	(mult:SF (match_operand:SF 1 "nonimmediate_operand" "%f")
! 		 (match_operand:SF 2 "nonimmediate_operand" "fm")))]
!   "TARGET_CE"
!   "fmul%.s %2,%1,%0")
  \f


  ;; divide instructions
***************
*** 1543,1547 ****
  		(match_operand:SI 2 "general_operand" "dmsK")))]
    "TARGET_68020"
!   "divsl %2,%0,%0")
  
  (define_insn "udivhi3"
--- 1290,1294 ----
  		(match_operand:SI 2 "general_operand" "dmsK")))]
    "TARGET_68020"
!   "divs%.l %2,%0,%0")
  
  (define_insn "udivhi3"
***************
*** 1550,1554 ****
  		 (match_operand:HI 2 "general_operand" "dmn")))]
    ""
!   "andl %#0xFFFF,%0\;divu %2,%0")
  
  (define_insn "udivhisi3"
--- 1297,1301 ----
  		 (match_operand:HI 2 "general_operand" "dmn")))]
    ""
!   "and%.l %#0xFFFF,%0\;divu %2,%0")
  
  (define_insn "udivhisi3"
***************
*** 1564,1596 ****
  		 (match_operand:SI 2 "general_operand" "dmsK")))]
    "TARGET_68020"
!   "divul %2,%0,%0")
! 
! (define_expand "divdf3"
!   [(set (match_operand:DF 0 "general_operand" "")
! 	(div:DF (match_operand:DF 1 "general_operand" "")
! 		(match_operand:DF 2 "general_operand" "")))]
!   "TARGET_68881"
!   "")
! 
! (define_insn ""
!   [(set (match_operand:DF 0 "general_operand" "=f")
! 	(div:DF (match_operand:DF 1 "general_operand" "f")
! 		(match_operand:DF 2 "general_operand" "fm")))]
!   "TARGET_68881"
!   "fdivd %2,%1,%0")
  
! (define_expand "divsf3"
!   [(set (match_operand:SF 0 "general_operand" "")
! 	(div:SF (match_operand:SF 1 "general_operand" "")
! 		(match_operand:SF 2 "general_operand" "")))]
!   "TARGET_68881"
!   "")
  
! (define_insn ""
!   [(set (match_operand:SF 0 "general_operand" "=f")
! 	(div:SF (match_operand:SF 1 "general_operand" "0")
! 		(match_operand:SF 2 "general_operand" "fm")))]
!   "TARGET_68881"
!   "fdivs %2,%0,%0")
  \f


  ;; Remainder instructions.
--- 1311,1339 ----
  		 (match_operand:SI 2 "general_operand" "dmsK")))]
    "TARGET_68020"
!   "divu%.l %2,%0,%0")
  
! (define_insn "divdf3"
!   [(set (match_operand:DF 0 "register_operand" "=f,f")
! 	(div:DF (match_operand:DF 1 "nonimmediate_operand" "f,fm")
! 		(match_operand:DF 2 "nonimmediate_operand" "fm,f")))]
!   "TARGET_CE"
!   "*
! {
!   if (FP_REG_P (operands[1]))
!     return \"fdiv%.d %2,%1,%0\";
!   return \"frdiv%.d %1,%2,%0\";
! }")
  
! (define_insn "divsf3"
!   [(set (match_operand:SF 0 "register_operand" "=f,f")
! 	(div:SF (match_operand:SF 1 "nonimmediate_operand" "f,fm")
! 		(match_operand:SF 2 "nonimmediate_operand" "fm,f")))]
!   "TARGET_CE"
!   "*
! {
!   if (FP_REG_P (operands[1]))
!     return \"fdiv%.s %2,%1,%0\";
!   return \"frdiv%.s %1,%2,%0\";
! }")
  \f


  ;; Remainder instructions.
***************
*** 1629,1633 ****
    /* The swap insn produces cc's that don't correspond to the result.  */
    CC_STATUS_INIT;
!   return \"andl %#0xFFFF,%0\;divu %2,%0\;swap %0\";
  }")
  
--- 1372,1376 ----
    /* The swap insn produces cc's that don't correspond to the result.  */
    CC_STATUS_INIT;
!   return \"and%.l %#0xFFFF,%0\;divu %2,%0\;swap %0\";
  }")
  
***************
*** 1651,1655 ****
  	(mod:SI (match_dup 1) (match_dup 2)))]
    "TARGET_68020"
!   "divsl %2,%0,%3")
  
  (define_insn "udivmodsi4"
--- 1394,1398 ----
  	(mod:SI (match_dup 1) (match_dup 2)))]
    "TARGET_68020"
!   "divs%.l %2,%0,%3")
  
  (define_insn "udivmodsi4"
***************
*** 1660,1664 ****
  	(umod:SI (match_dup 1) (match_dup 2)))]
    "TARGET_68020"
!   "divul %2,%0,%3")
  \f


  ;; logical-and instructions
--- 1403,1407 ----
  	(umod:SI (match_dup 1) (match_dup 2)))]
    "TARGET_68020"
!   "divu%.l %2,%0,%3")
  \f


  ;; logical-and instructions
***************
*** 1674,1681 ****
        && (INTVAL (operands[2]) | 0xffff) == 0xffffffff
        && (DATA_REG_P (operands[0])
! 	  || offsetable_memref_p (operands[0])))
      { 
        if (GET_CODE (operands[0]) != REG)
!         operands[0] = adj_offsetable_operand (operands[0], 2);
        operands[2] = gen_rtx (CONST_INT, VOIDmode,
  			     INTVAL (operands[2]) & 0xffff);
--- 1417,1424 ----
        && (INTVAL (operands[2]) | 0xffff) == 0xffffffff
        && (DATA_REG_P (operands[0])
! 	  || offsettable_memref_p (operands[0])))
      { 
        if (GET_CODE (operands[0]) != REG)
!         operands[0] = adj_offsettable_operand (operands[0], 2);
        operands[2] = gen_rtx (CONST_INT, VOIDmode,
  			     INTVAL (operands[2]) & 0xffff);
***************
*** 1683,1690 ****
        CC_STATUS_INIT;
        if (operands[2] == const0_rtx)
!         return \"clrw %0\";
!       return \"andw %2,%0\";
      }
!   return \"andl %2,%0\";
  }")
  
--- 1426,1433 ----
        CC_STATUS_INIT;
        if (operands[2] == const0_rtx)
!         return \"clr%.w %0\";
!       return \"and%.w %2,%0\";
      }
!   return \"and%.l %2,%0\";
  }")
  
***************
*** 1694,1698 ****
  		(match_operand:HI 2 "general_operand" "dn,dmn")))]
    ""
!   "andw %2,%0")
  
  (define_insn "andqi3"
--- 1437,1441 ----
  		(match_operand:HI 2 "general_operand" "dn,dmn")))]
    ""
!   "and%.w %2,%0")
  
  (define_insn "andqi3"
***************
*** 1701,1705 ****
  		(match_operand:QI 2 "general_operand" "dn,dmn")))]
    ""
!   "andb %2,%0")
  
  (define_insn ""
--- 1444,1448 ----
  		(match_operand:QI 2 "general_operand" "dn,dmn")))]
    ""
!   "and%.b %2,%0")
  
  (define_insn ""
***************
*** 1709,1713 ****
    "GET_CODE (operands[2]) == CONST_INT
     && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (HImode))"
!   "andw %1,%0")
  
  (define_insn ""
--- 1452,1456 ----
    "GET_CODE (operands[2]) == CONST_INT
     && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (HImode))"
!   "and%.w %1,%0")
  
  (define_insn ""
***************
*** 1717,1721 ****
    "GET_CODE (operands[2]) == CONST_INT
     && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))"
!   "andb %1,%0")
  \f


  ;; inclusive-or instructions
--- 1460,1464 ----
    "GET_CODE (operands[2]) == CONST_INT
     && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))"
!   "and%.b %1,%0")
  \f


  ;; inclusive-or instructions
***************
*** 1732,1742 ****
        && INTVAL (operands[2]) >> 16 == 0
        && (DATA_REG_P (operands[0])
! 	  || offsetable_memref_p (operands[0])))
      { 
        if (GET_CODE (operands[0]) != REG)
!         operands[0] = adj_offsetable_operand (operands[0], 2);
        /* Do not delete a following tstl %0 insn; that would be incorrect.  */
        CC_STATUS_INIT;
!       return \"orw %2,%0\";
      }
    if (GET_CODE (operands[2]) == CONST_INT
--- 1475,1485 ----
        && INTVAL (operands[2]) >> 16 == 0
        && (DATA_REG_P (operands[0])
! 	  || offsettable_memref_p (operands[0])))
      { 
        if (GET_CODE (operands[0]) != REG)
!         operands[0] = adj_offsettable_operand (operands[0], 2);
        /* Do not delete a following tstl %0 insn; that would be incorrect.  */
        CC_STATUS_INIT;
!       return \"or%.w %2,%0\";
      }
    if (GET_CODE (operands[2]) == CONST_INT
***************
*** 1743,1747 ****
        && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
        && (DATA_REG_P (operands[0])
! 	  || offsetable_memref_p (operands[0])))
      { 
        if (DATA_REG_P (operands[0]))
--- 1486,1490 ----
        && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
        && (DATA_REG_P (operands[0])
! 	  || offsettable_memref_p (operands[0])))
      { 
        if (DATA_REG_P (operands[0]))
***************
*** 1749,1753 ****
        else
          {
! 	  operands[0] = adj_offsetable_operand (operands[0], 3 - (logval / 8));
  	  operands[1] = gen_rtx (CONST_INT, VOIDmode, logval % 8);
  	}
--- 1492,1496 ----
        else
          {
! 	  operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8));
  	  operands[1] = gen_rtx (CONST_INT, VOIDmode, logval % 8);
  	}
***************
*** 1754,1758 ****
        return \"bset %1,%0\";
      }
!   return \"orl %2,%0\";
  }")
  
--- 1497,1501 ----
        return \"bset %1,%0\";
      }
!   return \"or%.l %2,%0\";
  }")
  
***************
*** 1762,1766 ****
  		(match_operand:HI 2 "general_operand" "dn,dmn")))]
    ""
!   "orw %2,%0")
  
  (define_insn "iorqi3"
--- 1505,1509 ----
  		(match_operand:HI 2 "general_operand" "dn,dmn")))]
    ""
!   "or%.w %2,%0")
  
  (define_insn "iorqi3"
***************
*** 1769,1773 ****
  		(match_operand:QI 2 "general_operand" "dn,dmn")))]
    ""
!   "orb %2,%0")
  \f


  ;; xor instructions
--- 1512,1516 ----
  		(match_operand:QI 2 "general_operand" "dn,dmn")))]
    ""
!   "or%.b %2,%0")
  \f


  ;; xor instructions
***************
*** 1782,1794 ****
    if (GET_CODE (operands[2]) == CONST_INT
        && INTVAL (operands[2]) >> 16 == 0
!       && (offsetable_memref_p (operands[0]) || DATA_REG_P (operands[0])))
      { 
        if (! DATA_REG_P (operands[0]))
! 	operands[0] = adj_offsetable_operand (operands[0], 2);
        /* Do not delete a following tstl %0 insn; that would be incorrect.  */
        CC_STATUS_INIT;
!       return \"eorw %2,%0\";
      }
!   return \"eorl %2,%0\";
  }")
  
--- 1525,1537 ----
    if (GET_CODE (operands[2]) == CONST_INT
        && INTVAL (operands[2]) >> 16 == 0
!       && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0])))
      { 
        if (! DATA_REG_P (operands[0]))
! 	operands[0] = adj_offsettable_operand (operands[0], 2);
        /* Do not delete a following tstl %0 insn; that would be incorrect.  */
        CC_STATUS_INIT;
!       return \"eor%.w %2,%0\";
      }
!   return \"eor%.l %2,%0\";
  }")
  
***************
*** 1798,1802 ****
  		(match_operand:HI 2 "general_operand" "dn")))]
    ""
!   "eorw %2,%0")
  
  (define_insn "xorqi3"
--- 1541,1545 ----
  		(match_operand:HI 2 "general_operand" "dn")))]
    ""
!   "eor%.w %2,%0")
  
  (define_insn "xorqi3"
***************
*** 1805,1809 ****
  		(match_operand:QI 2 "general_operand" "dn")))]
    ""
!   "eorb %2,%0")
  \f


  ;; negation instructions
--- 1548,1552 ----
  		(match_operand:QI 2 "general_operand" "dn")))]
    ""
!   "eor%.b %2,%0")
  \f


  ;; negation instructions
***************
*** 1813,1817 ****
  	(neg:SI (match_operand:SI 1 "general_operand" "0")))]
    ""
!   "negl %0")
  
  (define_insn "neghi2"
--- 1556,1560 ----
  	(neg:SI (match_operand:SI 1 "general_operand" "0")))]
    ""
!   "neg%.l %0")
  
  (define_insn "neghi2"
***************
*** 1819,1823 ****
  	(neg:HI (match_operand:HI 1 "general_operand" "0")))]
    ""
!   "negw %0")
  
  (define_insn "negqi2"
--- 1562,1566 ----
  	(neg:HI (match_operand:HI 1 "general_operand" "0")))]
    ""
!   "neg%.w %0")
  
  (define_insn "negqi2"
***************
*** 1825,1899 ****
  	(neg:QI (match_operand:QI 1 "general_operand" "0")))]
    ""
!   "negb %0")
  
! (define_expand "negsf2"
!   [(set (match_operand:SF 0 "general_operand" "")
! 	(neg:SF (match_operand:SF 1 "general_operand" "")))]
!   "TARGET_68881"
!   "")
! 
! (define_insn ""
!   [(set (match_operand:SF 0 "general_operand" "=f")
! 	(neg:SF (match_operand:SF 1 "general_operand" "fdm")))]
!   "TARGET_68881"
!   "*
! {
!   if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
!     return \"fnegs %1,%0\";
!   return \"fnegs %1,%0\";
! }")
! 
! (define_expand "negdf2"
!   [(set (match_operand:DF 0 "general_operand" "")
! 	(neg:DF (match_operand:DF 1 "general_operand" "")))]
!   "TARGET_68881"
!   "")
! 
! (define_insn ""
!   [(set (match_operand:DF 0 "general_operand" "=f")
! 	(neg:DF (match_operand:DF 1 "general_operand" "fm")))]
!   "TARGET_68881"
!   "*
! {
!   if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
!     return \"fnegd %1,%0\";
!   return \"fnegd %1,%0\";
! }")
  \f


  ;; Absolute value instructions
  
! (define_expand "abssf2"
!   [(set (match_operand:SF 0 "general_operand" "")
! 	(abs:SF (match_operand:SF 1 "general_operand" "")))]
!   "TARGET_68881"
!   "")
! 
! (define_insn ""
!   [(set (match_operand:SF 0 "general_operand" "=f")
! 	(abs:SF (match_operand:SF 1 "general_operand" "fdm")))]
!   "TARGET_68881"
!   "*
! {
!   if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
!     return \"fabss %1,%0\";
!   return \"fabss %1,%0\";
! }")
! 
! (define_expand "absdf2"
!   [(set (match_operand:DF 0 "general_operand" "")
! 	(abs:DF (match_operand:DF 1 "general_operand" "")))]
!   "TARGET_68881"
!   "")
! 
! (define_insn ""
!   [(set (match_operand:DF 0 "general_operand" "=f")
! 	(abs:DF (match_operand:DF 1 "general_operand" "fm")))]
!   "TARGET_68881"
!   "*
! {
!   if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
!     return \"fabsd %1,%0\";
!   return \"fabsd %1,%0\";
! }")
  \f


  ;; one complement instructions
--- 1568,1612 ----
  	(neg:QI (match_operand:QI 1 "general_operand" "0")))]
    ""
!   "neg%.b %0")
  
! (define_insn "negsf2"
!   [(set (match_operand:SF 0 "register_operand" "=f")
! 	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "fm")))]
!   "TARGET_CE"
!   "fneg%.s %1,%0")
! 
! (define_insn "negdf2"
!   [(set (match_operand:DF 0 "register_operand" "=f")
! 	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "fm")))]
!   "TARGET_CE"
!   "fneg%.d %1,%0")
  \f


  ;; Absolute value instructions
  
! (define_insn "abssf2"
!   [(set (match_operand:SF 0 "register_operand" "=f")
! 	(abs:SF (match_operand:SF 1 "nonimmediate_operand" "fm")))]
!   "TARGET_CE"
!   "fabs%.s %1,%0")
! 
! (define_insn "absdf2"
!   [(set (match_operand:DF 0 "register_operand" "=f")
! 	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "fm")))]
!   "TARGET_CE"
!   "fabs%.d %1,%0")
! \f


! ;; Square root instructions
! 
! (define_insn "sqrtsf2"
!   [(set (match_operand:SF 0 "register_operand" "=f")
! 	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "fm")))]
!   "TARGET_CE"
!   "fsqrt%.s %1,%0")
! 
! (define_insn "sqrtdf2"
!   [(set (match_operand:DF 0 "register_operand" "=f")
! 	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "fm")))]
!   "TARGET_CE"
!   "fsqrt%.d %1,%0")
  \f


  ;; one complement instructions
***************
*** 1903,1907 ****
  	(not:SI (match_operand:SI 1 "general_operand" "0")))]
    ""
!   "notl %0")
  
  (define_insn "one_cmplhi2"
--- 1616,1620 ----
  	(not:SI (match_operand:SI 1 "general_operand" "0")))]
    ""
!   "not%.l %0")
  
  (define_insn "one_cmplhi2"
***************
*** 1909,1913 ****
  	(not:HI (match_operand:HI 1 "general_operand" "0")))]
    ""
!   "notw %0")
  
  (define_insn "one_cmplqi2"
--- 1622,1626 ----
  	(not:HI (match_operand:HI 1 "general_operand" "0")))]
    ""
!   "not%.w %0")
  
  (define_insn "one_cmplqi2"
***************
*** 1915,1919 ****
  	(not:QI (match_operand:QI 1 "general_operand" "0")))]
    ""
!   "notb %0")
  \f


  ;; Optimized special case of shifting.
--- 1628,1632 ----
  	(not:QI (match_operand:QI 1 "general_operand" "0")))]
    ""
!   "not%.b %0")
  \f


  ;; Optimized special case of shifting.
***************
*** 1929,1934 ****
  {
    if (TARGET_68020)
!     return \"movb %1,%0\;extbl %0\";
!   return \"movb %1,%0\;extw %0\;extl %0\";
  }")
  
--- 1642,1647 ----
  {
    if (TARGET_68020)
!     return \"mov%.b %1,%0\;extb%.l %0\";
!   return \"mov%.b %1,%0\;ext%.w %0\;ext%.l %0\";
  }")
  
***************
*** 1942,1947 ****
  {
    if (reg_mentioned_p (operands[0], operands[1]))
!     return \"movb %1,%0\;andl %#0xFF,%0\";
!   return \"clrl %0\;movb %1,%0\";
  }")
  
--- 1655,1660 ----
  {
    if (reg_mentioned_p (operands[0], operands[1]))
!     return \"mov%.b %1,%0\;and%.l %#0xFF,%0\";
!   return \"clr%.l %0\;mov%.b %1,%0\";
  }")
  
***************
*** 1953,1957 ****
      && (INTVAL (operands[0]) & ~0xff) == 0)"
    "* cc_status.flags |= CC_REVERSED;
!   return \"cmpb %0,%1\";
  ")
  
--- 1666,1670 ----
      && (INTVAL (operands[0]) & ~0xff) == 0)"
    "* cc_status.flags |= CC_REVERSED;
!   return \"cmp%.b %0,%1\";
  ")
  
***************
*** 1963,1967 ****
      && (INTVAL (operands[1]) & ~0xff) == 0)"
    "*
!   return \"cmpb %1,%0\";
  ")
  
--- 1676,1680 ----
      && (INTVAL (operands[1]) & ~0xff) == 0)"
    "*
!   return \"cmp%.b %1,%0\";
  ")
  
***************
*** 1973,1977 ****
      && ((INTVAL (operands[0]) + 0x80) & ~0xff) == 0)"
    "* cc_status.flags |= CC_REVERSED;
!   return \"cmpb %0,%1\";
  ")
  
--- 1686,1690 ----
      && ((INTVAL (operands[0]) + 0x80) & ~0xff) == 0)"
    "* cc_status.flags |= CC_REVERSED;
!   return \"cmp%.b %0,%1\";
  ")
  
***************
*** 1983,1987 ****
      && ((INTVAL (operands[1]) + 0x80) & ~0xff) == 0)"
    "*
!   return \"cmpb %1,%0\";
  ")
  \f


--- 1696,1700 ----
      && ((INTVAL (operands[1]) + 0x80) & ~0xff) == 0)"
    "*
!   return \"cmp%.b %1,%0\";
  ")
  \f


***************
*** 1994,1998 ****
  		   (match_operand:SI 2 "general_operand" "dI")))]
    ""
!   "asll %2,%0")
  
  (define_insn "ashlhi3"
--- 1707,1711 ----
  		   (match_operand:SI 2 "general_operand" "dI")))]
    ""
!   "asl%.l %2,%0")
  
  (define_insn "ashlhi3"
***************
*** 2001,2005 ****
  		   (match_operand:HI 2 "general_operand" "dI")))]
    ""
!   "aslw %2,%0")
  
  (define_insn "ashlqi3"
--- 1714,1718 ----
  		   (match_operand:HI 2 "general_operand" "dI")))]
    ""
!   "asl%.w %2,%0")
  
  (define_insn "ashlqi3"
***************
*** 2008,2012 ****
  		   (match_operand:QI 2 "general_operand" "dI")))]
    ""
!   "aslb %2,%0")
  
  (define_insn "ashrsi3"
--- 1721,1725 ----
  		   (match_operand:QI 2 "general_operand" "dI")))]
    ""
!   "asl%.b %2,%0")
  
  (define_insn "ashrsi3"
***************
*** 2015,2019 ****
  		     (match_operand:SI 2 "general_operand" "dI")))]
    ""
!   "asrl %2,%0")
  
  (define_insn "ashrhi3"
--- 1728,1732 ----
  		     (match_operand:SI 2 "general_operand" "dI")))]
    ""
!   "asr%.l %2,%0")
  
  (define_insn "ashrhi3"
***************
*** 2022,2026 ****
  		     (match_operand:HI 2 "general_operand" "dI")))]
    ""
!   "asrw %2,%0")
  
  (define_insn "ashrqi3"
--- 1735,1739 ----
  		     (match_operand:HI 2 "general_operand" "dI")))]
    ""
!   "asr%.w %2,%0")
  
  (define_insn "ashrqi3"
***************
*** 2029,2033 ****
  		     (match_operand:QI 2 "general_operand" "dI")))]
    ""
!   "asrb %2,%0")
  \f


  ;; logical shift instructions
--- 1742,1746 ----
  		     (match_operand:QI 2 "general_operand" "dI")))]
    ""
!   "asr%.b %2,%0")
  \f


  ;; logical shift instructions
***************
*** 2038,2042 ****
  		   (match_operand:SI 2 "general_operand" "dI")))]
    ""
!   "lsll %2,%0")
  
  (define_insn "lshlhi3"
--- 1751,1755 ----
  		   (match_operand:SI 2 "general_operand" "dI")))]
    ""
!   "lsl%.l %2,%0")
  
  (define_insn "lshlhi3"
***************
*** 2045,2049 ****
  		   (match_operand:HI 2 "general_operand" "dI")))]
    ""
!   "lslw %2,%0")
  
  (define_insn "lshlqi3"
--- 1758,1762 ----
  		   (match_operand:HI 2 "general_operand" "dI")))]
    ""
!   "lsl%.w %2,%0")
  
  (define_insn "lshlqi3"
***************
*** 2052,2056 ****
  		   (match_operand:QI 2 "general_operand" "dI")))]
    ""
!   "lslb %2,%0")
  
  (define_insn "lshrsi3"
--- 1765,1769 ----
  		   (match_operand:QI 2 "general_operand" "dI")))]
    ""
!   "lsl%.b %2,%0")
  
  (define_insn "lshrsi3"
***************
*** 2059,2063 ****
  		     (match_operand:SI 2 "general_operand" "dI")))]
    ""
!   "lsrl %2,%0")
  
  (define_insn "lshrhi3"
--- 1772,1776 ----
  		     (match_operand:SI 2 "general_operand" "dI")))]
    ""
!   "lsr%.l %2,%0")
  
  (define_insn "lshrhi3"
***************
*** 2066,2070 ****
  		     (match_operand:HI 2 "general_operand" "dI")))]
    ""
!   "lsrw %2,%0")
  
  (define_insn "lshrqi3"
--- 1779,1783 ----
  		     (match_operand:HI 2 "general_operand" "dI")))]
    ""
!   "lsr%.w %2,%0")
  
  (define_insn "lshrqi3"
***************
*** 2073,2077 ****
  		     (match_operand:QI 2 "general_operand" "dI")))]
    ""
!   "lsrb %2,%0")
  \f


  ;; rotate instructions
--- 1786,1790 ----
  		     (match_operand:QI 2 "general_operand" "dI")))]
    ""
!   "lsr%.b %2,%0")
  \f


  ;; rotate instructions
***************
*** 2082,2086 ****
  		   (match_operand:SI 2 "general_operand" "dI")))]
    ""
!   "roll %2,%0")
  
  (define_insn "rotlhi3"
--- 1795,1799 ----
  		   (match_operand:SI 2 "general_operand" "dI")))]
    ""
!   "rol%.l %2,%0")
  
  (define_insn "rotlhi3"
***************
*** 2089,2093 ****
  		   (match_operand:HI 2 "general_operand" "dI")))]
    ""
!   "rolw %2,%0")
  
  (define_insn "rotlqi3"
--- 1802,1806 ----
  		   (match_operand:HI 2 "general_operand" "dI")))]
    ""
!   "rol%.w %2,%0")
  
  (define_insn "rotlqi3"
***************
*** 2096,2100 ****
  		   (match_operand:QI 2 "general_operand" "dI")))]
    ""
!   "rolb %2,%0")
  
  (define_insn "rotrsi3"
--- 1809,1813 ----
  		   (match_operand:QI 2 "general_operand" "dI")))]
    ""
!   "rol%.b %2,%0")
  
  (define_insn "rotrsi3"
***************
*** 2103,2107 ****
  		     (match_operand:SI 2 "general_operand" "dI")))]
    ""
!   "rorl %2,%0")
  
  (define_insn "rotrhi3"
--- 1816,1820 ----
  		     (match_operand:SI 2 "general_operand" "dI")))]
    ""
!   "ror%.l %2,%0")
  
  (define_insn "rotrhi3"
***************
*** 2110,2114 ****
  		     (match_operand:HI 2 "general_operand" "dI")))]
    ""
!   "rorw %2,%0")
  
  (define_insn "rotrqi3"
--- 1823,1827 ----
  		     (match_operand:HI 2 "general_operand" "dI")))]
    ""
!   "ror%.w %2,%0")
  
  (define_insn "rotrqi3"
***************
*** 2117,2121 ****
  		     (match_operand:QI 2 "general_operand" "dI")))]
    ""
!   "rorb %2,%0")
  \f


  ;; Special cases of bit-field insns which we should
--- 1830,1834 ----
  		     (match_operand:QI 2 "general_operand" "dI")))]
    ""
!   "ror%.b %2,%0")
  \f


  ;; Special cases of bit-field insns which we should
***************
*** 2145,2156 ****
    else
      operands[0]
!       = adj_offsetable_operand (operands[0], INTVAL (operands[2]) / 8);
  
    if (GET_CODE (operands[3]) == MEM)
!     operands[3] = adj_offsetable_operand (operands[3],
! 					  (32 - INTVAL (operands[1])) / 8);
    if (INTVAL (operands[1]) == 8)
!     return \"movb %3,%0\";
!   return \"movw %3,%0\";
  }")
  
--- 1858,1869 ----
    else
      operands[0]
!       = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8);
  
    if (GET_CODE (operands[3]) == MEM)
!     operands[3] = adj_offsettable_operand (operands[3],
! 					   (32 - INTVAL (operands[1])) / 8);
    if (INTVAL (operands[1]) == 8)
!     return \"mov%.b %3,%0\";
!   return \"mov%.w %3,%0\";
  }")
  
***************
*** 2176,2188 ****
    else
      operands[1]
!       = adj_offsetable_operand (operands[1], INTVAL (operands[3]) / 8);
  
    output_asm_insn (\"clrl %0\", operands);
    if (GET_CODE (operands[0]) == MEM)
!     operands[0] = adj_offsetable_operand (operands[0],
! 					  (32 - INTVAL (operands[1])) / 8);
    if (INTVAL (operands[2]) == 8)
!     return \"movb %1,%0\";
!   return \"movw %1,%0\";
  }")
  
--- 1889,1901 ----
    else
      operands[1]
!       = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
  
    output_asm_insn (\"clrl %0\", operands);
    if (GET_CODE (operands[0]) == MEM)
!     operands[0] = adj_offsettable_operand (operands[0],
! 					   (32 - INTVAL (operands[1])) / 8);
    if (INTVAL (operands[2]) == 8)
!     return \"mov%.b %1,%0\";
!   return \"mov%.w %1,%0\";
  }")
  
***************
*** 2208,2220 ****
    else
      operands[1]
!       = adj_offsetable_operand (operands[1], INTVAL (operands[3]) / 8);
  
    if (INTVAL (operands[2]) == 8)
!     return \"movb %1,%0\;extbl %0\";
!   return \"movw %1,%0\;extl %0\";
  }")
  \f


  ;; Bit field instructions, general cases.
! ;; "o,d" constraint causes a nonoffsetable memref to match the "o"
  ;; so that its address is reloaded.
  
--- 1921,1933 ----
    else
      operands[1]
!       = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
  
    if (INTVAL (operands[2]) == 8)
!     return \"mov%.b %1,%0\;extb%.l %0\";
!   return \"mov%.w %1,%0\;ext%.l %0\";
  }")
  \f


  ;; Bit field instructions, general cases.
! ;; "o,d" constraint causes a nonoffsettable memref to match the "o"
  ;; so that its address is reloaded.
  
***************
*** 2246,2250 ****
         || (GET_CODE (operands[1]) == CONST_INT
             && (~ INTVAL (operands[3]) & ((1 << INTVAL (operands[1]))- 1)) == 0))"
!   "bfchg [%c2,%c1]%0")
  
  (define_insn ""
--- 1959,1967 ----
         || (GET_CODE (operands[1]) == CONST_INT
             && (~ INTVAL (operands[3]) & ((1 << INTVAL (operands[1]))- 1)) == 0))"
!   "*
! {
!   CC_STATUS_INIT;
!   return \"bfchg [%c2,%c1]%0\";
! }")
  
  (define_insn ""
***************
*** 2254,2258 ****
  	(const_int 0))]
    "TARGET_68020 && TARGET_BITFIELD"
!   "bfclr [%c2,%c1]%0")
  
  (define_insn ""
--- 1971,1979 ----
  	(const_int 0))]
    "TARGET_68020 && TARGET_BITFIELD"
!   "*
! {
!   CC_STATUS_INIT;
!   return \"bfclr [%c2,%c1]%0\";
! }")
  
  (define_insn ""
***************
*** 2262,2266 ****
  	(const_int -1))]
    "TARGET_68020 && TARGET_BITFIELD"
!   "bfset [%c2,%c1]%0")
  
  (define_insn "insv"
--- 1983,1991 ----
  	(const_int -1))]
    "TARGET_68020 && TARGET_BITFIELD"
!   "*
! {
!   CC_STATUS_INIT;
!   return \"bfset [%c2,%c1]%0\";
! }")
  
  (define_insn "insv"
***************
*** 2297,2301 ****
  	(const_int 0))]
    "TARGET_68020 && TARGET_BITFIELD"
!   "bfclr [%c2,%c1]%0")
  
  (define_insn ""
--- 2022,2030 ----
  	(const_int 0))]
    "TARGET_68020 && TARGET_BITFIELD"
!   "*
! {
!   CC_STATUS_INIT;
!   return \"bfclr [%c2,%c1]%0\";
! }")
  
  (define_insn ""
***************
*** 2305,2309 ****
  	(const_int -1))]
    "TARGET_68020 && TARGET_BITFIELD"
!   "bfset [%c2,%c1]%0")
  
  (define_insn ""
--- 2034,2042 ----
  	(const_int -1))]
    "TARGET_68020 && TARGET_BITFIELD"
!   "*
! {
!   CC_STATUS_INIT;
!   return \"bfset [%c2,%c1]%0\";
! }")
  
  (define_insn ""
***************
*** 2506,2510 ****
    "*
    cc_status = cc_prev_status;
!   OUTPUT_JUMP (\"sne %0\", \"fsne %0\", \"sne %0\");
  ")
  
--- 2239,2243 ----
    "*
    cc_status = cc_prev_status;
!   OUTPUT_JUMP (\"sne %0\", \"fsneq %0\", \"sne %0\");
  ")
  
***************
*** 2515,2519 ****
    "*
    cc_status = cc_prev_status;
!   OUTPUT_JUMP (\"sgt %0\", \"fsgt %0\", \"andb %#0xc,%!\;sgt %0\");
  ")
  
--- 2248,2252 ----
    "*
    cc_status = cc_prev_status;
!   OUTPUT_JUMP (\"sgt %0\", \"fsgt %0\", \"and%.b %#0xc,%!\;sgt %0\");
  ")
  
***************
*** 2559,2563 ****
    "*
    cc_status = cc_prev_status;
!   OUTPUT_JUMP (\"sle %0\", \"fsle %0\", \"andb %#0xc,%!\;sle %0\");
  ")
  
--- 2292,2296 ----
    "*
    cc_status = cc_prev_status;
!   OUTPUT_JUMP (\"sle %0\", \"fsle %0\", \"and%.b %#0xc,%!\;sle %0\");
  ")
  
***************
*** 2603,2607 ****
    ""
    "*
!   OUTPUT_JUMP (\"jgt %l0\", \"fbgt %l0\", \"andb %#0xc,%!\;jgt %l0\");
  ")
  
--- 2336,2340 ----
    ""
    "*
!   OUTPUT_JUMP (\"jgt %l0\", \"fbgt %l0\", \"and%.b %#0xc,%!\;jgt %l0\");
  ")
  
***************
*** 2669,2673 ****
    ""
    "*
!   OUTPUT_JUMP (\"jle %l0\", \"fble %l0\", \"andb %#0xc,%!\;jle %l0\");
  ")
  
--- 2402,2406 ----
    ""
    "*
!   OUTPUT_JUMP (\"jle %l0\", \"fble %l0\", \"and%.b %#0xc,%!\;jle %l0\");
  ")
  
***************
*** 2717,2721 ****
    ""
    "*
!   OUTPUT_JUMP (\"jle %l0\", \"fbngt %l0\", \"andb %#0xc,%!\;jle %l0\");
  ")
  
--- 2450,2454 ----
    ""
    "*
!   OUTPUT_JUMP (\"jle %l0\", \"fbngt %l0\", \"and%.b %#0xc,%!\;jle %l0\");
  ")
  
***************
*** 2783,2787 ****
    ""
    "*
!   OUTPUT_JUMP (\"jgt %l0\", \"fbnle %l0\", \"andb %#0xc,%!\;jgt %l0\");
  ")
  
--- 2516,2520 ----
    ""
    "*
!   OUTPUT_JUMP (\"jgt %l0\", \"fbnle %l0\", \"and%.b %#0xc,%!\;jgt %l0\");
  ")
  
***************
*** 2894,2900 ****
    if (GET_CODE (operands[0]) == MEM)
      {
!       return \"subqw %#1,%0\;jcc %l1\";
      }
!   return \"subqw %#1,%0\;cmpw %#-1,%0\;jne %l1\";
  }")
  
--- 2627,2633 ----
    if (GET_CODE (operands[0]) == MEM)
      {
!       return \"subq%.w %#1,%0\;jcc %l1\";
      }
!   return \"subq%.w %#1,%0\;cmp%.w %#-1,%0\;jne %l1\";
  }")
  
***************
*** 2915,2922 ****
  {
    if (DATA_REG_P (operands[0]))
!     return \"dbra %0,%l1\;clrw %0\;subql %#1,%0\;jcc %l1\";
    if (GET_CODE (operands[0]) == MEM)
!     return \"subql %#1,%0\;jcc %l1\";
!   return \"subql %#1,%0\;cmpl %#-1,%0\;jne %l1\";
  }")
  
--- 2648,2655 ----
  {
    if (DATA_REG_P (operands[0]))
!     return \"dbra %0,%l1\;clr%.w %0\;subq%.l %#1,%0\;jcc %l1\";
    if (GET_CODE (operands[0]) == MEM)
!     return \"subq%.l %#1,%0\;jcc %l1\";
!   return \"subq%.l %#1,%0\;cmp%.l %#-1,%0\;jne %l1\";
  }")
  
***************
*** 2940,2945 ****
      return \"dbra %0,%l1\;clrw %0\;subql %#1,%0\;jcc %l1\";
    if (GET_CODE (operands[0]) == MEM)
!     return \"subql %#1,%0\;jcc %l1\";
!   return \"subql %#1,%0\;cmpl %#-1,%0\;jne %l1\";
  }")
  
--- 2673,2678 ----
      return \"dbra %0,%l1\;clrw %0\;subql %#1,%0\;jcc %l1\";
    if (GET_CODE (operands[0]) == MEM)
!     return \"subq%.l %#1,%0\;jcc %l1\";
!   return \"subq%.l %#1,%0\;cmp%.l %#-1,%0\;jne %l1\";
  }")
  
***************
*** 2948,2953 ****
    [(call (match_operand:QI 0 "general_operand" "o")
  	 (match_operand:SI 1 "general_operand" "g"))]
-   ;; Operand 1 not really used on the m68000.
- 
    ""
    "*
--- 2681,2684 ----
***************
*** 2957,2967 ****
  
    if (size == 0) 
!     return \"subl a0,a0\;jsr %0\;movl a6@(-4),a0\";
    else
!     {
!       xoperands[1] = gen_rtx (CONST_INT, VOIDmode, size/4 );
!       output_asm_insn (\"movl sp,a0\;movl %1,%-\", xoperands );
!       return \"jsr %0\;movl a6@(-4),a0\;addqw #4,sp\";
!     }
  }")
  
--- 2688,2707 ----
  
    if (size == 0) 
!     output_asm_insn (\"sub%.l a0,a0\;jbsr %0\", operands);
    else
!   {
!     xoperands[1] = gen_rtx (CONST_INT, VOIDmode, size/4);
!     output_asm_insn (\"mov%.l sp,a0\;pea %a1\", xoperands);
!     output_asm_insn (\"jbsr %0\", operands);
!     size = size + 4;
!     xoperands[1] = gen_rtx (CONST_INT, VOIDmode, size);
!     if (size <= 8)
!       output_asm_insn (\"addq%.l %1,sp\", xoperands);
!     else if (size < 0x8000)
!       output_asm_insn (\"add%.w %1,sp\", xoperands);
!     else
!       output_asm_insn (\"add%.l %1,sp\", xoperands);
!   }
!   return \"mov%.l a6@(-4),a0\";
  }")
  
***************
*** 2969,2976 ****
  ;; (which must be a hard register).
  (define_insn "call_value"
!   [(set (match_operand 0 "" "rf")
  	(call (match_operand:QI 1 "general_operand" "o")
  	      (match_operand:SI 2 "general_operand" "g")))]
-   ;; Operand 2 not really used on the m68000.
    ""
    "*
--- 2709,2715 ----
  ;; (which must be a hard register).
  (define_insn "call_value"
!   [(set (match_operand 0 "" "=rf")
  	(call (match_operand:QI 1 "general_operand" "o")
  	      (match_operand:SI 2 "general_operand" "g")))]
    ""
    "*
***************
*** 2980,2996 ****
  
    if (size == 0)
!     return \"subl a0,a0\;jsr %1\;movl a6@(-4),a0\";
    else
!     {
!       xoperands[2] = gen_rtx (CONST_INT, VOIDmode, size/4 );
!       output_asm_insn (\"movl sp,a0\;movl %2,%-\", xoperands );
!       return \"jsr %1\;movl a6@(-4),a0\;addqw #4,sp\";
!     }
! }")
! 
! (define_insn "return"
!   [(return)]
!   "0"
!   "ret 0")
  \f


  ;; This is the first machine-dependent peephole optimization.
--- 2719,2752 ----
  
    if (size == 0)
!     output_asm_insn(\"sub%.l a0,a0\;jbsr %1\", operands);
    else
!   {
!     xoperands[2] = gen_rtx (CONST_INT, VOIDmode, size/4);
!     output_asm_insn (\"mov%.l sp,a0\;pea %a2\", xoperands);
!     output_asm_insn (\"jbsr %1\", operands);
!     size = size + 4;
!     xoperands[2] = gen_rtx (CONST_INT, VOIDmode, size);
!     if (size <= 8)
!       output_asm_insn (\"addq%.l %2,sp\", xoperands);
!     else if (size < 0x8000)
!       output_asm_insn (\"add%.w %2,sp\", xoperands);
!     else
!       output_asm_insn (\"add%.l %2,sp\", xoperands);
!   }
!   return \"mov%.l a6@(-4),a0\";
! }")
! 
! (define_insn "nop"
!   [(const_int 0)]
!   ""
!   "nop")
! \f


! ;; This should not be used unless the add/sub insns can't be.
! 
! (define_insn ""
!   [(set (match_operand:SI 0 "general_operand" "=a")
! 	(match_operand:QI 1 "address_operand" "p"))]
!   ""
!   "lea %a1,%0")
  \f


  ;; This is the first machine-dependent peephole optimization.
***************
*** 2999,3016 ****
  ;; But it is mainly intended to test the support for these optimizations.
  
! (define_peephole
!   [(set (reg:SI 15) (plus:SI (reg:SI 15) (const_int 4)))
!    (set (match_operand:DF 0 "register_operand" "f")
! 	(match_operand:DF 1 "register_operand" "ad"))]
!   "FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
!   "*
! {
!   rtx xoperands[2];
!   xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
!   output_asm_insn (\"movl %1,%@\", xoperands);
!   output_asm_insn (\"movl %1,%-\", operands);
!   return \"fmoved %+,%0\";
! }
! ")
  \f


  
--- 2755,2773 ----
  ;; But it is mainly intended to test the support for these optimizations.
  
! ;Not applicable to Alliant -- floating results are returned in fp0
! ;(define_peephole
! ;  [(set (reg:SI 15) (plus:SI (reg:SI 15) (const_int 4)))
! ;   (set (match_operand:DF 0 "register_operand" "f")
! ;	(match_operand:DF 1 "register_operand" "ad"))]
! ;  "FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
! ;  "*
! ;{
! ;  rtx xoperands[2];
! ;  xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
! ;  output_asm_insn (\"mov%.l %1,%@\", xoperands);
! ;  output_asm_insn (\"mov%.l %1,%-\", operands);
! ;  return \"fmove%.d %+,%0\";
! ;}
! ;")
  \f


  
***************
*** 3025,3026 ****
--- 2782,2784 ----
  ;;- eval: (modify-syntax-entry ?} "){")
  ;;- End:
+ 
diff -rc2N gcc-1.35/config/convex.md gcc-1.36/config/convex.md
*** gcc-1.35/config/convex.md	Mon Apr 10 23:23:06 1989
--- gcc-1.36/config/convex.md	Sun Sep 17 15:16:03 1989
***************
*** 28,31 ****
--- 28,33 ----
  ;;- updates for most instructions.
  
+ ;; Put tstsi first among test insns so it matches a CONST_INT operand.
+ 
  (define_insn "tstsi"
    [(set (cc0)
***************
*** 72,81 ****
    "* return set_cmp (operands[0], fconst0_rtx, 's');")
  
! (define_insn "cmpdi"
!   [(set (cc0)
! 	(compare (match_operand:DI 0 "register_operand" "d")
! 		 (match_operand:DI 1 "register_operand" "d")))]
!   ""
!   "* return set_cmp (operands[0], operands[1], 'l');")
  
  (define_insn "cmpsi"
--- 74,78 ----
    "* return set_cmp (operands[0], fconst0_rtx, 's');")
  
! ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
  
  (define_insn "cmpsi"
***************
*** 100,103 ****
--- 97,107 ----
    "* return set_cmp (operands[0], operands[1], 'b');")
  
+ (define_insn "cmpdi"
+   [(set (cc0)
+ 	(compare (match_operand:DI 0 "register_operand" "d")
+ 		 (match_operand:DI 1 "register_operand" "d")))]
+   ""
+   "* return set_cmp (operands[0], operands[1], 'l');")
+ 
  (define_insn "cmpdf"
    [(set (cc0)
***************
*** 321,330 ****
    "and #0xffff,%0")
  
- (define_insn "zero_extendhidi2"
-   [(set (match_operand:DI 0 "register_operand" "=d")
- 	(zero_extend:DI (match_operand:HI 1 "register_operand" "0")))]
-   ""
-   "and #0xffff,%0")
- 
  (define_insn "zero_extendqihi2"
    [(set (match_operand:HI 0 "register_operand" "=r")
--- 325,328 ----
***************
*** 339,348 ****
    "and #0xff,%0")
  
- (define_insn "zero_extendqidi2"
-   [(set (match_operand:DI 0 "register_operand" "=d")
- 	(zero_extend:DI (match_operand:QI 1 "register_operand" "0")))]
-   ""
-   "and #0xff,%0")
- 
  (define_insn "zero_extendsidi2"
    [(set (match_operand:DI 0 "register_operand" "=d")
--- 337,340 ----
***************
*** 436,439 ****
--- 428,441 ----
    "add.l %2,%0")
  
+ ;; special case of addsi3, needed to specify an A reg for the destination 
+ ;; when the source is a sum involving FP or AP.
+ 
+ (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=a")
+ 	(plus:SI (match_operand:SI 1 "register_operand" "%a")
+ 		 (match_operand:SI 2 "immediate_operand" "i")))]
+   "operands[1] == frame_pointer_rtx || operands[1] == arg_pointer_rtx"
+   "ldea %a2(%1),%0")
+ 
  (define_insn "addsi3"
    [(set (match_operand:SI 0 "register_operand" "=d,a,a")
***************
*** 612,616 ****
    [(set (match_operand:DI 0 "register_operand" "=d")
  	(and:DI (match_operand:DI 1 "register_operand" "%0")
! 		(match_operand:DI 2 "nonmemory_operand" "dI")))]
    ""
    "and %2,%0")
--- 614,618 ----
    [(set (match_operand:DI 0 "register_operand" "=d")
  	(and:DI (match_operand:DI 1 "register_operand" "%0")
! 		(match_operand:DI 2 "register_operand" "d")))]
    ""
    "and %2,%0")
***************
*** 642,646 ****
    [(set (match_operand:DI 0 "register_operand" "=d")
  	(ior:DI (match_operand:DI 1 "register_operand" "%0")
! 		(match_operand:DI 2 "nonmemory_operand" "dI")))]
    ""
    "or %2,%0")
--- 644,648 ----
    [(set (match_operand:DI 0 "register_operand" "=d")
  	(ior:DI (match_operand:DI 1 "register_operand" "%0")
! 		(match_operand:DI 2 "register_operand" "d")))]
    ""
    "or %2,%0")
***************
*** 672,676 ****
    [(set (match_operand:DI 0 "register_operand" "=d")
  	(xor:DI (match_operand:DI 1 "register_operand" "%0")
! 		(match_operand:DI 2 "nonmemory_operand" "dI")))]
    ""
    "xor %2,%0")
--- 674,678 ----
    [(set (match_operand:DI 0 "register_operand" "=d")
  	(xor:DI (match_operand:DI 1 "register_operand" "%0")
! 		(match_operand:DI 2 "register_operand" "d")))]
    ""
    "xor %2,%0")
***************
*** 1145,1149 ****
    "*
  {
!   if (! RETURN_POPS_ARGS ()) 
      {
        if (operands[1] == const0_rtx)
--- 1147,1151 ----
    "*
  {
!   if (! RETURN_POPS_ARGS (ignoreme)) 
      {
        if (operands[1] == const0_rtx)
***************
*** 1162,1166 ****
  
  (define_insn "call_value"
!   [(set (match_operand 0 "" "g")
  	(call (match_operand:QI 1 "general_operand" "g")
  	      (match_operand:SI 2 "general_operand" "g")))]
--- 1164,1168 ----
  
  (define_insn "call_value"
!   [(set (match_operand 0 "" "=g")
  	(call (match_operand:QI 1 "general_operand" "g")
  	      (match_operand:SI 2 "general_operand" "g")))]
***************
*** 1168,1172 ****
    "*
  {
!   if (! RETURN_POPS_ARGS ()) 
      {
        if (operands[2] == const0_rtx)
--- 1170,1174 ----
    "*
  {
!   if (! RETURN_POPS_ARGS (ignoreme)) 
      {
        if (operands[2] == const0_rtx)
***************
*** 1189,1192 ****
--- 1191,1199 ----
    "rtn")
  
+ (define_insn "nop"
+   [(const_int 0)]
+   ""
+   "nop")
+ 
  (define_insn "tablejump"
    [(set (pc) (match_operand:SI 0 "address_operand" "p"))
***************
*** 1257,1261 ****
  ;;- eval: (modify-syntax-entry ?} "){")
  ;;- End:
- 
- 
  
--- 1264,1266 ----
diff -rc2N gcc-1.35/config/i386.md gcc-1.36/config/i386.md
*** gcc-1.35/config/i386.md	Thu Mar 23 04:48:59 1989
--- gcc-1.36/config/i386.md	Tue Aug 22 00:29:25 1989
***************
*** 38,45 ****
  ;;- 'c' for ecx
  ;;- 'b' for ebx
- ;;- 'S' for SIREGS (esi)
- ;;- 'D' for DIREGS (edi)
  ;;- 'f' for anything in FLOAT_REGS
  ;;- 'r' any (non-floating-point) register
  
  ;; the special asm out single letter directives following a '%' are:
--- 38,45 ----
  ;;- 'c' for ecx
  ;;- 'b' for ebx
  ;;- 'f' for anything in FLOAT_REGS
  ;;- 'r' any (non-floating-point) register
+ ;;- 'q' regs that allow byte operations (A, B, C and D)
+ ;;- 'A' A and D registers
  
  ;; the special asm out single letter directives following a '%' are:
***************
*** 50,53 ****
--- 50,55 ----
  
  \f


+ ;; Put tstsi first among test insns so it matches a CONST_INT operand.
+ 
  (define_insn "tstsi"
    [(set (cc0)
***************
*** 76,80 ****
  (define_insn "tstqi"
    [(set (cc0)
! 	(match_operand:QI 0 "general_operand" "rm"))]
    ""
    "*
--- 78,82 ----
  (define_insn "tstqi"
    [(set (cc0)
! 	(match_operand:QI 0 "general_operand" "qm"))]
    ""
    "*
***************
*** 99,103 ****
    xops[0] = FP_TOP;
    cc_status.flags |= CC_IN_80387;
!   output_asm_insn (\"ftst\;fstp %0(0)\;fnstsw %R0ax\;sahf\", xops);
    RETCOM (testsf);
  }")
--- 101,108 ----
    xops[0] = FP_TOP;
    cc_status.flags |= CC_IN_80387;
!   if (FP_REG_P (operands[0]) && ! top_dead_p (insn))
!     output_asm_insn (\"ftst\;fnstsw %R0ax\;sahf\", xops);
!   else
!     output_asm_insn (\"ftst\;fstp %0(0)\;fnstsw %R0ax\;sahf\", xops);
    RETCOM (testsf);
  }")
***************
*** 117,121 ****
    xops[0] = FP_TOP;
    cc_status.flags |= CC_IN_80387;
!   output_asm_insn (\"ftst\;fstp %0(0)\;fnstsw %R0ax\;sahf\", xops);
    RETCOM (testdf);
  }")
--- 122,129 ----
    xops[0] = FP_TOP;
    cc_status.flags |= CC_IN_80387;
!   if (FP_REG_P (operands[0]) && ! top_dead_p (insn))
!     output_asm_insn (\"ftst\;fnstsw %R0ax\;sahf\", xops);
!   else
!     output_asm_insn (\"ftst\;fstp %0(0)\;fnstsw %R0ax\;sahf\", xops);
    RETCOM (testdf);
  }")
***************
*** 123,126 ****
--- 131,136 ----
  ;;- compare instructions
  
+ ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
+ 
  (define_insn "cmpsi"
    [(set (cc0)
***************
*** 388,392 ****
  
  (define_insn "movsf"
!   [(set (match_operand:SF 0 "general_operand" "=mf,rmf,!rm")
  	(match_operand:SF 1 "general_operand" "m,rf,F"))]
    ""
--- 398,402 ----
  
  (define_insn "movsf"
!   [(set (match_operand:SF 0 "general_operand" "=rf,rmf,!rm")
  	(match_operand:SF 1 "general_operand" "m,rf,F"))]
    ""
***************
*** 425,429 ****
  
  (define_insn "movdf"
!   [(set (match_operand:DF 0 "general_operand" "=&rmf,rmf,!rm")
  	(match_operand:DF 1 "general_operand" "m,fr,F"))]
    ""
--- 435,439 ----
  
  (define_insn "movdf"
!   [(set (match_operand:DF 0 "general_operand" "=&rf,rmf,!rm")
  	(match_operand:DF 1 "general_operand" "m,fr,F"))]
    ""
***************
*** 514,519 ****
    "*
  {
!  CC_STATUS_INIT;
!  return \"lea%L0 %a1,%0\";
  }")
  \f


--- 524,537 ----
    "*
  {
!   CC_STATUS_INIT;
!   /* Adding a constant to a register is faster with an add.  */
!   if (GET_CODE (operands[1]) == PLUS
!       && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
!       && rtx_equal_p (operands[0], XEXP (operands[1], 0)))
!     {
!       operands[1] = XEXP (operands[1], 1);
!       return AS2 (add%L0,%1,%0);
!     }
!   return \"lea%L0 %a1,%0\";
  }")
  \f


***************
*** 523,529 ****
  ;;- truncation instructions
  (define_insn "truncsiqi2"
!   [(set (match_operand:QI 0 "general_operand" "=rm,r")
  	(truncate:QI
! 	 (match_operand:SI 1 "general_operand" "ri,m")))]
    ""
    "mov%B0 %1,%0")
--- 541,547 ----
  ;;- truncation instructions
  (define_insn "truncsiqi2"
!   [(set (match_operand:QI 0 "general_operand" "=qm,q")
  	(truncate:QI
! 	 (match_operand:SI 1 "general_operand" "qi,m")))]
    ""
    "mov%B0 %1,%0")
***************
*** 530,536 ****
  
  (define_insn "trunchiqi2"
!   [(set (match_operand:QI 0 "general_operand" "=rm,r")
  	(truncate:QI
! 	 (match_operand:HI 1 "general_operand" "ri,m")))]
    ""
    "mov%B0 %1,%0")
--- 548,554 ----
  
  (define_insn "trunchiqi2"
!   [(set (match_operand:QI 0 "general_operand" "=qm,q")
  	(truncate:QI
! 	 (match_operand:HI 1 "general_operand" "qi,m")))]
    ""
    "mov%B0 %1,%0")
***************
*** 639,643 ****
    "*
  {
!   fp_pop_sf (operands[0]);
    RETCOM (truncdfsf2);
  }")
--- 657,664 ----
    "*
  {
!   if (top_dead_p (insn))
!     fp_pop_sf (operands[0]);
!   else
!     fp_store_sf (operands[0]);
    RETCOM (truncdfsf2);
  }")
***************
*** 913,916 ****
--- 934,944 ----
  ;;- multiply instructions
  
+ ;(define_insn "mulqi3"
+ ;  [(set (match_operand:QI 0 "general_operand" "=a")
+ ;	(mult:QI (match_operand:QI 1 "general_operand" "%0")
+ ;		 (match_operand:QI 2 "general_operand" "qm")))]
+ ;  ""
+ ;  "mul%B0 %2,%0")
+ 
  (define_insn "mulhi3"
    [(set (match_operand:HI 0 "general_operand" "=r,r")
***************
*** 945,958 ****
  }")
  
! (define_insn "umulqihi3"
!   [(set (match_operand:HI 0 "general_operand" "=a")
! 	(umult:HI (match_operand:QI "general_operand" "%a")
! 		  (match_operand:QI "general_operand" "rm")))]
!   ""
!   "mul%B0 %2,%0")
  
  (define_insn "umulhi3"
    [(set (match_operand:HI 0 "general_operand" "=a")
! 	(umult:SI (match_operand:HI 1 "general_operand" "%a")
  		  (match_operand:HI 2 "general_operand" "rm")))
     (clobber (reg:HI 1))]
--- 973,994 ----
  }")
  
! ;; Turned off due to possible assembler bug.
! ;(define_insn "umulqi3"
! ;  [(set (match_operand:QI 0 "general_operand" "=a")
! ;	(umult:QI (match_operand:QI 1 "general_operand" "%0")
! ;		  (match_operand:QI 2 "general_operand" "qm")))]
! ;  ""
! ;  "mul%B0 %2,%0")
  
+ ;(define_insn "umulqihi3"
+ ;  [(set (match_operand:HI 0 "general_operand" "=a")
+ ;	(umult:HI (match_operand:QI 1 "general_operand" "%0")
+ ;		  (match_operand:QI 2 "general_operand" "qm")))]
+ ;  ""
+ ;  "mul%B0 %2,%0")
+ 
  (define_insn "umulhi3"
    [(set (match_operand:HI 0 "general_operand" "=a")
! 	(umult:SI (match_operand:HI 1 "general_operand" "%0")
  		  (match_operand:HI 2 "general_operand" "rm")))
     (clobber (reg:HI 1))]
***************
*** 962,966 ****
  (define_insn "umulsi3"
    [(set (match_operand:SI 0 "general_operand" "=a")
! 	(umult:SI (match_operand:SI 1 "general_operand" "%a")
  		  (match_operand:SI 2 "general_operand" "rm")))
     (clobber (reg:SI 1))]
--- 998,1002 ----
  (define_insn "umulsi3"
    [(set (match_operand:SI 0 "general_operand" "=a")
! 	(umult:SI (match_operand:SI 1 "general_operand" "%0")
  		  (match_operand:SI 2 "general_operand" "rm")))
     (clobber (reg:SI 1))]
***************
*** 1205,1220 ****
    if (REG_P (operands[2]))
      return AS2 (sal%L0,%R0cl,%0);
!   else if (REG_P (operands[1]) && GET_CODE (operands[2]) == CONST_INT)
!     switch (INTVAL (operands[2]))
!       {
!       case 1:
! 	return AS2 (add%L0,%1,%1);
!       case 2:
! 	CC_STATUS_INIT;
! 	return \"lea%L0 (,%1,4),%1\";
!       case 3:
! 	CC_STATUS_INIT;
! 	return \"lea%L0 (,%1,8),%1\";
!       }
    return AS2 (sal%L0,%2,%1);
  }")
--- 1241,1247 ----
    if (REG_P (operands[2]))
      return AS2 (sal%L0,%R0cl,%0);
!   else if (REG_P (operands[1]) && GET_CODE (operands[2]) == CONST_INT
! 	   && INTVAL (operands[2]) == 1)
!     return AS2 (add%L0,%1,%1);
    return AS2 (sal%L0,%2,%1);
  }")
***************
*** 1445,1458 ****
  }")
  \f


! ;;the seq ops are moved to md.old
  \f


  ;; Basic conditional jump instructions.
  ;; We ignore the overflow flag for signed branch instructions.
- ;; We accomplish this through the code in notice_update_cc in output-i386.c.
- ;; Based on '(cc_status.flags & CC_NO_OVERFLOW)' and '(cc_status.value2)'
- ;; (the rtx for the destination of the insn setting cc_status) we clear
- ;; the overflow flag (if necessary).
- ;; For register destinations we do this by 'or%z1 <reg>, <reg>';
- ;; for memory destinations we do this by 'cmp%z1 $0, <mem>'.
  
  (define_insn "beq"
--- 1472,1557 ----
  }")
  \f


! ;; Store-flag instructions.
! 
! (define_insn "seq"
!   [(set (match_operand:QI 0 "general_operand" "=q")
! 	(eq (cc0) (const_int 0)))]
!   ""
!   "*
!   cc_status = cc_prev_status;
!   return \"sete %0\";
! ")
! 
! (define_insn "sne"
!   [(set (match_operand:QI 0 "general_operand" "=q")
! 	(ne (cc0) (const_int 0)))]
!   ""
!   "*
!   cc_status = cc_prev_status;
!   return \"setne %0\";
! ")
! 
! (define_insn "sgt"
!   [(set (match_operand:QI 0 "general_operand" "=q")
! 	(gt (cc0) (const_int 0)))]
!   ""
!   "*
!   cc_status = cc_prev_status;
!   OUTPUT_JUMP (\"setg %0\", \"seta %0\", 0);
! ")
! 
! (define_insn "sgtu"
!   [(set (match_operand:QI 0 "general_operand" "=q")
! 	(gtu (cc0) (const_int 0)))]
!   ""
!   "* cc_status = cc_prev_status;
!      return \"seta %0\"; ")
! 
! (define_insn "slt"
!   [(set (match_operand:QI 0 "general_operand" "=q")
! 	(lt (cc0) (const_int 0)))]
!   ""
!   "* cc_status = cc_prev_status;
!      OUTPUT_JUMP (\"setl %0\", \"setb %0\", \"sets %0\"); ")
! 
! (define_insn "sltu"
!   [(set (match_operand:QI 0 "general_operand" "=q")
! 	(ltu (cc0) (const_int 0)))]
!   ""
!   "* cc_status = cc_prev_status;
!      return \"setb %0\"; ")
! 
! (define_insn "sge"
!   [(set (match_operand:QI 0 "general_operand" "=q")
! 	(ge (cc0) (const_int 0)))]
!   ""
!   "* cc_status = cc_prev_status;
!      OUTPUT_JUMP (\"setge %0\", \"setae %0\", \"setns %0\"); ")
! 
! (define_insn "sgeu"
!   [(set (match_operand:QI 0 "general_operand" "=q")
! 	(geu (cc0) (const_int 0)))]
!   ""
!   "* cc_status = cc_prev_status;
!      return \"setae %0\"; ")
! 
! (define_insn "sle"
!   [(set (match_operand:QI 0 "general_operand" "=q")
! 	(le (cc0) (const_int 0)))]
!   ""
!   "*
!   cc_status = cc_prev_status;
!   OUTPUT_JUMP (\"setle %0\", \"setbe %0\", 0);
! ")
! 
! (define_insn "sleu"
!   [(set (match_operand:QI 0 "general_operand" "=q")
! 	(leu (cc0) (const_int 0)))]
!   ""
!   "* cc_status = cc_prev_status;
!      return \"setbe %0\"; ")
  \f


  ;; Basic conditional jump instructions.
  ;; We ignore the overflow flag for signed branch instructions.
  
  (define_insn "beq"
***************
*** 1710,1714 ****
  ;; (which must be a hard register).
  (define_insn "call_value"
!   [(set (match_operand 0 "" "rf")
  	(call (match_operand:QI 1 "indirect_operand" "m")
  	      (match_operand:SI 2 "general_operand" "g")))]
--- 1809,1813 ----
  ;; (which must be a hard register).
  (define_insn "call_value"
!   [(set (match_operand 0 "" "=rf")
  	(call (match_operand:QI 1 "indirect_operand" "m")
  	      (match_operand:SI 2 "general_operand" "g")))]
***************
*** 1721,1725 ****
      {
        operands[1] = XEXP (operands[1], 0);
!       return \"call %*%1\";
      }
    else
--- 1820,1824 ----
      {
        operands[1] = XEXP (operands[1], 0);
!       output_asm_insn (\"call %*%1\", operands);
      }
    else
***************
*** 1741,1749 ****
  }")
  
! (define_insn "return"
!   [(return)]
!   "0"
!   "ret")
! 
  \f


  ;;- Local variables:
--- 1840,1847 ----
  }")
  
! (define_insn "nop"
!   [(const_int 0)]
!   ""
!   "nop")
  \f


  ;;- Local variables:
diff -rc2N gcc-1.35/config/i860.md gcc-1.36/config/i860.md
*** gcc-1.35/config/i860.md	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config/i860.md	Tue Sep  5 14:20:52 1989
***************
*** 0 ****
--- 1,2021 ----
+ ;;- Machine description for Intel 860 chip for GNU C compiler
+ ;;   Copyright (C) 1989 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+ 
+ 
+ ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
+ 
+ ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
+ ;;- updates for most instructions.
+ 
+ ;;- Operand classes for the register allocator:
+ \f


+ /* Bit-test instructions.  */
+ 
+ (define_insn ""
+   [(set (cc0) (eq (and:SI (match_operand:SI 0 "register_operand" "r")
+ 			  (match_operand:SI 1 "logic_operand" "rL"))
+ 		  (const_int 0)))]
+   ""
+   "*
+ {
+   cc_status.flags |= CC_ONLY_EQ;
+   return \"and %1,%0,r0\";
+ }")
+ 
+ (define_insn ""
+   [(set (cc0) (ne (and:SI (match_operand:SI 0 "register_operand" "r")
+ 			  (match_operand:SI 1 "logic_operand" "rL"))
+ 		  (const_int 0)))]
+   ""
+   "*
+ {
+   cc_status.flags |= CC_NEGATED;
+   cc_status.flags |= CC_ONLY_EQ;
+   return \"and %1,%0,r0\";
+ }")
+ 
+ (define_insn ""
+   [(set (cc0) (eq (and:SI (match_operand:SI 0 "register_operand" "r")
+ 			  (match_operand:SI 1 "immediate_operand" "i"))
+ 		  (const_int 0)))]
+   "GET_CODE (operands[1]) == CONST_INT && (INTVAL (operands[1]) & 0xffff) == 0"
+   "*
+ {
+   cc_status.flags |= CC_ONLY_EQ;
+   return \"andh h%%%1,%0,r0\";
+ }")
+ 
+ (define_insn ""
+   [(set (cc0) (ne (and:SI (match_operand:SI 0 "register_operand" "r")
+ 			  (match_operand:SI 1 "immediate_operand" "i"))
+ 		  (const_int 0)))]
+   "GET_CODE (operands[1]) == CONST_INT && (INTVAL (operands[1]) & 0xffff) == 0"
+   "*
+ {
+   cc_status.flags |= CC_NEGATED;
+   cc_status.flags |= CC_ONLY_EQ;
+   return \"andh h%%%1,%0,r0\";
+ }")
+ 
+ (define_insn ""
+   [(set (cc0) (eq (ashiftrt:SI
+ 		   (sign_extend:SI
+ 		    (ashift:QI (match_operand:QI 0 "register_operand" "r")
+ 			       (match_operand:QI 1 "logic_int" "n")))
+ 		   (match_operand:SI 2 "logic_int" "n"))
+ 		  (const_int 0)))]
+   ""
+   "*
+ {
+   int width = 8 - INTVAL (operands[2]);
+   int pos = 8 - width - INTVAL (operands[1]);
+   operands[2] = gen_rtx (CONST_INT, VOIDmode,
+ 			 ~((-1) << width) << pos);
+   return \"and %2,%0,r0\";
+ }")
+ \f


+ ;; Compare instructions.
+ ;; This controls RTL generation and register allocation.
+ 
+ ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
+ 
+ (define_insn "cmpeqsi"
+   [(set (cc0) (eq (match_operand:SI 0 "logic_operand" "r,rL")
+ 		  (match_operand:SI 1 "logic_operand" "L,r")))]
+   ""
+   "*
+ {
+   cc_status.flags &= ~ CC_CONDITION_MASK;
+   cc_status.flags |= CC_ONLY_EQ;
+   if (REG_P (operands[0]))
+     return \"xor %1,%0,r0\";
+   return \"xor %0,%1,r0\";
+ }")
+ 
+ (define_insn "cmpltsi"
+   [(set (cc0) (lt (match_operand:SI 0 "arith_operand" "r,rI")
+ 		  (match_operand:SI 1 "arith_operand" "I,r")))]
+   ""
+   "*
+ {
+   cc_status.flags &= ~ CC_CONDITION_MASK;
+   cc_status.flags |= CC_ONLY_LT;
+   if (REG_P (operands[1]))
+     return \"subs %0,%1,r0\";
+   cc_status.flags |= CC_REVERSED;
+   operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1]));
+   return \"adds %1,%0,r0\";
+ }")
+ 
+ (define_insn "cmpgtsi"
+   [(set (cc0) (gt (match_operand:SI 0 "arith_operand" "r,rI")
+ 		  (match_operand:SI 1 "arith_operand" "I,r")))]
+   ""
+   "*
+ {
+   cc_status.flags &= ~ CC_CONDITION_MASK;
+   cc_status.flags |= CC_ONLY_LT;
+   if (REG_P (operands[0]))
+     return \"subs %1,%0,r0\";
+   cc_status.flags |= CC_REVERSED;
+   operands[0] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[0]));
+   return \"adds %0,%1,r0\";
+ }")
+ 
+ (define_insn "cmpgeusi"
+   [(set (cc0) (geu (match_operand:SI 0 "arith_operand" "r,rI")
+ 		   (match_operand:SI 1 "arith_operand" "I,r")))]
+   ""
+   "*
+ {
+   cc_status.flags &= ~ CC_CONDITION_MASK;
+   cc_status.flags |= CC_ONLY_LEU;
+   if (REG_P (operands[1]))
+     return \"subu %0,%1,r0\";
+   cc_status.flags |= CC_REVERSED;
+   operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1]));
+   return \"addu %1,%0,r0\";
+ }")
+ 
+ (define_insn "cmpleusi"
+   [(set (cc0) (leu (match_operand:SI 0 "arith_operand" "r,rI")
+ 		   (match_operand:SI 1 "arith_operand" "I,r")))]
+   ""
+   "*
+ {
+   cc_status.flags &= ~ CC_CONDITION_MASK;
+   cc_status.flags |= CC_ONLY_LEU;
+   if (REG_P (operands[0]))
+     return \"subu %1,%0,r0\";
+   cc_status.flags |= CC_REVERSED;
+   operands[0] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[0]));
+   return \"addu %0,%1,r0\";
+ }")
+ 
+ (define_insn "cmpeqsf"
+   [(set (cc0) (eq (match_operand:SF 0 "reg_or_0_operand" "fG")
+ 		  (match_operand:SF 1 "reg_or_0_operand" "fG")))]
+   ""
+   "*
+ {
+   cc_status.flags &= ~ CC_CONDITION_MASK;
+   cc_status.flags |= CC_ONLY_EQ;
+   return \"pfeq.s %r1,%r0\";
+ }")
+ 
+ (define_insn "cmpltsf"
+   [(set (cc0) (lt (match_operand:SF 0 "reg_or_0_operand" "fG")
+ 		  (match_operand:SF 1 "reg_or_0_operand" "fG")))]
+   ""
+   "*
+ {
+   cc_status.flags &= ~ CC_CONDITION_MASK;
+   cc_status.flags |= CC_ONLY_LT;
+   return \"pfgt.s %r1,%r0\";
+ }")
+ 
+ (define_insn "cmpgtsf"
+   [(set (cc0) (gt (match_operand:SF 0 "reg_or_0_operand" "fG")
+ 		  (match_operand:SF 1 "reg_or_0_operand" "fG")))]
+   ""
+   "*
+ {
+   cc_status.flags &= ~ CC_CONDITION_MASK;
+   cc_status.flags |= CC_ONLY_LT;
+   return \"pfgt.s %r0,%r1\";
+ }")
+ 
+ (define_insn "cmplesf"
+   [(set (cc0) (le (match_operand:SF 0 "reg_or_0_operand" "fG")
+ 		  (match_operand:SF 1 "reg_or_0_operand" "fG")))]
+   ""
+   "*
+ {
+   cc_status.flags &= ~ CC_CONDITION_MASK;
+   cc_status.flags |= CC_ONLY_LE;
+   return \"pfle.s %r1,%r0\";
+ }")
+ 
+ (define_insn "cmpgesf"
+   [(set (cc0) (ge (match_operand:SF 0 "reg_or_0_operand" "fG")
+ 		  (match_operand:SF 1 "reg_or_0_operand" "fG")))]
+   ""
+   "*
+ {
+   cc_status.flags &= ~ CC_CONDITION_MASK;
+   cc_status.flags |= CC_ONLY_LE;
+   return \"pfle.s %r0,%r1\";
+ }")
+ 
+ (define_insn "cmpeqdf"
+   [(set (cc0) (eq (match_operand:DF 0 "reg_or_0_operand" "fG")
+ 		  (match_operand:DF 1 "reg_or_0_operand" "fG")))]
+   ""
+   "*
+ {
+   cc_status.flags &= ~ CC_CONDITION_MASK;
+   cc_status.flags |= CC_ONLY_EQ;
+   return \"pfeq.d %r1,%r0\";
+ }")
+ 
+ (define_insn "cmpltdf"
+   [(set (cc0) (lt (match_operand:DF 0 "reg_or_0_operand" "fG")
+ 		  (match_operand:DF 1 "reg_or_0_operand" "fG")))]
+   ""
+   "*
+ {
+   cc_status.flags &= ~ CC_CONDITION_MASK;
+   cc_status.flags |= CC_ONLY_LT;
+   return \"pfgt.d %r1,%r0\";
+ }")
+ 
+ (define_insn "cmpgtdf"
+   [(set (cc0) (gt (match_operand:DF 0 "reg_or_0_operand" "fG")
+ 		  (match_operand:DF 1 "reg_or_0_operand" "fG")))]
+   ""
+   "*
+ {
+   cc_status.flags &= ~ CC_CONDITION_MASK;
+   cc_status.flags |= CC_ONLY_LT;
+   return \"pfgt.d %r0,%r1\";
+ }")
+ 
+ (define_insn "cmpledf"
+   [(set (cc0) (le (match_operand:DF 0 "reg_or_0_operand" "fG")
+ 		  (match_operand:DF 1 "reg_or_0_operand" "fG")))]
+   ""
+   "*
+ {
+   cc_status.flags &= ~ CC_CONDITION_MASK;
+   cc_status.flags |= CC_ONLY_LE;
+   return \"pfle.d %r1,%r0\";
+ }")
+ 
+ (define_insn "cmpgedf"
+   [(set (cc0) (ge (match_operand:DF 0 "reg_or_0_operand" "fG")
+ 		  (match_operand:DF 1 "reg_or_0_operand" "fG")))]
+   ""
+   "*
+ {
+   cc_status.flags &= ~ CC_CONDITION_MASK;
+   cc_status.flags |= CC_ONLY_LE;
+   return \"pfle.d %r0,%r1\";
+ }")
+ 
+ (define_insn ""
+   [(set (cc0) (eq (zero_extend:SI (match_operand:HI 0 "load_operand" "m"))
+ 	          (match_operand:SI 1 "small_int" "I")))]
+   "INTVAL (operands[1]) >= 0"
+   "ld.s %0,r31\;xor %1,r31,r0")
+ 
+ (define_insn ""
+   [(set (cc0) (eq (match_operand:SI 0 "small_int" "I")
+ 	          (zero_extend:SI (match_operand:HI 1 "load_operand" "m"))))]
+   "INTVAL (operands[0]) >= 0"
+   "ld.s %1,r31\;xor %0,r31,r0")
+ \f


+ ;; Define the real conditional branch instructions.
+ 
+ (define_insn "cbranch"
+   [(set (pc) (if_then_else (cc0) (label_ref (match_operand 0 "" "")) (pc)))]
+   ""
+   "*
+ {
+   if (cc_prev_status.flags & CC_NEGATED)
+     return \"bnc %l0\";
+   else
+     return \"bc %l0\";
+ }")
+ 
+ (define_insn "inverse_cbranch"
+   [(set (pc) (if_then_else (cc0) (pc) (label_ref (match_operand 0 "" ""))))]
+   ""
+   "*
+ {
+   if (cc_prev_status.flags & CC_NEGATED)
+     return \"bc %l0\";
+   else
+     return \"bnc %l0\";
+ }")
+ 
+ ;; Other conditional branches, made by combining.
+ 
+ (define_insn ""
+   [(set (pc) (if_then_else (eq (match_operand:SI 0 "bte_operand" "%rK")
+ 			       (match_operand:SI 1 "bte_operand" "rJ"))
+ 			   (label_ref (match_operand 2 "" ""))
+ 			   (pc)))]
+   "GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == REG"
+   "bte %0,%r1,%2")
+ 
+ (define_insn ""
+   [(set (pc) (if_then_else (eq (match_operand:SI 0 "bte_operand" "%rK")
+ 			       (match_operand:SI 1 "bte_operand" "rJ"))
+ 			   (pc)
+ 			   (label_ref (match_operand 2 "" ""))))]
+   "GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == REG"
+   "btne %0,%r1,%2")
+ 
+ ;; Optimize fetching an unsigned half word and comparing against constant.
+ ;; No need to zero-extend.
+ 
+ (define_insn ""
+   [(set (pc) (if_then_else (eq (zero_extend:SI (match_operand:HI 0 "load_operand" "m"))
+ 			       (match_operand:SI 1 "immediate_operand" "K"))
+ 			   (label_ref (match_operand 2 "" ""))
+ 			   (pc)))]
+   "GET_CODE (operands[1]) == CONST_INT
+    && INTVAL (operands[1]) < 0x10 && INTVAL (operands[1]) >= 0"
+   "ld.s %0,r31\;bte %1,r31,%2")
+ 
+ (define_insn ""
+   [(set (pc) (if_then_else (eq (match_operand:SI 0 "immediate_operand" "K")
+ 			       (zero_extend:SI (match_operand:HI 1 "load_operand" "m")))
+ 			   (label_ref (match_operand 2 "" ""))
+ 			   (pc)))]
+   "GET_CODE (operands[0]) == CONST_INT
+    && INTVAL (operands[0]) < 0x10 && INTVAL (operands[0]) >= 0"
+   "ld.s %1,r31\;bte %0,r31,%2")
+ 
+ (define_insn ""
+   [(set (pc) (if_then_else (eq (zero_extend:SI (match_operand:HI 0 "load_operand" "m"))
+ 			       (match_operand:SI 1 "immediate_operand" "K"))
+ 			   (pc)
+ 			   (label_ref (match_operand 2 "" ""))))]
+   "GET_CODE (operands[1]) == CONST_INT
+    && INTVAL (operands[1]) < 0x10 && INTVAL (operands[1]) >= 0"
+   "ld.s %0,r31\;btne %1,r31,%2")
+ 
+ (define_insn ""
+   [(set (pc) (if_then_else (eq (match_operand:SI 0 "immediate_operand" "K")
+ 			       (zero_extend:SI (match_operand:HI 1 "load_operand" "m")))
+ 			   (pc)
+ 			   (label_ref (match_operand 2 "" ""))))]
+   "GET_CODE (operands[0]) == CONST_INT
+    && INTVAL (operands[0]) < 0x10 && INTVAL (operands[0]) >= 0"
+   "ld.s %1,r31\;btne %0,r31,%2")
+ 
+ (define_insn ""
+   [(set (pc) (if_then_else (eq (zero_extend:SI (match_operand:QI 0 "load_operand" "m"))
+ 			       (match_operand:SI 1 "immediate_operand" "K"))
+ 			   (label_ref (match_operand 2 "" ""))
+ 			   (pc)))]
+   "GET_CODE (operands[1]) == CONST_INT
+    && INTVAL (operands[1]) < 0x10 && INTVAL (operands[1]) >= 0"
+   "ld.b %0,r31\;bte %1,r31,%2")
+ 
+ (define_insn ""
+   [(set (pc) (if_then_else (eq (match_operand:SI 0 "immediate_operand" "K")
+ 			       (zero_extend:SI (match_operand:QI 1 "load_operand" "m")))
+ 			   (label_ref (match_operand 2 "" ""))
+ 			   (pc)))]
+   "GET_CODE (operands[0]) == CONST_INT
+    && INTVAL (operands[0]) < 0x10 && INTVAL (operands[0]) >= 0"
+   "ld.b %1,r31\;bte %0,r31,%2")
+ 
+ (define_insn ""
+   [(set (pc) (if_then_else (eq (zero_extend:SI (match_operand:QI 0 "load_operand" "m"))
+ 			       (match_operand:SI 1 "immediate_operand" "K"))
+ 			   (pc)
+ 			   (label_ref (match_operand 2 "" ""))))]
+   "GET_CODE (operands[1]) == CONST_INT
+    && INTVAL (operands[1]) < 0x10 && INTVAL (operands[1]) >= 0"
+   "ld.b %0,r31\;btne %1,r31,%2")
+ 
+ (define_insn ""
+   [(set (pc) (if_then_else (eq (match_operand:SI 0 "immediate_operand" "K")
+ 			       (zero_extend:SI (match_operand:QI 1 "load_operand" "m")))
+ 			   (pc)
+ 			   (label_ref (match_operand 2 "" ""))))]
+   "GET_CODE (operands[0]) == CONST_INT
+    && INTVAL (operands[0]) < 0x10 && INTVAL (operands[0]) >= 0"
+   "ld.b %1,r31\;btne %0,r31,%2")
+ \f


+ ;; Generation of conditionals.
+ 
+ ;; The first step is the emission of a standard-looking compare insn.
+ ;; Then a standard-named conditional branch pattern is run.
+ ;; That branch pattern looks back at the compare insn and deletes it.
+ ;; It then emits a machine-specific compare insn and a branch-if-true
+ ;; or a branch-if-false.
+ 
+ ;; These patterns have `abort' because they are supposed to be deleted
+ ;; in that fashion.
+ 
+ (define_insn "cmpsi"
+   [(set (cc0) (compare (match_operand:SI 0 "compare_operand" "")
+ 		       (match_operand:SI 1 "compare_operand" "")))]
+   ""
+   "* abort ();")
+ 
+ (define_insn "cmpsf"
+   [(set (cc0) (compare (match_operand:SF 0 "register_operand" "")
+ 		       (match_operand:SF 1 "register_operand" "")))]
+   ""
+   "* abort ();")
+ 
+ (define_insn "cmpdf"
+   [(set (cc0) (compare (match_operand:DF 0 "register_operand" "")
+ 		       (match_operand:DF 1 "register_operand" "")))]
+   ""
+   "* abort ();")
+ 
+ ;; These are the standard-named conditional branch patterns.
+ ;; Detailed comments are found in the first one only.
+ 
+ (define_expand "beq"
+   [(set (pc)
+ 	(if_then_else (eq (cc0)
+ 			  (const_int 0))
+ 		      (label_ref (match_operand 0 "" ""))
+ 		      (pc)))]
+   ""
+   "
+ {
+   rtx label = operands[0];
+   enum insn_code code;
+   rtx prev;
+ 
+   /* Get out of the sequence just started for us.  */
+ 
+   end_sequence ();
+   prev = get_last_insn ();
+ 
+   /* Examine the preceding compare insn, and get rid of it.  */
+ 
+   code = recog_memoized (prev);
+   insn_extract (prev);
+   NEXT_INSN (PREV_INSN (prev)) = 0;
+   set_last_insn (PREV_INSN (prev));
+ 
+   /* Now once again start a sequence for our new instructions.  */
+ 
+   start_sequence ();
+ 
+   /* Emit a single-condition compare insn according to
+      the type of operands and the condition to be tested.  */
+ 
+   if (code == CODE_FOR_cmpsi)
+     emit_insn (gen_cmpeqsi (recog_operand[0], recog_operand[1]));
+   else if (code == CODE_FOR_cmpsf)
+     emit_insn (gen_cmpeqsf (recog_operand[0], recog_operand[1]));
+   else if (code == CODE_FOR_cmpdf)
+     emit_insn (gen_cmpeqdf (recog_operand[0], recog_operand[1]));
+   else
+     abort ();
+ 
+   /* Emit branch-if-true.  */
+ 
+   emit_jump_insn (gen_cbranch (label));
+ 
+   DONE;
+ }")
+ 
+ (define_expand "bne"
+   [(set (pc)
+ 	(if_then_else (ne (cc0)
+ 			  (const_int 0))
+ 		      (label_ref (match_operand 0 "" ""))
+ 		      (pc)))]
+   ""
+   "
+ {
+   rtx label = operands[0];
+   enum insn_code code;
+   rtx prev;
+ 
+   end_sequence ();
+   prev = get_last_insn ();
+ 
+   code = recog_memoized (prev);
+   insn_extract (prev);
+   NEXT_INSN (PREV_INSN (prev)) = 0;
+   set_last_insn (PREV_INSN (prev));
+   start_sequence ();
+ 
+   if (code == CODE_FOR_cmpsi)
+     emit_insn (gen_cmpeqsi (recog_operand[0], recog_operand[1]));
+   else if (code == CODE_FOR_cmpsf)
+     emit_insn (gen_cmpeqsf (recog_operand[0], recog_operand[1]));
+   else if (code == CODE_FOR_cmpdf)
+     emit_insn (gen_cmpeqdf (recog_operand[0], recog_operand[1]));
+   else
+     abort ();
+   emit_jump_insn (gen_inverse_cbranch (label));
+ 
+   DONE;
+ }")
+ 
+ (define_expand "bgt"
+   [(set (pc)
+ 	(if_then_else (gt (cc0)
+ 			  (const_int 0))
+ 		      (label_ref (match_operand 0 "" ""))
+ 		      (pc)))]
+   ""
+   "
+ {
+   rtx label = operands[0];
+   enum insn_code code;
+   rtx prev;
+ 
+   end_sequence ();
+   prev = get_last_insn ();
+ 
+   code = recog_memoized (prev);
+   insn_extract (prev);
+   NEXT_INSN (PREV_INSN (prev)) = 0;
+   set_last_insn (PREV_INSN (prev));
+   start_sequence ();
+ 
+   if (code == CODE_FOR_cmpsi)
+     emit_insn (gen_cmpgtsi (recog_operand[0], recog_operand[1]));
+   else if (code == CODE_FOR_cmpsf)
+     emit_insn (gen_cmpgtsf (recog_operand[0], recog_operand[1]));
+   else if (code == CODE_FOR_cmpdf)
+     emit_insn (gen_cmpgtdf (recog_operand[0], recog_operand[1]));
+   else
+     abort ();
+   emit_jump_insn (gen_cbranch (label));
+   DONE;
+ }")
+ 
+ (define_expand "blt"
+   [(set (pc)
+ 	(if_then_else (lt (cc0)
+ 			  (const_int 0))
+ 		      (label_ref (match_operand 0 "" ""))
+ 		      (pc)))]
+   ""
+   "
+ {
+   rtx label = operands[0];
+   enum insn_code code;
+   rtx prev;
+ 
+   end_sequence ();
+   prev = get_last_insn ();
+ 
+   code = recog_memoized (prev);
+   insn_extract (prev);
+   NEXT_INSN (PREV_INSN (prev)) = 0;
+   set_last_insn (PREV_INSN (prev));
+   start_sequence ();
+ 
+   if (code == CODE_FOR_cmpsi)
+     emit_insn (gen_cmpltsi (recog_operand[0], recog_operand[1]));
+   else if (code == CODE_FOR_cmpsf)
+     emit_insn (gen_cmpltsf (recog_operand[0], recog_operand[1]));
+   else if (code == CODE_FOR_cmpdf)
+     emit_insn (gen_cmpltdf (recog_operand[0], recog_operand[1]));
+   else
+     abort ();
+   emit_jump_insn (gen_cbranch (label));
+   DONE;
+ }")
+ 
+ (define_expand "ble"
+   [(set (pc)
+ 	(if_then_else (le (cc0)
+ 			  (const_int 0))
+ 		      (label_ref (match_operand 0 "" ""))
+ 		      (pc)))]
+   ""
+   "
+ {
+   rtx label = operands[0];
+   enum insn_code code;
+   rtx prev;
+ 
+   end_sequence ();
+   prev = get_last_insn ();
+ 
+   code = recog_memoized (prev);
+   insn_extract (prev);
+   NEXT_INSN (PREV_INSN (prev)) = 0;
+   set_last_insn (PREV_INSN (prev));
+   start_sequence ();
+ 
+   if (code == CODE_FOR_cmpsi)
+     {
+       emit_insn (gen_cmpgtsi (recog_operand[0], recog_operand[1]));
+       emit_jump_insn (gen_inverse_cbranch (label));
+     }
+   else
+     {
+       if (code == CODE_FOR_cmpsf)
+ 	emit_insn (gen_cmplesf (recog_operand[0], recog_operand[1]));
+       else if (code == CODE_FOR_cmpdf)
+ 	emit_insn (gen_cmpledf (recog_operand[0], recog_operand[1]));
+       else
+ 	abort ();
+       emit_jump_insn (gen_cbranch (label));
+     }
+   DONE;
+ }")
+ 
+ (define_expand "bge"
+   [(set (pc)
+ 	(if_then_else (ge (cc0)
+ 			  (const_int 0))
+ 		      (label_ref (match_operand 0 "" ""))
+ 		      (pc)))]
+   ""
+   "
+ {
+   rtx label = operands[0];
+   enum insn_code code;
+   rtx prev;
+ 
+   end_sequence ();
+   prev = get_last_insn ();
+ 
+   code = recog_memoized (prev);
+   insn_extract (prev);
+   NEXT_INSN (PREV_INSN (prev)) = 0;
+   set_last_insn (PREV_INSN (prev));
+   start_sequence ();
+ 
+   if (code == CODE_FOR_cmpsi)
+     {
+       emit_insn (gen_cmpltsi (recog_operand[0], recog_operand[1]));
+       emit_jump_insn (gen_inverse_cbranch (label));
+     }
+   else
+     {
+       if (code == CODE_FOR_cmpsf)
+ 	emit_insn (gen_cmpgesf (recog_operand[0], recog_operand[1]));
+       else if (code == CODE_FOR_cmpdf)
+ 	emit_insn (gen_cmpgedf (recog_operand[0], recog_operand[1]));
+       else
+         abort ();
+       emit_jump_insn (gen_cbranch (label));
+     }
+   DONE;
+ }")
+ 
+ (define_expand "bgtu"
+   [(set (pc)
+ 	(if_then_else (gtu (cc0)
+ 			   (const_int 0))
+ 		      (label_ref (match_operand 0 "" ""))
+ 		      (pc)))]
+   ""
+   "
+ {
+   rtx label = operands[0];
+   enum insn_code code;
+   rtx prev;
+ 
+   end_sequence ();
+   prev = get_last_insn ();
+ 
+   code = recog_memoized (prev);
+   insn_extract (prev);
+   NEXT_INSN (PREV_INSN (prev)) = 0;
+   set_last_insn (PREV_INSN (prev));
+   start_sequence ();
+ 
+   if (code == CODE_FOR_cmpsi)
+     emit_insn (gen_cmpleusi (recog_operand[0], recog_operand[1]));
+   else
+     abort ();
+   emit_jump_insn (gen_inverse_cbranch (label));
+   DONE;
+ }")
+ 
+ (define_expand "bltu"
+   [(set (pc)
+ 	(if_then_else (ltu (cc0)
+ 			   (const_int 0))
+ 		      (label_ref (match_operand 0 "" ""))
+ 		      (pc)))]
+   ""
+   "
+ {
+   rtx label = operands[0];
+   enum insn_code code;
+   rtx prev;
+ 
+   end_sequence ();
+   prev = get_last_insn ();
+ 
+   code = recog_memoized (prev);
+   insn_extract (prev);
+   NEXT_INSN (PREV_INSN (prev)) = 0;
+   set_last_insn (PREV_INSN (prev));
+   start_sequence ();
+ 
+   if (code == CODE_FOR_cmpsi)
+     emit_insn (gen_cmpgeusi (recog_operand[0], recog_operand[1]));
+   else
+     abort ();
+   emit_jump_insn (gen_inverse_cbranch (label));
+   DONE;
+ }")
+ 
+ (define_expand "bgeu"
+   [(set (pc)
+ 	(if_then_else (geu (cc0)
+ 			   (const_int 0))
+ 		      (label_ref (match_operand 0 "" ""))
+ 		      (pc)))]
+   ""
+   "
+ {
+   rtx label = operands[0];
+   enum insn_code code;
+   rtx prev;
+ 
+   end_sequence ();
+   prev = get_last_insn ();
+ 
+   code = recog_memoized (prev);
+   insn_extract (prev);
+   NEXT_INSN (PREV_INSN (prev)) = 0;
+   set_last_insn (PREV_INSN (prev));
+   start_sequence ();
+ 
+   if (code == CODE_FOR_cmpsi)
+     emit_insn (gen_cmpgeusi (recog_operand[0], recog_operand[1]));
+   else
+     abort ();
+   emit_jump_insn (gen_cbranch (label));
+   DONE;
+ }")
+ 
+ (define_expand "bleu"
+   [(set (pc)
+ 	(if_then_else (leu (cc0)
+ 			   (const_int 0))
+ 		      (label_ref (match_operand 0 "" ""))
+ 		      (pc)))]
+   ""
+   "
+ {
+   rtx label = operands[0];
+   enum insn_code code;
+   rtx prev;
+ 
+   end_sequence ();
+   prev = get_last_insn ();
+ 
+   code = recog_memoized (prev);
+   insn_extract (prev);
+   NEXT_INSN (PREV_INSN (prev)) = 0;
+   set_last_insn (PREV_INSN (prev));
+   start_sequence ();
+ 
+   if (code == CODE_FOR_cmpsi)
+     emit_insn (gen_cmpleusi (recog_operand[0], recog_operand[1]));
+   else
+     abort ();
+   emit_jump_insn (gen_cbranch (label));
+   DONE;
+ }")
+ \f


+ ;; Move instructions
+ 
+ (define_insn "movsi"
+   [(set (match_operand:SI 0 "general_operand" "=r,m,f")
+ 	(match_operand:SI 1 "general_operand" "rmif,rfJ,rmfJ"))]
+   ""
+   "*
+ {
+   if (GET_CODE (operands[0]) == MEM)
+     {
+       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
+ 	return output_store (operands);
+       if (FP_REG_P (operands[1]))
+ 	return \"fst.l %1,%0\";
+       return \"st.l %r1,%0\";
+     }
+   if (GET_CODE (operands[1]) == MEM)
+     {
+       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
+ 	return output_load (operands);
+       if (FP_REG_P (operands[0]))
+ 	return \"fld.l %1,%0\";
+       return \"ld.l %1,%0\";
+     }
+   if (FP_REG_P (operands[1]) && FP_REG_P (operands[0]))
+     return \"fmov.ss %1,%0\";
+   if (FP_REG_P (operands[1]))
+     return \"fxfr %1,%0\";
+   if (FP_REG_P (operands[0]) && operands[1] == const0_rtx)
+     return \"fmov.ss f0,%0\";
+   if (FP_REG_P (operands[0]))
+     return \"ixfr %1,%0\";
+   return \"mov %1,%0\";
+ }")
+ 
+ (define_insn "movhi"
+   [(set (match_operand:HI 0 "general_operand" "=r,m")
+ 	(match_operand:HI 1 "general_operand" "rmi,rJ"))]
+   ""
+   "*
+ {
+   if (GET_CODE (operands[0]) == MEM)
+     {
+       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
+ 	return output_store (operands);
+       return \"st.s %r1,%0\";
+     }
+   if (GET_CODE (operands[1]) == MEM)
+     {
+       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
+ 	return output_load (operands);
+       return \"ld.s %1,%0\";
+     }
+   return \"mov %1,%0\";
+ }")
+ 
+ (define_insn "movqi"
+   [(set (match_operand:QI 0 "general_operand" "=r,m")
+ 	(match_operand:QI 1 "general_operand" "rmi,rJ"))]
+   ""
+   "*
+ {
+   if (GET_CODE (operands[0]) == MEM)
+     {
+       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
+ 	return output_store (operands);
+       return \"st.b %r1,%0\";
+     }
+   if (GET_CODE (operands[1]) == MEM)
+     {
+       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
+ 	return output_load (operands);
+       return \"ld.b %1,%0\";
+     }
+   return \"mov %1,%0\";
+ }")
+ 
+ ;; The definition of this insn does not really explain what it does,
+ ;; but it should suffice
+ ;; that anything generated as this insn will be recognized as one
+ ;; and that it won't successfully combine with anything.
+ (define_expand "movstrsi"
+   [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
+ 		   (mem:BLK (match_operand:BLK 1 "general_operand" "")))
+ 	      (use (match_operand:SI 2 "nonmemory_operand" ""))
+ 	      (use (match_operand:SI 3 "immediate_operand" ""))
+ 	      (clobber (match_dup 4))
+ 	      (clobber (match_dup 5))
+ 	      (clobber (match_dup 6))
+ 	      (clobber (match_dup 0))
+ 	      (clobber (match_dup 1))])]
+   ""
+   "
+ {
+   operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
+   operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
+   operands[4] = gen_reg_rtx (SImode);
+   operands[5] = gen_reg_rtx (SImode);
+   operands[6] = gen_reg_rtx (SImode);
+ }")
+ 
+ (define_insn ""
+   [(set (mem:BLK (match_operand:SI 0 "register_operand" "r"))
+ 	(mem:BLK (match_operand:SI 1 "register_operand" "r")))
+    (use (match_operand:SI 2 "nonmemory_operand" "rn"))
+    (use (match_operand:SI 3 "immediate_operand" "i"))
+    (clobber (match_operand:SI 4 "register_operand" "=r"))
+    (clobber (match_operand:SI 5 "register_operand" "=r"))
+    (clobber (match_operand:SI 6 "register_operand" "=r"))
+    (clobber (match_dup 0))
+    (clobber (match_dup 1))]
+   ""
+   "* return output_block_move (operands);")
+ \f


+ ;; Floating point move insns
+ 
+ ;; This pattern forces (set (reg:DF ...) (const_double ...))
+ ;; to be reloaded by putting the constant into memory.
+ ;; It must come before the more general movdf pattern.
+ (define_insn ""
+   [(set (match_operand:DF 0 "general_operand" "=r,f,o")
+ 	(match_operand:DF 1 "" "mG,m,G"))]
+   "GET_CODE (operands[1]) == CONST_DOUBLE"
+   "*
+ {
+   if (FP_REG_P (operands[0]))
+     return output_fp_move_double (operands);
+   if (operands[1] == dconst0_rtx && GET_CODE (operands[0]) == REG)
+     {
+       operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+       return \"mov r0,%0\;mov r0,%1\";
+     }
+   if (operands[1] == dconst0_rtx && GET_CODE (operands[0]) == MEM)
+     {
+       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
+ 	{
+ 	  if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
+ 		 && (cc_prev_status.flags & CC_HI_R31_ADJ)
+ 		 && XEXP (operands[0], 0) == cc_prev_status.mdep))
+ 	    {
+ 	      cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
+ 	      cc_status.mdep = XEXP (operands[0], 0);
+ 	      output_asm_insn (\"orh ha%%%m0,r0,r31\", operands);
+ 	    }
+ 	  return \"st.l r0,l%%%%m0(r31)\;st.l r0,l%%%%m0+4(r31)\";
+ 	}
+       operands[1] = adj_offsettable_operand (operands[0], 4);
+       return \"st.l r0,%0\;st.l r0,%1\";
+     }
+   return output_move_double (operands);
+ }")
+ 
+ (define_insn "movdf"
+   [(set (match_operand:DF 0 "general_operand" "=*rm,&*r,?f,?*rm")
+ 	(match_operand:DF 1 "general_operand" "*r,m,*rfmG,f"))]
+   ""
+   "*
+ {
+   if (GET_CODE (operands[0]) == MEM
+       && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
+     return output_store (operands);
+   if (GET_CODE (operands[1]) == MEM
+       && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
+     return output_load (operands);
+ 
+   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
+     return output_fp_move_double (operands);
+   return output_move_double (operands);
+ }")
+ 
+ (define_insn "movdi"
+   [(set (match_operand:DI 0 "general_operand" "=rm,&r,?f,?rm")
+ 	(match_operand:DI 1 "general_operand" "r,mi,rfm,f"))]
+   ""
+   "*
+ {
+   if (GET_CODE (operands[0]) == MEM
+       && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
+     return output_store (operands);
+   if (GET_CODE (operands[1]) == MEM
+       && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
+     return output_load (operands);
+ 
+   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
+     return output_fp_move_double (operands);
+   return output_move_double (operands);
+ }")
+ 
+ (define_insn "movsf"
+   [(set (match_operand:SF 0 "general_operand" "=*rf,m")
+ 	(match_operand:SF 1 "general_operand" "*rfmG,*rf"))]
+   ""
+   "*
+ {
+   if (GET_CODE (operands[0]) == MEM
+       && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
+     return output_store (operands);
+   if (GET_CODE (operands[1]) == MEM
+       && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
+     return output_load (operands);
+   if (FP_REG_P (operands[0]))
+     {
+       if (FP_REG_P (operands[1]))
+ 	return \"fmov.ss %1,%0\";
+       if (GET_CODE (operands[1]) == REG)
+ 	return \"ixfr %1,%0\";
+       if (operands[1] == fconst0_rtx)
+         return \"fmov.ss f0,%0\";
+       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
+ 	{
+ 	  cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
+ 	  cc_status.mdep = XEXP (operands[1], 0);
+ 	  return \"orh ha%%%m1,r0,r31\;fld.l l%%%m1(r31),%0\";
+ 	}
+       return \"fld.l %1,%0\";
+     }
+   if (FP_REG_P (operands[1]))
+     {
+       if (GET_CODE (operands[0]) == REG)
+ 	return \"fxfr %1,%0\";
+       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
+ 	{
+ 	  if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
+ 		 && (cc_prev_status.flags & CC_HI_R31_ADJ)
+ 		 && XEXP (operands[0], 0) == cc_prev_status.mdep))
+ 	    {
+ 	      cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
+ 	      cc_status.mdep = XEXP (operands[0], 0);
+ 	      output_asm_insn (\"orh ha%%%m0,r0,r31\", operands);
+ 	    }
+ 	  return \"fst.l %r1,l%%%m0(r31)\";
+ 	}
+       return \"fst.l %r1,%0\";
+     }
+   if (GET_CODE (operands[0]) == MEM)
+     return \"st.l %r1,%0\";
+   if (GET_CODE (operands[1]) == MEM)
+     return \"ld.l %1,%0\";
+   if (operands[1] == fconst0_rtx)
+     return \"mov r0,%0\";
+   return \"mov %1,%0\";
+ }")
+ \f


+ ;; Special load insns for REG+REG addresses.
+ ;; Such addresses are not "legitimate" because st rejects them.
+ 
+ (define_insn ""
+   [(set (match_operand:DF 0 "register_operand" "rf")
+ 	(match_operand:DF 1 "indexed_operand" "m"))]
+   ""
+   "*
+ {
+   if (FP_REG_P (operands[0]))
+     return output_fp_move_double (operands);
+   return output_move_double (operands);
+ }")
+ 
+ (define_insn ""
+   [(set (match_operand:SF 0 "register_operand" "rf")
+ 	(match_operand:SF 1 "indexed_operand" "m"))]
+   ""
+   "*
+ {
+   if (FP_REG_P (operands[0]))
+     return \"fld.l %1,%0\";
+   return \"ld.l %1,%0\";
+ }")
+ 
+ (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "rf")
+ 	(match_operand:SI 1 "indexed_operand" "m"))]
+   ""
+   "*
+ {
+   if (FP_REG_P (operands[0]))
+     return \"fld.l %1,%0\";
+   return \"ld.l %1,%0\";
+ }")
+ 
+ (define_insn ""
+   [(set (match_operand:HI 0 "register_operand" "r")
+ 	(match_operand:HI 1 "indexed_operand" "m"))]
+   ""
+   "ld.s %1,%0")
+ 
+ (define_insn ""
+   [(set (match_operand:QI 0 "register_operand" "r")
+ 	(match_operand:QI 1 "indexed_operand" "m"))]
+   ""
+   "ld.b %1,%0")
+ 
+ ;; Likewise for floating-point store insns.
+ 
+ (define_insn ""
+   [(set (match_operand:DF 0 "indexed_operand" "m")
+ 	(match_operand:DF 1 "register_operand" "f"))]
+   ""
+   "fst.d %1,%0")
+ 
+ (define_insn ""
+   [(set (match_operand:SF 0 "indexed_operand" "m")
+ 	(match_operand:SF 1 "register_operand" "f"))]
+   ""
+   "fst.l %1,%0")
+ \f


+ ;;- truncation instructions
+ (define_insn "truncsiqi2"
+   [(set (match_operand:QI 0 "general_operand" "=g")
+ 	(truncate:QI
+ 	 (match_operand:SI 1 "register_operand" "r")))]
+   ""
+   "*
+ {
+   if (GET_CODE (operands[0]) == MEM)
+     if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
+       {
+ 	if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
+ 	       && (cc_prev_status.flags & CC_HI_R31_ADJ)
+ 	       && XEXP (operands[0], 0) == cc_prev_status.mdep))
+ 	  {
+ 	    cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
+ 	    cc_status.mdep = XEXP (operands[0], 0);
+ 	    output_asm_insn (\"orh ha%%%m0,r0,r31\", operands);
+ 	  }
+ 	return \"st.b %1,l%%%m0(r31)\";
+       }
+     else
+       return \"st.b %1,%0\";
+   return \"mov %1,%0\";
+ }")
+ 
+ (define_insn "trunchiqi2"
+   [(set (match_operand:QI 0 "general_operand" "=g")
+ 	(truncate:QI
+ 	 (match_operand:HI 1 "register_operand" "r")))]
+   ""
+   "*
+ {
+   if (GET_CODE (operands[0]) == MEM)
+     if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
+       {
+ 	if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
+ 	       && (cc_prev_status.flags & CC_HI_R31_ADJ)
+ 	       && XEXP (operands[0], 0) == cc_prev_status.mdep))
+ 	  {
+ 	    cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
+ 	    cc_status.mdep = XEXP (operands[0], 0);
+ 	    output_asm_insn (\"orh ha%%%m0,r0,r31\", operands);
+ 	  }
+ 	return \"st.b %1,l%%%m0(r31)\";
+       }
+     else
+       return \"st.b %1,%0\";
+   return \"mov %1,%0\";
+ }")
+ 
+ (define_insn "truncsihi2"
+   [(set (match_operand:HI 0 "general_operand" "=g")
+ 	(truncate:HI
+ 	 (match_operand:SI 1 "register_operand" "r")))]
+   ""
+   "*
+ {
+   if (GET_CODE (operands[0]) == MEM)
+     if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
+       {
+ 	if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
+ 	       && (cc_prev_status.flags & CC_HI_R31_ADJ)
+ 	       && XEXP (operands[0], 0) == cc_prev_status.mdep))
+ 	  {
+ 	    cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
+ 	    cc_status.mdep = XEXP (operands[0], 0);
+ 	    output_asm_insn (\"orh ha%%%m0,r0,r31\", operands);
+ 	  }
+ 	return \"st.s %1,l%%%m0(r31)\";
+       }
+     else
+       return \"st.s %1,%0\";
+   return \"mov %1,%0\";
+ }")
+ \f


+ ;;- zero extension instructions
+ 
+ ;; Note that the one starting from HImode comes before those for QImode
+ ;; so that a constant operand will match HImode, not QImode.
+ 
+ (define_insn "zero_extendhisi2"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(zero_extend:SI
+ 	 (match_operand:HI 1 "register_operand" "r")))]
+   ""
+   "and 0xffff,%1,%0")
+ 
+ (define_insn "zero_extendqihi2"
+   [(set (match_operand:HI 0 "register_operand" "=r")
+ 	(zero_extend:HI
+ 	 (match_operand:QI 1 "register_operand" "r")))]
+   ""
+   "and 0xff,%1,%0")
+ 
+ (define_insn "zero_extendqisi2"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(zero_extend:SI
+ 	 (match_operand:QI 1 "register_operand" "r")))]
+   ""
+   "and 0xff,%1,%0")
+ \f


+ ;;- sign extension instructions
+ ;; Note that the one starting from HImode comes before those for QImode
+ ;; so that a constant operand will match HImode, not QImode.
+ 
+ (define_insn "extendhisi2"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(sign_extend:SI
+ 	 (match_operand:HI 1 "general_operand" "mr")))]
+   ""
+   "*
+ {
+   if (REG_P (operands[1]))
+     return \"shl 16,%1,%0\;shra 16,%0,%0\";
+   if (GET_CODE (operands[1]) == CONST_INT)
+     abort ();
+   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
+     {
+       cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
+       cc_status.mdep = XEXP (operands[1], 0);
+       return \"orh ha%%%m1,r0,r31\;ld.s l%%%m1(r31),%0\";
+     }
+   else
+     return \"ld.s %1,%0\";
+ }")
+ 
+ (define_insn "extendqihi2"
+   [(set (match_operand:HI 0 "register_operand" "=r")
+ 	(sign_extend:HI
+ 	 (match_operand:QI 1 "general_operand" "mr")))]
+   ""
+   "*
+ {
+   if (REG_P (operands[1]))
+     return \"shl 24,%1,%0\;shra 24,%0,%0\";
+   if (GET_CODE (operands[1]) == CONST_INT)
+     abort ();
+   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
+     {
+       cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
+       cc_status.mdep = XEXP (operands[1], 0);
+       return \"orh ha%%%m1,r0,r31\;ld.b l%%%m1(r31),%0\";
+     }
+   else
+     return \"ld.b %1,%0\";
+ }")
+ 
+ (define_insn "extendqisi2"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(sign_extend:SI
+ 	 (match_operand:QI 1 "general_operand" "mr")))]
+   ""
+   "*
+ {
+   if (REG_P (operands[1]))
+     return \"shl 24,%1,%0\;shra 24,%0,%0\";
+   if (GET_CODE (operands[1]) == CONST_INT)
+     abort ();
+   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
+     {
+       cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
+       cc_status.mdep = XEXP (operands[1], 0);
+       return \"orh ha%%%m1,r0,r31\;ld.b l%%%m1(r31),%0\";
+     }
+   else
+     return \"ld.b %1,%0\";
+ }")
+ 
+ (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(sign_extend:SI
+ 	 (match_operand:HI 1 "indexed_operand" "m")))]
+   ""
+   "ld.s %1,%0")
+ 
+ (define_insn ""
+   [(set (match_operand:HI 0 "register_operand" "=r")
+ 	(sign_extend:HI
+ 	 (match_operand:QI 1 "indexed_operand" "m")))]
+   ""
+   "ld.b %1,%0")
+ 
+ (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(sign_extend:SI
+ 	 (match_operand:QI 1 "indexed_operand" "m")))]
+   ""
+   "ld.b %1,%0")
+ 
+ ;; Signed bitfield extractions come out looking like
+ ;;	(shiftrt (sign_extend (shift <Y> <C1>)) <C2>)
+ ;; which we expand poorly as four shift insns.
+ ;; These patters yeild two shifts:
+ ;;	(shiftrt (shift <Y> <C3>) <C4>)
+ (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(ashiftrt:SI
+ 	 (sign_extend:SI
+ 	  (match_operand:QI 1 "register_operand" "r"))
+ 	 (match_operand:SI 2 "logic_int" "n")))]
+   ""
+   "*
+ {
+   return \"shl 24,%1,%0\;shra 24+%2,%0,%0\";
+ }")
+ 
+ (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(ashiftrt:SI
+ 	 (sign_extend:SI
+ 	  (subreg:QI (ashift:SI (match_operand:SI 1 "register_operand" "r")
+ 				(match_operand:SI 2 "logic_int" "n")) 0))
+ 	 (match_operand:SI 3 "logic_int" "n")))]
+   ""
+   "*
+ {
+   return \"shl 0x18+%2,%1,%0\;shra 0x18+%3,%0,%0\";
+ }")
+ 
+ (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(ashiftrt:SI
+ 	 (sign_extend:SI
+ 	  (ashift:QI (match_operand:QI 1 "register_operand" "r")
+ 		     (match_operand:QI 2 "logic_int" "n")))
+ 	 (match_operand:SI 3 "logic_int" "n")))]
+   ""
+   "*
+ {
+   return \"shl 0x18+%2,%1,%0\;shra 0x18+%3,%0,%0\";
+ }")
+ \f


+ ;; Special patterns for optimizing bit-field instructions.
+ 
+ ;; First two patterns are for bitfields that came from memory
+ ;; testing only the high bit.  They work with old combiner.
+ 
+ (define_insn ""
+   [(set (cc0)
+ 	(eq (zero_extend:SI (subreg:QI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r")
+ 						    (const_int 7)) 0))
+ 	    (const_int 0)))]
+   ""
+   "and 128,%0,r0")
+ 
+ (define_insn ""
+   [(set (cc0)
+ 	(eq (sign_extend:SI (subreg:QI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r")
+ 						    (const_int 7)) 0))
+ 	    (const_int 0)))]
+   ""
+   "and 128,%0,r0")
+ 
+ ;; next two patterns are good for bitfields coming from memory
+ ;; (via pseudo-register) or from a register, though this optimization
+ ;; is only good for values contained wholly within the bottom 13 bits
+ (define_insn ""
+   [(set (cc0)
+ 	(eq 
+ 	 (and:SI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r")
+ 			      (match_operand:SI 1 "logic_int" "n"))
+ 		 (match_operand:SI 2 "logic_int" "n"))
+ 	 (const_int 0)))]
+   "LOGIC_INTVAL (INTVAL (operands[2]) << INTVAL (operands[1]))"
+   "*
+ {
+   operands[2] = gen_rtx (CONST_INT, VOIDmode,
+ 			 (INTVAL (operands[2]) << INTVAL (operands[1])));
+   return \"and %2,%0,r0\";
+ }")
+ 
+ (define_insn ""
+   [(set (cc0)
+ 	(eq 
+ 	 (and:SI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r")
+ 			      (match_operand:SI 1 "logic_int" "n"))
+ 		 (match_operand:SI 2 "logic_int" "n"))
+ 	 (const_int 0)))]
+   "LOGIC_INTVAL (INTVAL (operands[2]) << INTVAL (operands[1]))"
+   "*
+ {
+   operands[2] = gen_rtx (CONST_INT, VOIDmode,
+ 			 (INTVAL (operands[2]) << INTVAL (operands[1])));
+   return \"and %2,%0,r0\";
+ }")
+ \f


+ ;; Conversions between float and double.
+ 
+ (define_insn "extendsfdf2"
+   [(set (match_operand:DF 0 "register_operand" "=f")
+ 	(float_extend:DF
+ 	 (match_operand:SF 1 "register_operand" "f")))]
+   ""
+   "fmov.sd %1,%0")
+ 
+ (define_insn "truncdfsf2"
+   [(set (match_operand:SF 0 "register_operand" "=f")
+ 	(float_truncate:SF
+ 	 (match_operand:DF 1 "register_operand" "f")))]
+   ""
+   "fmov.ds %1,%0")
+ \f


+ ;; Conversion between fixed point and floating point.
+ ;; Note that among the fix-to-float insns
+ ;; the ones that start with SImode come first.
+ ;; That is so that an operand that is a CONST_INT
+ ;; (and therefore lacks a specific machine mode).
+ ;; will be recognized as SImode (which is always valid)
+ ;; rather than as QImode or HImode.
+ 
+ ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
+ ;; to be reloaded by putting the constant into memory.
+ ;; It must come before the more general floatsisf2 pattern.
+ (define_expand "floatsidf2"
+   [(set (match_dup 2) (match_dup 3))
+    (set (match_dup 4) (xor:SI (match_operand:SI 1 "register_operand" "")
+ 			      (const_int -2147483648)))
+    (set (subreg:SI (match_dup 5) 1) (match_dup 4))
+    (set (subreg:SI (match_dup 5) 0) (subreg:SI (match_dup 2) 0))
+    (set (match_operand:DF 0 "register_operand" "")
+ 	(minus:DF (match_dup 5) (match_dup 2)))]
+   ""
+   "
+ {
+   /* Generate desired value, in float format of host machine.  */
+   double d = (double) (1 << 30) * ((double) (1 << 22) + (double) (1 << 1));
+   operands[2] = gen_reg_rtx (DFmode);
+   operands[3] = immed_double_const (d, DFmode);
+   operands[4] = gen_reg_rtx (SImode);
+   operands[5] = gen_reg_rtx (DFmode);
+ }")
+ \f


+ ;; Floating to fixed conversion.
+ 
+ (define_expand "fix_truncdfsi2"
+   ;; This first insn produces a double-word value
+   ;; in which only the low word is valid.
+   [(set (match_dup 2)
+ 	(fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
+    (set (match_operand:SI 0 "register_operand" "=f")
+ 	(subreg:SI (match_dup 2) 0))]
+   ""
+   "
+ {
+   operands[2] = gen_reg_rtx (DImode);
+ }")
+ 
+ ;; Recognize the first insn generated above.
+ ;; This RTL looks like a fix_truncdfdi2 insn,
+ ;; but we dont call it that, because only 32 bits
+ ;; of the result are valid.
+ ;; This pattern will work for the intended purposes 
+ ;; as long as we do not have any fixdfdi2 or fix_truncdfdi2.
+ (define_insn ""
+   [(set (match_operand:DI 0 "register_operand" "=f")
+ 	(fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
+   ""
+   "ftrunc.dd %1,%0")
+ 
+ (define_expand "fix_truncsfsi2"
+   ;; This first insn produces a double-word value
+   ;; in which only the low word is valid.
+   [(set (match_dup 2)
+ 	(fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
+    (set (match_operand:SI 0 "register_operand" "=f")
+ 	(subreg:SI (match_dup 2) 0))]
+   ""
+   "
+ {
+   operands[2] = gen_reg_rtx (DImode);
+ }")
+ 
+ ;; Recognize the first insn generated above.
+ ;; This RTL looks like a fix_truncsfdi2 insn,
+ ;; but we dont call it that, because only 32 bits
+ ;; of the result are valid.
+ ;; This pattern will work for the intended purposes 
+ ;; as long as we do not have any fixsfdi2 or fix_truncsfdi2.
+ (define_insn ""
+   [(set (match_operand:DI 0 "register_operand" "=f")
+ 	(fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
+   ""
+   "ftrunc.sd %1,%0")
+ \f


+ ;;- arithmetic instructions
+ 
+ (define_insn "addsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r,*f")
+ 	(plus:SI (match_operand:SI 1 "nonmemory_operand" "%r,*f")
+ 		 (match_operand:SI 2 "nonmemory_operand" "rn,*f")))]
+   ""
+   "*
+ {
+   if (which_alternative == 1)
+     return \"fiadd.ss %2,%1,%0\";
+   if (REG_P (operands[2]))
+     return \"addu %2,%1,%0\";
+   if (SMALL_INT (operands[2]))
+     return \"addu %2,%1,%0\";
+   cc_status.flags &= ~CC_KNOW_HI_R31;
+   return \"orh h%%%2,r0,r31\;or l%%%2,r31,r31\;addu %1,r31,%0\";
+ }")
+ 
+ (define_insn "adddi3"
+   [(set (match_operand:DI 0 "register_operand" "=f")
+ 	(plus:DI (match_operand:DI 1 "register_operand" "%f")
+ 		 (match_operand:DI 2 "register_operand" "f")))]
+   ""
+   "fiadd.ss %1,%2,%0")
+ 
+ (define_insn "subsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r,r,*f")
+ 	(minus:SI (match_operand:SI 1 "register_operand" "r,I,*f")
+ 		  (match_operand:SI 2 "nonmemory_operand" "rn,r,*f")))]
+   ""
+   "*
+ {
+   if (which_alternative == 2)
+     return \"fisub.ss %1,%2,%0\";
+   if (REG_P (operands[2]))
+     return \"subu %1,%2,%0\";
+   if (SMALL_INT (operands[2]) && INTVAL (operands[2]) != -0x10000)
+     {
+       operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]));
+       return \"addu %2,%1,%0\";
+     }
+   cc_status.flags &= ~CC_KNOW_HI_R31;
+   return \"orh h%%%2,r0,r31\;or l%%%2,r31,r31\;sub %1,r31,%0\";
+ }")
+ 
+ (define_insn "subdi3"
+   [(set (match_operand:DI 0 "register_operand" "=f")
+ 	(minus:DI (match_operand:DI 1 "register_operand" "%f")
+ 		  (match_operand:DI 2 "register_operand" "f")))]
+   ""
+   "fisub.ss %1,%2,%0")
+ 
+ (define_expand "mulsi3"
+   [(set (subreg:SI (match_dup 4) 0) (match_operand:SI 1 "general_operand" ""))
+    (set (subreg:SI (match_dup 5) 0) (match_operand:SI 2 "general_operand" ""))
+    (clobber (match_dup 3))
+    (set (subreg:SI (match_dup 3) 0)
+ 	(mult:SI (subreg:SI (match_dup 4) 0) (subreg:SI (match_dup 5) 0)))
+    (set (match_operand:SI 0 "register_operand" "") (subreg:SI (match_dup 3) 0))]
+   ""
+   "
+ {
+   operands[3] = gen_reg_rtx (DImode);
+   operands[4] = gen_reg_rtx (DImode);
+   operands[5] = gen_reg_rtx (DImode);
+ }")
+ 
+ (define_insn ""
+   [(set (subreg:SI (match_operand:DI 0 "register_operand" "=f") 0)
+ 	(mult:SI (subreg:SI (match_operand:DI 1 "register_operand" "f") 0)
+ 		 (subreg:SI (match_operand:DI 2 "register_operand" "f") 0)))]
+   ""
+   "fmlow.dd %2,%1,%0")
+ \f


+ ;;- and instructions (with compliment also)			   
+ (define_insn "andsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(and:SI (match_operand:SI 1 "nonmemory_operand" "%r")
+ 		(match_operand:SI 2 "nonmemory_operand" "rn")))]
+   ""
+   "*
+ {
+   rtx xop[3];
+ 
+   if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
+     return \"and %2,%1,%0\";
+   if ((INTVAL (operands[2]) & 0xffff) == 0)
+     {
+       operands[2] = gen_rtx (CONST_INT, VOIDmode, 
+ 			     (unsigned) INTVAL (operands[2]) >> 16);
+       return \"andh %2,%1,%0\";
+     }
+   xop[0] = operands[0];
+   xop[1] = operands[1];
+   xop[2] = gen_rtx (CONST_INT, VOIDmode, ~(INTVAL (operands[2]) & 0xffff));
+   output_asm_insn (\"andnot %2,%1,%0\", xop);
+   operands[2] = gen_rtx (CONST_INT, VOIDmode, 
+ 			 ~(unsigned) INTVAL (operands[2]) >> 16);
+   return \"andnoth %2,%0,%0\";
+ }")
+ 
+ (define_insn "andcbsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(and:SI (match_operand:SI 1 "register_operand" "r")
+ 		(not:SI (match_operand:SI 2 "register_operand" "rn"))))]
+   ""
+   "*
+ {
+   rtx xop[3];
+ 
+   if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
+     return \"andnot %2,%1,%0\";
+   if ((INTVAL (operands[2]) & 0xffff) == 0)
+     {
+       operands[2] = gen_rtx (CONST_INT, VOIDmode, 
+ 			     (unsigned) INTVAL (operands[2]) >> 16);
+       return \"andnoth %2,%1,%0\";
+     }
+   xop[0] = operands[0];
+   xop[1] = operands[1];
+   xop[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) & 0xffff));
+   output_asm_insn (\"andnot %2,%1,%0\", xop);
+   operands[2] = gen_rtx (CONST_INT, VOIDmode, 
+ 			 (unsigned) INTVAL (operands[2]) >> 16);
+   return \"andnoth %2,%0,%0\";
+ }")
+ 
+ (define_insn "iorsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(ior:SI (match_operand:SI 1 "nonmemory_operand" "%r")
+ 		(match_operand:SI 2 "nonmemory_operand" "rn")))]
+   ""
+   "*
+ {
+   rtx xop[3];
+ 
+   if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
+     return \"or %2,%1,%0\";
+   if ((INTVAL (operands[2]) & 0xffff) == 0)
+     {
+       operands[2] = gen_rtx (CONST_INT, VOIDmode, 
+ 			     (unsigned) INTVAL (operands[2]) >> 16);
+       return \"orh %2,%1,%0\";
+     }
+   xop[0] = operands[0];
+   xop[1] = operands[1];
+   xop[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) & 0xffff));
+   output_asm_insn (\"or %2,%1,%0\", xop);
+   operands[2] = gen_rtx (CONST_INT, VOIDmode, 
+ 			 (unsigned) INTVAL (operands[2]) >> 16);
+   return \"orh %2,%0,%0\";
+ }")
+ 
+ (define_insn "xorsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(xor:SI (match_operand:SI 1 "nonmemory_operand" "%r")
+ 		(match_operand:SI 2 "nonmemory_operand" "rn")))]
+   ""
+   "*
+ {
+   rtx xop[3];
+ 
+   if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
+     return \"xor %2,%1,%0\";
+   if ((INTVAL (operands[2]) & 0xffff) == 0)
+     {
+       operands[2] = gen_rtx (CONST_INT, VOIDmode, 
+ 			     (unsigned) INTVAL (operands[2]) >> 16);
+       return \"xorh %2,%1,%0\";
+     }
+   xop[0] = operands[0];
+   xop[1] = operands[1];
+   xop[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) & 0xffff));
+   output_asm_insn (\"xor %2,%1,%0\", xop);
+   operands[2] = gen_rtx (CONST_INT, VOIDmode, 
+ 			 (unsigned) INTVAL (operands[2]) >> 16);
+   return \"xorh %2,%0,%0\";
+ }")
+ 
+ (define_insn "negsi2"
+   [(set (match_operand:SI 0 "general_operand" "=r")
+ 	(neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
+   ""
+   "subu r0,%1,%0")
+ 
+ (define_insn "one_cmplsi2"
+   [(set (match_operand:SI 0 "general_operand" "=r")
+ 	(not:SI (match_operand:SI 1 "arith_operand" "r")))]
+   ""
+   "subu -1,%1,%0")
+ \f


+ ;; Floating point arithmetic instructions.
+ 
+ (define_insn "adddf3"
+   [(set (match_operand:DF 0 "register_operand" "=f")
+ 	(plus:DF (match_operand:DF 1 "register_operand" "f")
+ 		 (match_operand:DF 2 "register_operand" "f")))]
+   ""
+   "fadd.dd %1,%2,%0")
+ 
+ (define_insn "addsf3"
+   [(set (match_operand:SF 0 "register_operand" "=f")
+ 	(plus:SF (match_operand:SF 1 "register_operand" "f")
+ 		 (match_operand:SF 2 "register_operand" "f")))]
+   ""
+   "fadd.ss %1,%2,%0")
+ 
+ (define_insn "subdf3"
+   [(set (match_operand:DF 0 "register_operand" "=f")
+ 	(minus:DF (match_operand:DF 1 "register_operand" "f")
+ 		  (match_operand:DF 2 "register_operand" "f")))]
+   ""
+   "fsub.dd %1,%2,%0")
+ 
+ (define_insn "subsf3"
+   [(set (match_operand:SF 0 "register_operand" "=f")
+ 	(minus:SF (match_operand:SF 1 "register_operand" "f")
+ 		  (match_operand:SF 2 "register_operand" "f")))]
+   ""
+   "fsub.ss %1,%2,%0")
+ 
+ (define_insn "muldf3"
+   [(set (match_operand:DF 0 "register_operand" "=f")
+ 	(mult:DF (match_operand:DF 1 "register_operand" "f")
+ 		 (match_operand:DF 2 "register_operand" "f")))]
+   ""
+   "fmul.dd %1,%2,%0")
+ 
+ (define_insn "mulsf3"
+   [(set (match_operand:SF 0 "register_operand" "=f")
+ 	(mult:SF (match_operand:SF 1 "register_operand" "f")
+ 		 (match_operand:SF 2 "register_operand" "f")))]
+   ""
+   "fmul.ss %1,%2,%0")
+ 
+ (define_insn "negdf2"
+   [(set (match_operand:DF 0 "register_operand" "=f")
+ 	(neg:DF (match_operand:DF 1 "register_operand" "f")))]
+   ""
+   "fsub.dd f0,%1,%0")
+ 
+ (define_insn "negsf2"
+   [(set (match_operand:SF 0 "register_operand" "=f")
+ 	(neg:SF (match_operand:SF 1 "register_operand" "f")))]
+   ""
+   "fsub.ss f0,%1,%0")
+ \f


+ ;; Shift instructions
+ 
+ ;; Optimized special case of shifting.
+ ;; Must precede the general case.
+ 
+ (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
+ 		     (const_int 24)))]
+   ""
+   "*
+ {
+   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
+     {
+       cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
+       cc_status.mdep = XEXP (operands[1], 0);
+       return \"orh ha%%%m1,r0,r31\;ld.b l%%%m1(r31),%0\";
+     }
+   return \"ld.b %1,%0\";
+ }")
+ 
+ \f


+ ;;- arithmetic shift instructions
+ (define_insn "ashlsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(ashift:SI (match_operand:SI 1 "register_operand" "r")
+ 		   (match_operand:SI 2 "nonmemory_operand" "rn")))]
+   ""
+   "*
+ {
+   if (GET_CODE (operands[2]) == CONST_INT
+       && INTVAL (operands[2]) >= 32)
+     return \"mov r0,%0\";
+   return \"shl %2,%1,%0\";
+ }")
+ 
+ (define_insn "ashlhi3"
+   [(set (match_operand:HI 0 "register_operand" "=r")
+ 	(ashift:HI (match_operand:HI 1 "register_operand" "r")
+ 		   (match_operand:HI 2 "nonmemory_operand" "rn")))]
+   ""
+   "*
+ {
+   if (GET_CODE (operands[2]) == CONST_INT
+       && INTVAL (operands[2]) >= 16)
+     return \"mov r0,%0\";
+   return \"shl %2,%1,%0\";
+ }")
+ 
+ (define_insn "ashlqi3"
+   [(set (match_operand:QI 0 "register_operand" "=r")
+ 	(ashift:QI (match_operand:QI 1 "register_operand" "r")
+ 		   (match_operand:QI 2 "nonmemory_operand" "rn")))]
+   ""
+   "*
+ {
+   if (GET_CODE (operands[2]) == CONST_INT
+       && INTVAL (operands[2]) >= 8)
+     return \"mov r0,%0\";
+   return \"shl %2,%1,%0\";
+ }")
+ 
+ (define_insn "ashrsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
+ 		     (match_operand:SI 2 "nonmemory_operand" "rn")))]
+   ""
+   "*
+ {
+   if (GET_CODE (operands[2]) == CONST_INT
+       && INTVAL (operands[2]) >= 32)
+     return \"shra 31,%1,%0\";
+   return \"shra %2,%1,%0\";
+ }")
+ 
+ (define_insn "lshrsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+ 		     (match_operand:SI 2 "nonmemory_operand" "rn")))]
+   ""
+   "*
+ {
+   if (GET_CODE (operands[2]) == CONST_INT
+       && INTVAL (operands[2]) >= 32)
+     return \"mov r0,%0\";
+   return \"shr %2,%1,%0\";
+ }")
+ \f


+ ;; Unconditional and other jump instructions
+ 
+ (define_insn "jump"
+   [(set (pc) (label_ref (match_operand 0 "" "")))]
+   ""
+   "*
+ {
+   return \"br %l0\;nop\";
+ }")
+ 
+ ;; Here are two simple peepholes which fill the delay slot of
+ ;; an unconditional branch.
+ 
+ (define_peephole
+   [(set (match_operand:SI 0 "register_operand" "=rf")
+ 	(match_operand:SI 1 "single_insn_src_p" "p"))
+    (set (pc) (label_ref (match_operand 2 "" "")))]
+   ""
+   "* return output_delayed_branch (\"br %l2\", operands, insn);")
+ 
+ (define_peephole
+   [(set (match_operand:SI 0 "memory_operand" "=m")
+ 	(match_operand:SI 1 "reg_or_0_operand" "rfJ"))
+    (set (pc) (label_ref (match_operand 2 "" "")))]
+   ""
+   "* return output_delayed_branch (\"br %l2\", operands, insn);")
+ 
+ (define_insn "tablejump"
+   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
+    (use (label_ref (match_operand 1 "" "")))]
+   ""
+   "bri %0\;nop")
+ 
+ (define_peephole
+   [(set (match_operand:SI 0 "memory_operand" "=m")
+ 	(match_operand:SI 1 "reg_or_0_operand" "rfJ"))
+    (set (pc) (match_operand:SI 2 "register_operand" "r"))
+    (use (label_ref (match_operand 3 "" "")))]
+   ""
+   "* return output_delayed_branch (\"bri %2\", operands, insn);")
+ 
+ ;;- jump to subroutine
+ (define_expand "call"
+   [(call (match_operand:SI 0 "memory_operand" "m")
+ 	 (match_operand 1 "" "i"))]
+   ;; operand[2] is next_arg_register
+   ""
+   "
+ {
+   if (INTVAL (operands[1]) > 0)
+     {
+       emit_move_insn (arg_pointer_rtx, stack_pointer_rtx);
+       emit_insn (gen_rtx (USE, VOIDmode, arg_pointer_rtx));
+     }
+ }")
+ 
+ ;;- jump to subroutine
+ (define_insn ""
+   [(call (match_operand:SI 0 "memory_operand" "m")
+ 	 (match_operand 1 "" "i"))]
+   ;; operand[2] is next_arg_register
+   ""
+   "*
+ {
+   /* strip the MEM.  */
+   operands[0] = XEXP (operands[0], 0);
+   CC_STATUS_INIT;
+   if (GET_CODE (operands[0]) == REG)
+     return \"calli %0\;nop\";
+   return \"call %0\;nop\";
+ }")
+ 
+ (define_peephole
+   [(set (match_operand:SI 0 "register_operand" "=rf")
+ 	(match_operand:SI 1 "single_insn_src_p" "p"))
+    (call (match_operand:SI 2 "memory_operand" "m")
+ 	 (match_operand 3 "" "i"))]
+   ;;- Don't use operand 1 for most machines.
+   "! reg_mentioned_p (operands[0], operands[2])"
+   "*
+ {
+   /* strip the MEM.  */
+   operands[2] = XEXP (operands[2], 0);
+   if (GET_CODE (operands[2]) == REG)
+     return output_delayed_branch (\"calli %2\", operands, insn);
+   return output_delayed_branch (\"call %2\", operands, insn);
+ }")
+ 
+ (define_peephole
+   [(set (match_operand:SI 0 "memory_operand" "=m")
+ 	(match_operand:SI 1 "reg_or_0_operand" "rfJ"))
+    (call (match_operand:SI 2 "memory_operand" "m")
+ 	 (match_operand 3 "" "i"))]
+   ;;- Don't use operand 1 for most machines.
+   ""
+   "*
+ {
+   /* strip the MEM.  */
+   operands[2] = XEXP (operands[2], 0);
+   if (GET_CODE (operands[2]) == REG)
+     return output_delayed_branch (\"calli %2\", operands, insn);
+   return output_delayed_branch (\"call %2\", operands, insn);
+ }")
+ 
+ (define_expand "call_value"
+   [(set (match_operand 0 "register_operand" "rf")
+ 	(call (match_operand:SI 1 "memory_operand" "m")
+ 	      (match_operand 2 "" "i")))]
+   ;; operand 3 is next_arg_register
+   ""
+   "
+ {
+   if (INTVAL (operands[2]) > 0)
+     {
+       emit_move_insn (arg_pointer_rtx, stack_pointer_rtx);
+       emit_insn (gen_rtx (USE, VOIDmode, arg_pointer_rtx));
+     }
+ }")
+ 
+ (define_insn ""
+   [(set (match_operand 0 "register_operand" "=rf")
+ 	(call (match_operand:SI 1 "memory_operand" "m")
+ 	      (match_operand 2 "" "i")))]
+   ;; operand 3 is next_arg_register
+   ""
+   "*
+ {
+   /* strip the MEM.  */
+   operands[1] = XEXP (operands[1], 0);
+   CC_STATUS_INIT;
+   if (GET_CODE (operands[1]) == REG)
+     return \"calli %1\;nop\";
+   return \"call %1\;nop\";
+ }")
+ 
+ (define_peephole
+   [(set (match_operand:SI 0 "register_operand" "=rf")
+ 	(match_operand:SI 1 "single_insn_src_p" "p"))
+    (set (match_operand 2 "" "=rf")
+ 	(call (match_operand:SI 3 "memory_operand" "m")
+ 	      (match_operand 4 "" "i")))]
+   ;;- Don't use operand 4 for most machines.
+   "! reg_mentioned_p (operands[0], operands[3])"
+   "*
+ {
+   /* strip the MEM.  */
+   operands[3] = XEXP (operands[3], 0);
+   if (GET_CODE (operands[3]) == REG)
+     return output_delayed_branch (\"calli %3\", operands, insn);
+   return output_delayed_branch (\"call %3\", operands, insn);
+ }")
+ 
+ (define_peephole
+   [(set (match_operand:SI 0 "memory_operand" "=m")
+ 	(match_operand:SI 1 "reg_or_0_operand" "rJf"))
+    (set (match_operand 2 "" "=rf")
+ 	(call (match_operand:SI 3 "memory_operand" "m")
+ 	      (match_operand 4 "" "i")))]
+   ;;- Don't use operand 4 for most machines.
+   ""
+   "*
+ {
+   /* strip the MEM.  */
+   operands[3] = XEXP (operands[3], 0);
+   if (GET_CODE (operands[3]) == REG)
+     return output_delayed_branch (\"calli %3\", operands, insn);
+   return output_delayed_branch (\"call %3\", operands, insn);
+ }")
+ \f


+ (define_insn "nop"
+   [(const_int 0)]
+   ""
+   "nop")
+ \f


+ (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "r")
+ 	(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
+ 			 (label_ref (match_operand 2 "" "")))))]
+   ""
+   "*
+ {
+   cc_status.flags = 0;
+   return \"mov %l2,r31\;ld.l r31(%1),%0\";
+ }")
+   
+ (define_peephole
+   [(set (match_operand:SI 0 "register_operand" "=rf")
+ 	(match_operand:SI 1 "single_insn_src_p" "p"))
+    (set (pc) (match_operand:SI 2 "register_operand" "r"))
+    (use (label_ref (match_operand 3 "" "")))]
+   "REGNO (operands[0]) != REGNO (operands[2])"
+   "* return output_delayed_branch (\"bri %2\", operands, insn);")
+ \f


+ ;;- Local variables:
+ ;;- mode:emacs-lisp
+ ;;- comment-start: ";;- "
+ ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
+ ;;- eval: (modify-syntax-entry ?[ "(]")
+ ;;- eval: (modify-syntax-entry ?] ")[")
+ ;;- eval: (modify-syntax-entry ?{ "(}")
+ ;;- eval: (modify-syntax-entry ?} "){")
+ ;;- End:
+ 
diff -rc2N gcc-1.35/config/m68k.md gcc-1.36/config/m68k.md
*** gcc-1.35/config/m68k.md	Wed Apr 12 22:03:52 1989
--- gcc-1.36/config/m68k.md	Sat Sep 16 04:30:03 1989
***************
*** 1,5 ****
  ;;- Machine description for GNU compiler
  ;;- Motorola 68000 Version
! ;;   Copyright (C) 1987 Free Software Foundation, Inc.
  
  ;; This file is part of GNU CC.
--- 1,5 ----
  ;;- Machine description for GNU compiler
  ;;- Motorola 68000 Version
! ;;   Copyright (C) 1987, 1988 Free Software Foundation, Inc.
  
  ;; This file is part of GNU CC.
***************
*** 50,54 ****
  ;; info.
  
! ;;- Immedidate integer operands Constrains:
  ;;- 'I'  1 .. 8
  ;;- 'J'  -32768 .. 32767
--- 50,54 ----
  ;; info.
  
! ;;- Immediate integer operand constraints:
  ;;- 'I'  1 .. 8
  ;;- 'J'  -32768 .. 32767
***************
*** 241,244 ****
--- 241,246 ----
  }")
  \f


+ ;; Put tstsi first among test insns so it matches a CONST_INT operand.
+ 
  (define_insn "tstsi"
    [(set (cc0)
***************
*** 364,369 ****
  ;; compare instructions.
  
  ;; A composite of the cmp, cmpa, & cmpi m68000 op codes.
- ;; We use d*a in the constraints because compares with data regs are faster.
  (define_insn "cmpsi"
    [(set (cc0)
--- 366,372 ----
  ;; compare instructions.
  
+ ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
+ 
  ;; A composite of the cmp, cmpa, & cmpi m68000 op codes.
  (define_insn "cmpsi"
    [(set (cc0)
***************
*** 599,603 ****
    "* { return output_btst (operands, operands[1], operands[0], insn, 31); }")
  
! ;; Nonoffsetable mem refs are ok in this one pattern
  ;; since we don't try to adjust them.
  (define_insn ""
--- 602,606 ----
    "* { return output_btst (operands, operands[1], operands[0], insn, 31); }")
  
! ;; Nonoffsettable mem refs are ok in this one pattern
  ;; since we don't try to adjust them.
  (define_insn ""
***************
*** 605,609 ****
  			    (const_int 1)
  			    (match_operand:SI 1 "general_operand" "i")))]
!   "GET_CODE (operands[1]) == CONST_INT"
    "*
  {
--- 608,613 ----
  			    (const_int 1)
  			    (match_operand:SI 1 "general_operand" "i")))]
!   "GET_CODE (operands[1]) == CONST_INT
!    && (unsigned) INTVAL (operands[1]) < 8"
    "*
  {
***************
*** 613,617 ****
  
  (define_insn ""
!   ;; The constraint "o,d" here means that a nonoffsetable memref
    ;; will match the first alternative, and its address will be reloaded.
    ;; Copying the memory contents into a reg would be incorrect if the
--- 617,621 ----
  
  (define_insn ""
!   ;; The constraint "o,d" here means that a nonoffsettable memref
    ;; will match the first alternative, and its address will be reloaded.
    ;; Copying the memory contents into a reg would be incorrect if the
***************
*** 625,630 ****
    if (GET_CODE (operands[0]) == MEM)
      {
!       operands[0] = adj_offsetable_operand (operands[0],
! 					    INTVAL (operands[1]) / 8);
        operands[1] = gen_rtx (CONST_INT, VOIDmode, 
  			     7 - INTVAL (operands[1]) % 8);
--- 629,634 ----
    if (GET_CODE (operands[0]) == MEM)
      {
!       operands[0] = adj_offsettable_operand (operands[0],
! 					     INTVAL (operands[1]) / 8);
        operands[1] = gen_rtx (CONST_INT, VOIDmode, 
  			     7 - INTVAL (operands[1]) % 8);
***************
*** 645,650 ****
    if (GET_CODE (operands[0]) == MEM)
      {
!       operands[0] = adj_offsetable_operand (operands[0],
! 					    INTVAL (operands[1]) / 8);
        operands[1] = gen_rtx (CONST_INT, VOIDmode, 
  			     7 - INTVAL (operands[1]) % 8);
--- 649,654 ----
    if (GET_CODE (operands[0]) == MEM)
      {
!       operands[0] = adj_offsettable_operand (operands[0],
! 					     INTVAL (operands[1]) / 8);
        operands[1] = gen_rtx (CONST_INT, VOIDmode, 
  			     7 - INTVAL (operands[1]) % 8);
***************
*** 716,719 ****
--- 720,730 ----
    if (ADDRESS_REG_P (operands[0]))
      return \"sub%.l %0,%0\";
+   /* moveq is faster on the 68000.  */
+   if (DATA_REG_P (operands[0]) && !TARGET_68020)
+ #ifdef MOTOROLA
+     return \"moveq%.l %#0,%0\";
+ #else
+     return \"moveq %#0,%0\";
+ #endif
    return \"clr%.l %0\";
  }")
***************
*** 853,861 ****
  
  (define_insn "movqi"
!   [(set (match_operand:QI 0 "general_operand" "=d,*a,m")
! 	(match_operand:QI 1 "general_operand" "dmi*a,d*a,dmi"))]
    ""
    "*
  {
    if (operands[1] == const0_rtx)
      return \"clr%.b %0\";
--- 864,896 ----
  
  (define_insn "movqi"
!   [(set (match_operand:QI 0 "general_operand" "=d,*a,m,m,?*a")
! 	(match_operand:QI 1 "general_operand" "dmi*a,d*a,dmi,?*a,m"))]
    ""
    "*
  {
+   rtx xoperands[4];
+   if (ADDRESS_REG_P (operands[0]) && GET_CODE (operands[1]) == MEM)
+     {
+       xoperands[1] = operands[1];
+       xoperands[2]
+         = gen_rtx (MEM, QImode,
+ 		   gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, const1_rtx));
+       xoperands[3] = stack_pointer_rtx;
+       /* Just pushing a byte puts it in the high byte of the halfword.  */
+       /* We must put it in the low half, the second byte.  */
+       output_asm_insn (\"subq%.w %#2,%3\;move%.b %1,%2\", xoperands);
+       return \"move%.w %+,%0\";
+     }
+   if (ADDRESS_REG_P (operands[1]) && GET_CODE (operands[0]) == MEM)
+     {
+       xoperands[0] = operands[0];
+       xoperands[1] = operands[1];
+       xoperands[2]
+         = gen_rtx (MEM, QImode,
+ 		   gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, const1_rtx));
+       xoperands[3] = stack_pointer_rtx;
+       output_asm_insn (\"move%.w %1,%-\;move%.b %2,%0\;addq%.w %#2,%3\", xoperands);
+       return \"\";
+     }
    if (operands[1] == const0_rtx)
      return \"clr%.b %0\";
***************
*** 1019,1023 ****
        if (REG_P (operands[0]))
  	{
! 	  output_asm_insn (\"fmove.d %f1,%-\;move%.l %+,%0\", operands);
  	  operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
  	  return \"move%.l %+,%0\";
--- 1054,1058 ----
        if (REG_P (operands[0]))
  	{
! 	  output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands);
  	  operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
  	  return \"move%.l %+,%0\";
***************
*** 1052,1056 ****
      return \"move%.l %1,%0\";
    if (GET_CODE (operands[1]) == MEM)
!     operands[1] = adj_offsetable_operand (operands[1], 3);
    return \"move%.b %1,%0\";
  }")
--- 1087,1091 ----
      return \"move%.l %1,%0\";
    if (GET_CODE (operands[1]) == MEM)
!     operands[1] = adj_offsettable_operand (operands[1], 3);
    return \"move%.b %1,%0\";
  }")
***************
*** 1063,1070 ****
    "*
  {
    if (GET_CODE (operands[0]) == REG)
      return \"move%.l %1,%0\";
    if (GET_CODE (operands[1]) == MEM)
!     operands[1] = adj_offsetable_operand (operands[1], 1);
    return \"move%.b %1,%0\";
  }")
--- 1098,1109 ----
    "*
  {
+   if (GET_CODE (operands[0]) == REG
+       && (GET_CODE (operands[1]) == MEM
+ 	  || GET_CODE (operands[1]) == CONST_INT))
+     return \"move%.w %1,%0\";
    if (GET_CODE (operands[0]) == REG)
      return \"move%.l %1,%0\";
    if (GET_CODE (operands[1]) == MEM)
!     operands[1] = adj_offsettable_operand (operands[1], 1);
    return \"move%.b %1,%0\";
  }")
***************
*** 1080,1084 ****
      return \"move%.l %1,%0\";
    if (GET_CODE (operands[1]) == MEM)
!     operands[1] = adj_offsetable_operand (operands[1], 2);
    return \"move%.w %1,%0\";
  }")
--- 1119,1123 ----
      return \"move%.l %1,%0\";
    if (GET_CODE (operands[1]) == MEM)
!     operands[1] = adj_offsettable_operand (operands[1], 2);
    return \"move%.w %1,%0\";
  }")
***************
*** 1139,1143 ****
      {
        output_asm_insn (\"clr%.w %0\", operands);
!       operands[0] = adj_offsetable_operand (operands[0], 2);
        return \"move%.w %1,%0\";
      }
--- 1178,1182 ----
      {
        output_asm_insn (\"clr%.w %0\", operands);
!       operands[0] = adj_offsettable_operand (operands[0], 2);
        return \"move%.w %1,%0\";
      }
***************
*** 1175,1179 ****
      {
        output_asm_insn (\"clr%.b %0\", operands);
!       operands[0] = adj_offsetable_operand (operands[0], 1);
        return \"move%.b %1,%0\";
      }
--- 1214,1218 ----
      {
        output_asm_insn (\"clr%.b %0\", operands);
!       operands[0] = adj_offsettable_operand (operands[0], 1);
        return \"move%.b %1,%0\";
      }
***************
*** 1227,1231 ****
      {
        output_asm_insn (\"clr%.l %0\", operands);
!       operands[0] = adj_offsetable_operand (operands[0], 3);
        return \"move%.b %1,%0\";
      }
--- 1266,1270 ----
      {
        output_asm_insn (\"clr%.l %0\", operands);
!       operands[0] = adj_offsettable_operand (operands[0], 3);
        return \"move%.b %1,%0\";
      }
***************
*** 1527,1530 ****
--- 1566,1570 ----
    if (GET_CODE (operands[2]) == CONST_INT)
      {
+ #ifndef NO_ADDSUB_Q
        if (INTVAL (operands[2]) > 0
  	  && INTVAL (operands[2]) <= 8)
***************
*** 1541,1544 ****
--- 1581,1585 ----
  		  : \"subq%.l %2,%0\");
  	}
+ #endif
        if (ADDRESS_REG_P (operands[0])
  	  && INTVAL (operands[2]) >= -0x8000
***************
*** 1563,1566 ****
--- 1604,1608 ----
    "*
  {
+ #ifndef NO_ADDSUB_Q
    if (GET_CODE (operands[2]) == CONST_INT)
      {
***************
*** 1579,1582 ****
--- 1621,1625 ----
  	}
      }
+ #endif
    return \"add%.w %2,%0\";
  }")
***************
*** 1596,1599 ****
--- 1639,1643 ----
    "*
  {
+ #ifndef NO_ADDSUB_Q
    if (GET_CODE (operands[2]) == CONST_INT)
      {
***************
*** 1610,1613 ****
--- 1654,1658 ----
         }
      }
+ #endif
    return \"add%.b %2,%0\";
  }")
***************
*** 1703,1706 ****
--- 1748,1752 ----
        if (operands_match_p (operands[0], operands[2]))
  	{
+ #ifndef NO_ADDSUB_Q
  	  if (GET_CODE (operands[1]) == CONST_INT)
  	    {
***************
*** 1709,1712 ****
--- 1755,1759 ----
  		return \"subq%.l %1,%0\;neg%.l %0\";
  	    }
+ #endif
  	  return \"sub%.l %1,%0\;neg%.l %0\";
  	}
***************
*** 1728,1734 ****
--- 1775,1783 ----
    if (GET_CODE (operands[2]) == CONST_INT)
      {
+ #ifndef NO_ADDSUB_Q
        if (INTVAL (operands[2]) > 0
  	  && INTVAL (operands[2]) <= 8)
  	return \"subq%.l %2,%0\";
+ #endif
        if (ADDRESS_REG_P (operands[0])
  	  && INTVAL (operands[2]) >= -0x8000
***************
*** 2244,2251 ****
        && (INTVAL (operands[2]) | 0xffff) == 0xffffffff
        && (DATA_REG_P (operands[0])
! 	  || offsetable_memref_p (operands[0])))
      { 
        if (GET_CODE (operands[0]) != REG)
!         operands[0] = adj_offsetable_operand (operands[0], 2);
        operands[2] = gen_rtx (CONST_INT, VOIDmode,
  			     INTVAL (operands[2]) & 0xffff);
--- 2293,2300 ----
        && (INTVAL (operands[2]) | 0xffff) == 0xffffffff
        && (DATA_REG_P (operands[0])
! 	  || offsettable_memref_p (operands[0])))
      { 
        if (GET_CODE (operands[0]) != REG)
!         operands[0] = adj_offsettable_operand (operands[0], 2);
        operands[2] = gen_rtx (CONST_INT, VOIDmode,
  			     INTVAL (operands[2]) & 0xffff);
***************
*** 2302,2309 ****
        && INTVAL (operands[2]) >> 16 == 0
        && (DATA_REG_P (operands[0])
! 	  || offsetable_memref_p (operands[0])))
      { 
        if (GET_CODE (operands[0]) != REG)
!         operands[0] = adj_offsetable_operand (operands[0], 2);
        /* Do not delete a following tstl %0 insn; that would be incorrect.  */
        CC_STATUS_INIT;
--- 2351,2358 ----
        && INTVAL (operands[2]) >> 16 == 0
        && (DATA_REG_P (operands[0])
! 	  || offsettable_memref_p (operands[0])))
      { 
        if (GET_CODE (operands[0]) != REG)
!         operands[0] = adj_offsettable_operand (operands[0], 2);
        /* Do not delete a following tstl %0 insn; that would be incorrect.  */
        CC_STATUS_INIT;
***************
*** 2313,2317 ****
        && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
        && (DATA_REG_P (operands[0])
! 	  || offsetable_memref_p (operands[0])))
      { 
        if (DATA_REG_P (operands[0]))
--- 2362,2366 ----
        && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
        && (DATA_REG_P (operands[0])
! 	  || offsettable_memref_p (operands[0])))
      { 
        if (DATA_REG_P (operands[0]))
***************
*** 2321,2325 ****
        else
          {
! 	  operands[0] = adj_offsetable_operand (operands[0], 3 - (logval / 8));
  	  operands[1] = gen_rtx (CONST_INT, VOIDmode, logval % 8);
  	}
--- 2370,2374 ----
        else
          {
! 	  operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8));
  	  operands[1] = gen_rtx (CONST_INT, VOIDmode, logval % 8);
  	}
***************
*** 2354,2361 ****
    if (GET_CODE (operands[2]) == CONST_INT
        && INTVAL (operands[2]) >> 16 == 0
!       && (offsetable_memref_p (operands[0]) || DATA_REG_P (operands[0])))
      { 
        if (! DATA_REG_P (operands[0]))
! 	operands[0] = adj_offsetable_operand (operands[0], 2);
        /* Do not delete a following tstl %0 insn; that would be incorrect.  */
        CC_STATUS_INIT;
--- 2403,2410 ----
    if (GET_CODE (operands[2]) == CONST_INT
        && INTVAL (operands[2]) >> 16 == 0
!       && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0])))
      { 
        if (! DATA_REG_P (operands[0]))
! 	operands[0] = adj_offsettable_operand (operands[0], 2);
        /* Do not delete a following tstl %0 insn; that would be incorrect.  */
        CC_STATUS_INIT;
***************
*** 2757,2765 ****
    else
      operands[0]
!       = adj_offsetable_operand (operands[0], INTVAL (operands[2]) / 8);
  
    if (GET_CODE (operands[3]) == MEM)
!     operands[3] = adj_offsetable_operand (operands[3],
! 					  (32 - INTVAL (operands[1])) / 8);
    if (INTVAL (operands[1]) == 8)
      return \"move%.b %3,%0\";
--- 2806,2814 ----
    else
      operands[0]
!       = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8);
  
    if (GET_CODE (operands[3]) == MEM)
!     operands[3] = adj_offsettable_operand (operands[3],
! 					   (32 - INTVAL (operands[1])) / 8);
    if (INTVAL (operands[1]) == 8)
      return \"move%.b %3,%0\";
***************
*** 2788,2797 ****
    else
      operands[1]
!       = adj_offsetable_operand (operands[1], INTVAL (operands[3]) / 8);
  
    output_asm_insn (\"clr%.l %0\", operands);
    if (GET_CODE (operands[0]) == MEM)
!     operands[0] = adj_offsetable_operand (operands[0],
! 					  (32 - INTVAL (operands[1])) / 8);
    if (INTVAL (operands[2]) == 8)
      return \"move%.b %1,%0\";
--- 2837,2846 ----
    else
      operands[1]
!       = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
  
    output_asm_insn (\"clr%.l %0\", operands);
    if (GET_CODE (operands[0]) == MEM)
!     operands[0] = adj_offsettable_operand (operands[0],
! 					   (32 - INTVAL (operands[1])) / 8);
    if (INTVAL (operands[2]) == 8)
      return \"move%.b %1,%0\";
***************
*** 2820,2824 ****
    else
      operands[1]
!       = adj_offsetable_operand (operands[1], INTVAL (operands[3]) / 8);
  
    if (INTVAL (operands[2]) == 8)
--- 2869,2873 ----
    else
      operands[1]
!       = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
  
    if (INTVAL (operands[2]) == 8)
***************
*** 2828,2832 ****
  \f


  ;; Bit field instructions, general cases.
! ;; "o,d" constraint causes a nonoffsetable memref to match the "o"
  ;; so that its address is reloaded.
  
--- 2877,2881 ----
  \f


  ;; Bit field instructions, general cases.
! ;; "o,d" constraint causes a nonoffsettable memref to match the "o"
  ;; so that its address is reloaded.
  
***************
*** 3627,3630 ****
--- 3676,3680 ----
    "*
  {
+   CC_STATUS_INIT;
    if (DATA_REG_P (operands[0]))
      return \"dbra %0,%l1\";
***************
*** 3632,3637 ****
      {
  #ifdef MOTOROLA
!       return \"subq%.w %#1,%0\;jbcc %l1\";
  #else
        return \"subqw %#1,%0\;jcc %l1\";
  #endif
--- 3682,3691 ----
      {
  #ifdef MOTOROLA
! #ifdef NO_ADDSUB_Q
!       return \"sub%.w %#1,%0\;jbcc %l1\";
  #else
+       return \"subq%.w %#1,%0\;jbcc %l1\";
+ #endif
+ #else /* not MOTOROLA */
        return \"subqw %#1,%0\;jcc %l1\";
  #endif
***************
*** 3639,3647 ****
  #ifdef MOTOROLA
  #ifdef HPUX_ASM
!   return \"subq%.w %#1,%0\;cmp%.w %0,%#-1\;jbne %l1\";
  #else
    return \"subq%.w %#1,%0\;cmp%.w %#-1,%0\;jbne %l1\";
  #endif
! #else
    return \"subqw %#1,%0\;cmpw %#-1,%0\;jne %l1\";
  #endif
--- 3693,3705 ----
  #ifdef MOTOROLA
  #ifdef HPUX_ASM
! #ifndef NO_ADDSUB_Q
!   return \"sub%.w %#1,%0\;cmp%.w %0,%#-1\;jbne %l1\";
  #else
+   return \"subq%.w %#1,%0\;cmp%.w %0,%#-1\;jbne %l1\";
+ #endif
+ #else /* not HPUX_ASM */
    return \"subq%.w %#1,%0\;cmp%.w %#-1,%0\;jbne %l1\";
  #endif
! #else /* not MOTOROLA */
    return \"subqw %#1,%0\;cmpw %#-1,%0\;jne %l1\";
  #endif
***************
*** 3663,3673 ****
--- 3721,3743 ----
    "*
  {
+   CC_STATUS_INIT;
  #ifdef MOTOROLA
+ #ifndef NO_ADDSUB_Q
    if (DATA_REG_P (operands[0]))
+     return \"dbra %0,%l1\;clr.w %0\;sub.l %#1,%0\;jbcc %l1\";
+   if (GET_CODE (operands[0]) == MEM)
+     return \"sub.l %#1,%0\;jbcc %l1\";
+ #else
+   if (DATA_REG_P (operands[0]))
      return \"dbra %0,%l1\;clr.w %0\;subq.l %#1,%0\;jbcc %l1\";
    if (GET_CODE (operands[0]) == MEM)
      return \"subq.l %#1,%0\;jbcc %l1\";
+ #endif /* not NO_ADDSUB_Q */
  #ifdef HPUX_ASM
+ #ifndef NO_ADDSUB_Q
+   return \"sub.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\";
+ #else
    return \"subq.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\";
+ #endif
  #else
    return \"subq.l %#1,%0\;cmp.l %#-1,%0\;jbne %l1\";
***************
*** 3698,3702 ****
--- 3768,3779 ----
    "*
  {
+   CC_STATUS_INIT;
  #ifdef MOTOROLA
+ #ifndef NO_ADDSUB_Q
+   if (DATA_REG_P (operands[0]))
+     return \"dbra %0,%l1\;clr.w %0\;sub.l %#1,%0\;jbcc %l1\";
+   if (GET_CODE (operands[0]) == MEM)
+     return \"sub.l %#1,%0\;jbcc %l1\";
+ #else
    if (DATA_REG_P (operands[0]))
      return \"dbra %0,%l1\;clr.w %0\;subq.l %#1,%0\;jbcc %l1\";
***************
*** 3703,3708 ****
--- 3780,3790 ----
    if (GET_CODE (operands[0]) == MEM)
      return \"subq.l %#1,%0\;jbcc %l1\";
+ #endif
  #ifdef HPUX_ASM
+ #ifndef NO_ADDSUB_Q
+   return \"sub.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\";
+ #else
    return \"subq.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\";
+ #endif
  #else
    return \"subq.l %#1,%0\;cmp.l %#-1,%0\;jbne %l1\";
***************
*** 3735,3739 ****
  ;; (which must be a hard register).
  (define_insn "call_value"
!   [(set (match_operand 0 "" "rf")
  	(call (match_operand:QI 1 "general_operand" "o")
  	      (match_operand:SI 2 "general_operand" "g")))]
--- 3817,3821 ----
  ;; (which must be a hard register).
  (define_insn "call_value"
!   [(set (match_operand 0 "" "=rf")
  	(call (match_operand:QI 1 "general_operand" "o")
  	      (match_operand:SI 2 "general_operand" "g")))]
***************
*** 3748,3755 ****
  ")
  
! (define_insn "return"
!   [(return)]
!   "0"
!   "ret 0")
  \f


  ;; This should not be used unless the add/sub insns can't be.
--- 3830,3837 ----
  ")
  
! (define_insn "nop"
!   [(const_int 0)]
!   ""
!   "nop")
  \f


  ;; This should not be used unless the add/sub insns can't be.
diff -rc2N gcc-1.35/config/m88k.md gcc-1.36/config/m88k.md
*** gcc-1.35/config/m88k.md	Wed Feb 22 12:31:13 1989
--- gcc-1.36/config/m88k.md	Fri Aug 18 22:22:41 1989
***************
*** 633,637 ****
    if (operands[1] == dconst0_rtx && GET_CODE (operands[0]) == MEM)
      {
!       operands[1] = adj_offsetable_operand (operands[0], 4);
        return \"st r0,%0\;st r0,%1\";
      }
--- 633,637 ----
    if (operands[1] == dconst0_rtx && GET_CODE (operands[0]) == MEM)
      {
!       operands[1] = adj_offsettable_operand (operands[0], 4);
        return \"st r0,%0\;st r0,%1\";
      }
***************
*** 1280,1288 ****
    else
      operands[0]
!       = adj_offsetable_operand (operands[0], INTVAL (operands[2]) / 8);
  
    if (GET_CODE (operands[3]) == MEM)
!     operands[3] = adj_offsetable_operand (operands[3],
! 					  (32 - INTVAL (operands[1])) / 8);
    if (INTVAL (operands[1]) == 8)
      return \"st.b %3,%0\";
--- 1280,1288 ----
    else
      operands[0]
!       = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8);
  
    if (GET_CODE (operands[3]) == MEM)
!     operands[3] = adj_offsettable_operand (operands[3],
! 					   (32 - INTVAL (operands[1])) / 8);
    if (INTVAL (operands[1]) == 8)
      return \"st.b %3,%0\";
***************
*** 1306,1314 ****
    else
      operands[1]
!       = adj_offsetable_operand (operands[1], INTVAL (operands[3]) / 8);
  
    if (GET_CODE (operands[0]) == MEM)
!     operands[0] = adj_offsetable_operand (operands[0],
! 					  (32 - INTVAL (operands[1])) / 8);
    if (INTVAL (operands[2]) == 8)
      return \"ld.bu %0,%1\";
--- 1306,1314 ----
    else
      operands[1]
!       = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
  
    if (GET_CODE (operands[0]) == MEM)
!     operands[0] = adj_offsettable_operand (operands[0],
! 					   (32 - INTVAL (operands[1])) / 8);
    if (INTVAL (operands[2]) == 8)
      return \"ld.bu %0,%1\";
***************
*** 1332,1336 ****
    else
      operands[1]
!       = adj_offsetable_operand (operands[1], INTVAL (operands[3]) / 8);
  
    if (INTVAL (operands[2]) == 8)
--- 1332,1336 ----
    else
      operands[1]
!       = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
  
    if (INTVAL (operands[2]) == 8)
***************
*** 1957,1961 ****
  ;;- jump to subroutine
  (define_insn "call_value"
!   [(set (match_operand 0 "" "r")
  	(call (match_operand:SI 1 "memory_operand" "m")
  	      (match_operand:SI 2 "general_operand" "g")))
--- 1957,1961 ----
  ;;- jump to subroutine
  (define_insn "call_value"
!   [(set (match_operand 0 "" "=r")
  	(call (match_operand:SI 1 "memory_operand" "m")
  	      (match_operand:SI 2 "general_operand" "g")))
***************
*** 1972,1976 ****
  
  (define_insn ""
!   [(set (match_operand 0 "" "r")
  	(call (match_operand:SI 1 "memory_operand" "m")
  	      (match_operand:SI 2 "general_operand" "g")))
--- 1972,1976 ----
  
  (define_insn ""
!   [(set (match_operand 0 "" "=r")
  	(call (match_operand:SI 1 "memory_operand" "m")
  	      (match_operand:SI 2 "general_operand" "g")))
***************
*** 2006,2009 ****
--- 2006,2014 ----
    "GET_CODE (operands[0]) == SYMBOL_REF"
    "bsr.n %0")
+ 
+ (define_insn "nop"
+   [(const_int 0)]
+   ""
+   "nop")
  \f


  ;; Recognize jbs and jbc instructions.
diff -rc2N gcc-1.35/config/mips.md gcc-1.36/config/mips.md
*** gcc-1.35/config/mips.md	Sun Apr 16 23:57:42 1989
--- gcc-1.36/config/mips.md	Thu Sep 21 12:06:18 1989
***************
*** 22,26 ****
--- 22,239 ----
  ;;------------------------------------------------------------------------
  ;;
+ \f


+ ;;
+ ;;  ....................
+ ;;
+ ;;  Peephole Optimizations for
+ ;;
+ ;;          ARITHMETIC
+ ;;
+ ;;  ....................
+ ;;
+ 					;;- The following peepholes are
+ 					;;- motivated by the fact that
+ 					;;- stack movement result in some
+ 					;;- cases in embarrassing sequences
+ 					;;- of addiu SP,SP,int
+ 					;;-    addiu SP,SP,other_int
+ 
+ 					;;- --------------------
+ 					;;- REMARK: this would be done better
+ 					;;- by analysis of dependencies in
+ 					;;- basic blocks, prior to REG ALLOC,
+ 					;;- and simplification of trees:
+ 					;;-      (+  (+ REG const) const)
+ 					;;- ->   (+ REG newconst)
+ 					;;- --------------------
+ (define_peephole
+   [(set (match_operand:SI 0 "general_operand" "=r")
+ 	(plus:SI (match_operand:SI 1 "general_operand" "r")
+ 		 (match_operand:SI 2 "general_operand" "IJ")))
+    (set (match_operand:SI 3 "general_operand" "=r")
+ 	(plus:SI (match_dup 0)
+ 		 (match_operand:SI 4 "general_operand" "IJ")))]
+   "					/* DATA FLOW SEMANTICS*/
+    (((REGNO (operands[0])) == (REGNO (operands[3])))
+     ||
+       dead_or_set_p (insn, operands[0]))
+   &&
+    (                                   /* CONSTRAINTS         */
+        (GET_CODE (operands[2]) == CONST_INT)
+     && ((CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'I'))
+         ||(CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')))
+     &&  (GET_CODE (operands[4]) == CONST_INT)
+     && ((CONST_OK_FOR_LETTER_P (INTVAL (operands[4]), 'I'))
+         ||(CONST_OK_FOR_LETTER_P (INTVAL (operands[4]), 'J'))))
+   "
+   "*
+ {
+   rtx ops[3];
+   int i;
+   i = INTVAL (operands[2]) + INTVAL (operands[4]);
+   if  (i == 0)
+     {
+       if  ((REGNO (operands[3])) == (REGNO (operands[1])))
+ 	{
+ 	  if  ((REGNO (operands[0])) == (REGNO (operands[3])))
+ 	    return \"\\t\\t# NULL %0 <- %1 + %2; %3 <- %0 + %4\";
+ 	  else
+ 	    return \"\\t\\t# NULL %0 <- %1 + %2; %3 <- %0 + %4 and dead %0\";
+ 	}
+       else
+ 	return \"add%:\\t%3,%1,$0\\t# %0 <- %1 + %2; %3 <- %0 + %4 and dead %0\";
+     }
+   else
+     {
+       ops[0] = operands[3];
+       ops[1] = operands[1];
+       ops[2] = gen_rtx (CONST_INT, VOIDmode, i);
+       output_asm_insn (\"addi%:\\t%0,%1,%2\\t# simplification of:\", ops);
+       return \"\\t\\t\\t#  %0 <- %1 + %2; %3 <- %0 + %4 and dead %0\";
+     }
+ }")
+ 
+ 
+ 
+ 
+ (define_peephole
+   [(set (match_operand:SI 0 "general_operand" "=r")
+ 	(plus:SI (match_operand:SI 1 "general_operand" "r")
+ 		 (match_operand:SI 2 "general_operand" "IJ")))
+    (set (match_operand:SI 3 "general_operand" "=r")
+ 	(minus:SI (match_dup 0)
+ 		  (match_operand:SI 4 "general_operand" "IJ")))]
+   "(((REGNO (operands[0])) == (REGNO (operands[3])))
+     ||
+       dead_or_set_p (insn, operands[0]))
+   &&
+    (                                   /* CONSTRAINTS         */
+        (GET_CODE (operands[2]) == CONST_INT)
+     && ((CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'I'))
+         ||(CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')))
+     &&  (GET_CODE (operands[4]) == CONST_INT)
+     && ((CONST_OK_FOR_LETTER_P (INTVAL (operands[4]), 'I'))
+         ||(CONST_OK_FOR_LETTER_P (INTVAL (operands[4]), 'J'))))
+   "
+   "*
+ {
+   rtx ops[3];
+   int i;
+   i = INTVAL (operands[2]) - INTVAL (operands[4]);
+   if  (i == 0)
+     {
+       if  ((REGNO (operands[3])) == (REGNO (operands[1])))
+ 	{
+ 	  if  ((REGNO (operands[0])) == (REGNO (operands[3])))
+ 	    return \"\\t\\t# NULL %0 <- %1 + %2; %3 <- %0 - %4\";
+ 	  else
+ 	    return \"\\t\\t# NULL %0 <- %1 + %2; %3 <- %0 - %4 and dead %0\";
+ 	}
+       else
+ 	return \"add%:\\t%3,%1,$0\\t# %0 <- %1 + %2; %3 <- %0 - %4 and dead %0\";
+     }
+   else
+     {
+       ops[0] = operands[3];
+       ops[1] = operands[1];
+       ops[2] = gen_rtx (CONST_INT, VOIDmode, i);
+       output_asm_insn (\"addi%:\\t%0,%1,%2\\t# simplification of:\", ops);
+       return \"\\t\\t\\t#  %0 <- %1 + %2; %3 <- %0 - %4 and dead %0\";
+     }
+ }")
+ 
+ 
+ (define_peephole
+   [(set (match_operand:SI 0 "general_operand" "=r")
+ 	(minus:SI (match_operand:SI 1 "general_operand" "r")
+ 		  (match_operand:SI 2 "general_operand" "IJ")))
+    (set (match_operand:SI 3 "general_operand" "=r")
+ 	(plus:SI (match_dup 0)
+ 		 (match_operand:SI 4 "general_operand" "IJ")))]
+   "(((REGNO (operands[0])) == (REGNO (operands[3])))
+     ||
+       dead_or_set_p (insn, operands[0]))
+   &&
+    (                                   /* CONSTRAINTS         */
+        (GET_CODE (operands[2]) == CONST_INT)
+     && ((CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'I'))
+         ||(CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')))
+     &&  (GET_CODE (operands[4]) == CONST_INT)
+     && ((CONST_OK_FOR_LETTER_P (INTVAL (operands[4]), 'I'))
+         ||(CONST_OK_FOR_LETTER_P (INTVAL (operands[4]), 'J'))))
+   "
+   "*
+ {
+   rtx ops[3];
+   int i;
+   i = (- INTVAL (operands[2])) + INTVAL (operands[4]);
+   if  (i == 0)
+     {
+       if  ((REGNO (operands[3])) == (REGNO (operands[1])))
+ 	{
+ 	  if  ((REGNO (operands[0])) == (REGNO (operands[3])))
+ 	    return \"\\t\\t# NULL %0 <- %1 - %2; %3 <- %0 + %4\";
+ 	  else
+ 	    return \"\\t\\t# NULL %0 <- %1 - %2; %3 <- %0 + %4 and dead %0\";
+ 	}
+       else
+ 	return \"add%:\\t%3,%1,$0\\t# %0 <- %1 - %2; %3 <- %0 + %4 and dead %0\";
+     }
+   else
+     {
+       ops[0] = operands[3];
+       ops[1] = operands[1];
+       ops[2] = gen_rtx (CONST_INT, VOIDmode, i);
+       output_asm_insn (\"addi%:\\t%0,%1,%2\\t# simplification of:\", ops);
+       return \"\\t\\t\\t#  %0 <- %1 - %2; %3 <- %0 + %4 and dead %0\";
+     }
+ }")
+ 
+ 
  
+ 
+ (define_peephole
+   [(set (match_operand:SI 0 "general_operand" "=r")
+ 	(minus:SI (match_operand:SI 1 "general_operand" "r")
+ 		  (match_operand:SI 2 "general_operand" "IJ")))
+    (set (match_operand:SI 3 "general_operand" "=r")
+ 	(minus:SI (match_dup 0)
+ 		  (match_operand:SI 4 "general_operand" "IJ")))]
+   "((REGNO (operands[0]) == REGNO (operands[3])
+      || dead_or_set_p (insn, operands[0]))
+     &&
+     (GET_CODE (operands[2]) == CONST_INT
+      && (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'I')
+ 	 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
+      && GET_CODE (operands[4]) == CONST_INT
+      && (CONST_OK_FOR_LETTER_P (INTVAL (operands[4]), 'I')
+ 	 || CONST_OK_FOR_LETTER_P (INTVAL (operands[4]), 'J'))))"
+   "*
+ {
+   rtx ops[3];
+   int i = - (INTVAL (operands[2]) + INTVAL (operands[4]));
+ 
+   if  (i == 0)
+     {
+       if  (REGNO (operands[3]) == REGNO (operands[1]))
+ 	{
+ 	  if  (REGNO (operands[0]) == REGNO (operands[3]))
+ 	    return \"\\t\\t# NULL %0 <- %1 - %2; %3 <- %0 - %4\";
+ 	  else
+ 	    return \"\\t\\t# NULL %0 <- %1 - %2; %3 <- %0 - %4 and dead %0\";
+ 	}
+       else
+ 	return \"add%:\\t%3,%1,$0\\t# %0 <- %1 - %2; %3 <- %0 - %4 and dead %0\";
+     }
+   else
+     {
+       ops[0] = operands[3];
+       ops[1] = operands[1];
+       ops[2] = gen_rtx (CONST_INT, VOIDmode, i);
+       output_asm_insn (\"addi%:\\t%0,%1,%2\\t# simplification of:\", ops);
+       return \"\\t\\t\\t#  %0 <- %1 - %2; %3 <- %0 - %4 and dead %0\";
+     }
+ }")
+ 
  \f


  ;;
***************
*** 37,44 ****
  		 (match_operand:DF 2 "general_operand" "f")))]
    ""
!   "*
! {
!    return \"add.d\\t%0,%1,%2\";
! }")
  
  (define_insn "addsf3"
--- 250,254 ----
  		 (match_operand:DF 2 "general_operand" "f")))]
    ""
!   "add.d\\t%0,%1,%2")
  
  (define_insn "addsf3"
***************
*** 47,71 ****
  		 (match_operand:SF 2 "general_operand" "f")))]
    ""
!   "*
! {
!    return \"add.s\\t%0,%1,%2\";
!  }")
  
  (define_insn "addsi3"
!   [(set (match_operand:SI 0 "general_operand" "=r")
! 	(plus:SI (match_operand:SI 1 "general_operand" "r")
  		 (match_operand:SI 2 "general_operand" "rIJ")))]
    ""
    "*
! {  if(GET_CODE(operands[2])==CONST_INT)
!      { if (CONST_OK_FOR_LETTER_P(INTVAL(operands[2]),'I'))
!            { return \"addi%u\\t%0,%1,%x2\\t#addsi3\\t%1,%d2 -> %0\";
!            }
!        else  if (CONST_OK_FOR_LETTER_P(INTVAL(operands[2]),'J'))
!                  return \"add%u\\t%0,%1,$0\\t#addsi3\\t%1,%2 -> %0\";
!              else return \"ERROR op2 not zero \\t#addsi3\\t%1,%2 -> %0\";
!      }
!      else
!      return \"add%u\\t%0,%1,%2\\t#addsi3\\t%1,%2 -> %0\";
  }")
  
--- 257,279 ----
  		 (match_operand:SF 2 "general_operand" "f")))]
    ""
!   "add.s\\t%0,%1,%2")
  
  (define_insn "addsi3"
!   [(set (match_operand:SI 0 "register_operand" "=r")
! 	(plus:SI (match_operand:SI 1 "register_operand" "%r")
  		 (match_operand:SI 2 "general_operand" "rIJ")))]
    ""
    "*
! {
!   if (GET_CODE (operands[2]) == CONST_INT)
!     {
!       if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'I'))
! 	return \"addi%:\\t%0,%1,%x2\\t#addsi3\\t%1,%d2 -> %0\";
!       else  if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
! 	return \"add%:\\t%0,%1,$0\\t#addsi3\\t%1,%2 -> %0\";
!       else abort_with_insn (insn, \"Constant does not fit descriptor\");
!     }
!   else
!     return \"add%:\\t%0,%1,%2\\t#addsi3\\t%1,%2 -> %0\";
  }")
  
***************
*** 73,80 ****
    [(set (match_operand:HI 0 "general_operand" "=r")
  	(plus:HI (match_operand:HI 1 "general_operand" "%r")
! 		 (match_operand:HI 2 "general_operand" "r")))]
    ""
    "*
! { return \"add%u\\t%0,%1,%2\\t#addhi3 %1,%2 -> %0\";
  
  }")
--- 281,298 ----
    [(set (match_operand:HI 0 "general_operand" "=r")
  	(plus:HI (match_operand:HI 1 "general_operand" "%r")
! 		 (match_operand:HI 2 "general_operand" "rIJ")))]
    ""
    "*
! {
!   if (GET_CODE (operands[2]) == CONST_INT)
!     {
!       if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'I'))
! 	return \"addi%:\\t%0,%1,%x2\\t#addhi3\\t%1,%d2 -> %0\";
!       else  if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
! 	return \"add%:\\t%0,%1,$0\\t#addhi3\\t%1,%2 -> %0\";
!       else abort_with_insn (insn, \"Constant does not fit descriptor\");
!     }
!   else
!     return \"add%:\\t%0,%1,%2\\t#addhi3 %1,%2 -> %0\";
  
  }")
***************
*** 83,91 ****
    [(set (match_operand:QI 0 "general_operand" "=r")
  	(plus:QI (match_operand:QI 1 "general_operand" "%r")
! 		 (match_operand:QI 2 "general_operand" "r")))]
    ""
    "*
! { return \"add%u\\t%0,%1,%2\\t#addqi3 %1,%2 -> %0\";
!  
  }")
  \f


--- 301,318 ----
    [(set (match_operand:QI 0 "general_operand" "=r")
  	(plus:QI (match_operand:QI 1 "general_operand" "%r")
! 		 (match_operand:QI 2 "general_operand" "rIJ")))]
    ""
    "*
! {
!   if (GET_CODE (operands[2]) == CONST_INT)
!     {
!       if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'I'))
! 	return \"addi%:\\t%0,%1,%x2\\t#addqi3\\t%1,%d2 -> %0\";
!       else  if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
! 	return \"add%:\\t%0,%1,$0\\t#addqi3\\t%1,%2 -> %0\";
!       else abort_with_insn (insn, \"Constant does not fit descriptor\");
!     }
!   else
!     return \"add%:\\t%0,%1,%2\\t#addqi3 %1,%2 -> %0\";
  }")
  \f


***************
*** 97,104 ****
  		  (match_operand:DF 2 "general_operand" "f")))]
    ""
!   "*
! {
!    return \"sub.d\\t%0,%1,%2\";
! }")
  
  (define_insn "subsf3"
--- 324,328 ----
  		  (match_operand:DF 2 "general_operand" "f")))]
    ""
!   "sub.d\\t%0,%1,%2")
  
  (define_insn "subsf3"
***************
*** 107,114 ****
  		  (match_operand:SF 2 "general_operand" "f")))]
    ""
!   "*
! {
!    return \"sub.s\\t%0,%1,%2\";
! }")
  
  (define_insn "subsi3"
--- 331,335 ----
  		  (match_operand:SF 2 "general_operand" "f")))]
    ""
!   "sub.s\\t%0,%1,%2")
  
  (define_insn "subsi3"
***************
*** 118,138 ****
    ""
    "*
! {  if(GET_CODE(operands[2])==CONST_INT)
!      { if (CONST_OK_FOR_LETTER_P(INTVAL(operands[2]),'I'))
!            { rtx ops[4];
!              ops[0]=operands[0];
!              ops[1]=operands[1];
!              ops[3]=operands[2];
!              ops[2]=gen_rtx(CONST_INT,VOIDmode,-INTVAL(operands[2]));
! 	     output_asm_insn( \"addi%u\\t%0,%1,%x2\\t#subsi3\\t%1,%d3 -> %0\"
!              ,ops);
!              return \"\";
!            }
!        else  if (CONST_OK_FOR_LETTER_P(INTVAL(operands[2]),'J'))
!                  return \"sub%u\\t%0,%1,$0\\t#subsi3\\t%1,%2 -> %0\";
!              else return \"ERROR op2 not zero \\t#subsi3\\t%1,%2 -> %0\";
!      }
!      else
!      return \"sub%u\\t%0,%1,%2\\t#subsi3 %1,%2 -> %0\";
  }")
  
--- 339,362 ----
    ""
    "*
! {
!   if (GET_CODE (operands[2]) == CONST_INT)
!     {
!       if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'I'))
! 	{
! 	  rtx ops[4];
! 	  ops[0] = operands[0];
! 	  ops[1] = operands[1];
! 	  ops[3] = operands[2];
! 	  ops[2] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[2]));
! 	  output_asm_insn (\"addi%:\\t%0,%1,%x2\\t#subsi3\\t%1,%d3 -> %0\",
! 			   ops);
! 	  return \"\";
! 	}
!       else  if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
! 	return \"sub%:\\t%0,%1,$0\\t#subsi3\\t%1,%2 -> %0\";
!       else abort_with_insn (insn, \"Constant does not fit descriptor\");
!     }
!   else
!     return \"sub%:\\t%0,%1,%2\\t#subsi3 %1,%2 -> %0\";
  }")
  
***************
*** 143,147 ****
    ""
    "*
! {  return \"sub%u\\t%0,%1,%2\\t#subhi3 %1,%2 -> %0\";
  }")
  
--- 367,390 ----
    ""
    "*
! {
!   if (GET_CODE (operands[2]) == CONST_INT)
!     {
!       if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'I'))
! 	{
! 	  rtx ops[4];
! 	  ops[0] = operands[0];
! 	  ops[1] = operands[1];
! 	  ops[3] = operands[2];
! 	  ops[2] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[2]));
! 	  output_asm_insn (\"addi%:\\t%0,%1,%x2\\t#subhi3\\t%1,%d3 -> %0\"
! 			   , ops);
! 	  return \"\";
! 	}
!       else  if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
! 	return \"sub%:\\t%0,%1,$0\\t#subhi3\\t%1,%2 -> %0\";
!       else abort_with_insn (insn, \"Constant does not fit descriptor\");
!     }
!   else
!     return \"sub%:\\t%0,%1,%2\\t#subhi3 %1,%2 -> %0\";
  }")
  
***************
*** 152,156 ****
    ""
    "*
! {  return \"sub%u\\t%0,%1,%2\\t#subqi3 %1,%2 -> %0\";
  }")
  \f


--- 395,418 ----
    ""
    "*
! {
!   if (GET_CODE (operands[2]) == CONST_INT)
!     {
!       if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'I'))
! 	{
! 	  rtx ops[4];
! 	  ops[0] = operands[0];
! 	  ops[1] = operands[1];
! 	  ops[3] = operands[2];
! 	  ops[2] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[2]));
! 	  output_asm_insn (\"addi%:\\t%0,%1,%x2\\t#subqi3\\t%1,%d3 -> %0\"
! 			   , ops);
! 	  return \"\";
! 	}
!       else  if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
! 	return \"sub%:\\t%0,%1,$0\\t#subqi3\\t%1,%2 -> %0\";
!       else abort_with_insn (insn, \"Constant does not fit descriptor\");
!     }
!   else
!     return \"sub%:\\t%0,%1,%2\\t#subqi3 %1,%2 -> %0\";
  }")
  \f


***************
*** 162,168 ****
  		 (match_operand:DF 2 "general_operand" "f")))]
    ""
!   "*
! {   return \"mul.d\\t%0,%1,%2\";
! }")
  
  (define_insn "mulsf3"
--- 424,428 ----
  		 (match_operand:DF 2 "general_operand" "f")))]
    ""
!   "mul.d\\t%0,%1,%2")
  
  (define_insn "mulsf3"
***************
*** 171,177 ****
  		 (match_operand:SF 2 "general_operand" "f")))]
    ""
!   "*
! {   return \"mul.s\\t%0,%1,%2\";
! }")
  
  (define_insn "mulsi3"
--- 431,435 ----
  		 (match_operand:SF 2 "general_operand" "f")))]
    ""
!   "mul.s\\t%0,%1,%2")
  
  (define_insn "mulsi3"
***************
*** 180,186 ****
  		 (match_operand:SI 2 "general_operand" "r")))]
    ""
!   "*
! {  return \"mul\\t%0,%1,%2\\t#mulsi3 %1,%2 -> %0\";
! }")
  
  (define_insn "mulhi3"
--- 438,442 ----
  		 (match_operand:SI 2 "general_operand" "r")))]
    ""
!   "mul\\t%0,%1,%2\\t#mulsi3 %1,%2 -> %0")
  
  (define_insn "mulhi3"
***************
*** 189,195 ****
  		 (match_operand:HI 2 "general_operand" "r")))]
    ""
!   "*
! {  return \"mul\\t%0,%1,%2\\t#mulhi3 %1,%2 -> %0\";
! }")
  
  (define_insn "mulqi3"
--- 445,449 ----
  		 (match_operand:HI 2 "general_operand" "r")))]
    ""
!   "mul\\t%0,%1,%2\\t#mulhi3 %1,%2 -> %0")
  
  (define_insn "mulqi3"
***************
*** 198,204 ****
  		 (match_operand:QI 2 "general_operand" "r")))]
    ""
!   "*
! {  return \"mul\\t%0,%1,%2\\t#mulhi3 %1,%2 -> %0\";
!  }")
  \f


  ;;- Divide instructions.
--- 452,456 ----
  		 (match_operand:QI 2 "general_operand" "r")))]
    ""
!   "mul\\t%0,%1,%2\\t#mulhi3 %1,%2 -> %0")
  \f


  ;;- Divide instructions.
***************
*** 209,215 ****
  		(match_operand:DF 2 "general_operand" "f")))]
    ""
!   "*
! {  return \"div.d\\t%0,\\t%1,%2\";
! }")
  
  (define_insn "divsf3"
--- 461,465 ----
  		(match_operand:DF 2 "general_operand" "f")))]
    ""
!   "div.d\\t%0,\\t%1,%2")
  
  (define_insn "divsf3"
***************
*** 218,224 ****
  		(match_operand:SF 2 "general_operand" "f")))]
    ""
!   "*
! {  return \"div.s\\t%0,%1,%2\";
! }")
  
  (define_insn "divsi3"
--- 468,472 ----
  		(match_operand:SF 2 "general_operand" "f")))]
    ""
!   "div.s\\t%0,%1,%2")
  
  (define_insn "divsi3"
***************
*** 227,233 ****
  		(match_operand:SI 2 "general_operand" "r")))]
    ""
!   "*
! {  return \"div\\t%0,%1,%2\\t#divsi3 %1,%2 -> %0\";
!  }")
  
  (define_insn "divhi3"
--- 475,479 ----
  		(match_operand:SI 2 "general_operand" "r")))]
    ""
!   "div\\t%0,%1,%2\\t#divsi3 %1,%2 -> %0")
  
  (define_insn "divhi3"
***************
*** 236,242 ****
  		(match_operand:HI 2 "general_operand" "r")))]
    ""
!   "*
! {  return \"div\\t%0,%1,%2\\t#divhi3 %1,%2 -> %0\";
! }")
  
  (define_insn "divqi3"
--- 482,486 ----
  		(match_operand:HI 2 "general_operand" "r")))]
    ""
!   "div\\t%0,%1,%2\\t#divhi3 %1,%2 -> %0")
  
  (define_insn "divqi3"
***************
*** 245,251 ****
  		(match_operand:QI 2 "general_operand" "r")))]
    ""
!   "*
! {  return \"div\\t%0,%1,%2\\t#divqi3 %1,%2 -> %0\";
! }")
  \f


  ;;
--- 489,493 ----
  		(match_operand:QI 2 "general_operand" "r")))]
    ""
!   "div\\t%0,%1,%2\\t#divqi3 %1,%2 -> %0")
  \f


  ;;
***************
*** 256,317 ****
  ;;  ....................
  ;;
  (define_insn "anddi3"
!  [(set (match_operand:DI 0 "general_operand" "=r")
! 	(and:DI (match_operand:DI 1 "general_operand" "r")
                  (match_operand:DI 2 "general_operand" "r")))]
    ""
!  "*
!   {rtx xops[3];
!     if(  (REGNO(operands[0]) != (REGNO(operands[1]) +1))
!        &&
!          (REGNO(operands[0]) != (REGNO(operands[2]) +1)))
!     {                                 /* TAKE CARE OF OVERLAPS */
!      xops[0] =  gen_rtx(REG,SImode,REGNO(operands[0]));
!      xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1]));
!      xops[2] =  gen_rtx(REG,SImode,REGNO(operands[2]));
!      output_asm_insn(\"and\\t%0,%1,%2\\t#anddi %1,%2 -> %0\",xops);
!      xops[0] =  gen_rtx(REG,SImode, REGNO(xops[0])+1);
!      xops[1] =  gen_rtx(REG,SImode, REGNO(xops[1])+1);
!      xops[2] =  gen_rtx(REG,SImode, REGNO(xops[2])+1);
!      output_asm_insn(\"and\\t%0,%1,%2\\t#anddi %1,%2 -> %0\",xops);
!      }
!     else
!        abort();
!     return \"\";  } 
!  "
! )
  
  (define_insn "andsi3"
    [(set (match_operand:SI 0 "general_operand" "=r,&r")
! 	(and:SI (match_operand:SI 1 "general_operand" "r,r")
! 		 (match_operand:SI 2 "general_operand" "rJ,I")))]
    ""
    "*
! { rtx xops[3];
!     if(GET_CODE(operands[2])==CONST_INT)
!      { if (CONST_OK_FOR_LETTER_P(INTVAL(operands[2]),'I'))
!          if(INTVAL(operands[2]) >= 0)
!            { return \"andi\\t%0,%1,%x2\\t#andsi3\\t%1,%d2 -> %0\";
!            }
! 	 else
!            { xops[0]= operands[0];
!              xops[1]= operands[1];;
!              xops[2]= gen_rtx(CONST_INT,VOIDmode,
! 				        (INTVAL(operands[2]))>>16);
!              output_asm_insn(\"lui\\t%0,%x2\\t#load higher part (andsi3)\",
! 					  xops);
!              xops[2]= gen_rtx(CONST_INT,VOIDmode,
! 				       0xffff & (INTVAL(operands[2])));
!              output_asm_insn(\"addi%u\\t%0,$0,%x2\\t#load lower part (andsi3)\",
! 					  xops);
!              output_asm_insn(\"and\\t%0,%0,%1\\t#andsi3\",xops);
!              return \"\";
!            }
!        else  if (CONST_OK_FOR_LETTER_P(INTVAL(operands[2]),'J'))
!                  return \"and\\t%0,%1,$0\\t#andsi3\\t%1,%2 -> %0\";
!              else return \"ERROR op2 not zero \\t#andsi3\\t%1,%2 -> %0\";
!      }
!      else
!      return \"and\\t%0,%1,%2\\t#andsi3\\t%1,%2 -> %0\";
  }")
  
--- 498,565 ----
  ;;  ....................
  ;;
+ 
  (define_insn "anddi3"
!   [(set (match_operand:DI 0 "general_operand" "=r")
! 	(and:DI (match_operand:DI 1 "general_operand" "%r")
                  (match_operand:DI 2 "general_operand" "r")))]
    ""
!   "*
! {
!   rtx xops[3];
!   if ((REGNO (operands[0]) != (REGNO (operands[1]) +1))
!       &&
!       (REGNO (operands[0]) != (REGNO (operands[2]) +1)))
!     {
!       /* TAKE CARE OF OVERLAPS */
!       xops[0] =  gen_rtx (REG, SImode, REGNO (operands[0]));
!       xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1]));
!       xops[2] =  gen_rtx (REG, SImode, REGNO (operands[2]));
!       output_asm_insn (\"and\\t%0,%1,%2\\t#anddi %1,%2 -> %0\", xops);
!       xops[0] =  gen_rtx (REG, SImode, REGNO (xops[0])+1);
!       xops[1] =  gen_rtx (REG, SImode, REGNO (xops[1])+1);
!       xops[2] =  gen_rtx (REG, SImode, REGNO (xops[2])+1);
!       output_asm_insn (\"and\\t%0,%1,%2\\t#anddi %1,%2 -> %0\", xops);
!     }
!   else
!     abort ();
!   return \"\";
! }")
  
  (define_insn "andsi3"
    [(set (match_operand:SI 0 "general_operand" "=r,&r")
! 	(and:SI (match_operand:SI 1 "general_operand" "%r,r")
! 		(match_operand:SI 2 "general_operand" "rJ,I")))]
    ""
    "*
! {
!   rtx xops[3];
!   if (GET_CODE (operands[2]) == CONST_INT)
!     {
!       if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'I'))
! 	if (INTVAL (operands[2]) >= 0)
! 	  {
! 	    return \"andi\\t%0,%1,%x2\\t#andsi3\\t%1,%d2 -> %0\";
! 	  }
! 	else
! 	  {
! 	    xops[0] = operands[0];
! 	    xops[1] = operands[1];;
! 	    xops[2] = gen_rtx (CONST_INT, VOIDmode,
! 			       (INTVAL (operands[2]))>>16);
! 	    output_asm_insn (\"lui\\t%0,%x2\\t#load higher part (andsi3)\",
! 			     xops);
! 	    xops[2] = gen_rtx (CONST_INT, VOIDmode,
! 			       0xffff & (INTVAL (operands[2])));
! 	    output_asm_insn (\"addi%:\\t%0,$0,%x2\\t#load lower part (andsi3)\",
! 			     xops);
! 	    output_asm_insn (\"and\\t%0,%0,%1\\t#andsi3\", xops);
! 	    return \"\";
! 	  }
!       else  if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
! 	return \"and\\t%0,%1,$0\\t#andsi3\\t%1,%2 -> %0\";
!       else return \"ERROR op2 not zero \\t#andsi3\\t%1,%2 -> %0\";
!     }
!   else
!     return \"and\\t%0,%1,%2\\t#andsi3\\t%1,%2 -> %0\";
  }")
  
***************
*** 319,328 ****
    [(set (match_operand:HI 0 "general_operand" "=r")
  	(and:HI (match_operand:HI 1 "general_operand" "%r")
! 		 (match_operand:HI 2 "general_operand" "r")))]
    ""
!   "*
! { return \"and\\t%0,%1,%2\\t#andhi3 %1,%2 -> %0\";
! 
! }")
  
  (define_insn "andqi3"
--- 567,573 ----
    [(set (match_operand:HI 0 "general_operand" "=r")
  	(and:HI (match_operand:HI 1 "general_operand" "%r")
! 		(match_operand:HI 2 "general_operand" "r")))]
    ""
!   "and\\t%0,%1,%2\\t#andhi3 %1,%2 -> %0")
  
  (define_insn "andqi3"
***************
*** 329,380 ****
    [(set (match_operand:QI 0 "general_operand" "=r")
  	(and:QI (match_operand:QI 1 "general_operand" "%r")
! 		 (match_operand:QI 2 "general_operand" "r")))]
    ""
!   "*
! { return \"and\\t%0,%1,%2\\t#andqi3 %1,%2 -> %0\";
!  
! }")
  (define_insn "iordi3"
!  [(set (match_operand:DI 0 "general_operand" "=r")
! 	(ior:DI (match_operand:DI 1 "general_operand" "r")
                  (match_operand:DI 2 "general_operand" "r")))]
    ""
!  "*
!   {rtx xops[3];
!     if(  (REGNO(operands[0]) != (REGNO(operands[1]) +1))
!        &&
!          (REGNO(operands[0]) != (REGNO(operands[2]) +1)))
!     {                                 /* TAKE CARE OF OVERLAPS */
!      xops[0] =  gen_rtx(REG,SImode,REGNO(operands[0]));
!      xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1]));
!      xops[2] =  gen_rtx(REG,SImode,REGNO(operands[2]));
!      output_asm_insn(\"or\\t%0,%1,%2\\t#iordi3 %1,%2 -> %0\",xops);
!      xops[0] =  gen_rtx(REG,SImode, REGNO(xops[0])+1);
!      xops[1] =  gen_rtx(REG,SImode, REGNO(xops[1])+1);
!      xops[2] =  gen_rtx(REG,SImode, REGNO(xops[2])+1);
!      output_asm_insn(\"or\\t%0,%1,%2\\t#iordi3 %1,%2 -> %0\",xops);
!      }
!     else
!        abort();
!     return \"\";  } 
!  "
! )
  
  (define_insn "iorsi3"
    [(set (match_operand:SI 0 "general_operand" "=r")
! 	(ior:SI (match_operand:SI 1 "general_operand" "r")
! 		 (match_operand:SI 2 "general_operand" "rIJ")))]
    ""
    "*
! {  if(GET_CODE(operands[2])==CONST_INT)
!      { if (CONST_OK_FOR_LETTER_P(INTVAL(operands[2]),'I'))
!            { return \"ori\\t%0,%1,%x2\\t#iorsi3\\t%1,%d2 -> %0\";
!            }
!        else  if (CONST_OK_FOR_LETTER_P(INTVAL(operands[2]),'J'))
!                  return \"or\\t%0,%1,$0\\t#iorsi3\\t%1,%2 -> %0\";
!              else return \"ERROR op2 not zero \\t#iorsi3\\t%1,%2 -> %0\";
!      }
!      else
!      return \"or\\t%0,%1,%2\\t#iorsi3\\t%1,%2 -> %0\";
  }")
  
--- 574,627 ----
    [(set (match_operand:QI 0 "general_operand" "=r")
  	(and:QI (match_operand:QI 1 "general_operand" "%r")
! 		(match_operand:QI 2 "general_operand" "r")))]
    ""
!   "and\\t%0,%1,%2\\t#andqi3 %1,%2 -> %0")
! 
  (define_insn "iordi3"
!   [(set (match_operand:DI 0 "general_operand" "=r")
! 	(ior:DI (match_operand:DI 1 "general_operand" "%r")
                  (match_operand:DI 2 "general_operand" "r")))]
    ""
!   "*
! {
!   rtx xops[3];
!   if ((REGNO (operands[0]) != (REGNO (operands[1]) +1))
!       &&
!       (REGNO (operands[0]) != (REGNO (operands[2]) +1)))
!     {
!       /* TAKE CARE OF OVERLAPS */
!       xops[0] =  gen_rtx (REG, SImode, REGNO (operands[0]));
!       xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1]));
!       xops[2] =  gen_rtx (REG, SImode, REGNO (operands[2]));
!       output_asm_insn (\"or\\t%0,%1,%2\\t#iordi3 %1,%2 -> %0\", xops);
!       xops[0] =  gen_rtx (REG, SImode, REGNO (xops[0])+1);
!       xops[1] =  gen_rtx (REG, SImode, REGNO (xops[1])+1);
!       xops[2] =  gen_rtx (REG, SImode, REGNO (xops[2])+1);
!       output_asm_insn (\"or\\t%0,%1,%2\\t#iordi3 %1,%2 -> %0\", xops);
!     }
!   else
!     abort ();
!   return \"\";
! }")
  
  (define_insn "iorsi3"
    [(set (match_operand:SI 0 "general_operand" "=r")
! 	(ior:SI (match_operand:SI 1 "general_operand" "%r")
! 		(match_operand:SI 2 "general_operand" "rIJ")))]
    ""
    "*
! {
!   if (GET_CODE (operands[2]) == CONST_INT)
!     {
!       if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'I'))
! 	{
! 	  return \"ori\\t%0,%1,%x2\\t#iorsi3\\t%1,%d2 -> %0\";
! 	}
!       else  if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
! 	return \"or\\t%0,%1,$0\\t#iorsi3\\t%1,%2 -> %0\";
!       else return \"ERROR op2 not zero \\t#iorsi3\\t%1,%2 -> %0\";
!     }
!   else
!     return \"or\\t%0,%1,%2\\t#iorsi3\\t%1,%2 -> %0\";
  }")
  
***************
*** 382,391 ****
    [(set (match_operand:HI 0 "general_operand" "=r")
  	(ior:HI (match_operand:HI 1 "general_operand" "%r")
! 		 (match_operand:HI 2 "general_operand" "r")))]
    ""
!   "*
! { return \"or\\t%0,%1,%2\\t#iorhi3 %1,%2 -> %0\";
! 
! }")
  
  (define_insn "iorqi3"
--- 629,635 ----
    [(set (match_operand:HI 0 "general_operand" "=r")
  	(ior:HI (match_operand:HI 1 "general_operand" "%r")
! 		(match_operand:HI 2 "general_operand" "r")))]
    ""
!   "or\\t%0,%1,%2\\t#iorhi3 %1,%2 -> %0")
  
  (define_insn "iorqi3"
***************
*** 392,443 ****
    [(set (match_operand:QI 0 "general_operand" "=r")
  	(ior:QI (match_operand:QI 1 "general_operand" "%r")
! 		 (match_operand:QI 2 "general_operand" "r")))]
    ""
!   "*
! { return \"or\\t%0,%1,%2\\t#iorqi3 %1,%2 -> %0\";
!  
! }")
  (define_insn "xordi3"
!  [(set (match_operand:DI 0 "general_operand" "=r")
  	(xor:DI (match_operand:DI 1 "general_operand" "r")
                  (match_operand:DI 2 "general_operand" "r")))]
    ""
!  "*
!   {rtx xops[3];
!     if(  (REGNO(operands[0]) != (REGNO(operands[1]) +1))
!        &&
!          (REGNO(operands[0]) != (REGNO(operands[2]) +1)))
!     {                                 /* TAKE CARE OF OVERLAPS */
!      xops[0] =  gen_rtx(REG,SImode,REGNO(operands[0]));
!      xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1]));
!      xops[2] =  gen_rtx(REG,SImode,REGNO(operands[2]));
!      output_asm_insn(\"xor\\t%0,%1,%2\\t#xordi3 %1,%2 -> %0\",xops);
!      xops[0] =  gen_rtx(REG,SImode, REGNO(xops[0])+1);
!      xops[1] =  gen_rtx(REG,SImode, REGNO(xops[1])+1);
!      xops[2] =  gen_rtx(REG,SImode, REGNO(xops[2])+1);
!      output_asm_insn(\"xor\\t%0,%1,%2\\t#xordi3 %1,%2 -> %0\",xops);
!      }
!     else
!        abort();
!     return \"\";  } 
!  "
! )
  
  (define_insn "xorsi3"
    [(set (match_operand:SI 0 "general_operand" "=r")
! 	(xor:SI (match_operand:SI 1 "general_operand" "r")
! 		 (match_operand:SI 2 "general_operand" "rIJ")))]
    ""
    "*
! {  if(GET_CODE(operands[2])==CONST_INT)
!      { if (CONST_OK_FOR_LETTER_P(INTVAL(operands[2]),'I'))
!            { return \"xori\\t%0,%1,%x2\\t#xorsi3\\t%1,%d2 -> %0\";
!            }
!        else  if (CONST_OK_FOR_LETTER_P(INTVAL(operands[2]),'J'))
!                  return \"xor\\t%0,%1,$0\\t#xorsi3\\t%1,%2 -> %0\";
!              else return \"ERROR op2 not zero \\t#xorsi3\\t%1,%2 -> %0\";
!      }
!      else
!      return \"xor\\t%0,%1,%2\\t#xorsi3\\t%1,%2 -> %0\";
  }")
  
--- 636,689 ----
    [(set (match_operand:QI 0 "general_operand" "=r")
  	(ior:QI (match_operand:QI 1 "general_operand" "%r")
! 		(match_operand:QI 2 "general_operand" "r")))]
    ""
!   "or\\t%0,%1,%2\\t#iorqi3 %1,%2 -> %0")
! 
  (define_insn "xordi3"
!   [(set (match_operand:DI 0 "general_operand" "=r")
  	(xor:DI (match_operand:DI 1 "general_operand" "r")
                  (match_operand:DI 2 "general_operand" "r")))]
    ""
!   "*
! {
!   rtx xops[3];
!   if ((REGNO (operands[0]) != (REGNO (operands[1]) +1))
!       &&
!       (REGNO (operands[0]) != (REGNO (operands[2]) +1)))
!     {
!       /* TAKE CARE OF OVERLAPS */
!       xops[0] =  gen_rtx (REG, SImode, REGNO (operands[0]));
!       xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1]));
!       xops[2] =  gen_rtx (REG, SImode, REGNO (operands[2]));
!       output_asm_insn (\"xor\\t%0,%1,%2\\t#xordi3 %1,%2 -> %0\", xops);
!       xops[0] =  gen_rtx (REG, SImode, REGNO (xops[0])+1);
!       xops[1] =  gen_rtx (REG, SImode, REGNO (xops[1])+1);
!       xops[2] =  gen_rtx (REG, SImode, REGNO (xops[2])+1);
!       output_asm_insn (\"xor\\t%0,%1,%2\\t#xordi3 %1,%2 -> %0\", xops);
!     }
!   else
!     abort ();
!   return \"\";
! }")
  
  (define_insn "xorsi3"
    [(set (match_operand:SI 0 "general_operand" "=r")
! 	(xor:SI (match_operand:SI 1 "general_operand" "%r")
! 		(match_operand:SI 2 "general_operand" "rIJ")))]
    ""
    "*
! {
!   if (GET_CODE (operands[2]) == CONST_INT)
!     {
!       if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'I'))
! 	{
! 	  return \"xori\\t%0,%1,%x2\\t#xorsi3\\t%1,%d2 -> %0\";
! 	}
!       else  if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
! 	return \"xor\\t%0,%1,$0\\t#xorsi3\\t%1,%2 -> %0\";
!       else return \"ERROR op2 not zero \\t#xorsi3\\t%1,%2 -> %0\";
!     }
!   else
!     return \"xor\\t%0,%1,%2\\t#xorsi3\\t%1,%2 -> %0\";
  }")
  
***************
*** 445,454 ****
    [(set (match_operand:HI 0 "general_operand" "=r")
  	(xor:HI (match_operand:HI 1 "general_operand" "%r")
! 		 (match_operand:HI 2 "general_operand" "r")))]
    ""
!   "*
! { return \"xor\\t%0,%1,%2\\t#xorhi3 %1,%2 -> %0\";
! 
! }")
  
  (define_insn "xorqi3"
--- 691,697 ----
    [(set (match_operand:HI 0 "general_operand" "=r")
  	(xor:HI (match_operand:HI 1 "general_operand" "%r")
! 		(match_operand:HI 2 "general_operand" "r")))]
    ""
!   "xor\\t%0,%1,%2\\t#xorhi3 %1,%2 -> %0")
  
  (define_insn "xorqi3"
***************
*** 455,464 ****
    [(set (match_operand:QI 0 "general_operand" "=r")
  	(xor:QI (match_operand:QI 1 "general_operand" "%r")
! 		 (match_operand:QI 2 "general_operand" "r")))]
    ""
!   "*
! { return \"xor\\t%0,%1,%2\\t#xorqi3 %1,%2 -> %0\";
!  
! }")
  \f


  ;;
--- 698,704 ----
    [(set (match_operand:QI 0 "general_operand" "=r")
  	(xor:QI (match_operand:QI 1 "general_operand" "%r")
! 		(match_operand:QI 2 "general_operand" "r")))]
    ""
!   "xor\\t%0,%1,%2\\t#xorqi3 %1,%2 -> %0")
  \f


  ;;
***************
*** 465,469 ****
  ;;  ....................
  ;;
! ;;          TRUNCATION 
  ;;
  ;;  ....................
--- 705,709 ----
  ;;  ....................
  ;;
! ;;          TRUNCATION
  ;;
  ;;  ....................
***************
*** 473,478 ****
  ;; are ordered widest source type first.
  
- ;;                                      CHARACTERS ARE CONSIDERED UNSIGNED
- ;;                                      --------------- cf. tm.h ---------
  
  (define_insn "truncsiqi2"
--- 713,716 ----
***************
*** 480,508 ****
  	(truncate:QI (match_operand:SI 1 "general_operand" "r")))]
    ""
!   "* 
!    if (DEFAULT_SIGNED_CHAR)
!    return \"ERROR(SIGNED CHAR)\\tandi\\t%0,%1,0xff\\t#truncsiqi2\\t %1 -> %0\";
!    else
!    return \"andi\\t%0,%1,0xff\\t#truncsiqi2\\t %1 -> %0\";"
! )
! (define_insn ""
!   [(set (match_operand:QI 0 "general_operand" "=r,r")
! 	(subreg:QI (match_operand:SI 1 "general_operand" "r,*m") 0))]
!   ""
!   "*
!    if (GET_CODE(operands[1]) == MEM)
!       { rtx nops[3];
!         nops[0]= operands[0];
!         nops[2]=operands[1];
!         nops[1]= addr_compensate(operands[1], QImode, SImode,0);
!         output_asm_insn(\"lbu\\t%0,%1\\t#(subreg:QI %1 0)->%0\",nops);
!         return \"\";
!       }
!    else
!    if (DEFAULT_SIGNED_CHAR)
!    return \"ERROR(SIGNED CHAR)\\tandi\\t%0,%1,0xff\\t#subreg truncsiqi2\\t %1 -> %0\";
!    else
!    return \"andi\\t%0,%1,0xff\\t#subreg truncsiqi2\\t %1 -> %0\";"
! )
  
  (define_insn "truncsihi2"
--- 718,722 ----
  	(truncate:QI (match_operand:SI 1 "general_operand" "r")))]
    ""
!   "andi\\t%0,%1,0xff\\t#truncsiqi2\\t %1 -> %0")
  
  (define_insn "truncsihi2"
***************
*** 510,515 ****
  	(truncate:HI (match_operand:SI 1 "general_operand" "r")))]
    ""
!   "* 
!     output_asm_insn(\"sll\\t%0,%1,0x10\\t#truncsihi2\\t %1 -> %0\",
                      operands);
      return \"sra\\t%0,%0,0x10\\t#truncsihi2\\t %1 -> %0\";
--- 724,729 ----
  	(truncate:HI (match_operand:SI 1 "general_operand" "r")))]
    ""
!   "*
!     output_asm_insn (\"sll\\t%0,%1,0x10\\t#truncsihi2\\t %1 -> %0\",
                      operands);
      return \"sra\\t%0,%0,0x10\\t#truncsihi2\\t %1 -> %0\";
***************
*** 516,529 ****
  ")
  
- (define_insn ""
-   [(set (match_operand:HI 0 "general_operand" "=r")
- 	(subreg:HI (match_operand:SI 1 "general_operand" "r") 0))]
-   ""
-   "* 
-     output_asm_insn(\"sll\\t%0,%1,0x10\\t#subreg truncsihi2\\t %1 -> %0\",
-                     operands);
-     return \"sra\\t%0,%0,0x10\\t#subreg truncsihi2\\t %1 -> %0\";
- ")
- 
  (define_insn "trunchiqi2"
    [(set (match_operand:QI 0 "general_operand" "=r")
--- 730,733 ----
***************
*** 530,550 ****
  	(truncate:QI (match_operand:HI 1 "general_operand" "r")))]
    ""
!   "* 
!    if (DEFAULT_SIGNED_CHAR)
!    return \"ERROR(SIGNED CHAR)\\tandi\\t%0,%1,0xff\\t#trunchiqi2\\t %1 -> %0\";
!    else
!    return \"andi\\t%0,%1,0xff\\t#trunchiqi2\\t %1 -> %0\";")
! 
! (define_insn ""
!   [(set (match_operand:QI 0 "general_operand" "=r")
! 	(subreg:QI (match_operand:HI 1 "general_operand" "r") 0))]
!   ""
!   "* 
!    if (DEFAULT_SIGNED_CHAR)
!    return \"ERROR(SIGNED CHAR)\\tandi\\t%0,%1,0xff\\t#subreg trunchiqi2\\t %1 -> %0\";
!    else
!    return \"andi\\t%0,%1,0xff\\t#subreg trunchiqi2\\t %1 -> %0\";")
  
- 
  (define_insn "truncdfsf2"
    [(set (match_operand:SF 0 "general_operand" "=f")
--- 734,739 ----
  	(truncate:QI (match_operand:HI 1 "general_operand" "r")))]
    ""
!   "andi\\t%0,%1,0xff\\t#trunchiqi2\\t %1 -> %0")
  
  (define_insn "truncdfsf2"
    [(set (match_operand:SF 0 "general_operand" "=f")
***************
*** 552,558 ****
    ""
    "cvt.s.d\\t%0,%1\\t#truncdfsf2\\t %1 -> %0")
- 
- 
- 
  \f


  ;;
--- 741,744 ----
***************
*** 567,583 ****
  ;; are ordered widest source type first.
  
! ;;                                      CHARACTERS ARE CONSIDERED UNSIGNED
! ;;                                      --------------- cf. tm.h ---------
  
  (define_insn "zero_extendhisi2"
!   [(set (match_operand:SI 0 "general_operand" "=r")
! 	(zero_extend:SI (match_operand:HI 1 "general_operand" "r")))]
    ""
!   "* 
!     output_asm_insn(\"sll\\t%0,%1,0x10\\t#zero_extendhisi2\\t %1 -> %0\",
!                     operands);
!     return \"srl\\t%0,%0,0x10\\t#zero_extendhisi2\\t %1 -> %0\";
!   "
! )
  
  (define_insn "zero_extendqihi2"
--- 753,773 ----
  ;; are ordered widest source type first.
  
! 
  
  (define_insn "zero_extendhisi2"
!   [(set (match_operand:SI 0 "general_operand" "=r,r")
! 	(zero_extend:SI (match_operand:HI 1 "general_operand" "r,m")))]
    ""
!   "*
! {
!   if (which_alternative == 0)
!     {
!       output_asm_insn (\"sll\\t%0,%1,0x10\\t#zero_extendhisi2\\t %1 -> %0\",
! 		       operands);
!       return \"srl\\t%0,%0,0x10\\t#zero_extendhisi2\\t %1 -> %0\";
!     }
!   else
!     return \"lhu\\t%0,%1\\t#zero extendhisi2 %1 -> %0\";
! }")
  
  (define_insn "zero_extendqihi2"
***************
*** 585,604 ****
  	(zero_extend:HI (match_operand:QI 1 "general_operand" "r")))]
    ""
!   "* 
!     output_asm_insn(\"sll\\t%0,%1,0x18\\t#zero_extendqihi2\\t %1 -> %0\",
                      operands);
      return \"srl\\t%0,%0,0x18\\t#zero_extendqihi2\\t %1 -> %0\";
!   "
! )
  
  
  (define_insn "zero_extendqisi2"
!   [(set (match_operand:SI 0 "general_operand" "=r")
! 	(zero_extend:SI (match_operand:QI 1 "general_operand" "r")))]
    ""
!   "* 
!     return \"andi\\t%0,%1,0xff\\t#zero_extendqisi2\\t %1 -> %0\";
!   "
! )
  
  \f


--- 775,798 ----
  	(zero_extend:HI (match_operand:QI 1 "general_operand" "r")))]
    ""
!   "*
!     output_asm_insn (\"sll\\t%0,%1,0x18\\t#zero_extendqihi2\\t %1 -> %0\",
                      operands);
      return \"srl\\t%0,%0,0x18\\t#zero_extendqihi2\\t %1 -> %0\";
!   ")
  
  
  (define_insn "zero_extendqisi2"
!   [(set (match_operand:SI 0 "general_operand" "=r,r")
! 	(zero_extend:SI (match_operand:QI 1 "general_operand" "r,m")))]
    ""
!   "*
! {
!   if (which_alternative == 0)
!     {
!       return \"andi\\t%0,%1,0xff\\t#zero_extendqisi2\\t %1 -> %0\";
!     }
!   else
!     return \"lbu\\t%0,%1\\t#zero extendqisi2 %1 -> %0\";
! }")
  
  \f


***************
*** 614,630 ****
  ;; are ordered widest source type first.
  
! ;;                                      CHARACTERS ARE CONSIDERED UNSIGNED
! ;;                                      --------------- cf. tm.h ---------
  
  (define_insn "extendhisi2"
!   [(set (match_operand:SI 0 "general_operand" "=r")
! 	(sign_extend:SI (match_operand:HI 1 "general_operand" "r")))]
    ""
!   "* 
!     output_asm_insn(\"sll\\t%0,%1,0x10\\t#extendhisi2\\t %1 -> %0\",
!                     operands);
!     return \"sra\\t%0,%0,0x10\\t#extendhisi2\\t %1 -> %0\";
!   "
! )
  
  (define_insn "extendqihi2"
--- 808,828 ----
  ;; are ordered widest source type first.
  
! 
  
  (define_insn "extendhisi2"
!   [(set (match_operand:SI 0 "general_operand" "=r,r")
! 	(sign_extend:SI (match_operand:HI 1 "general_operand" "r,m")))]
    ""
!   "*
! {
!   if (which_alternative == 0)
!     {
!       output_asm_insn (\"sll\\t%0,%1,0x10\\t#sign extendhisi2\\t %1 -> %0\",
! 		       operands);
!       return \"sra\\t%0,%0,0x10\\t#sign extendhisi2\\t %1 -> %0\";
!     }
!   else
!     return \"lh\\t%0,%1\\t#sign extendhisi2 %1 -> %0\";
! }")
  
  (define_insn "extendqihi2"
***************
*** 632,653 ****
  	(sign_extend:HI (match_operand:QI 1 "general_operand" "r")))]
    ""
!   "* 
!     output_asm_insn(\"sll\\t%0,%1,0x18\\t#extendqihi2\\t %1 -> %0\",
                      operands);
!     return \"sra\\t%0,%0,0x18\\t#extendqihi2\\t %1 -> %0\";
!   "
! )
  
  
  (define_insn "extendqisi2"
!   [(set (match_operand:SI 0 "general_operand" "=r")
! 	(sign_extend:SI (match_operand:QI 1 "general_operand" "r")))]
    ""
!   "* 
!     output_asm_insn(\"sll\\t%0,%1,0x18\\t#extendqisi2\\t %1 -> %0\",
!                     operands);
!     return \"sra\\t%0,%0,0x18\\t#extendqisi2\\t %1 -> %0\";
!   "
! )
  
  
--- 830,855 ----
  	(sign_extend:HI (match_operand:QI 1 "general_operand" "r")))]
    ""
!   "*
!     output_asm_insn (\"sll\\t%0,%1,0x18\\t#sign extendqihi2\\t %1 -> %0\",
                      operands);
!     return \"sra\\t%0,%0,0x18\\t#sign extendqihi2\\t %1 -> %0\";
!   ")
  
  
  (define_insn "extendqisi2"
!   [(set (match_operand:SI 0 "general_operand" "=r,r")
! 	(sign_extend:SI (match_operand:QI 1 "general_operand" "r,m")))]
    ""
!   "*
! {
!   if (which_alternative == 0)
!     {
!       output_asm_insn (\"sll\\t%0,%1,0x18\\t#sign extendqisi2\\t %1 -> %0\",
! 		       operands);
!       return \"sra\\t%0,%0,0x18\\t#sign extendqisi2\\t %1 -> %0\";
!     }
!   else
!     return \"lb\\t%0,%1\\t#sign extendqisi2 %1 -> %0\";
! }")
  
  
***************
*** 656,663 ****
  	(float_extend:DF (match_operand:SF 1 "general_operand" "f")))]
    ""
!   "* 
!     return \"cvt.d.s\\t%0,%1\\t#extendsfdf2\\t %1 -> %0\";
!   "
! )
  \f


  
--- 858,862 ----
  	(float_extend:DF (match_operand:SF 1 "general_operand" "f")))]
    ""
!   "cvt.d.s\\t%0,%1\\t#extendsfdf2\\t %1 -> %0")
  \f


  
***************
*** 668,671 ****
--- 867,872 ----
  ;;
  ;;  ....................
+ 
+ 
  (define_insn "fix_truncdfsi2"
    [(set (match_operand:SI 0 "general_operand" "=r")
***************
*** 673,678 ****
     (clobber (reg:DF 44))]
    ""
!   "cvt.w.d\\t$f12,%1\\t#fix_truncdfsi2\\t%1 -> %0\;mfc1\\t%0,$f12\\t#fix_truncdfsi2\\t%1 -> %0"
! )
  
  (define_insn "fix_truncsfsi2"
--- 874,879 ----
     (clobber (reg:DF 44))]
    ""
!   "trunc.w.d\\t$f12,%1,%0\\t#fix_truncdfsi2\\t%1 -> %0\;mfc1\\t%0,$f12\\t#fix_truncdfsi2\\t%1 -> %0")
! 
  
  (define_insn "fix_truncsfsi2"
***************
*** 679,686 ****
    [(set (match_operand:SI 0 "general_operand" "=r")
  	(fix:SI (fix:SF (match_operand:SF 1 "general_operand" "f"))))
!   (clobber (reg:DF 44))]
    ""
!   "cvt.w.s\\t $f12,%1\\t#fix_truncsfsi2\\t%1 -> %0\;mfc1\\t%0,$f12\\t#fix_truncsfsi2\\t%1 -> %0"
! )
  (define_insn "floatsidf2"
    [(set (match_operand:DF 0 "general_operand" "=f")
--- 880,887 ----
    [(set (match_operand:SI 0 "general_operand" "=r")
  	(fix:SI (fix:SF (match_operand:SF 1 "general_operand" "f"))))
!    (clobber (reg:DF 44))]
    ""
!   "trunc.w.s\\t$f12,%1,%0\\t#fix_truncsfsi2\\t%1 -> %0\;mfc1\\t%0,$f12\\t#fix_truncsfsi2\\t%1 -> %0")
! 
  (define_insn "floatsidf2"
    [(set (match_operand:DF 0 "general_operand" "=f")
***************
*** 687,692 ****
  	(float:DF (match_operand:SI 1 "general_operand" "r")))]
    ""
!   "mtc1\\t%1,%0\\t#floatsidf2\\t%1 -> %0\;cvt.d.w\\t%0,%0\\t#floatsidf2\\t%1 -> %0"
! )
  (define_insn "floatsisf2"
    [(set (match_operand:SF 0 "general_operand" "=f")
--- 888,894 ----
  	(float:DF (match_operand:SI 1 "general_operand" "r")))]
    ""
!   "mtc1\\t%1,%0\\t#floatsidf2\\t%1 -> %0\;cvt.d.w\\t%0,%0\\t#floatsidf2\\t%1 -> %0")
! 
! 
  (define_insn "floatsisf2"
    [(set (match_operand:SF 0 "general_operand" "=f")
***************
*** 693,698 ****
  	(float:SF (match_operand:SI 1 "general_operand" "r")))]
    ""
!   "mtc1\\t%1,%0\\t#floatsisf2\\t%1 -> %0\;cvt.s.w\\t%0,%0\\t#floatsisf2\\t%1 -> %0"
! )
  \f


  					;;- Wild things used when
--- 895,899 ----
  	(float:SF (match_operand:SI 1 "general_operand" "r")))]
    ""
!   "mtc1\\t%1,%0\\t#floatsisf2\\t%1 -> %0\;cvt.s.w\\t%0,%0\\t#floatsisf2\\t%1 -> %0")
  \f


  					;;- Wild things used when
***************
*** 699,703 ****
  					;;- unions make double and int
  					;;- overlap.
! 					;;- 
  					;;- This must be supported
  					;;- since corresponding code
--- 900,904 ----
  					;;- unions make double and int
  					;;- overlap.
! 					;;-
  					;;- This must be supported
  					;;- since corresponding code
***************
*** 705,836 ****
  
  (define_insn ""
!   [(set (subreg:DF 
!             (match_operand:DI 0 "register_operand" "=ry")
!          0)
! 	    (match_operand:DF 1  "register_operand" "rf"))
     (clobber (match_operand  2  "register_operand" "rf"))]
    ""
!   "* 
!   {rtx xops[2];
!        xops[0] =  gen_rtx(REG,SImode,REGNO(operands[0]));
  #ifndef DECSTATION
!        xops[1] =  gen_rtx(REG,DFmode,REGNO(operands[1])+1);
! #else
!        xops[1] =  gen_rtx(REG,DFmode,REGNO(operands[1]));
! #endif
!        output_asm_insn(\"mfc1\\t%0,%1\\t# %1 -> (subreg:DF %0 0) \\t likely Union\"
!                        ,xops);
!        xops[0] =  gen_rtx(REG,SImode,REGNO(operands[0])+1);
! #ifndef DECSTATION
!        xops[1] =  gen_rtx(REG,DFmode,REGNO(operands[1]));
! #else
!        xops[1] =  gen_rtx(REG,DFmode,REGNO(operands[1])+1);
! #endif
!        output_asm_insn(\"mfc1\\t%0,%1\\t# %1 -> (subreg:DF %0 0)  \"
!                        ,xops);
!        return(\"\");
!     }
!   "
! )
  
- (define_insn ""
-   [(set (subreg:DF 
-             (match_operand:DI 0 "register_operand" "=ry")
-          0)
- 	    (match_operand:DF 1  "register_operand" "rf"))]
-   ""
-   "* 
-   {rtx xops[2];
-        xops[0] =  gen_rtx(REG,SImode,REGNO(operands[0]));
- #ifndef DECSTATION
-        xops[1] =  gen_rtx(REG,DFmode,REGNO(operands[1])+1);
- #else
-        xops[1] =  gen_rtx(REG,DFmode,REGNO(operands[1]));
- #endif
-        output_asm_insn(\"mfc1\\t%0,%1\\t# %1 -> (subreg:DF %0 0) \\t likely Union\"
-                        ,xops);
-        xops[0] =  gen_rtx(REG,SImode,REGNO(operands[0])+1);
- #ifndef DECSTATION
-        xops[1] =  gen_rtx(REG,DFmode,REGNO(operands[1]));
- #else
-        xops[1] =  gen_rtx(REG,DFmode,REGNO(operands[1])+1);
- #endif
-        output_asm_insn(\"mfc1\\t%0,%1\\t# %1 -> (subreg:DF %0 0)  \"
-                        ,xops);
-        return(\"\");
-     }
-   "
- )
  
  (define_insn ""
    [(set (match_operand:DF 0  "register_operand" "=rf")
!         (subreg:DF 
!             (match_operand:DI 1 "register_operand" "ry")
!          0)
! 	    )
     (clobber (match_operand  2  "register_operand" "rf"))]
    ""
!   "* 
!   {rtx xops[2];
!        xops[0] =  gen_rtx(REG,DFmode,REGNO(operands[0]));
  #ifndef DECSTATION
!        xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1])+1);
! #else
!        xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1]));
! #endif
!        output_asm_insn(\"mtc1\\t%1,%0\\t# (subreg:DF %1) -> %0  \\t\"
!                        ,xops);
!        xops[0] =  gen_rtx(REG,DFmode,REGNO(operands[0])+1);
! #ifndef DECSTATION
!        xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1]));
! #else
!        xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1])+1);
! #endif
!        output_asm_insn(\"mtc1\\t%1,%0\\t# (subreg:DF %1) -> %0  \\t\"
!                        ,xops);
!        return(\"\");
!     }
!   "
! )
  
  (define_insn ""
    [(set (match_operand:DF 0  "register_operand" "=rf")
!         (subreg:DF 
!             (match_operand:DI 1 "register_operand" "ry")
!          0)
! 	    )]
    ""
!   "* 
!   {rtx xops[2];
!        xops[0] =  gen_rtx(REG,DFmode,REGNO(operands[0]));
! #ifndef DECSTATION
!        xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1])+1);
! #else
!        xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1]));
! #endif
!        output_asm_insn(\"mtc1\\t%1,%0\\t# (subreg:DF %1) -> %0  \\t\"
!                        ,xops);
!        xops[0] =  gen_rtx(REG,DFmode,REGNO(operands[0])+1);
! #ifndef DECSTATION
!        xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1]));
! #else
!        xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1])+1);
! #endif
!        output_asm_insn(\"mtc1\\t%1,%0\\t# (subreg:DF %1) -> %0  \\t\"
!                        ,xops);
! 
!        return(\"\");
!     }
!   "
! )
! 
! \f


  ;;
  ;;  ....................
  ;;
! ;;          MOVES 
  ;;
  ;;          and
! ;;    
  ;;          LOADS AND STORES
  ;;
--- 906,1028 ----
  
  (define_insn ""
!   [(set (subreg:DF (match_operand:DI 0 "register_operand" "=ry") 0)
! 	(match_operand:DF 1  "register_operand" "rf"))
     (clobber (match_operand  2  "register_operand" "rf"))]
    ""
!   "*
! {
!   rtx xops[2];
!   xops[0] =  gen_rtx (REG, SImode, REGNO (operands[0]));
  #ifndef DECSTATION
!   xops[1] =  gen_rtx (REG, DFmode, REGNO (operands[1])+1);
! #else
!   xops[1] =  gen_rtx (REG, DFmode, REGNO (operands[1]));
! #endif
!   output_asm_insn (\"mfc1\\t%0,%1\\t# %1 -> (subreg:DF %0 0) \\t likely Union\"
! 		   , xops);
!   xops[0] =  gen_rtx (REG, SImode, REGNO (operands[0])+1);
! #ifndef DECSTATION
!   xops[1] =  gen_rtx (REG, DFmode, REGNO (operands[1]));
! #else
!   xops[1] =  gen_rtx (REG, DFmode, REGNO (operands[1])+1);
! #endif
!   output_asm_insn (\"mfc1\\t%0,%1\\t# %1 -> (subreg:DF %0 0)  \"
! 		   , xops);
!   return (\"\");
! }")
! 
! 
! 
! (define_insn ""
!   [(set (subreg:DF (match_operand:DI 0 "register_operand" "=ry") 0)
! 	(match_operand:DF 1  "register_operand" "rf"))]
!   ""
!   "*
! {
!   rtx xops[2];
!   xops[0] =  gen_rtx (REG, SImode, REGNO (operands[0]));
! #ifndef DECSTATION
!   xops[1] =  gen_rtx (REG, DFmode, REGNO (operands[1])+1);
! #else
!   xops[1] =  gen_rtx (REG, DFmode, REGNO (operands[1]));
! #endif
!   output_asm_insn (\"mfc1\\t%0,%1\\t# %1 -> (subreg:DF %0 0) \\t likely Union\"
! 		   , xops);
!   xops[0] =  gen_rtx (REG, SImode, REGNO (operands[0])+1);
! #ifndef DECSTATION
!   xops[1] =  gen_rtx (REG, DFmode, REGNO (operands[1]));
! #else
!   xops[1] =  gen_rtx (REG, DFmode, REGNO (operands[1])+1);
! #endif
!   output_asm_insn (\"mfc1\\t%0,%1\\t# %1 -> (subreg:DF %0 0)  \"
! 		   ,xops);
!   return (\"\");
! }")
  
  
+ 
  (define_insn ""
    [(set (match_operand:DF 0  "register_operand" "=rf")
!         (subreg:DF (match_operand:DI 1 "register_operand" "ry") 0))
     (clobber (match_operand  2  "register_operand" "rf"))]
    ""
!   "*
! {
!   rtx xops[2];
!   xops[0] =  gen_rtx (REG, DFmode, REGNO (operands[0]));
  #ifndef DECSTATION
!   xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1])+1);
! #else
!   xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1]));
! #endif
!   output_asm_insn (\"mtc1\\t%1,%0\\t# (subreg:DF %1) -> %0  \\t\"
! 		   , xops);
!   xops[0] =  gen_rtx (REG, DFmode, REGNO (operands[0])+1);
! #ifndef DECSTATION
!   xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1]));
! #else
!   xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1])+1);
! #endif
!   output_asm_insn (\"mtc1\\t%1,%0\\t# (subreg:DF %1) -> %0  \\t\"
! 		   , xops);
!   return (\"\");
! }")
! 
  
+ 
  (define_insn ""
    [(set (match_operand:DF 0  "register_operand" "=rf")
!         (subreg:DF (match_operand:DI 1 "register_operand" "ry") 0))]
    ""
!   "*
! {
!   rtx xops[2];
!   xops[0] =  gen_rtx (REG, DFmode, REGNO (operands[0]));
! #ifndef DECSTATION
!   xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1])+1);
! #else
!   xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1]));
! #endif
!   output_asm_insn (\"mtc1\\t%1,%0\\t# (subreg:DF %1) -> %0  \\t\"
! 		   , xops);
!   xops[0] =  gen_rtx (REG, DFmode, REGNO (operands[0])+1);
! #ifndef DECSTATION
!   xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1]));
! #else
!   xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1])+1);
! #endif
!   output_asm_insn (\"mtc1\\t%1,%0\\t# (subreg:DF %1) -> %0  \\t\"
! 		   , xops);
! 
!   return (\"\");
! }")
! \f


  ;;
  ;;  ....................
  ;;
! ;;          MOVES
  ;;
  ;;          and
! ;;
  ;;          LOADS AND STORES
  ;;
***************
*** 838,1026 ****
  
  (define_insn "movdi"
!  [(set (match_operand:DI 0 "general_operand" "=r,*r,*m")
! 	(match_operand:DI 1 "general_operand" "r,*m,*r"))]
    ""
!  "*
!  { extern rtx change_address();
!    extern rtx plus_constant();
! 
!   if( which_alternative == 0)
!   {rtx xops[2];
!     if(REGNO(operands[0]) != (REGNO(operands[1]) +1))
!     {                                 /* TAKE CARE OF OVERLAPS */
!      xops[0] =  gen_rtx(REG,SImode,REGNO(operands[0]));
!      xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1]));
!      output_asm_insn(\"add%u\\t%0,$0,%1\\t#movdi %1 -> %0\",xops);
!      xops[0] =  gen_rtx(REG,SImode, REGNO(xops[0])+1);
!      xops[1] =  gen_rtx(REG,SImode, REGNO(xops[1])+1);
!      output_asm_insn(\"add%u\\t%0,$0,%1\\t#movdi %1 -> %0\",xops);
!      }
!     else
!     {                               /* TAKE CARE OF OVERLAPS */
!      xops[0] =  gen_rtx(REG,SImode,REGNO(operands[0])+1);
!      xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1])+1);
!      output_asm_insn(\"add%u\\t%0,$0,%1\\t#movdi %1 -> %0\",xops);
!      xops[0] =  gen_rtx(REG,SImode, REGNO(xops[0])-1);
!      xops[1] =  gen_rtx(REG,SImode, REGNO(xops[1])-1);
!      output_asm_insn(\"add%u\\t%0,$0,%1\\t#movdi %1 -> %0\",xops);
!      }
!     return \"\";  }
!    else if(which_alternative == 1)
!      {                             /* No overlap here */
!        rtx xops[2];
!        xops[0] =  gen_rtx(REG,SImode,REGNO(operands[0]));
!        if (GET_CODE(operands[1]) == MEM)
!             xops[1] =  gen_rtx(MEM,SImode,XEXP(operands[1],0));
!        else abort();
!        output_asm_insn(\"lw\\t%0,%1\\t#movdi %1(mem) -> %0\",xops);
!        xops[0] =  gen_rtx(REG,SImode,REGNO(operands[0])+1);
!                                    /* See change_address in emit-rtl.c */
!                                    /* See plus_constant in explow.c   */
!        if (GET_CODE(operands[1]) == MEM)
!             xops[1] = change_address(operands[1],SImode,
!                                  plus_constant(XEXP(operands[1],0),4));
!        else abort();
!        output_asm_insn(\"lw\\t%0,%1\\t#movdi %1(mem) -> %0\",xops);
!        return \"\";
!       }
!      else
!      {                             /* No overlap here */
!        rtx xops[2];
!        xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1]));
!        if (GET_CODE(operands[0]) == MEM)
!             xops[0] =  gen_rtx(MEM,SImode,XEXP(operands[0],0));
!        else abort();
!        output_asm_insn(\"sw\\t%1,%0\\t#movdi %1 -> %0(mem)\",xops);
!        xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1])+1);
!                                    /* See change_address in emit-rtl.c */
!                                    /* See plus_constant in explow.c   */
!        if (GET_CODE(operands[0]) == MEM)
!             xops[0] = change_address(operands[0],SImode,
!                                  plus_constant(XEXP(operands[0],0),4));
!        else abort();
!        output_asm_insn(\"sw\\t%1,%0\\t#movdi %1 -> %0 (mem)\",xops);
!        return \"\";
!       }
!   }
!  "
! )
  
  (define_insn "movsi"
!   [(set (match_operand:SI 0 "general_operand" "=r,r,m,r")
! 	(match_operand:SI 1 "general_operand" "r,m,r,i"))]
    ""
    "*
! { if ((GET_CODE (operands[0]) == REG) && (GET_CODE (operands[1]) == REG))
!     {  return \"add%u\\t%0,$0,%1\\t#movsi\\t%1 -> %0 \";}
! else
!   {if ((GET_CODE (operands[0]) == REG )
!        &&
!        (GET_CODE (operands[1]) == CONST_INT))
!      { rtx xops[3];
!        xops[0] = operands[0];
!        xops[2] = gen_rtx(CONST_INT,VOIDmode,
! 					 INTVAL(operands[1]));
! 
!        if  ( ((INTVAL(operands[1]))>>16)  
!             && ((INTVAL(operands[1])) & 0xffff))
! 	 {if(!( (-INTVAL(operands[1]))>>16))
! 	   {  xops[1] = gen_rtx(CONST_INT,VOIDmode,
! 			    (INTVAL(operands[1])) & 0xffff);
! 	      output_asm_insn(\"addi%u\\t%0,$0,%x1\\t#movsi low part of %2\",
! 			      xops);
! 	    }
! 	   else
! 	   {
! 	    xops[1] = gen_rtx(CONST_INT,VOIDmode,
! 					 (INTVAL(operands[1]))>>16);
! 	    output_asm_insn(\"lui\\t%0,%x1\\t#movsi high part of %2\",xops);
! 	    xops[1] = gen_rtx(CONST_INT,VOIDmode,
! 			    (INTVAL(operands[1])) & 0xffff);
!             output_asm_insn(\"ori\\t%0,%x1\\t#movsi low part of %2\",xops);
!           }}
!         else
!           if  ((INTVAL(operands[1]))>>16)
! 	    { xops[1] = gen_rtx(CONST_INT,VOIDmode,
! 					 (INTVAL(operands[1]))>>16);
! 	      output_asm_insn(\"lui\\t%0,%x1\\t#movsi high part of %2\",xops);
! 					xops[1] = gen_rtx(CONST_INT,VOIDmode,
! 			                (INTVAL(operands[1])) & 0xffff);
! 	    }
!           else
! 	    {	
! 	      xops[1] = gen_rtx(CONST_INT,VOIDmode,
! 			    (INTVAL(operands[1])) & 0xffff);
! 	      output_asm_insn(\"ori\\t%0,$0,%x1\\t#movsi low part of %2\",
! 			      xops);
  	    }
!        return \"\";		   
!      }
    else
!     if (GET_CODE (operands[0]) == REG )
!       {if (  (GET_CODE(operands[1]) == SYMBOL_REF)
! 	   ||(GET_CODE(operands[1]) == LABEL_REF)
! 	  )
!            {return \"la\\t%0,%1\\t#movsi %1 -> %0\";}
!        else
!            {if (GET_CODE(operands[1]) == CONST)
! 	       {return \"la\\t%0,%1\\t#movsi %1(AExp) -> %0\";}
!            else
!               {return \"lw\\t%0,%1\\t#movsi %1 -> %0\";}}}
!     else
!            { 
!              return \"sw\\t%1,%0\\t#movsi %1 -> %0\";}}
  }")
  
  (define_insn "movhi"
!   [(set (match_operand:HI 0 "general_operand" "=r,r,m,r")
! 	(match_operand:HI 1 "general_operand" "r,m,r,i"))]
    ""
    "*
- 
- { if((GET_CODE (operands[0]) == REG) && (GET_CODE (operands[1]) == REG))
-     {  return \"add%u\\t%0,$0,%1\\t#move.h %1 -> %0 \";
- 				}
- else
-  {if ((GET_CODE (operands[0]) == REG )
-     &&
-     (GET_CODE (operands[1]) == CONST_INT))
  {
!  return \"addi%u\\t%0,$0,%x1\\t# movhi %1 -> %0\";		   
! 	}
!       else
!       {if (GET_CODE (operands[0]) == REG)
! 	  {return \"lh\\t%0,%1\\t#movhi %1 -> %0\";}
! 		  else
! 		  {return \"sh\\t%1,%0\\t#movhi %1 -> %0\";}}}
  }")
  
- 
  (define_insn "movqi"
!   [(set (match_operand:QI 0 "general_operand" "=r,r,m,r")
! 	(match_operand:QI 1 "general_operand" "r,m,r,i"))]
    ""
    "*
! { if ((GET_CODE (operands[0]) == REG) && (GET_CODE (operands[1]) == REG))
!     {  return \"add%u\\t%0,$0,%1\\t#move.b %1 -> %0 \";
! 	      }
!   {if ((GET_CODE (operands[0]) == REG )
!        &&
!        (GET_CODE (operands[1]) == CONST_INT))
!       {
!        return \"addi%u\\t%0,$0,%x1\\t# movqi %1 -> %0\";		   
! 	      }
!     
!     /* Should say that I am not padding high order ;;
!     ** bits correctly
!     */
!     else
!     {if (GET_CODE (operands[0]) == REG)
! 	{return \"lbu\\t%0,%1\\t#movqi %1 -> %0\";}
! 		else
! 		{return \"sb\\t%1,%0\\t#movqi %1 -> %0\";}}}
  }")
- 
  \f


- 
  (define_insn "movsf"
    [(set (match_operand:SF 0 "general_operand" "=f,f,m,f")
--- 1030,1275 ----
  
  (define_insn "movdi"
!   [(set (match_operand:DI 0 "general_operand" "=r,*r,*m")
! 	(match_operand:DI 1 "general_operand" "r,*miF,*r"))]
    ""
!   "*
! {
!   extern rtx change_address ();
!   extern rtx plus_constant ();
  
+   if (which_alternative == 0)
+     {
+       rtx xops[2];
+       if (REGNO (operands[0]) != (REGNO (operands[1]) +1))
+ 	{
+ 	  /* TAKE CARE OF OVERLAPS */
+ 	  xops[0] =  gen_rtx (REG, SImode, REGNO (operands[0]));
+ 	  xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1]));
+ 	  output_asm_insn (\"add%:\\t%0,$0,%1\\t#movdi %1 -> %0\", xops);
+ 	  xops[0] =  gen_rtx (REG, SImode, REGNO (xops[0])+1);
+ 	  xops[1] =  gen_rtx (REG, SImode, REGNO (xops[1])+1);
+ 	  output_asm_insn (\"add%:\\t%0,$0,%1\\t#movdi %1 -> %0\", xops);
+ 	}
+       else
+ 	{
+ 	  /* TAKE CARE OF OVERLAPS */
+ 	  xops[0] =  gen_rtx (REG, SImode, REGNO (operands[0])+1);
+ 	  xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1])+1);
+ 	  output_asm_insn (\"add%:\\t%0,$0,%1\\t#movdi %1 -> %0\", xops);
+ 	  xops[0] =  gen_rtx (REG, SImode, REGNO (xops[0])-1);
+ 	  xops[1] =  gen_rtx (REG, SImode, REGNO (xops[1])-1);
+ 	  output_asm_insn (\"add%:\\t%0,$0,%1\\t#movdi %1 -> %0\", xops);
+ 	}
+       return \"\";
+     }
+   else if (which_alternative == 1)
+     {
+       /* No overlap here */
+       rtx xops[2];
+       xops[0] =  gen_rtx (REG, SImode, REGNO (operands[0]));
+       if (GET_CODE (operands[1]) == MEM)
+ 	{
+ 	  xops[1] =  gen_rtx (MEM, SImode, XEXP (operands[1], 0));
+ 	  output_asm_insn (\"lw\\t%0,%1\\t#movdi %1 (mem) -> %0\", xops);
+ 	}
+       else if (CONSTANT_P (operands[1]))
+ 	{
+ #ifdef WORDS_BIG_ENDIAN
+ 	  xops[1] = const0_rtx;
+ #else
+ 	  xops[1] = operands[1];
+ #endif
+ 	  output_load_immediate (xops);
+ 	}
+       else if (GET_CODE (operands[1]) == CONST_DOUBLE)
+ 	{
+ 	  xops[1] = gen_rtx (CONST_INT, VOIDmode,
+ 			     CONST_DOUBLE_LOW (operands[1]));
+ 	  output_load_immediate (xops);
+ 	}
+       else
+ 	abort ();
+       xops[0] =  gen_rtx (REG, SImode, REGNO (operands[0])+1);
+       if (offsettable_memref_p (operands[1]))
+ 	{
+ 	  xops[1] = adj_offsettable_operand (gen_rtx (MEM, SImode,
+ 						      XEXP (operands[1], 0)),
+ 					     4);
+ 	  output_asm_insn (\"lw\\t%0,%1\\t#movdi %1(mem) -> %0\", xops);
+ 	}
+       else if (GET_CODE (operands[1]) == MEM)
+ 	{
+ 	  abort ();
+ 	  output_asm_insn (\"lw\\t%0,%1\\t#movdi %1(mem) -> %0\", xops);
+ 	}
+       else if (CONSTANT_P (operands[1]))
+ 	{
+ #ifdef WORDS_BIG_ENDIAN
+ 	  xops[1] = operands[1];
+ #else
+ 	  xops[1] = const0_rtx;
+ #endif
+ 	  output_load_immediate (xops);
+ 	}
+       else if (GET_CODE (operands[1]) == CONST_DOUBLE)
+ 	{
+ 	  xops[1] = gen_rtx (CONST_INT, VOIDmode,
+ 			     CONST_DOUBLE_HIGH (operands[1]));
+ 	  output_load_immediate (xops);
+ 	}
+       else abort ();
+       return \"\";
+     }
+   else
+     {
+       /* No overlap here */
+       rtx xops[2];
+       xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1]));
+       if (GET_CODE (operands[0]) == MEM)
+ 	xops[0] =  gen_rtx (MEM, SImode, XEXP (operands[0], 0));
+       else abort ();
+       output_asm_insn (\"sw\\t%1,%0\\t#movdi %1 -> %0(mem)\", xops);
+       xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1])+1);
+       if (offsettable_memref_p (operands[0]))
+ 	{
+ 	  xops[0] = adj_offsettable_operand (gen_rtx (MEM, SImode,
+ 						      XEXP (operands[0], 0)),
+ 					     4);
+ 	  output_asm_insn (\"sw\\t%1,%0\\t#movdi %1 -> %0 (mem)\", xops);
+ 	}
+       else if (GET_CODE (operands[0]) == MEM)
+ 	{
+ 	  abort ();
+ 	  output_asm_insn (\"sw\\t%1,%0\\t#movdi %1(mem) -> %0\", xops);
+ 	}
+       else abort ();
+       return \"\";
+     }
+ }")
+ \f


  (define_insn "movsi"
!   [(set (match_operand:SI 0 "general_operand" "=r,r,m,r,r,m,*r")
! 	(match_operand:SI 1 "general_operand" "r,m,r,i,J,J,*p"))]
    ""
    "*
! {
!   if (which_alternative >= 4)
!     {
!       if (which_alternative == 4)
! 	return \"add%:\\t%0,$0,$0\\t#movsi\\t%1 == 0  -> %0\";
!       else if (which_alternative == 5)
! 	return \"sw\\t$0,%0\\t#movsi\\t%1 == 0  -> %0\";
!       else if (which_alternative == 6)
! 	{
! 	  rtx xops[4];
! 	  register rtx addr;
! 	  xops[0] = operands[0];
! 	  addr = operands[1];
! 	  if ((GET_CODE (addr) == PLUS)
! 	      && (GET_CODE (XEXP (addr, 0)) == REG))
! 	    {
! 	      xops[1] = XEXP (addr, 0);
! 	      xops[2] = XEXP (addr, 1);
! 	      xops[3] = addr;
! 	      output_asm_insn (\"addiu\\t%0,%1,%2\\t#movsi (*p)\\t%a3 -> %0\", xops);
! 	      return \"\";
  	    }
! 	  else abort ();
! 	}
!     }
!   else if ((GET_CODE (operands[0]) == REG) && (GET_CODE (operands[1]) == REG))
!     return \"add%:\\t%0,$0,%1\\t#movsi\\t%1 -> %0 \";
!   else if (GET_CODE (operands[0]) == REG
! 	   &&
! 	   GET_CODE (operands[1]) == CONST_INT)
!     {
!       output_load_immediate (operands);
!       return \"\";
!     }
!   else if (GET_CODE (operands[0]) == REG)
!     {
!       if (GET_CODE (operands[1]) == SYMBOL_REF
! 	  || GET_CODE (operands[1]) == LABEL_REF)
! 	return \"la\\t%0,%a1\\t#movsi %a1 -> %0\";
!       else if (GET_CODE (operands[1]) == CONST)
! 	return \"la\\t%0,%a1\\t#movsi %a1(AExp) -> %0\";
!       else
! 	return \"lw\\t%0,%1\\t#movsi %1 -> %0\";
!     }
    else
!     return \"sw\\t%1,%0\\t#movsi %1 -> %0\";
  }")
  
+ (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=*r")
+ 	(match_operand:SI 1 "address_operand" "*p"))]
+   "FIXED_FRAME_PTR_REL_P (operands[1])"
+   "*
+ {
+   rtx xops[4];
+   register rtx addr;
+   xops[0] = operands[0];
+   addr = operands[1];
+   if (GET_CODE (addr) == PLUS
+       && GET_CODE (XEXP (addr, 0)) == REG)
+     {
+       xops[1] = XEXP (addr, 0);
+       xops[2] = XEXP (addr, 1);
+       xops[3] = addr;
+       output_asm_insn (\"addiu\\t%0,%1,%2\\t#movsi (*p)\\t%a3 -> %0\", xops);
+       return \"\";
+     }
+   else
+     abort ();
+ }")
+ \f


  (define_insn "movhi"
!   [(set (match_operand:HI 0 "general_operand" "=r,r,m,r,r,m")
! 	(match_operand:HI 1 "general_operand" "r,m,r,i,J,J"))]
    ""
    "*
  {
!   if (which_alternative == 4)
!     return \"add%:\\t%0,$0,$0\\t#movhi\\t%1 == 0  -> %0\";
!   else if (which_alternative == 5)
!     return \"sh\\t$0,%0\\t#movhi\\t%1 == 0  -> %0\";
!   else if (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG)
!     return \"add%:\\t%0,$0,%1\\t#move.h %1 -> %0 \";
!   else if (GET_CODE (operands[0]) == REG
! 	   && GET_CODE (operands[1]) == CONST_INT)
!     return \"addi%:\\t%0,$0,%x1\\t# movhi %1 -> %0\";
!   else if (GET_CODE (operands[0]) == REG)
!     return \"lh\\t%0,%1\\t#movhi %1 -> %0\";
!   else
!     return \"sh\\t%1,%0\\t#movhi %1 -> %0\";
  }")
  
  (define_insn "movqi"
!   [(set (match_operand:QI 0 "general_operand" "=r,r,m,r,r,m")
! 	(match_operand:QI 1 "general_operand" "r,m,r,i,J,J"))]
    ""
    "*
! {
!   if (which_alternative == 4)
!     return \"add%:\\t%0,$0,$0\\t#movqi\\t%1 == 0  -> %0\";
!   else if (which_alternative == 5)
!     return \"sb\\t$0,%0\\t#movqi\\t%1 == 0  -> %0\";
!   else if (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG)
!     return \"add%:\\t%0,$0,%1\\t#move.b %1 -> %0 \";
! 
!   if ((GET_CODE (operands[0]) == REG )
!       &&
!       (GET_CODE (operands[1]) == CONST_INT))
!     return \"addi%:\\t%0,$0,%x1\\t# movqi %1 -> %0\";
! 
!   /* Should say that I am not padding high order
!    ** bits correctly
!    */
!   else if (GET_CODE (operands[0]) == REG)
!     return \"lb\\t%0,%1\\t#movqi %1 -> %0\";
!   else
!     return \"sb\\t%1,%0\\t#movqi %1 -> %0\";
  }")
  \f


  (define_insn "movsf"
    [(set (match_operand:SF 0 "general_operand" "=f,f,m,f")
***************
*** 1029,1071 ****
    ""
    "*
! { if ((GET_CODE (operands[0]) == REG) && (GET_CODE (operands[1]) == REG))
!     {  return \"mov.s %0,%1\\t#movsf %1 -> %0 \";
! 	      }
!   {if ((GET_CODE (operands[0]) == REG )
!        &&
!        (GET_CODE (operands[1]) == CONST_DOUBLE))
!       { rtx xops[3];
!        xops[0] = operands[0];
!        xops[1] = gen_rtx(CONST_INT,VOIDmode,
! 			 (XINT(operands[1],0))>>16);
!        xops[2] = gen_rtx(CONST_INT,VOIDmode,
! 			XINT(operands[1],0));
!        output_asm_insn(\"lui\\t$24,%x1\\t#move  high part of %2\",xops);
!        xops[1] = gen_rtx(CONST_INT,VOIDmode,
! 			 (XINT(operands[1],0)) & 0xff);
!        output_asm_insn(\"ori\\t$24,%x1\\t#move low part of %2\",xops);
!        output_asm_insn(\"mtc1\\t$24,%0\",xops);
! 
!        xops[0] = gen_rtx(REG,SFmode, REGNO(xops[0])+1);
!        xops[1] = gen_rtx(CONST_INT,VOIDmode,
! 			 (XINT(operands[1],1))>>16);
!        xops[2] = gen_rtx(CONST_INT,VOIDmode,
! 			XINT(operands[1],1));
!        output_asm_insn(\"lui\\t$24,%x1\\t#move  high part of %2\",xops);
!        xops[1] = gen_rtx(CONST_INT,VOIDmode,
! 			 (XINT(operands[1],1)) & 0xff);
!        output_asm_insn(\"ori\\t$24,%x1\\t#move low part of %2\",xops);
! 
!        output_asm_insn(\"mtc1\\t$24,%0\",xops);
!        return \"cvt.s.d\\t %0,%0 \";
!       	      }
!     /* Should say that I am not padding high order ;;
!     ** bits correctly
!     */
!     else
!     {if (GET_CODE (operands[0]) == REG)
! 	{return \"l.s\\t %0,%1\\t#movsf %1 -> %0\";}
! 		else
! 		{return \"s.s\\t %1,%0\\t#movsf %1 -> %0\";}}}
  }")
  
--- 1278,1320 ----
    ""
    "*
! {
!   if (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG)
!     return \"mov.s %0,%1\\t#movsf %1 -> %0 \";
! 
!   if (GET_CODE (operands[0]) == REG
!       && GET_CODE (operands[1]) == CONST_DOUBLE)
!     {
!       rtx xops[3];
!       xops[0] = operands[0];
!       xops[1] = gen_rtx (CONST_INT, VOIDmode,
! 			 (XINT (operands[1], 0))>>16);
!       xops[2] = gen_rtx (CONST_INT, VOIDmode,
! 			 XINT (operands[1], 0));
!       output_asm_insn (\"lui\\t$24,%x1\\t#move  high part of %2\", xops);
!       xops[1] = gen_rtx (CONST_INT, VOIDmode,
! 			 (XINT (operands[1], 0)) & 0xff);
!       output_asm_insn (\"ori\\t$24,%x1\\t#move low part of %2\", xops);
!       output_asm_insn (\"mtc1\\t$24,%0\", xops);
! 
!       xops[0] = gen_rtx (REG, SFmode, REGNO (xops[0])+1);
!       xops[1] = gen_rtx (CONST_INT, VOIDmode,
! 			 (XINT (operands[1], 1))>>16);
!       xops[2] = gen_rtx (CONST_INT, VOIDmode,
! 			 XINT (operands[1], 1));
!       output_asm_insn (\"lui\\t$24,%x1\\t#move  high part of %2\", xops);
!       xops[1] = gen_rtx (CONST_INT, VOIDmode,
! 			 (XINT (operands[1], 1)) & 0xff);
!       output_asm_insn (\"ori\\t$24,%x1\\t#move low part of %2\", xops);
! 
!       output_asm_insn (\"mtc1\\t$24,%0\", xops);
!       return \"cvt.s.d\\t %0,%0 \";
!     }
!   /* Should say that I am not padding high order
!    ** bits correctly
!    */
!   else if (GET_CODE (operands[0]) == REG)
!     return \"l.s\\t %0,%1\\t#movsf %1 -> %0\";
!   else
!     return \"s.s\\t %1,%0\\t#movsf %1 -> %0\";
  }")
  
***************
*** 1077,1164 ****
     (clobber (reg:SI 24))]
    ""
!   "*  if(which_alternative >3)
!   {rtx xops[2];
!     if(REGNO(operands[1]) == 6)
!      {
!        xops[0] =  gen_rtx(REG,DFmode,REGNO(operands[0]));
! #ifndef DECSTATION
!        xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1])+1);
! #else
!         xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1]));
! #endif
!        output_asm_insn(\"mtc1\\t%1,%0\\t# %1 -> %0  \\tcalling sequence trick\"
!                        ,xops);
!        xops[0] =  gen_rtx(REG,DFmode,REGNO(operands[0])+1);
! #ifndef DECSTATION
!        xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1]));
! #else
!         xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1])+1);
! #endif
!        output_asm_insn(\"mtc1\\t%1,%0\\t# %1 -> %0  \\tcalling sequence trick\"
!                        ,xops);
!        return(\"\");
!      }
!     else 
!      if(REGNO(operands[0]) == 6)
!     {
!        xops[0] =  gen_rtx(REG,SImode,REGNO(operands[0]));
! #ifndef DECSTATION
!        xops[1] =  gen_rtx(REG,DFmode,REGNO(operands[1])+1);
! #else
!         xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1]));
! #endif
!        output_asm_insn(\"mfc1\\t%0,%1\\t# %1 -> %0  \\tcalling sequence trick\"
!                        ,xops);
!        xops[0] =  gen_rtx(REG,SImode,REGNO(operands[0])+1);
! #ifndef DECSTATION
!        xops[1] =  gen_rtx(REG,DFmode,REGNO(operands[1]));
! #else
!         xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1])+1);
! #endif
!        output_asm_insn(\"mfc1\\t%0,%1\\t# %1 -> %0  \\tcalling sequence trick\"
!                        ,xops);
!        return(\"\");
!     }
!     else {abort_with_insn(insn,
!          \"Matched *y constraint and register number wrong\");}
!   }
!   else
!   { if ((GET_CODE (operands[0]) == REG) && (GET_CODE (operands[1]) == REG))
!     {  return \"mov.d\\t%0,%1\\t#movdf %1 -> %0 \";
! 	      }
!   {if ((GET_CODE (operands[0]) == REG )
!        &&
!        (GET_CODE (operands[1]) == CONST_DOUBLE))
!       { rtx xops[3];
!        xops[0] = operands[0];
!        xops[1] = gen_rtx(CONST_INT,VOIDmode,
! 			 (XINT(operands[1],0))>>16);
!        xops[2] = gen_rtx(CONST_INT,VOIDmode,
! 			XINT(operands[1],0));
!        output_asm_insn(\"lui\\t$24,%x1\\t#move  high part of %2\",xops);
!        xops[1] = gen_rtx(CONST_INT,VOIDmode,
! 			 (XINT(operands[1],0)) & 0xff);
!        output_asm_insn(\"ori\\t$24,%x1\\t#move low part of %2\",xops);
!        output_asm_insn(\"mtc1\\t%0,$24\",xops);
! 
!        xops[0] = gen_rtx(REG,SFmode, REGNO(xops[0])+1);
!        xops[1] = gen_rtx(CONST_INT,VOIDmode,
! 			 (XINT(operands[1],1))>>16);
!        xops[2] = gen_rtx(CONST_INT,VOIDmode,
! 			XINT(operands[1],1));
!        output_asm_insn(\"lui\\t$24,%x1\\t#move  high part of %2\",xops);
!        xops[1] = gen_rtx(CONST_INT,VOIDmode,
! 			 (XINT(operands[1],1)) & 0xff);
!        output_asm_insn(\"ori\\t$24,%x1\\t#move low part of %2\",xops);
! 
!        output_asm_insn(\"mtc1\\t%0,$24\",xops);
!        return \"# \";
! 
! 	      }
!         else
!     {if (GET_CODE (operands[0]) == REG)
! 	{return \"l.d\\t %0,%1\\t#movdf %1 -> %0\";}
! 		else
! 		{return \"s.d\\t %1,%0\\t#movdf %1 -> %0\";}}}
  }")
  
--- 1326,1418 ----
     (clobber (reg:SI 24))]
    ""
!   "*
! {
!   if (which_alternative > 3)
!     {
!       rtx xops[2];
! 
!       if (REGNO (operands[1]) == 6)
! 	{
! 	  xops[0] =  gen_rtx (REG, DFmode, REGNO (operands[0]));
! #ifndef DECSTATION
! 	  xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1])+1);
! #else
! 	  xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1]));
! #endif
! 	  output_asm_insn (\"mtc1\\t%1,%0\\t# %1 -> %0  \\tcalling sequence trick\"
! 			   , xops);
! 	  xops[0] =  gen_rtx (REG, DFmode, REGNO (operands[0])+1);
! #ifndef DECSTATION
! 	  xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1]));
! #else
! 	  xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1])+1);
! #endif
! 	  output_asm_insn (\"mtc1\\t%1,%0\\t# %1 -> %0  \\tcalling sequence trick\"
! 			   , xops);
! 	  return (\"\");
! 	}
!       else if (REGNO (operands[0]) == 6)
! 	{
! 	  xops[0] =  gen_rtx (REG, SImode, REGNO (operands[0]));
! #ifndef DECSTATION
! 	  xops[1] =  gen_rtx (REG, DFmode, REGNO (operands[1])+1);
! #else
! 	  xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1]));
! #endif
! 	  output_asm_insn (\"mfc1\\t%0,%1\\t# %1 -> %0  \\tcalling sequence trick\"
! 			   , xops);
! 	  xops[0] =  gen_rtx (REG, SImode, REGNO (operands[0])+1);
! #ifndef DECSTATION
! 	  xops[1] =  gen_rtx (REG, DFmode, REGNO (operands[1]));
! #else
! 	  xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1])+1);
! #endif
! 	  output_asm_insn (\"mfc1\\t%0,%1\\t# %1 -> %0  \\tcalling sequence trick\"
! 			   , xops);
! 	  return (\"\");
! 	}
!       else
! 	abort_with_insn (insn,
! 			 \"Matched *y constraint and register number wrong\");
!     }
!   else
!     {
!       if (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG)
! 	return \"mov.d\\t%0,%1\\t#movdf %1 -> %0 \";
! 
!       if (GET_CODE (operands[0]) == REG
! 	  && GET_CODE (operands[1]) == CONST_DOUBLE)
! 	{
! 	  rtx xops[3];
! 	  xops[0] = operands[0];
! 	  xops[1] = gen_rtx (CONST_INT, VOIDmode,
! 			     (XINT (operands[1], 0))>>16);
! 	  xops[2] = gen_rtx (CONST_INT, VOIDmode,
! 			     XINT (operands[1], 0));
! 	  output_asm_insn (\"lui\\t$24,%x1\\t#move  high part of %2\", xops);
! 	  xops[1] = gen_rtx (CONST_INT, VOIDmode,
! 			     (XINT (operands[1], 0)) & 0xff);
! 	  output_asm_insn (\"ori\\t$24,%x1\\t#move low part of %2\", xops);
! 	  output_asm_insn (\"mtc1\\t%0,$24\", xops);
! 
! 	  xops[0] = gen_rtx (REG, SFmode, REGNO (xops[0])+1);
! 	  xops[1] = gen_rtx (CONST_INT, VOIDmode,
! 			     (XINT (operands[1], 1))>>16);
! 	  xops[2] = gen_rtx (CONST_INT, VOIDmode,
! 			     XINT (operands[1], 1));
! 	  output_asm_insn (\"lui\\t$24,%x1\\t#move  high part of %2\", xops);
! 	  xops[1] = gen_rtx (CONST_INT, VOIDmode,
! 			     (XINT (operands[1], 1)) & 0xff);
! 	  output_asm_insn (\"ori\\t$24,%x1\\t#move low part of %2\", xops);
! 
! 	  output_asm_insn (\"mtc1\\t%0,$24\", xops);
! 	  return \"# \";
! 
! 	}
!       else if (GET_CODE (operands[0]) == REG)
! 	return \"l.d\\t %0,%1\\t#movdf %1 -> %0\";
!       else
! 	return \"s.d\\t %1,%0\\t#movdf %1 -> %0\";
!     }
  }")
  
***************
*** 1165,1179 ****
  (define_insn ""
    [(set (match_operand:SF 0 "general_operand" "=f,f,m")
! 	(match_operand:SF 1 "general_operand" "f,m,f"))
!    ]
    ""
    "*
! { if ((GET_CODE (operands[0]) == REG) && (GET_CODE (operands[1]) == REG))
!     {  return \"mov.s %0,%1\\t#movsf %1 -> %0 \";
! 	      }
!     {if (GET_CODE (operands[0]) == REG)
! 	{return \"l.s\\t %0,%1\\t#movsf %1 -> %0\";}
! 		else
! 		{return \"s.s\\t %1,%0\\t#movsf %1 -> %0\";}}
  }")
  
--- 1419,1433 ----
  (define_insn ""
    [(set (match_operand:SF 0 "general_operand" "=f,f,m")
! 	(match_operand:SF 1 "general_operand" "f,m,f"))]
    ""
    "*
! {
!   if (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG)
!     return \"mov.s %0,%1\\t#movsf %1 -> %0 \";
! 
!   if (GET_CODE (operands[0]) == REG)
!     return \"l.s\\t %0,%1\\t#movsf %1 -> %0\";
!   else
!     return \"s.s\\t %1,%0\\t#movsf %1 -> %0\";
  }")
  
***************
*** 1182,1254 ****
  (define_insn ""
    [(set (match_operand:DF 0 "general_operand" "=f,f,m,*f,*y")
! 	(match_operand:DF 1 "general_operand" "f,m,f,*y,*f"))
!   ]
    ""
    "*
!   if(which_alternative >2)
!   {rtx xops[2];
!     if(REGNO(operands[1]) == 6)
!      {
!        xops[0] =  gen_rtx(REG,DFmode,REGNO(operands[0]));
! #ifndef DECSTATION
!        xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1])+1);
! #else
!         xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1]));
! #endif
!        output_asm_insn(\"mtc1\\t%1,%0\\t# %1 -> %0  \\tcalling sequence trick\"
!                        ,xops);
!        xops[0] =  gen_rtx(REG,DFmode,REGNO(operands[0])+1);
! #ifndef DECSTATION
!        xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1]));
! #else
!         xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1])+1);
! #endif
!        output_asm_insn(\"mtc1\\t%1,%0\\t# %1 -> %0  \\tcalling sequence trick\"
!                        ,xops);
!        return(\"\");
!      }
!     else
!     if(REGNO(operands[0]) == 6)
!     {
!        xops[0] =  gen_rtx(REG,SImode,REGNO(operands[0]));
! #ifndef DECSTATION
!        xops[1] =  gen_rtx(REG,DFmode,REGNO(operands[1])+1);
! #else
!         xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1]));
! #endif
!        output_asm_insn(\"mfc1\\t%0,%1\\t# %1 -> %0  \\tcalling sequence trick\"
!                        ,xops);
!        xops[0] =  gen_rtx(REG,SImode,REGNO(operands[0])+1);
! #ifndef DECSTATION
!        xops[1] =  gen_rtx(REG,DFmode,REGNO(operands[1]));
! #else
!         xops[1] =  gen_rtx(REG,SImode,REGNO(operands[1])+1);
! #endif
!        output_asm_insn(\"mfc1\\t%0,%1\\t# %1 -> %0  \\tcalling sequence trick\"
!                        ,xops);
!        return(\"\");
!     }
!     else {abort_with_insn(insn,
!          \"Matched *y constraint and register number wrong\");}
!   }
!   else
!   { if ((GET_CODE (operands[0]) == REG) && (GET_CODE (operands[1]) == REG))
!     {  return \"mov.d\\t%0,%1\\t#movdf %1 -> %0 \";
! 	      }
!     {if (GET_CODE (operands[0]) == REG)
! 	{return \"l.d\\t %0,%1\\t#movdf %1 -> %0\";}
! 		else
! 		{return \"s.d\\t %1,%0\\t#movdf %1 -> %0\";}}
!   }")
! 
! \f


! (define_insn ""
    [(set (match_operand:SI 0 "general_operand" "=r")
! 	 (match_operand:QI 1 "general_operand" "r"))]
    ""
!   "* 
!     return \"andi\\t%0,%1,0xff\\t#Wild zero_extendqisi2\\t %1 -> %0\";
!   "
! )
  
  
--- 1436,1507 ----
  (define_insn ""
    [(set (match_operand:DF 0 "general_operand" "=f,f,m,*f,*y")
! 	(match_operand:DF 1 "general_operand" "f,m,f,*y,*f"))]
    ""
    "*
! {
!   if (which_alternative > 2)
!     {
!       rtx xops[2];
!       if (REGNO (operands[1]) == 6)
! 	{
! 	  xops[0] =  gen_rtx (REG, DFmode, REGNO (operands[0]));
! #ifndef DECSTATION
! 	  xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1])+1);
! #else
! 	  xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1]));
! #endif
! 	  output_asm_insn (\"mtc1\\t%1,%0\\t# %1 -> %0  \\tcalling sequence trick\"
! 			   , xops);
! 	  xops[0] =  gen_rtx (REG, DFmode, REGNO (operands[0])+1);
! #ifndef DECSTATION
! 	  xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1]));
! #else
! 	  xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1])+1);
! #endif
! 	  output_asm_insn (\"mtc1\\t%1,%0\\t# %1 -> %0  \\tcalling sequence trick\"
! 			   , xops);
! 	  return (\"\");
! 	}
!       else if (REGNO (operands[0]) == 6)
! 	{
! 	  xops[0] =  gen_rtx (REG, SImode, REGNO (operands[0]));
! #ifndef DECSTATION
! 	  xops[1] =  gen_rtx (REG, DFmode, REGNO (operands[1])+1);
! #else
! 	  xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1]));
! #endif
! 	  output_asm_insn (\"mfc1\\t%0,%1\\t# %1 -> %0  \\tcalling sequence trick\"
! 			   , xops);
! 	  xops[0] =  gen_rtx (REG, SImode, REGNO (operands[0])+1);
! #ifndef DECSTATION
! 	  xops[1] =  gen_rtx (REG, DFmode, REGNO (operands[1]));
! #else
! 	  xops[1] =  gen_rtx (REG, SImode, REGNO (operands[1])+1);
! #endif
! 	  output_asm_insn (\"mfc1\\t%0,%1\\t# %1 -> %0  \\tcalling sequence trick\"
! 			   , xops);
! 	  return (\"\");
! 	}
!       else
! 	abort_with_insn (insn,
! 			 \"Matched *y constraint and register number wrong\");
!     }
!   else
!     {
!       if ((GET_CODE (operands[0]) == REG) && (GET_CODE (operands[1]) == REG))
! 	return \"mov.d\\t%0,%1\\t#movdf %1 -> %0 \";
! 
!       if (GET_CODE (operands[0]) == REG)
! 	return \"l.d\\t %0,%1\\t#movdf %1 -> %0\";
!       else
! 	return \"s.d\\t %1,%0\\t#movdf %1 -> %0\";
!     }
! }")
! \f


! (define_insn ""
    [(set (match_operand:SI 0 "general_operand" "=r")
! 	(match_operand:QI 1 "general_operand" "r"))]
    ""
!   "andi\\t%0,%1,0xff\\t#Wild zero_extendqisi2\\t %1 -> %0")
  
  
***************
*** 1270,1282 ****
  {
    if (GET_CODE (operands[2]) == CONST_INT)
!     {operands[2]=gen_rtx(CONST_INT,VOIDmode,(XINT(operands[2],0))& 0x1f);
!      output_asm_insn(\"sll\\t%0,%1,%2\\t#ashlqi3\\t (%1<<%2) -> %0\",operands);
      }
    else
!      output_asm_insn(\"sll\\t%0,%1,%2\\t#ashlqi3\\t (%1<<%2) -> %0 (asm syntax)\",
! 		      operands);
    return \"andi\\t%0,%0,0xff\\t#ashlqi3\";
  }")
  
  (define_insn "ashlhi3"
    [(set (match_operand:HI 0 "general_operand" "=r")
--- 1523,1538 ----
  {
    if (GET_CODE (operands[2]) == CONST_INT)
!     {
!       operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
!       output_asm_insn (\"sll\\t%0,%1,%2\\t#ashlqi3\\t (%1<<%2) -> %0\", operands);
      }
    else
!     output_asm_insn (\"sll\\t%0,%1,%2\\t#ashlqi3\\t (%1<<%2) -> %0 (asm syntax)\",
! 		     operands);
    return \"andi\\t%0,%0,0xff\\t#ashlqi3\";
  }")
  
+ 
+ 
  (define_insn "ashlhi3"
    [(set (match_operand:HI 0 "general_operand" "=r")
***************
*** 1287,1300 ****
  {
    if (GET_CODE (operands[2]) == CONST_INT)
!     {operands[2]=gen_rtx(CONST_INT,VOIDmode,(XINT(operands[2],0))& 0x1f);
!      output_asm_insn( \"sll\\t%0,%1,%2\\t#ashlhi3\\t (%1<<%2) -> %0\",
! 				operands);
      }
    else
!      output_asm_insn( \"sll\\t%0,%1,%2\\t#ashlhi3\\t (%1<<%2) -> %0 (asm syntax)\",
!                                 operands);
    return \"sll\\t%0,%0,0x10\;sra\\t%0,%0,0x10\\t#ashlhi3\";
  }")
  
  (define_insn "ashlsi3"
    [(set (match_operand:SI 0 "general_operand" "=r")
--- 1543,1559 ----
  {
    if (GET_CODE (operands[2]) == CONST_INT)
!     {
!       operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
!       output_asm_insn (\"sll\\t%0,%1,%2\\t#ashlhi3\\t (%1<<%2) -> %0\",
! 		       operands);
      }
    else
!     output_asm_insn (\"sll\\t%0,%1,%2\\t#ashlhi3\\t (%1<<%2) -> %0 (asm syntax)\",
! 		     operands);
    return \"sll\\t%0,%0,0x10\;sra\\t%0,%0,0x10\\t#ashlhi3\";
  }")
  
+ 
+ 
  (define_insn "ashlsi3"
    [(set (match_operand:SI 0 "general_operand" "=r")
***************
*** 1305,1310 ****
  {
    if (GET_CODE (operands[2]) == CONST_INT)
!     {operands[2]=gen_rtx(CONST_INT,VOIDmode,(XINT(operands[2],0))& 0x1f);
!      return \"sll\\t%0,%1,%2\\t#ashlsi3\\t (%1<<%2) -> %0\";
      }
    return \"sll\\t%0,%1,%2\\t#ashlsi3\\t (%1<<%2) -> %0 (asm syntax)\";
--- 1564,1570 ----
  {
    if (GET_CODE (operands[2]) == CONST_INT)
!     {
!       operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
!       return \"sll\\t%0,%1,%2\\t#ashlsi3\\t (%1<<%2) -> %0\";
      }
    return \"sll\\t%0,%1,%2\\t#ashlsi3\\t (%1<<%2) -> %0 (asm syntax)\";
***************
*** 1311,1314 ****
--- 1571,1576 ----
  }")
  
+ 
+ 
  (define_insn "ashrsi3"
    [(set (match_operand:SI 0 "general_operand" "=r")
***************
*** 1319,1324 ****
  {
    if (GET_CODE (operands[2]) == CONST_INT)
!     {operands[2]=gen_rtx(CONST_INT,VOIDmode,(XINT(operands[2],0))& 0x1f);
!      return \"sra\\t%0,%1,%2\\t#ashrsi3\\t (%1>>%2) -> %0\";
      }
    return \"sra\\t%0,%1,%2\\t#ashrsi3\\t (%1>>%2) -> %0 (asm syntax for srav)\";
--- 1581,1587 ----
  {
    if (GET_CODE (operands[2]) == CONST_INT)
!     {
!       operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
!       return \"sra\\t%0,%1,%2\\t#ashrsi3\\t (%1>>%2) -> %0\";
      }
    return \"sra\\t%0,%1,%2\\t#ashrsi3\\t (%1>>%2) -> %0 (asm syntax for srav)\";
***************
*** 1325,1332 ****
  }")
  
  (define_insn "lshrsi3"
    [(set (match_operand:SI 0 "general_operand" "=r")
  	(lshiftrt:SI (match_operand:SI 1 "general_operand" "r")
! 		   (match_operand:SI 2 "arith32_operand" "rn")))]
    ""
    "*
--- 1588,1597 ----
  }")
  
+ 
+ 
  (define_insn "lshrsi3"
    [(set (match_operand:SI 0 "general_operand" "=r")
  	(lshiftrt:SI (match_operand:SI 1 "general_operand" "r")
! 		     (match_operand:SI 2 "arith32_operand" "rn")))]
    ""
    "*
***************
*** 1333,1338 ****
  {
    if (GET_CODE (operands[2]) == CONST_INT)
!     {operands[2]=gen_rtx(CONST_INT,VOIDmode,(XINT(operands[2],0))& 0x1f);
!      return \"srl\\t%0,%1,%2\\t#lshrsi3\\t (%1>>%2) -> %0\";
      }
    return \"srl\\t%0,%1,%2\\t#lshrsi3\\t (%1>>%2) -> %0 (asm syntax)\";
--- 1598,1604 ----
  {
    if (GET_CODE (operands[2]) == CONST_INT)
!     {
!       operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
!       return \"srl\\t%0,%1,%2\\t#lshrsi3\\t (%1>>%2) -> %0\";
      }
    return \"srl\\t%0,%1,%2\\t#lshrsi3\\t (%1>>%2) -> %0 (asm syntax)\";
***************
*** 1340,1343 ****
--- 1606,1611 ----
  
  
+ 
+ 
  (define_insn "negsi2"
    [(set (match_operand:SI 0 "general_operand" "=r")
***************
*** 1344,1348 ****
  	(neg:SI (match_operand:SI 1 "arith_operand" "r")))]
    ""
!   "sub%u\\t%0,$0,%1\\t#negsi2")
  
  
--- 1612,1616 ----
  	(neg:SI (match_operand:SI 1 "arith_operand" "r")))]
    ""
!   "sub%:\\t%0,$0,%1\\t#negsi2")
  
  
***************
*** 1353,1356 ****
--- 1621,1626 ----
    "neg.d\\t%0,%1\\t#negdf2")
  
+ 
+ 
  (define_insn "negsf2"
  
***************
*** 1367,1370 ****
--- 1637,1642 ----
    "nor\\t%0,$0,%1\\t#one_cmplsi2")
  
+ 
+ 
  (define_insn "one_cmplhi2"
    [(set (match_operand:HI 0 "general_operand" "=r")
***************
*** 1373,1376 ****
--- 1645,1650 ----
    "nor\\t%0,$0,%1\\t#one_cmplhi2")
  
+ 
+ 
  (define_insn "one_cmplqi2"
    [(set (match_operand:QI 0 "general_operand" "=r")
***************
*** 1378,1383 ****
    ""
    "nor\\t%0,$0,%1\\t#one_cmplqi2")
- 
- 
  \f


  ;;
--- 1652,1655 ----
***************
*** 1390,1394 ****
  
  					;;- MERGED CMPSI + BEQ
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
--- 1662,1666 ----
  
  					;;- MERGED CMPSI + BEQ
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
***************
*** 1398,1403 ****
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))
!   ]
    ""
    "beq \\t%0,%1,%l2\\t#beq MIPS primitive insn")
--- 1670,1674 ----
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))]
    ""
    "beq \\t%0,%1,%l2\\t#beq MIPS primitive insn")
***************
*** 1404,1408 ****
  
  					;;- MERGED CMPSI + INV BEQ
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
--- 1675,1679 ----
  
  					;;- MERGED CMPSI + INV BEQ
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
***************
*** 1412,1422 ****
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))
! 		      ))
!   ]
    ""
    "beq \\t%0,%1,%l2\\t#beq inverted primitive insn")
  					;;- MERGED CMPSI + BNE
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
--- 1683,1691 ----
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))))]
    ""
    "beq \\t%0,%1,%l2\\t#beq inverted primitive insn")
  					;;- MERGED CMPSI + BNE
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
***************
*** 1426,1431 ****
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))
!   ]
    ""
    "bne \\t%0,%1,%l2\\t#bne MIPS primitive insn")
--- 1695,1699 ----
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))]
    ""
    "bne \\t%0,%1,%l2\\t#bne MIPS primitive insn")
***************
*** 1432,1436 ****
  
  					;;- MERGED CMPSI + INV BNE
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
--- 1700,1704 ----
  
  					;;- MERGED CMPSI + INV BNE
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
***************
*** 1440,1446 ****
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))
! 		      ))
!   ]
    ""
    "bne \\t%0,%1,%l2\\t#bne inverted primitive insn")
--- 1708,1712 ----
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))))]
    ""
    "bne \\t%0,%1,%l2\\t#bne inverted primitive insn")
***************
*** 1447,1451 ****
  
  					;;- MERGED CMPSI + BGT
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
--- 1713,1717 ----
  
  					;;- MERGED CMPSI + BGT
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
***************
*** 1455,1460 ****
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))
!   ]
    ""
    "bgt \\t%0,%1,%l2\\t#bgt MIPS composite insn")
--- 1721,1725 ----
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))]
    ""
    "bgt \\t%0,%1,%l2\\t#bgt MIPS composite insn")
***************
*** 1461,1465 ****
  
  					;;- MERGED CMPSI + INV BGT
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
--- 1726,1730 ----
  
  					;;- MERGED CMPSI + INV BGT
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
***************
*** 1469,1479 ****
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))
! 		      ))
!   ]
    ""
    "bgt \\t%0,%1,%l2\\t#bgt inverted composite insn")
  					;;- MERGED CMPSI + BLT
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
--- 1734,1742 ----
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))))]
    ""
    "bgt \\t%0,%1,%l2\\t#bgt inverted composite insn")
  					;;- MERGED CMPSI + BLT
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
***************
*** 1483,1488 ****
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))
!   ]
    ""
    "blt \\t%0,%1,%l2\\t#blt MIPS composite insn")
--- 1746,1750 ----
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))]
    ""
    "blt \\t%0,%1,%l2\\t#blt MIPS composite insn")
***************
*** 1489,1493 ****
  
  					;;- MERGED CMPSI + INV BLT
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
--- 1751,1755 ----
  
  					;;- MERGED CMPSI + INV BLT
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
***************
*** 1497,1507 ****
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))
! 		      ))
!   ]
    ""
    "blt \\t%0,%1,%l2\\t#blt inverted composite insn")
  					;;- MERGED CMPSI + BGE
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
--- 1759,1767 ----
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))))]
    ""
    "blt \\t%0,%1,%l2\\t#blt inverted composite insn")
  					;;- MERGED CMPSI + BGE
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
***************
*** 1511,1516 ****
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))
!   ]
    ""
    "bge \\t%0,%1,%l2\\t#bge composite insn")
--- 1771,1775 ----
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))]
    ""
    "bge \\t%0,%1,%l2\\t#bge composite insn")
***************
*** 1517,1521 ****
  
  					;;- MERGED CMPSI + INV BGE
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
--- 1776,1780 ----
  
  					;;- MERGED CMPSI + INV BGE
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
***************
*** 1525,1535 ****
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))
! 		      ))
!   ]
    ""
    "bge \\t%0,%1,%l2\\t#bge inverted composite insn")
  					;;- MERGED CMPSI + BLE
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
--- 1784,1792 ----
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))))]
    ""
    "bge \\t%0,%1,%l2\\t#bge inverted composite insn")
  					;;- MERGED CMPSI + BLE
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
***************
*** 1539,1544 ****
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))
!   ]
    ""
    "ble \\t%0,%1,%l2\\t#ble composite insn")
--- 1796,1800 ----
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))]
    ""
    "ble \\t%0,%1,%l2\\t#ble composite insn")
***************
*** 1545,1549 ****
  
  					;;- MERGED CMPSI + INV BLE
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
--- 1801,1805 ----
  
  					;;- MERGED CMPSI + INV BLE
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
***************
*** 1553,1559 ****
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))
! 		      ))
!   ]
    ""
    "ble \\t%0,%1,%l2\\t#ble inverted composite insn")
--- 1809,1813 ----
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))))]
    ""
    "ble \\t%0,%1,%l2\\t#ble inverted composite insn")
***************
*** 1561,1565 ****
  \f


  					;;- MERGED CMPSI + BGT
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
--- 1815,1819 ----
  \f


  					;;- MERGED CMPSI + BGT
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
***************
*** 1567,1574 ****
     (set (pc)
  	(if_then_else (gtu (cc0)
! 			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))
!   ]
    ""
    "bgtu \\t%0,%1,%l2\\t#bgtu MIPS composite insn")
--- 1821,1827 ----
     (set (pc)
  	(if_then_else (gtu (cc0)
! 			   (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))]
    ""
    "bgtu \\t%0,%1,%l2\\t#bgtu MIPS composite insn")
***************
*** 1575,1579 ****
  
  					;;- MERGED CMPSI + INV BGT
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
--- 1828,1832 ----
  
  					;;- MERGED CMPSI + INV BGT
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
***************
*** 1581,1593 ****
     (set (pc)
  	(if_then_else (leu (cc0)
! 			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))
! 		      ))
!   ]
    ""
    "bgtu \\t%0,%1,%l2\\t#bgtu inverted composite insn")
  					;;- MERGED CMPSI + INV BLTU
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
--- 1834,1844 ----
     (set (pc)
  	(if_then_else (leu (cc0)
! 			   (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))))]
    ""
    "bgtu \\t%0,%1,%l2\\t#bgtu inverted composite insn")
  					;;- MERGED CMPSI + INV BLTU
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
***************
*** 1595,1607 ****
     (set (pc)
  	(if_then_else (geu (cc0)
! 			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))
! 		      ))
!   ]
    ""
!   "blt \\t%0,%1,%l2\\t#blt inverted composite insn")
  					;;- MERGED CMPSI + BGEU
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
--- 1846,1856 ----
     (set (pc)
  	(if_then_else (geu (cc0)
! 			   (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))))]
    ""
!   "bltu \\t%0,%1,%l2\\t#blt inverted composite insn")
  					;;- MERGED CMPSI + BGEU
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
***************
*** 1609,1616 ****
     (set (pc)
  	(if_then_else (geu (cc0)
! 			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))
!   ]
    ""
    "bgeu \\t%0,%1,%l2\\t#bgeu composite insn")
--- 1858,1864 ----
     (set (pc)
  	(if_then_else (geu (cc0)
! 			   (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))]
    ""
    "bgeu \\t%0,%1,%l2\\t#bgeu composite insn")
***************
*** 1617,1621 ****
  
  					;;- MERGED CMPSI + INV BGEU
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
--- 1865,1869 ----
  
  					;;- MERGED CMPSI + INV BGEU
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
***************
*** 1623,1635 ****
     (set (pc)
  	(if_then_else (ltu (cc0)
! 			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))
! 		      ))
!   ]
    ""
    "bgeu \\t%0,%1,%l2\\t#bgeu inverted composite insn")
  					;;- MERGED CMPSI + BLE
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
--- 1871,1881 ----
     (set (pc)
  	(if_then_else (ltu (cc0)
! 			   (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))))]
    ""
    "bgeu \\t%0,%1,%l2\\t#bgeu inverted composite insn")
  					;;- MERGED CMPSI + BLE
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
***************
*** 1637,1644 ****
     (set (pc)
  	(if_then_else (leu (cc0)
! 			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))
!   ]
    ""
    "bleu \\t%0,%1,%l2\\t#bleu composite insn")
--- 1883,1889 ----
     (set (pc)
  	(if_then_else (leu (cc0)
! 			   (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))]
    ""
    "bleu \\t%0,%1,%l2\\t#bleu composite insn")
***************
*** 1645,1649 ****
  
  					;;- MERGED CMPSI + INV BLE
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
--- 1890,1894 ----
  
  					;;- MERGED CMPSI + INV BLE
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
***************
*** 1651,1663 ****
     (set (pc)
  	(if_then_else (gtu (cc0)
! 			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))
! 		      ))
!   ]
    ""
    "bleu \\t%0,%1,%l2\\t#bleu inverted composite insn")
  					;;- MERGED CMPSI + BLTU
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
--- 1896,1906 ----
     (set (pc)
  	(if_then_else (gtu (cc0)
! 			   (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))))]
    ""
    "bleu \\t%0,%1,%l2\\t#bleu inverted composite insn")
  					;;- MERGED CMPSI + BLTU
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
***************
*** 1665,1672 ****
     (set (pc)
  	(if_then_else (ltu (cc0)
! 			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))
!   ]
    ""
    "bltu \\t%0,%1,%l2\\t#bltu MIPS composite insn")
--- 1908,1914 ----
     (set (pc)
  	(if_then_else (ltu (cc0)
! 			   (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))]
    ""
    "bltu \\t%0,%1,%l2\\t#bltu MIPS composite insn")
***************
*** 1673,1677 ****
  
  					;;- MERGED CMPSI + INV BLTU
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
--- 1915,1919 ----
  
  					;;- MERGED CMPSI + INV BLTU
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SI 0 "general_operand" "r")
***************
*** 1679,1687 ****
     (set (pc)
  	(if_then_else (geu (cc0)
! 			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))
! 		      ))
!   ]
    ""
    "bltu \\t%0,%1,%l2\\t#bltu inverted composite insn")
--- 1921,1927 ----
     (set (pc)
  	(if_then_else (geu (cc0)
! 			   (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))))]
    ""
    "bltu \\t%0,%1,%l2\\t#bltu inverted composite insn")
***************
*** 1691,1695 ****
  
  					;;- MERGED CMPSF + BEQ
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SF 0 "general_operand" "f")
--- 1931,1935 ----
  
  					;;- MERGED CMPSF + BEQ
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SF 0 "general_operand" "f")
***************
*** 1699,1704 ****
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))
!   ]
    ""
    "c.eq.s\\t%0,%1\\t# Merged CMPSF + BEQ \;bc1t\\t%l2\\t# Merged CMPSF + BEQ ")
--- 1939,1943 ----
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))]
    ""
    "c.eq.s\\t%0,%1\\t# Merged CMPSF + BEQ \;bc1t\\t%l2\\t# Merged CMPSF + BEQ ")
***************
*** 1706,1710 ****
  					;;- MERGED CMPSF + INV BEQ
  
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SF 0 "general_operand" "f")
--- 1945,1949 ----
  					;;- MERGED CMPSF + INV BEQ
  
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SF 0 "general_operand" "f")
***************
*** 1714,1720 ****
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))
! 		      ))
!   ]
    ""
    "c.eq.s\\t%0,%1\\t# Merged CMPSF + BEQ \;bc1t\\t%l2\\t# Merged CMPSF + BEQ ")
--- 1953,1957 ----
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))))]
    ""
    "c.eq.s\\t%0,%1\\t# Merged CMPSF + BEQ \;bc1t\\t%l2\\t# Merged CMPSF + BEQ ")
***************
*** 1722,1726 ****
  					;;- MERGED CMPSF + BNE
  
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SF 0 "general_operand" "f")
--- 1959,1963 ----
  					;;- MERGED CMPSF + BNE
  
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SF 0 "general_operand" "f")
***************
*** 1730,1735 ****
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))
!   ]
    ""
    "c.eq.s\\t%0,%1\\t# Merged CMPSF + BNE \;bc1f\\t%l2\\t# Merged CMPSF + BNE ")
--- 1967,1971 ----
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))]
    ""
    "c.eq.s\\t%0,%1\\t# Merged CMPSF + BNE \;bc1f\\t%l2\\t# Merged CMPSF + BNE ")
***************
*** 1736,1740 ****
  
  					;;- MERGED CMPSF + INV BNE
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SF 0 "general_operand" "f")
--- 1972,1976 ----
  
  					;;- MERGED CMPSF + INV BNE
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SF 0 "general_operand" "f")
***************
*** 1744,1750 ****
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))
! 		      ))
!   ]
    ""
    "c.eq.s\\t%0,%1\\t# Merged CMPSF + I.BNE \;bc1f\\t%l2\\t# Merged CMPSF +I.BNE ")
--- 1980,1984 ----
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))))]
    ""
    "c.eq.s\\t%0,%1\\t# Merged CMPSF + I.BNE \;bc1f\\t%l2\\t# Merged CMPSF +I.BNE ")
***************
*** 1751,1755 ****
  
  					;;- MERGED CMPSF + BGT
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SF 0 "general_operand" "f")
--- 1985,1989 ----
  
  					;;- MERGED CMPSF + BGT
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SF 0 "general_operand" "f")
***************
*** 1759,1769 ****
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))
!   ]
    ""
!   "c.le.s\\t%1,%0\\t# Merged CMPSF + BGT \;bc1f\\t%l2\\t# Merged CMPSF + BGT ")
  
  					;;- MERGED CMPSF + INV BGT
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SF 0 "general_operand" "f")
--- 1993,2002 ----
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))]
    ""
!   "c.le.s\\t%0,%1\\t# Merged CMPSF + BGT \;bc1f\\t%l2\\t# Merged CMPSF + BGT ")
  
  					;;- MERGED CMPSF + INV BGT
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SF 0 "general_operand" "f")
***************
*** 1773,1779 ****
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))
! 		      ))
!   ]
    ""
    "c.le.s\\t%0,%1\\t# Merged CMPSF + I.BGT \;bc1f\\t%l2\\t# Merged CMPSF +I. BGT ")
--- 2006,2010 ----
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))))]
    ""
    "c.le.s\\t%0,%1\\t# Merged CMPSF + I.BGT \;bc1f\\t%l2\\t# Merged CMPSF +I. BGT ")
***************
*** 1780,1784 ****
  
  					;;- MERGED CMPSF + BLT
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SF 0 "general_operand" "f")
--- 2011,2015 ----
  
  					;;- MERGED CMPSF + BLT
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SF 0 "general_operand" "f")
***************
*** 1788,1793 ****
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))
!   ]
    ""
    "c.lt.s\\t%0,%1\\t# Merged CMPSF + BLT \;bc1t\\t%l2\\t# Merged CMPSF + BLT ")
--- 2019,2023 ----
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))]
    ""
    "c.lt.s\\t%0,%1\\t# Merged CMPSF + BLT \;bc1t\\t%l2\\t# Merged CMPSF + BLT ")
***************
*** 1794,1798 ****
  
  					;;- MERGED CMPSF + INV BLT
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SF 0 "general_operand" "f")
--- 2024,2028 ----
  
  					;;- MERGED CMPSF + INV BLT
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SF 0 "general_operand" "f")
***************
*** 1802,1808 ****
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))
! 		      ))
!   ]
    ""
    "c.lt.s\\t%0,%1\\t# Merged CMPSF + I.BLT \;bc1t\\t%l2\\t# Merged CMPSF + I.BLT ")
--- 2032,2036 ----
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))))]
    ""
    "c.lt.s\\t%0,%1\\t# Merged CMPSF + I.BLT \;bc1t\\t%l2\\t# Merged CMPSF + I.BLT ")
***************
*** 1809,1813 ****
  
  					;;- MERGED CMPSF + BGE
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SF 0 "general_operand" "f")
--- 2037,2041 ----
  
  					;;- MERGED CMPSF + BGE
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SF 0 "general_operand" "f")
***************
*** 1817,1822 ****
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))
!   ]
    ""
    "c.lt.s\\t%0,%1\\t# Merged CMPSF + BGE \;bc1f\\t%l2\\t# Merged CMPSF + BGE")
--- 2045,2049 ----
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))]
    ""
    "c.lt.s\\t%0,%1\\t# Merged CMPSF + BGE \;bc1f\\t%l2\\t# Merged CMPSF + BGE")
***************
*** 1823,1827 ****
  
  					;;- MERGED CMPSF + INV BGE
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SF 0 "general_operand" "f")
--- 2050,2054 ----
  
  					;;- MERGED CMPSF + INV BGE
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SF 0 "general_operand" "f")
***************
*** 1831,1841 ****
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))
! 		      ))
!   ]
    ""
    "c.lt.s\\t%0,%1\\t# Merged CMPSF +INV  BGE \;bc1f\\t%l2\\t# Merged CMPSF +INV BGE ")
  					;;- MERGED CMPSF + BLE
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SF 0 "general_operand" "f")
--- 2058,2066 ----
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))))]
    ""
    "c.lt.s\\t%0,%1\\t# Merged CMPSF +INV  BGE \;bc1f\\t%l2\\t# Merged CMPSF +INV BGE ")
  					;;- MERGED CMPSF + BLE
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SF 0 "general_operand" "f")
***************
*** 1845,1850 ****
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))
!   ]
    ""
    "c.le.s\\t%0,%1\\t# Merged CMPSF + BLE \;bc1t\\t%l2\\t# Merged CMPSF + BLE ")
--- 2070,2074 ----
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))]
    ""
    "c.le.s\\t%0,%1\\t# Merged CMPSF + BLE \;bc1t\\t%l2\\t# Merged CMPSF + BLE ")
***************
*** 1851,1855 ****
  
  					;;- MERGED CMPSF + INV BLE
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:SF 0 "general_operand" "f")
--- 2075,2079 ----
  
  					;;- MERGED CMPSF + INV BLE
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:SF 0 "general_operand" "f")
***************
*** 1859,1865 ****
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))
! 		      ))
!   ]
    ""
    "c.le.s\\t%0,%1\\t# Merged CMPSF + INV BLE \;bc1t\\t%l2\\t# Merged CMPSF +I. BLE")
--- 2083,2087 ----
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))))]
    ""
    "c.le.s\\t%0,%1\\t# Merged CMPSF + INV BLE \;bc1t\\t%l2\\t# Merged CMPSF +I. BLE")
***************
*** 1870,1874 ****
  					;;- MERGED CMPDF + BEQ
  
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:DF 0 "general_operand" "f")
--- 2092,2096 ----
  					;;- MERGED CMPDF + BEQ
  
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:DF 0 "general_operand" "f")
***************
*** 1878,1883 ****
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))
!   ]
    ""
    "c.eq.d\\t%0,%1\\t# Merged CMPDF + BEQ \;bc1t\\t%l2\\t# Merged CMPDF + BEQ ")
--- 2100,2104 ----
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))]
    ""
    "c.eq.d\\t%0,%1\\t# Merged CMPDF + BEQ \;bc1t\\t%l2\\t# Merged CMPDF + BEQ ")
***************
*** 1885,1889 ****
  					;;- MERGED CMPDF + INV BEQ
  
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:DF 0 "general_operand" "f")
--- 2106,2110 ----
  					;;- MERGED CMPDF + INV BEQ
  
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:DF 0 "general_operand" "f")
***************
*** 1893,1899 ****
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))
! 		      ))
!   ]
    ""
    "c.eq.d\\t%0,%1\\t# Merged CMPDF + I.BEQ \;bc1t\\t%l2\\t# Merged CMPDF +I. BEQ ")
--- 2114,2118 ----
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))))]
    ""
    "c.eq.d\\t%0,%1\\t# Merged CMPDF + I.BEQ \;bc1t\\t%l2\\t# Merged CMPDF +I. BEQ ")
***************
*** 1901,1905 ****
  					;;- MERGED CMPDF + BNE
  
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:DF 0 "general_operand" "f")
--- 2120,2124 ----
  					;;- MERGED CMPDF + BNE
  
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:DF 0 "general_operand" "f")
***************
*** 1909,1914 ****
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))
!   ]
    ""
    "c.eq.d\\t%0,%1\\t# Merged CMPDF + BNE \;bc1f\\t%l2\\t# Merged CMPDF + BNE ")
--- 2128,2132 ----
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))]
    ""
    "c.eq.d\\t%0,%1\\t# Merged CMPDF + BNE \;bc1f\\t%l2\\t# Merged CMPDF + BNE ")
***************
*** 1915,1919 ****
  
  					;;- MERGED CMPDF + INV BNE
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:DF 0 "general_operand" "f")
--- 2133,2137 ----
  
  					;;- MERGED CMPDF + INV BNE
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:DF 0 "general_operand" "f")
***************
*** 1923,1929 ****
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))
! 		      ))
!   ]
    ""
    "c.eq.d\\t%0,%1\\t# Merged CMPDF +I. BNE \;bc1f\\t%l2\\t# Merged CMPDF +I BNE")
--- 2141,2145 ----
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))))]
    ""
    "c.eq.d\\t%0,%1\\t# Merged CMPDF +I. BNE \;bc1f\\t%l2\\t# Merged CMPDF +I BNE")
***************
*** 1930,1934 ****
  
  					;;- MERGED CMPDF + BGT
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:DF 0 "general_operand" "f")
--- 2146,2150 ----
  
  					;;- MERGED CMPDF + BGT
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:DF 0 "general_operand" "f")
***************
*** 1938,1943 ****
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))
!   ]
    ""
    "c.le.d\\t%0,%1\\t# Merged CMPDF + BGT \;bc1f\\t%l2\\t# Merged CMPDF + BGT ")
--- 2154,2158 ----
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))]
    ""
    "c.le.d\\t%0,%1\\t# Merged CMPDF + BGT \;bc1f\\t%l2\\t# Merged CMPDF + BGT ")
***************
*** 1944,1948 ****
  
  					;;- MERGED CMPDF + INV BGT
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:DF 0 "general_operand" "f")
--- 2159,2163 ----
  
  					;;- MERGED CMPDF + INV BGT
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:DF 0 "general_operand" "f")
***************
*** 1952,1958 ****
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))
! 		      ))
!   ]
    ""
    "c.le.d\\t%0,%1\\t# Merged CMPDF + I. BGT \;bc1f\\t%l2\\t# Merged CMPDF + I. BGT ")
--- 2167,2171 ----
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))))]
    ""
    "c.le.d\\t%0,%1\\t# Merged CMPDF + I. BGT \;bc1f\\t%l2\\t# Merged CMPDF + I. BGT ")
***************
*** 1959,1963 ****
  
  					;;- MERGED CMPDF + BLT
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:DF 0 "general_operand" "f")
--- 2172,2176 ----
  
  					;;- MERGED CMPDF + BLT
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:DF 0 "general_operand" "f")
***************
*** 1967,1972 ****
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))
!   ]
    ""
    "c.lt.d\\t%0,%1\\t# Merged CMPDF + BLT \;bc1t\\t%l2\\t# Merged CMPDF + BLT ")
--- 2180,2184 ----
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))]
    ""
    "c.lt.d\\t%0,%1\\t# Merged CMPDF + BLT \;bc1t\\t%l2\\t# Merged CMPDF + BLT ")
***************
*** 1973,1977 ****
  
  					;;- MERGED CMPDF + INV BLT
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:DF 0 "general_operand" "f")
--- 2185,2189 ----
  
  					;;- MERGED CMPDF + INV BLT
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:DF 0 "general_operand" "f")
***************
*** 1981,1987 ****
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))
! 		      ))
!   ]
    ""
    "c.lt.d\\t%0,%1\\t# Merged CMPDF + I.BLT \;bc1t\\t%l2\\t# Merged CMPDF + I.BLT")
--- 2193,2197 ----
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))))]
    ""
    "c.lt.d\\t%0,%1\\t# Merged CMPDF + I.BLT \;bc1t\\t%l2\\t# Merged CMPDF + I.BLT")
***************
*** 1988,1992 ****
  
  					;;- MERGED CMPDF + BGE
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:DF 0 "general_operand" "f")
--- 2198,2202 ----
  
  					;;- MERGED CMPDF + BGE
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:DF 0 "general_operand" "f")
***************
*** 1996,2001 ****
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))
!   ]
    ""
    "c.lt.d\\t%0,%1\\t# Merged CMPDF + BGE \;bc1f\\t%l2\\t# Merged CMPDF + BGE")
--- 2206,2210 ----
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))]
    ""
    "c.lt.d\\t%0,%1\\t# Merged CMPDF + BGE \;bc1f\\t%l2\\t# Merged CMPDF + BGE")
***************
*** 2002,2006 ****
  
  					;;- MERGED CMPDF + INV BGE
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:DF 0 "general_operand" "f")
--- 2211,2215 ----
  
  					;;- MERGED CMPDF + INV BGE
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:DF 0 "general_operand" "f")
***************
*** 2010,2020 ****
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))
! 		      ))
!   ]
    ""
    "c.lt.d\\t%0,%1\\t# Merged CMPDF +I. BGE \;bc1f\\t%l2\\t# Merged CMPDF +I. BGE")
  					;;- MERGED CMPDF + BLE
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:DF 0 "general_operand" "f")
--- 2219,2227 ----
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))))]
    ""
    "c.lt.d\\t%0,%1\\t# Merged CMPDF +I. BGE \;bc1f\\t%l2\\t# Merged CMPDF +I. BGE")
  					;;- MERGED CMPDF + BLE
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:DF 0 "general_operand" "f")
***************
*** 2024,2029 ****
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))
!   ]
    ""
    "c.le.d\\t%0,%1\\t# Merged CMPDF + BLE \;bc1t\\t%l2\\t# Merged CMPDF + BLE ")
--- 2231,2235 ----
  			  (const_int 0))
  		      (label_ref (match_operand 2 "" ""))
! 		      (pc)))]
    ""
    "c.le.d\\t%0,%1\\t# Merged CMPDF + BLE \;bc1t\\t%l2\\t# Merged CMPDF + BLE ")
***************
*** 2030,2034 ****
  
  					;;- MERGED CMPDF + INV BLE
! (define_peephole 
    [(set (cc0)
  	(compare (match_operand:DF 0 "general_operand" "f")
--- 2236,2240 ----
  
  					;;- MERGED CMPDF + INV BLE
! (define_peephole
    [(set (cc0)
  	(compare (match_operand:DF 0 "general_operand" "f")
***************
*** 2038,2044 ****
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))
! 		      ))
!   ]
    ""
    "c.le.d\\t%0,%1\\t# Merged CMPDF +I. BLE \;bc1t\\t%l2\\t# Merged CMPDF + I.BLE ")
--- 2244,2248 ----
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 2 "" ""))))]
    ""
    "c.le.d\\t%0,%1\\t# Merged CMPDF +I. BLE \;bc1t\\t%l2\\t# Merged CMPDF + I.BLE ")
***************
*** 2055,2146 ****
  
  					;;- Order is significant here
! 					;;- because there are untyped 
  					;;- comparisons generated by
  					;;- the optimizer
!                                         ;;- (set (cc0)			
                                          ;;-      (compare (const_int 2)
                                          ;;-           (const_int 1)))
-  
- (define_insn "cmpsi"
-   [(set (cc0)
- 	(compare (match_operand:SI 0 "general_operand" "r")
- 		 (match_operand:SI 1 "general_operand" "r")))]
-   ""
-   "* 
-     compare_collect(SImode,operands[0],operands[1]);
-     return      \" #\\tcmpsi\\t%0,%1\";
-   ")
- 
- (define_insn "cmphi"
-   [(set (cc0)
- 	(compare (match_operand:HI 0 "general_operand" "r")
- 		 (match_operand:HI 1 "general_operand" "r")))]
-   ""
-   "* 
-     compare_collect(HImode,operands[0],operands[1]);
-     return      \" #\\tcmphi\\t%0,%1\";
-   ")
  
! (define_insn "cmpqi"
    [(set (cc0)
! 	(compare (match_operand:QI 0 "general_operand" "r")
! 		 (match_operand:QI 1 "general_operand" "r")))]
    ""
!   "* 
!     compare_collect(QImode,operands[0],operands[1]);
!     return      \" #\\tcmpqi\\t%0,%1\";
!   ")
  
  (define_insn "cmpdf"
    [(set (cc0)
! 	(compare (match_operand:DF 0 "general_operand" "f")
! 		 (match_operand:DF 1 "general_operand" "f")))]
    ""
!   "* 
!     compare_collect(DFmode,operands[0],operands[1]);
!     return      \" #\\tcmpdf\\t%0,%1\" ;
!   ")
! 
  
  (define_insn "cmpsf"
    [(set (cc0)
! 	(compare (match_operand:SF 0 "general_operand" "f")
! 		 (match_operand:SF 1 "general_operand" "f")))]
    ""
!   "* 
!     compare_collect(SFmode,operands[0],operands[1]);
!     return      \" #\\tcmpsf\\t%0,%1\" ;
!   ")
  
  
  (define_insn ""
    [(set (cc0)
!           (match_operand:QI 0 "general_operand" "r"))
!   ]
    ""
!   "* 
!     compare_collect(QImode,operands[0],gen_rtx(REG,QImode,0));
!     return      \" #\\t(set (cc0)\\t%0)\";
!   ")
  (define_insn ""
    [(set (cc0)
!           (match_operand:HI 0 "general_operand" "r"))
!   ]
    ""
!   "* 
!     compare_collect(HImode,operands[0],gen_rtx(REG,HImode,0));
!     return      \" #\\t(set (cc0)\\t%0)\";
! "
! )
! (define_insn ""
!   [(set (cc0)
!           (match_operand:SI 0 "general_operand" "r"))
!   ]
!   ""
!   "* 
!     compare_collect(SImode,operands[0],gen_rtx(REG,SImode,0));
!     return      \" #\\t(set (cc0)\\t%0)\";
! "
! )
  \f


  ;;
--- 2259,2348 ----
  
  					;;- Order is significant here
! 					;;- because there are untyped
  					;;- comparisons generated by
  					;;- the optimizer
!                                         ;;- (set (cc0)
                                          ;;-      (compare (const_int 2)
                                          ;;-           (const_int 1)))
  
! (define_insn "cmpsi"
    [(set (cc0)
! 	(compare (match_operand:SI 0 "register_operand" "r")
! 		 (match_operand:SI 1 "register_operand" "r")))]
    ""
!   "*
!     compare_collect (SImode, operands[0], operands[1]);
!     return \" #\\tcmpsi\\t%0,%1\";
! ")
! 
! ;; These patterns are hopelessly invalid, because
! ;; comparing subword values properly requires extending them.
! 
! ;; (define_insn "cmphi"
! ;;   [(set (cc0)
! ;; 	(compare (match_operand:HI 0 "general_operand" "r")
! ;; 		 (match_operand:HI 1 "general_operand" "r")))]
! ;;   ""
! ;;   "*
! ;;     compare_collect (HImode, operands[0], operands[1]);
! ;;     return      \" #\\tcmphi\\t%0,%1\";
! ;;   ")
! ;; 
! ;; (define_insn "cmpqi"
! ;;   [(set (cc0)
! ;; 	(compare (match_operand:QI 0 "general_operand" "r")
! ;; 		 (match_operand:QI 1 "general_operand" "r")))]
! ;;   ""
! ;;   "*
! ;;     compare_collect (QImode, operands[0], operands[1]);
! ;;     return      \" #\\tcmpqi\\t%0,%1\";
! ;;   ")
  
  (define_insn "cmpdf"
    [(set (cc0)
! 	(compare (match_operand:DF 0 "register_operand" "f")
! 		 (match_operand:DF 1 "register_operand" "f")))]
    ""
!   "*
!     compare_collect (DFmode, operands[0], operands[1]);
!     return \" #\\tcmpdf\\t%0,%1\" ;
! ")
  
  (define_insn "cmpsf"
    [(set (cc0)
! 	(compare (match_operand:SF 0 "register_operand" "f")
! 		 (match_operand:SF 1 "register_operand" "f")))]
    ""
!   "*
!     compare_collect (SFmode, operands[0], operands[1]);
!     return \" #\\tcmpsf\\t%0,%1\" ;
! ")
  
+ (define_insn ""
+   [(set (cc0)
+ 	(match_operand:QI 0 "general_operand" "r"))]
+   ""
+   "*
+     compare_collect (QImode, operands[0], gen_rtx (REG, QImode, 0));
+     return \" #\\t (set (cc0)\\t%0)\";
+ ")
  
  (define_insn ""
    [(set (cc0)
! 	(match_operand:HI 0 "general_operand" "r"))]
    ""
!   "*
!     compare_collect (HImode, operands[0], gen_rtx (REG, HImode, 0));
!     return \" #\\t (set (cc0)\\t%0)\";
! ")
! 
  (define_insn ""
    [(set (cc0)
! 	(match_operand:SI 0 "general_operand" "r"))]
    ""
!   "*
!     compare_collect (SImode, operands[0], gen_rtx (REG, SImode, 0));
!     return \" #\\t (set (cc0)\\t%0)\";
! ")
  \f


  ;;
***************
*** 2150,2154 ****
  ;;
  ;;  ....................
! \f


  (define_insn "jump"
    [(set (pc)
--- 2352,2356 ----
  ;;
  ;;  ....................
! 
  (define_insn "jump"
    [(set (pc)
***************
*** 2156,2163 ****
    ""
    "*
!     if (GET_CODE(operands[0]) == REG)
!           return \"j\\t%%0\\t#jump %l0 (jr not asm syntax)\";
!           else return \"j\\t%l0\\t#jump %l0\";
!   ")
  
  
--- 2358,2367 ----
    ""
    "*
! {
!   if (GET_CODE (operands[0]) == REG)
!     return \"j\\t%%0\\t#jump %l0 (jr not asm syntax)\";
!   else
!     return \"j\\t%l0\\t#jump %l0\";
! }")
  
  
***************
*** 2170,2190 ****
    ""
    "*
!    {rtx br_ops[3];
!     enum machine_mode mode;
!    compare_restore(br_ops,  &mode, insn);
!    br_ops[2] = operands[0];
!    if ( mode == DFmode)
!       {output_asm_insn(\"c.eq.d\\t%0,%1\\t#beq\", br_ops);
!        output_asm_insn(\"bc1t\\t%2\\t#beq\", br_ops);
!       }
!       else if  (mode == SFmode)
!       { output_asm_insn(\"c.eq.s\\t%0,%1\\t#beq\", br_ops);
!         output_asm_insn(\"bc1t\\t%2\\t#beq\", br_ops);
!       } 
!            else { output_asm_insn(\"beq\\t%0,%1,%2\\t#beq\", br_ops);
!            }
!    return \"\";
!    }
!    ") 
  
  (define_insn "bne"
--- 2374,2399 ----
    ""
    "*
! {
!   rtx br_ops[3];
!   enum machine_mode mode;
!   compare_restore (br_ops,  &mode, insn);
!   br_ops[2] = operands[0];
!   if (mode == DFmode)
!     {
!       output_asm_insn (\"c.eq.d\\t%0,%1\\t#beq\", br_ops);
!       output_asm_insn (\"bc1t\\t%2\\t#beq\", br_ops);
!     }
!   else if  (mode == SFmode)
!     {
!       output_asm_insn (\"c.eq.s\\t%0,%1\\t#beq\", br_ops);
!       output_asm_insn (\"bc1t\\t%2\\t#beq\", br_ops);
!     }
!   else
!     {
!       output_asm_insn (\"beq\\t%0,%1,%2\\t#beq\", br_ops);
!     }
!   return \"\";
! }
!    ")
  
  (define_insn "bne"
***************
*** 2196,2215 ****
    ""
    "*
!    {rtx br_ops[3];
!     enum machine_mode mode;
!    compare_restore(br_ops,  &mode, insn);
!    br_ops[2] = operands[0];
!    if ( mode == DFmode)
!       {output_asm_insn(\"c.eq.d\\t%0,%1\\t#bne\", br_ops);
!        output_asm_insn(\"bc1f\\t%2\\t#bne\", br_ops);
!       }
!       else if  (mode == SFmode)
!       { output_asm_insn(\"c.eq.s\\t%0,%1\\t#bne\", br_ops);
!        output_asm_insn(\"bc1f\\t%2\\t#bne\", br_ops);
!       } 
!            else { output_asm_insn(\"bne\\t%0,%1,%2\\t#bne\", br_ops);
!            }
!    return \"\";
!    }
  
  ")
--- 2405,2429 ----
    ""
    "*
! {
!   rtx br_ops[3];
!   enum machine_mode mode;
!   compare_restore (br_ops,  &mode, insn);
!   br_ops[2] = operands[0];
!   if (mode == DFmode)
!     {
!       output_asm_insn (\"c.eq.d\\t%0,%1\\t#bne\", br_ops);
!       output_asm_insn (\"bc1f\\t%2\\t#bne\", br_ops);
!     }
!   else if  (mode == SFmode)
!     {
!       output_asm_insn (\"c.eq.s\\t%0,%1\\t#bne\", br_ops);
!       output_asm_insn (\"bc1f\\t%2\\t#bne\", br_ops);
!     }
!   else
!     {
!       output_asm_insn (\"bne\\t%0,%1,%2\\t#bne\", br_ops);
!     }
!   return \"\";
! }
  
  ")
***************
*** 2223,2242 ****
    ""
    "*
!    {rtx br_ops[3];
!     enum machine_mode mode;
!    compare_restore(br_ops,  &mode, insn);
!    br_ops[2] = operands[0];
!    if ( mode == DFmode)
!       {output_asm_insn(\"c.le.d\\t%0,%1\\t#bgt branch %0 > %1\", br_ops);
!        output_asm_insn(\"bc1f\\t%2\\t#bgt\", br_ops);
!       }
!       else if  (mode == SFmode)
!       { output_asm_insn(\"c.le.s\\t%0,%1\\t#bgt branch %0 > %1\", br_ops);
!        output_asm_insn(\"bc1f\\t%2\\t#bgt\", br_ops);
!       } 
!            else { output_asm_insn(\"bgt\\t%0,%1,%2\\t#bgt\", br_ops);
!            }
!    return \"\";
!    }
  
  ")
--- 2437,2461 ----
    ""
    "*
! {
!   rtx br_ops[3];
!   enum machine_mode mode;
!   compare_restore (br_ops,  &mode, insn);
!   br_ops[2] = operands[0];
!   if (mode == DFmode)
!     {
!       output_asm_insn (\"c.le.d\\t%0,%1\\t#bgt branch %0 > %1\", br_ops);
!       output_asm_insn (\"bc1f\\t%2\\t#bgt\", br_ops);
!     }
!   else if  (mode == SFmode)
!     {
!       output_asm_insn (\"c.le.s\\t%0,%1\\t#bgt branch %0 > %1\", br_ops);
!       output_asm_insn (\"bc1f\\t%2\\t#bgt\", br_ops);
!     }
!   else
!     {
!       output_asm_insn (\"bgt\\t%0,%1,%2\\t#bgt\", br_ops);
!     }
!   return \"\";
! }
  
  ")
***************
*** 2250,2269 ****
    ""
    "*
!    {rtx br_ops[3];
!     enum machine_mode mode;
!    compare_restore(br_ops,  &mode, insn);
!    br_ops[2] = operands[0];
!    if ( mode == DFmode)
!       {output_asm_insn(\"c.lt.d\\t%0,%1\\t#blt\", br_ops);
!        output_asm_insn(\"bc1t\\t%2\\t#blt\", br_ops);
!       }
!       else if  (mode == SFmode)
!       { output_asm_insn(\"c.lt.s\\t%0,%1\\t#blt\", br_ops);
!        output_asm_insn(\"bc1t\\t%2\\t#blt\", br_ops);
!       } 
!            else { output_asm_insn(\"blt\\t%0,%1,%2\\t#blt\", br_ops);
!            }
!    return \" #\\tblt \\t%l0\\t#blt\";
!    }
  ")
  \f


--- 2469,2493 ----
    ""
    "*
! {
!   rtx br_ops[3];
!   enum machine_mode mode;
!   compare_restore (br_ops,  &mode, insn);
!   br_ops[2] = operands[0];
!   if (mode == DFmode)
!     {
!       output_asm_insn (\"c.lt.d\\t%0,%1\\t#blt\", br_ops);
!       output_asm_insn (\"bc1t\\t%2\\t#blt\", br_ops);
!     }
!   else if  (mode == SFmode)
!     {
!       output_asm_insn (\"c.lt.s\\t%0,%1\\t#blt\", br_ops);
!       output_asm_insn (\"bc1t\\t%2\\t#blt\", br_ops);
!     }
!   else
!     {
!       output_asm_insn (\"blt\\t%0,%1,%2\\t#blt\", br_ops);
!     }
!   return \" #\\tblt \\t%l0\\t#blt\";
! }
  ")
  \f


***************
*** 2271,2275 ****
    [(set (pc)
  	(if_then_else (gtu (cc0)
! 			  (const_int 0))
  		      (label_ref (match_operand 0 "" ""))
  		      (pc)))]
--- 2495,2499 ----
    [(set (pc)
  	(if_then_else (gtu (cc0)
! 			   (const_int 0))
  		      (label_ref (match_operand 0 "" ""))
  		      (pc)))]
***************
*** 2276,2295 ****
    ""
    "*
!    {rtx br_ops[3];
!     enum machine_mode mode;
!    compare_restore(br_ops,  &mode, insn);
!    br_ops[2] = operands[0];
!    if ( mode == DFmode)
!       {output_asm_insn(\"c.le.d\\t%0,%1\\t#bgtu\", br_ops);
!        output_asm_insn(\"bc1f\\t%2\\t#bgtu\", br_ops);
!       }
!       else if  (mode == SFmode)
!       { output_asm_insn(\"c.le.s\\t%0,%1\\t#bgtu\", br_ops);
!        output_asm_insn(\"bc1f\\t%2\\t#bgtu\", br_ops);
!       } 
!            else { output_asm_insn(\"bgtu\\t%0,%1,%2\\t#bgtu\", br_ops);
!            }
!    return \" #\\tbgtu \\t%l0\\t#bgtu\";
!    }
  
  ")
--- 2500,2524 ----
    ""
    "*
! {
!   rtx br_ops[3];
!   enum machine_mode mode;
!   compare_restore (br_ops,  &mode, insn);
!   br_ops[2] = operands[0];
!   if (mode == DFmode)
!     {
!       output_asm_insn (\"c.le.d\\t%0,%1\\t#bgtu\", br_ops);
!       output_asm_insn (\"bc1f\\t%2\\t#bgtu\", br_ops);
!     }
!   else if  (mode == SFmode)
!     {
!       output_asm_insn (\"c.le.s\\t%0,%1\\t#bgtu\", br_ops);
!       output_asm_insn (\"bc1f\\t%2\\t#bgtu\", br_ops);
!     }
!   else
!     {
!       output_asm_insn (\"bgtu\\t%0,%1,%2\\t#bgtu\", br_ops);
!     }
!   return \" #\\tbgtu \\t%l0\\t#bgtu\";
! }
  
  ")
***************
*** 2298,2302 ****
    [(set (pc)
  	(if_then_else (ltu (cc0)
! 			  (const_int 0))
  		      (label_ref (match_operand 0 "" ""))
  		      (pc)))]
--- 2527,2531 ----
    [(set (pc)
  	(if_then_else (ltu (cc0)
! 			   (const_int 0))
  		      (label_ref (match_operand 0 "" ""))
  		      (pc)))]
***************
*** 2303,2322 ****
    ""
    "*
!    {rtx br_ops[3];
!     enum machine_mode mode;
!    compare_restore(br_ops,  &mode, insn);
!    br_ops[2] = operands[0];
!    if ( mode == DFmode)
!       {output_asm_insn(\"c.lt.d\\t%0,%1\\t#bltu\", br_ops);
!        output_asm_insn(\"bc1t\\t%2\\t#bltu\", br_ops);
!       }
!       else if  (mode == SFmode)
!       { output_asm_insn(\"c.lt.s\\t%0,%1\\t#bltu\", br_ops);
!        output_asm_insn(\"bc1t\\t%2\\t#bltu\", br_ops);
!       } 
!            else { output_asm_insn(\"bltu\\t%0,%1,%2\\t#bltu\", br_ops);
!            }
!    return \"\";
!    }
  ")
  
--- 2532,2556 ----
    ""
    "*
! {
!   rtx br_ops[3];
!   enum machine_mode mode;
!   compare_restore (br_ops,  &mode, insn);
!   br_ops[2] = operands[0];
!   if (mode == DFmode)
!     {
!       output_asm_insn (\"c.lt.d\\t%0,%1\\t#bltu\", br_ops);
!       output_asm_insn (\"bc1t\\t%2\\t#bltu\", br_ops);
!     }
!   else if  (mode == SFmode)
!     {
!       output_asm_insn (\"c.lt.s\\t%0,%1\\t#bltu\", br_ops);
!       output_asm_insn (\"bc1t\\t%2\\t#bltu\", br_ops);
!     }
!   else
!     {
!       output_asm_insn (\"bltu\\t%0,%1,%2\\t#bltu\", br_ops);
!     }
!   return \"\";
! }
  ")
  
***************
*** 2329,2348 ****
    ""
    "*
!    {rtx br_ops[3];
!     enum machine_mode mode;
!    compare_restore(br_ops,  &mode, insn);
!    br_ops[2] = operands[0];
!    if ( mode == DFmode)
!       {output_asm_insn(\"c.lt.d\\t%0,%1\\t#bge\", br_ops);
!        output_asm_insn(\"bc1f\\t%2\\t#bge\", br_ops);
!       }
!       else if  (mode == SFmode)
!       { output_asm_insn(\"c.lt.s\\t%0,%1\\t#bge\", br_ops);
!        output_asm_insn(\"bc1f\\t%2\\t#bge\", br_ops);
!       } 
!            else { output_asm_insn(\"bge\\t%0,%1,%2\\t#bge\", br_ops);
!            }
!    return \"\";
!    }
  ")
  
--- 2563,2587 ----
    ""
    "*
! {
!   rtx br_ops[3];
!   enum machine_mode mode;
!   compare_restore (br_ops,  &mode, insn);
!   br_ops[2] = operands[0];
!   if (mode == DFmode)
!     {
!       output_asm_insn (\"c.lt.d\\t%0,%1\\t#bge\", br_ops);
!       output_asm_insn (\"bc1f\\t%2\\t#bge\", br_ops);
!     }
!   else if  (mode == SFmode)
!     {
!       output_asm_insn (\"c.lt.s\\t%0,%1\\t#bge\", br_ops);
!       output_asm_insn (\"bc1f\\t%2\\t#bge\", br_ops);
!     }
!   else
!     {
!       output_asm_insn (\"bge\\t%0,%1,%2\\t#bge\", br_ops);
!     }
!   return \"\";
! }
  ")
  
***************
*** 2350,2354 ****
    [(set (pc)
  	(if_then_else (geu (cc0)
! 			  (const_int 0))
  		      (label_ref (match_operand 0 "" ""))
  		      (pc)))]
--- 2589,2593 ----
    [(set (pc)
  	(if_then_else (geu (cc0)
! 			   (const_int 0))
  		      (label_ref (match_operand 0 "" ""))
  		      (pc)))]
***************
*** 2355,2374 ****
    ""
    "*
!    {rtx br_ops[3];
!     enum machine_mode mode;
!    compare_restore(br_ops,  &mode, insn);
!    br_ops[2] = operands[0];
!    if ( mode == DFmode)
!       {output_asm_insn(\"c.lt.d\\t%0,%1\\t#bgeu\", br_ops);
!        output_asm_insn(\"bc1f\\t%2\\t#bgeu\", br_ops);
!       }
!       else if  (mode == SFmode)
!       { output_asm_insn(\"c.lt.s\\t%0,%1\\t#bgeu\", br_ops);
!        output_asm_insn(\"bc1f\\t%2\\t#bgeu\", br_ops);
!       } 
!            else { output_asm_insn(\"bgeu\\t%0,%1,%2\\t#bgeu\", br_ops);
!            }
!    return \"\";
!    }
  ")
  
--- 2594,2618 ----
    ""
    "*
! {
!   rtx br_ops[3];
!   enum machine_mode mode;
!   compare_restore (br_ops,  &mode, insn);
!   br_ops[2] = operands[0];
!   if (mode == DFmode)
!     {
!       output_asm_insn (\"c.lt.d\\t%0,%1\\t#bgeu\", br_ops);
!       output_asm_insn (\"bc1f\\t%2\\t#bgeu\", br_ops);
!     }
!   else if  (mode == SFmode)
!     {
!       output_asm_insn (\"c.lt.s\\t%0,%1\\t#bgeu\", br_ops);
!       output_asm_insn (\"bc1f\\t%2\\t#bgeu\", br_ops);
!     }
!   else
!     {
!       output_asm_insn (\"bgeu\\t%0,%1,%2\\t#bgeu\", br_ops);
!     }
!   return \"\";
! }
  ")
  
***************
*** 2381,2401 ****
    ""
    "*
!    {rtx br_ops[3];
!     enum machine_mode mode;
!    compare_restore(br_ops,  &mode, insn);
!    br_ops[2] = operands[0];
!    if ( mode == DFmode)
!       {output_asm_insn(\"c.le.d\\t%0,%1\\t#ble\", br_ops);
!        output_asm_insn(\"bc1t\\t%2\\t#ble\", br_ops);
!       }
!       else if  (mode == SFmode)
!       { output_asm_insn(\"c.le.s\\t%0,%1\\t#ble\", br_ops);
!        output_asm_insn(\"bc1t\\t%2\\t#ble\", br_ops);
!       } 
!            else { output_asm_insn(\"ble\\t%0,%1,%2\\t#ble\", br_ops);
!            }
!    return \"\";
!    }  
  ")
  (define_insn "bleu"
    [(set (pc)
--- 2625,2651 ----
    ""
    "*
! {
!   rtx br_ops[3];
!   enum machine_mode mode;
!   compare_restore (br_ops,  &mode, insn);
!   br_ops[2] = operands[0];
!   if (mode == DFmode)
!     {
!       output_asm_insn (\"c.le.d\\t%0,%1\\t#ble\", br_ops);
!       output_asm_insn (\"bc1t\\t%2\\t#ble\", br_ops);
!     }
!   else if  (mode == SFmode)
!     {
!       output_asm_insn (\"c.le.s\\t%0,%1\\t#ble\", br_ops);
!       output_asm_insn (\"bc1t\\t%2\\t#ble\", br_ops);
!     }
!   else
!     {
!       output_asm_insn (\"ble\\t%0,%1,%2\\t#ble\", br_ops);
!     }
!   return \"\";
! }
  ")
+ 
  (define_insn "bleu"
    [(set (pc)
***************
*** 2406,2563 ****
    ""
    "*
!    {rtx br_ops[3];
!     enum machine_mode mode;
!    compare_restore(br_ops,  &mode, insn);
!    br_ops[2] = operands[0];
!    if ( mode == DFmode)
!       {output_asm_insn(\"c.le.d\\t%0,%1\\t#ble\", br_ops);
!        output_asm_insn(\"bc1t\\t%2\\t#ble\", br_ops);
!       }
!       else if  (mode == SFmode)
!       { output_asm_insn(\"c.le.s\\t%0,%1\\t#ble\", br_ops);
!        output_asm_insn(\"bc1t\\t%2\\t#ble\", br_ops);
!       } 
!            else { output_asm_insn(\"bleu\\t%0,%1,%2\\t#bleu\", br_ops);
!            }
!    return \" #\\tbleu \\t%l0\\t#bleu\";
!    }  
! ")
! 
! 
! \f


! 
! (define_insn ""
!   [(set (pc)
! 	(if_then_else (ne (cc0)
! 			  (const_int 0))
! 		      (pc)
! 		      (label_ref (match_operand 0 "" ""))
! 		     ))]
!   ""
!   "*
!    {rtx br_ops[3];
!     enum machine_mode mode;
!    compare_restore(br_ops,  &mode, insn);
!    br_ops[2] = operands[0];
!    if ( mode == DFmode)
!       {output_asm_insn(\"c.eq.d\\t%0,%1\\t#beq\", br_ops);
!        output_asm_insn(\"bc1t\\t%2\\t#beq\", br_ops);
!       }
!       else if  (mode == SFmode)
!       { output_asm_insn(\"c.eq.s\\t%0,%1\\t#beq\", br_ops);
!         output_asm_insn(\"bc1t\\t%2\\t#beq\", br_ops);
!       } 
!            else { output_asm_insn(\"beq\\t%0,%1,%2\\t#beq Inv.\", br_ops);
!            }
!    return \"\";
!    }
! ")
! 
! (define_insn ""
!   [(set (pc)
! 	(if_then_else (eq (cc0)
! 			  (const_int 0)) 
! 		      (pc)
! 		      (label_ref (match_operand 0 "" ""))
! 		      ))]
!   ""
!   "*
!    {rtx br_ops[3];
!     enum machine_mode mode;
!    compare_restore(br_ops,  &mode, insn);
!    br_ops[2] = operands[0];
!    if ( mode == DFmode)
!       {output_asm_insn(\"c.eq.d\\t%0,%1\\t#bne\", br_ops);
!        output_asm_insn(\"bc1f\\t%2\\t#bne\", br_ops);
!       }
!       else if  (mode == SFmode)
!       { output_asm_insn(\"c.eq.s\\t%0,%1\\t#bne\", br_ops);
!        output_asm_insn(\"bc1f\\t%2\\t#beq\", br_ops);
!       } 
!            else { output_asm_insn(\"bne\\t%0,%1,%2\\t#bne Inv.\", br_ops);
!            }
!    return \"\";
!    }
! 
! ")
! 
! (define_insn ""
!   [(set (pc)
! 	(if_then_else (le (cc0)
! 			  (const_int 0))
! 		      (pc)
! 		      (label_ref (match_operand 0 "" ""))
! 		      ))]
!   ""
!   "*
!    {rtx br_ops[3];
!     enum machine_mode mode;
!    compare_restore(br_ops,  &mode, insn);
!    br_ops[2] = operands[0];
!    if ( mode == DFmode)
!       {output_asm_insn(\"c.le.d\\t%0,%1\\t#bgt\", br_ops);
!        output_asm_insn(\"bc1f\\t%2\\t#beq\", br_ops);
!       }
!       else if  (mode == SFmode)
!       { output_asm_insn(\"c.le.s\\t%0,%1\\t#bgt\", br_ops);
!        output_asm_insn(\"bc1f\\t%2\\t#beq\", br_ops);
!       } 
!            else { output_asm_insn(\"bgt\\t%0,%1,%2\\t#bgt Inv.\", br_ops);
!            }
!    return \"\";
!    }
  ")
  (define_insn ""
    [(set (pc)
  	(if_then_else (leu (cc0)
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 0 "" ""))
! 		      ))]
    ""
    "*
!    {rtx br_ops[3];
!     enum machine_mode mode;
!    compare_restore(br_ops,  &mode, insn);
!    br_ops[2] = operands[0];
!    if ( mode == DFmode)
!       {output_asm_insn(\"c.le.d\\t%0,%1\\t#bgt\", br_ops);
!        output_asm_insn(\"bc1f\\t%2\\t#beq\", br_ops);
!       }
!       else if  (mode == SFmode)
!       { output_asm_insn(\"c.le.s\\t%0,%1\\t#bgt\", br_ops);
!        output_asm_insn(\"bc1f\\t%2\\t#beq\", br_ops);
!       } 
!            else { output_asm_insn(\"bgtu\\t%0,%1,%2\\t#bgtu Inv.\", br_ops);
!            }
!    return \" #\\tbgtu \\t%l0\\t#bgtu\";
!    }
! ")
! 
! (define_insn ""
!   [(set (pc)
! 	(if_then_else (ge (cc0)
! 			  (const_int 0))
! 		      (pc)
! 		      (label_ref (match_operand 0 "" ""))
! 		      ))]
!   ""
!   "*
!    {rtx br_ops[3];
!     enum machine_mode mode;
!    compare_restore(br_ops,  &mode, insn);
!    br_ops[2] = operands[0];
!    if ( mode == DFmode)
!       {output_asm_insn(\"c.lt.d\\t%0,%1\\t#blt\", br_ops);
!        output_asm_insn(\"bc1t\\t%2\\t#beq\", br_ops);
!       }
!       else if  (mode == SFmode)
!       { output_asm_insn(\"c.lt.s\\t%0,%1\\t#blt\", br_ops);
!        output_asm_insn(\"bc1t\\t%2\\t#beq\", br_ops);
!       } 
!            else { output_asm_insn(\"blt\\t%0,%1,%2\\t#blt Inv.\", br_ops);
!            }
!    return \"\";
!    }
  ")
  
--- 2656,2836 ----
    ""
    "*
! {
!   rtx br_ops[3];
!   enum machine_mode mode;
!   compare_restore (br_ops,  &mode, insn);
!   br_ops[2] = operands[0];
!   if (mode == DFmode)
!     {
!       output_asm_insn (\"c.le.d\\t%0,%1\\t#ble\", br_ops);
!       output_asm_insn (\"bc1t\\t%2\\t#ble\", br_ops);
!     }
!   else if  (mode == SFmode)
!     {
!       output_asm_insn (\"c.le.s\\t%0,%1\\t#ble\", br_ops);
!       output_asm_insn (\"bc1t\\t%2\\t#ble\", br_ops);
!     }
!   else
!     {
!       output_asm_insn (\"bleu\\t%0,%1,%2\\t#bleu\", br_ops);
!     }
!   return \" #\\tbleu \\t%l0\\t#bleu\";
! }
! ")
! \f


! (define_insn ""
!   [(set (pc)
! 	(if_then_else (ne (cc0)
! 			  (const_int 0))
! 		      (pc)
! 		      (label_ref (match_operand 0 "" ""))))]
!   ""
!   "*
! {
!   rtx br_ops[3];
!   enum machine_mode mode;
!   compare_restore (br_ops,  &mode, insn);
!   br_ops[2] = operands[0];
!   if (mode == DFmode)
!     {
!       output_asm_insn (\"c.eq.d\\t%0,%1\\t#beq\", br_ops);
!       output_asm_insn (\"bc1t\\t%2\\t#beq\", br_ops);
!     }
!   else if  (mode == SFmode)
!     {
!       output_asm_insn (\"c.eq.s\\t%0,%1\\t#beq\", br_ops);
!       output_asm_insn (\"bc1t\\t%2\\t#beq\", br_ops);
!     }
!   else
!     {
!       output_asm_insn (\"beq\\t%0,%1,%2\\t#beq Inv.\", br_ops);
!     }
!   return \"\";
! }
! ")
! 
! (define_insn ""
!   [(set (pc)
! 	(if_then_else (eq (cc0)
! 			  (const_int 0))
! 		      (pc)
! 		      (label_ref (match_operand 0 "" ""))))]
!   ""
!   "*
! {
!   rtx br_ops[3];
!   enum machine_mode mode;
!   compare_restore (br_ops,  &mode, insn);
!   br_ops[2] = operands[0];
!   if (mode == DFmode)
!     {
!       output_asm_insn (\"c.eq.d\\t%0,%1\\t#bne\", br_ops);
!       output_asm_insn (\"bc1f\\t%2\\t#bne\", br_ops);
!     }
!   else if  (mode == SFmode)
!     {
!       output_asm_insn (\"c.eq.s\\t%0,%1\\t#bne\", br_ops);
!       output_asm_insn (\"bc1f\\t%2\\t#beq\", br_ops);
!     }
!   else
!     {
!       output_asm_insn (\"bne\\t%0,%1,%2\\t#bne Inv.\", br_ops);
!     }
!   return \"\";
! }
! 
! ")
! 
! (define_insn ""
!   [(set (pc)
! 	(if_then_else (le (cc0)
! 			  (const_int 0))
! 		      (pc)
! 		      (label_ref (match_operand 0 "" ""))))]
!   ""
!   "*
! {
!   rtx br_ops[3];
!   enum machine_mode mode;
!   compare_restore (br_ops,  &mode, insn);
!   br_ops[2] = operands[0];
!   if (mode == DFmode)
!     {
!       output_asm_insn (\"c.le.d\\t%0,%1\\t#bgt\", br_ops);
!       output_asm_insn (\"bc1f\\t%2\\t#beq\", br_ops);
!     }
!   else if  (mode == SFmode)
!     {
!       output_asm_insn (\"c.le.s\\t%0,%1\\t#bgt\", br_ops);
!       output_asm_insn (\"bc1f\\t%2\\t#beq\", br_ops);
!     }
!   else
!     {
!       output_asm_insn (\"bgt\\t%0,%1,%2\\t#bgt Inv.\", br_ops);
!     }
!   return \"\";
! }
  ")
+ 
  (define_insn ""
    [(set (pc)
  	(if_then_else (leu (cc0)
+ 			   (const_int 0))
+ 		      (pc)
+ 		      (label_ref (match_operand 0 "" ""))))]
+   ""
+   "*
+ {
+   rtx br_ops[3];
+   enum machine_mode mode;
+   compare_restore (br_ops,  &mode, insn);
+   br_ops[2] = operands[0];
+   if (mode == DFmode)
+     {
+       output_asm_insn (\"c.le.d\\t%0,%1\\t#bgt\", br_ops);
+       output_asm_insn (\"bc1f\\t%2\\t#beq\", br_ops);
+     }
+   else if  (mode == SFmode)
+     {
+       output_asm_insn (\"c.le.s\\t%0,%1\\t#bgt\", br_ops);
+       output_asm_insn (\"bc1f\\t%2\\t#beq\", br_ops);
+     }
+   else
+     {
+       output_asm_insn (\"bgtu\\t%0,%1,%2\\t#bgtu Inv.\", br_ops);
+     }
+   return \" #\\tbgtu \\t%l0\\t#bgtu\";
+ }
+ ")
+ 
+ (define_insn ""
+   [(set (pc)
+ 	(if_then_else (ge (cc0)
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 0 "" ""))))]
    ""
    "*
! {
!   rtx br_ops[3];
!   enum machine_mode mode;
!   compare_restore (br_ops,  &mode, insn);
!   br_ops[2] = operands[0];
!   if (mode == DFmode)
!     {
!       output_asm_insn (\"c.lt.d\\t%0,%1\\t#blt\", br_ops);
!       output_asm_insn (\"bc1t\\t%2\\t#beq\", br_ops);
!     }
!   else if  (mode == SFmode)
!     {
!       output_asm_insn (\"c.lt.s\\t%0,%1\\t#blt\", br_ops);
!       output_asm_insn (\"bc1t\\t%2\\t#beq\", br_ops);
!     }
!   else
!     {
!       output_asm_insn (\"blt\\t%0,%1,%2\\t#blt Inv.\", br_ops);
!     }
!   return \"\";
! }
  ")
  
***************
*** 2565,2696 ****
    [(set (pc)
  	(if_then_else (geu (cc0)
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 0 "" ""))
! 		      ))]
    ""
    "*
!    {rtx br_ops[3];
!     enum machine_mode mode;
!    compare_restore(br_ops,  &mode, insn);
!    br_ops[2] = operands[0];
!    if ( mode == DFmode)
!       {output_asm_insn(\"c.lt.d\\t%0,%1\\t#bltu\", br_ops);
!        output_asm_insn(\"bc1t\\t%2\\t#bltu\", br_ops);
!       }
!       else if  (mode == SFmode)
!       { output_asm_insn(\"c.lt.s\\t%0,%1\\t#bltu\", br_ops);
!        output_asm_insn(\"bc1t\\t%2\\t#bltu\", br_ops);
!       } 
!            else { output_asm_insn(\"bltu\\t%0,%1,%2\\t#bltu Inv.\", br_ops);
!            }
!    return \" #\\tbltu \\t%l0\\t#bltu\";
!    }
! ")
! 
! (define_insn ""
!   [(set (pc)
! 	(if_then_else (lt (cc0)
! 			  (const_int 0))
! 		      (pc)
! 		      (label_ref (match_operand 0 "" ""))
! 		      ))]
!   ""
!   "*
!    {rtx br_ops[3];
!     enum machine_mode mode;
!    compare_restore(br_ops,  &mode, insn);
!    br_ops[2] = operands[0];
!    if ( mode == DFmode)
!       {output_asm_insn(\"c.lt.d\\t%0,%1\\t#bge\", br_ops);
!        output_asm_insn(\"bc1f\\t%2\\t#bge (DF) Inv.\", br_ops);
!       }
!       else if  (mode == SFmode)
!       { output_asm_insn(\"c.lt.s\\t%0,%1\\t#bge\", br_ops);
!        output_asm_insn(\"bc1f\\t%2\\t#bge (SF) Inv.\", br_ops);
!       } 
!            else { output_asm_insn(\"bge\\t%0,%1,%2\\t#bge Inv.\", br_ops);
!            }
!    return \"\";
!    }
  ")
  (define_insn ""
    [(set (pc)
  	(if_then_else (ltu (cc0)
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 0 "" ""))
! 		      ))]
    ""
    "*
!    {rtx br_ops[3];
!     enum machine_mode mode;
!    compare_restore(br_ops,  &mode, insn);
!    br_ops[2] = operands[0];
!    if ( mode == DFmode)
!       {output_asm_insn(\"c.lt.d\\t%0,%1\\t#bge\", br_ops);
!        output_asm_insn(\"bc1f\\t%2\\t#bgeu (DF)  Inv.\", br_ops);
!       }
!       else if  (mode == SFmode)
!       { output_asm_insn(\"c.lt.s\\t%0,%1\\t#bge\", br_ops);
!        output_asm_insn(\"bc1f\\t%2\\t#bgeu (SF )Inv.\", br_ops);
!       } 
!            else { output_asm_insn(\"bgeu\\t%0,%1,%2\\t#bgeu Inv.\", br_ops);
!            }
!    return \" #\\tbgeu \\t%l0\\t#bgeu\";
!    }
! ")
! 
! (define_insn ""
!   [(set (pc)
! 	(if_then_else (gt (cc0)
! 			  (const_int 0))
! 		      (pc)
! 		      (label_ref (match_operand 0 "" ""))
! 		      ))]
!   ""
!   "*
!    {rtx br_ops[3];
!     enum machine_mode mode;
!    compare_restore(br_ops,  &mode, insn);
!    br_ops[2] = operands[0];
!    if ( mode == DFmode)
!       {output_asm_insn(\"c.le.d\\t%0,%1\\t#ble\", br_ops);
!        output_asm_insn(\"bc1t\\t%2\\t#ble\", br_ops);
!       }
!       else if  (mode == SFmode)
!       { output_asm_insn(\"c.le.s\\t%0,%1\\t#ble\", br_ops);
!        output_asm_insn(\"bc1t\\t%2\\t#ble\", br_ops);
!       } 
!            else { output_asm_insn(\"ble\\t%0,%1,%2\\t#ble Inv.\", br_ops);
!            }
!    return \"\";
!    }  
  ")
  (define_insn ""
    [(set (pc)
  	(if_then_else (gtu (cc0)
! 			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 0 "" ""))
! 		      ))]
    ""
    "*
!    {rtx br_ops[3];
!     enum machine_mode mode;
!    compare_restore(br_ops,  &mode, insn);
!    br_ops[2] = operands[0];
!    if ( mode == DFmode)
!       {output_asm_insn(\"c.le.d\\t%0,%1\\t#bleu\", br_ops);
!        output_asm_insn(\"bc1t\\t%2\\t#bleu\", br_ops);
!       }
!       else if  (mode == SFmode)
!       { output_asm_insn(\"c.le.s\\t%0,%1\\t#bleu\", br_ops);
!        output_asm_insn(\"bc1t\\t%2\\t#bleu\", br_ops);
!       } 
!            else { output_asm_insn(\"bleu\\t%0,%1,%2\\t#bleu Inv.\", br_ops);
!            }
!    return \"\";
!    }  
  ")
  
--- 2838,2991 ----
    [(set (pc)
  	(if_then_else (geu (cc0)
+ 			   (const_int 0))
+ 		      (pc)
+ 		      (label_ref (match_operand 0 "" ""))))]
+   ""
+   "*
+ {
+   rtx br_ops[3];
+   enum machine_mode mode;
+   compare_restore (br_ops,  &mode, insn);
+   br_ops[2] = operands[0];
+   if (mode == DFmode)
+     {
+       output_asm_insn (\"c.lt.d\\t%0,%1\\t#bltu\", br_ops);
+       output_asm_insn (\"bc1t\\t%2\\t#bltu\", br_ops);
+     }
+   else if  (mode == SFmode)
+     {
+       output_asm_insn (\"c.lt.s\\t%0,%1\\t#bltu\", br_ops);
+       output_asm_insn (\"bc1t\\t%2\\t#bltu\", br_ops);
+     }
+   else
+     {
+       output_asm_insn (\"bltu\\t%0,%1,%2\\t#bltu Inv.\", br_ops);
+     }
+   return \" #\\tbltu \\t%l0\\t#bltu\";
+ }
+ ")
+ 
+ (define_insn ""
+   [(set (pc)
+ 	(if_then_else (lt (cc0)
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 0 "" ""))))]
    ""
    "*
! {
!   rtx br_ops[3];
!   enum machine_mode mode;
!   compare_restore (br_ops,  &mode, insn);
!   br_ops[2] = operands[0];
!   if (mode == DFmode)
!     {
!       output_asm_insn (\"c.lt.d\\t%0,%1\\t#bge\", br_ops);
!       output_asm_insn (\"bc1f\\t%2\\t#bge (DF) Inv.\", br_ops);
!     }
!   else if  (mode == SFmode)
!     {
!       output_asm_insn (\"c.lt.s\\t%0,%1\\t#bge\", br_ops);
!       output_asm_insn (\"bc1f\\t%2\\t#bge (SF) Inv.\", br_ops);
!     }
!   else
!     {
!       output_asm_insn (\"bge\\t%0,%1,%2\\t#bge Inv.\", br_ops);
!     }
!   return \"\";
! }
  ")
+ 
  (define_insn ""
    [(set (pc)
  	(if_then_else (ltu (cc0)
+ 			   (const_int 0))
+ 		      (pc)
+ 		      (label_ref (match_operand 0 "" ""))))]
+   ""
+   "*
+ {
+   rtx br_ops[3];
+   enum machine_mode mode;
+   compare_restore (br_ops,  &mode, insn);
+   br_ops[2] = operands[0];
+   if (mode == DFmode)
+     {
+       output_asm_insn (\"c.lt.d\\t%0,%1\\t#bge\", br_ops);
+       output_asm_insn (\"bc1f\\t%2\\t#bgeu (DF)  Inv.\", br_ops);
+     }
+   else if  (mode == SFmode)
+     {
+       output_asm_insn (\"c.lt.s\\t%0,%1\\t#bge\", br_ops);
+       output_asm_insn (\"bc1f\\t%2\\t#bgeu (SF )Inv.\", br_ops);
+     }
+   else
+     {
+       output_asm_insn (\"bgeu\\t%0,%1,%2\\t#bgeu Inv.\", br_ops);
+     }
+   return \" #\\tbgeu \\t%l0\\t#bgeu\";
+ }
+ ")
+ 
+ (define_insn ""
+   [(set (pc)
+ 	(if_then_else (gt (cc0)
  			  (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 0 "" ""))))]
    ""
    "*
! {
!   rtx br_ops[3];
!   enum machine_mode mode;
!   compare_restore (br_ops,  &mode, insn);
!   br_ops[2] = operands[0];
!   if (mode == DFmode)
!     {
!       output_asm_insn (\"c.le.d\\t%0,%1\\t#ble\", br_ops);
!       output_asm_insn (\"bc1t\\t%2\\t#ble\", br_ops);
!     }
!   else if  (mode == SFmode)
!     {
!       output_asm_insn (\"c.le.s\\t%0,%1\\t#ble\", br_ops);
!       output_asm_insn (\"bc1t\\t%2\\t#ble\", br_ops);
!     }
!   else
!     {
!       output_asm_insn (\"ble\\t%0,%1,%2\\t#ble Inv.\", br_ops);
!     }
!   return \"\";
! }
  ")
+ 
  (define_insn ""
    [(set (pc)
  	(if_then_else (gtu (cc0)
! 			   (const_int 0))
  		      (pc)
! 		      (label_ref (match_operand 0 "" ""))))]
    ""
    "*
! {
!   rtx br_ops[3];
!   enum machine_mode mode;
!   compare_restore (br_ops,  &mode, insn);
!   br_ops[2] = operands[0];
!   if (mode == DFmode)
!     {
!       output_asm_insn (\"c.le.d\\t%0,%1\\t#bleu\", br_ops);
!       output_asm_insn (\"bc1t\\t%2\\t#bleu\", br_ops);
!     }
!   else if  (mode == SFmode)
!     {
!       output_asm_insn (\"c.le.s\\t%0,%1\\t#bleu\", br_ops);
!       output_asm_insn (\"bc1t\\t%2\\t#bleu\", br_ops);
!     }
!   else
!     {
!       output_asm_insn (\"bleu\\t%0,%1,%2\\t#bleu Inv.\", br_ops);
!     }
!   return \"\";
! }
  ")
  
***************
*** 2697,2706 ****
  (define_insn "tablejump"
    [(set (pc)
! 	 (match_operand:SI 0 "general_operand" "r")) 
!   (use (label_ref (match_operand 1 "" "")))
!   ]
    ""
!   "j\\t%0\\t# tablejump, label %l1\\t(jr not asm syntax)")
! 
  \f


  ;;
--- 2992,2999 ----
  (define_insn "tablejump"
    [(set (pc)
! 	(match_operand:SI 0 "general_operand" "r"))
!    (use (label_ref (match_operand 1 "" "")))]
    ""
!   "j\\t%0\\t# tablejump, label %l1\\t (jr not asm syntax)")
  \f


  ;;
***************
*** 2716,2732 ****
     (clobber (reg:SI 31))]
    ""
!   "* if(GET_CODE(XEXP(operands[0],0)) == SYMBOL_REF)
!         return \"jal\\t%0\\t# call with %1 arguments\";
!     else { operands[0] = XEXP(operands[0],0);
!            return \"jal\\t$31,%0\\t# call with  %1 arguments (reg)\";
!          }
!   " )
  
  
  (define_expand "call_value"
!   [(set (match_operand 0 "" "rf")
  	(call (match_operand:SI 1 "memory_operand" "m")
  	      (match_operand 2 "" "i")))
!        (clobber (reg:SI 31))]
    ;; operand 3 is next_arg_register
    ""
--- 3009,3029 ----
     (clobber (reg:SI 31))]
    ""
!   "*
! {
!   if (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
!     return \"jal\\t%0\\t# call with %1 arguments\";
!   else
!     {
!       operands[0] = XEXP (operands[0], 0);
!       return \"jal\\t$31,%0\\t# call with  %1 arguments (reg)\";
!     }
! }" )
  
  
  (define_expand "call_value"
!   [(set (match_operand 0 "" "=rf")
  	(call (match_operand:SI 1 "memory_operand" "m")
  	      (match_operand 2 "" "i")))
!    (clobber (reg:SI 31))]
    ;; operand 3 is next_arg_register
    ""
***************
*** 2736,2740 ****
    rtvec vec;
  
!     fn_rtx = operands[1];
  
    nregs_rtx = const0_rtx;
--- 3033,3037 ----
    rtvec vec;
  
!   fn_rtx = operands[1];
  
    nregs_rtx = const0_rtx;
***************
*** 2752,2773 ****
  
  (define_insn ""
!   [(set (match_operand 0 "general_operand" "g,f")
          (call (match_operand 1 "general_operand" "g,g")
                (match_operand 2 "general_operand" "g,g")))
     (clobber (match_operand 3 "general_operand" "g,g"))]
! ""
! "* if(GET_CODE(XEXP(operands[1],0)) == SYMBOL_REF)
!      return \"jal\\t%1\\t# call  %1  regle 2-call (VOIDmode)\";
!     else { operands[1] = XEXP(operands[1],0);
!            return \"jal\\t$31,%1\\t# call %1 regle 2-call (VOIDmode,reg)\";
!          }
! ")
! 
! 					;;- RETURN == BRANCH TO EPILOGUE
! ;;-- (define_insn "return"			
! ;;--   [(return)
! ;;--    (use (reg:SI 31))]
! ;;--   ""
! ;;--   "#\\t\\t ---- return")
  \f


  ;;
--- 3049,3079 ----
  
  (define_insn ""
!   [(set (match_operand 0 "general_operand" "=g,f")
          (call (match_operand 1 "general_operand" "g,g")
                (match_operand 2 "general_operand" "g,g")))
     (clobber (match_operand 3 "general_operand" "g,g"))]
!   ""
!   "*
! {
!   if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
!     return \"jal\\t%1\\t# call  %1  regle 2-call (VOIDmode)\";
!   else
!     {
!       operands[1] = XEXP (operands[1], 0);
!       return \"jal\\t$31,%1\\t# call %1 regle 2-call (VOIDmode, reg)\";
!     }
! }")
! 
! (define_insn "nop"
!   [(const_int 0)]
!   ""
!   "nop")
! 
! (define_expand "probe"
!   [(set (reg:SI 29) (minus:SI (reg:SI 29) (const_int 4)))
!    (set (mem:SI (reg:SI 29)) (const_int 0))
!    (set (reg:SI 29) (plus:SI (reg:SI 29) (const_int 4)))]
!   ""
!   "")
  \f


  ;;
***************
*** 2781,2783 ****
  ;;- eval: (modify-syntax-entry ?} "){")
  ;;- End:
- 
--- 3087,3088 ----
diff -rc2N gcc-1.35/config/ns32k.md gcc-1.36/config/ns32k.md
*** gcc-1.35/config/ns32k.md	Sat Apr  1 23:14:30 1989
--- gcc-1.36/config/ns32k.md	Fri Aug 18 22:22:54 1989
***************
*** 85,101 ****
    return \"cmpf %1,%0\"; }")
  
! (define_insn "cmpdf"
!   [(set (cc0)
! 	(compare (match_operand:DF 0 "general_operand" "fmF")
! 		 (match_operand:DF 1 "general_operand" "fmF")))]
!   "TARGET_32081"
!   "cmpl %0,%1")
! 
! (define_insn "cmpsf"
!   [(set (cc0)
! 	(compare (match_operand:SF 0 "general_operand" "fmF")
! 		 (match_operand:SF 1 "general_operand" "fmF")))]
!   "TARGET_32081"
!   "cmpf %0,%1")
  
  (define_insn "cmpsi"
--- 85,89 ----
    return \"cmpf %1,%0\"; }")
  
! ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
  
  (define_insn "cmpsi"
***************
*** 188,191 ****
--- 176,193 ----
    return \"cmpb %0,%1\";
  }")
+ 
+ (define_insn "cmpdf"
+   [(set (cc0)
+ 	(compare (match_operand:DF 0 "general_operand" "fmF")
+ 		 (match_operand:DF 1 "general_operand" "fmF")))]
+   "TARGET_32081"
+   "cmpl %0,%1")
+ 
+ (define_insn "cmpsf"
+   [(set (cc0)
+ 	(compare (match_operand:SF 0 "general_operand" "fmF")
+ 		 (match_operand:SF 1 "general_operand" "fmF")))]
+   "TARGET_32081"
+   "cmpf %0,%1")
  \f


  (define_insn "movdf"
***************
*** 245,249 ****
      {
        /* Is there a better machine-independent way to to this?  */
!       operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]));
        return \"movd %1,%0\";
      }
--- 247,252 ----
      {
        /* Is there a better machine-independent way to to this?  */
!       operands[1] = gen_rtx (CONST_INT, VOIDmode,
! 			     CONST_DOUBLE_LOW (operands[1]));
        return \"movd %1,%0\";
      }
***************
*** 289,297 ****
      }
    else if (GET_CODE (operands[1]) == REG)
!     if (REGNO (operands[1]) < 16)
!       return \"movd %1,%0\";
!     else if (REGNO (operands[1]) == 16)
!       return \"addr 0(fp),%0\";
!     else return \"addr tos,%0\";
    else if (GET_CODE (operands[1]) == MEM)
      return \"movd %1,%0\";
--- 292,314 ----
      }
    else if (GET_CODE (operands[1]) == REG)
!     {
!       if (REGNO (operands[1]) < 16)
!         return \"movd %1,%0\";
!       else if (REGNO (operands[1]) == FRAME_POINTER_REGNUM)
! 	{
! 	  if (GET_CODE(operands[0]) == REG)
! 	    return \"sprd fp,%0\";
! 	  else
! 	    return \"addr 0(fp),%0\" ;
! 	}
!       else if (REGNO (operands[1]) == STACK_POINTER_REGNUM)
! 	{
! 	  if (GET_CODE(operands[0]) == REG)
! 	    return \"sprd sp,%0\";
! 	  else
! 	    return \"addr 0(sp),%0\" ;
! 	}
!       else abort (0);
!     }
    else if (GET_CODE (operands[1]) == MEM)
      return \"movd %1,%0\";
***************
*** 1827,1832 ****
      {
        if (INTVAL (operands[3]) >= 8)
! 	operands[1] = adj_offsetable_operand (operands[1],
! 					      INTVAL (operands[3]) >> 3);
        return \"extsd %1,%0,%3,%2\";
      }
--- 1844,1849 ----
      {
        if (INTVAL (operands[3]) >= 8)
! 	operands[1] = adj_offsettable_operand (operands[1],
! 					       INTVAL (operands[3]) >> 3);
        return \"extsd %1,%0,%3,%2\";
      }
***************
*** 1844,1849 ****
      {
        if (INTVAL (operands[3]) >= 8)
! 	operands[1] = adj_offsetable_operand (operands[1],
! 					      INTVAL (operands[3]) >> 3);
        return \"extsd %1,%0,%3,%2\";
      }
--- 1861,1866 ----
      {
        if (INTVAL (operands[3]) >= 8)
! 	operands[1] = adj_offsettable_operand (operands[1],
! 					       INTVAL (operands[3]) >> 3);
        return \"extsd %1,%0,%3,%2\";
      }
***************
*** 1874,1878 ****
        if (GET_CODE (operands[0]) == MEM && INTVAL (operands[2]) >= 8)
  	{
! 	  operands[0] = adj_offsetable_operand (operands[0],
  					        INTVAL (operands[2]) / 8);
            operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) % 8);
--- 1891,1895 ----
        if (GET_CODE (operands[0]) == MEM && INTVAL (operands[2]) >= 8)
  	{
! 	  operands[0] = adj_offsettable_operand (operands[0],
  					        INTVAL (operands[2]) / 8);
            operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) % 8);
***************
*** 1899,1904 ****
        if (GET_CODE (operands[0]) == MEM && INTVAL (operands[2]) >= 8)
  	{
! 	  operands[0] = adj_offsetable_operand (operands[0],
! 					        INTVAL (operands[2]) / 8);
            operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) % 8);
  	}
--- 1916,1921 ----
        if (GET_CODE (operands[0]) == MEM && INTVAL (operands[2]) >= 8)
  	{
! 	  operands[0] = adj_offsettable_operand (operands[0],
! 					         INTVAL (operands[2]) / 8);
            operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) % 8);
  	}
***************
*** 2231,2235 ****
  
  (define_insn "call_value"
!   [(set (match_operand 0 "" "fg")
  	(call (match_operand:QI 1 "general_operand" "g")
  	      (match_operand:QI 2 "general_operand" "g")))]
--- 2248,2252 ----
  
  (define_insn "call_value"
!   [(set (match_operand 0 "" "=fg")
  	(call (match_operand:QI 1 "general_operand" "g")
  	      (match_operand:QI 2 "general_operand" "g")))]
***************
*** 2289,2292 ****
--- 2306,2314 ----
    ""
    "absb %1,%0")
+ 
+ (define_insn "nop"
+   [(const_int 0)]
+   ""
+   "nop")
  
  ;;(define_insn "tablejump"
diff -rc2N gcc-1.35/config/out-alliant.c gcc-1.36/config/out-alliant.c
*** gcc-1.35/config/out-alliant.c	Wed Mar 29 15:26:58 1989
--- gcc-1.36/config/out-alliant.c	Thu Jun 15 17:51:48 1989
***************
*** 1,4 ****
! /* Subroutines for insn-output.c for Alliant computers.
!    Copyright (C) 1988 Free Software Foundation, Inc.
  
  This file is part of GNU CC.
--- 1,4 ----
! /* Subroutines for insn-output.c for Alliant FX computers.
!    Copyright (C) 1989 Free Software Foundation, Inc.
  
  This file is part of GNU CC.
***************
*** 19,25 ****
  
  
! /* Some output-actions in m68k.md need these.  */
  #include <stdio.h>
- 
  extern FILE *asm_out_file;
  
--- 19,24 ----
  
  
! /* Some output-actions in alliant.md need these.  */
  #include <stdio.h>
  extern FILE *asm_out_file;
  
***************
*** 27,32 ****
     smallest class which contains that register.  */
  enum reg_class regno_reg_class[]
!   = { DATA_REGS, ADDR_REGS, FP_REGS,
!       LO_FPA_REGS, LO_FPA_REGS, FPA_REGS, FPA_REGS };
  
  static rtx find_addr_reg ();
--- 26,30 ----
     smallest class which contains that register.  */
  enum reg_class regno_reg_class[]
!   = { DATA_REGS, ADDR_REGS, FP_REGS };
  
  static rtx find_addr_reg ();
***************
*** 41,47 ****
--- 39,54 ----
    operands[0] = countop;
    operands[1] = dataop;
+ 
    if (GET_CODE (countop) == CONST_INT)
      {
        register int count = INTVAL (countop);
+       /* If COUNT is bigger than size of storage unit in use,
+ 	 advance to the containing unit of same size.  */
+       if (count > signpos)
+ 	{
+ 	  int offset = (count & ~signpos) / 8;
+ 	  count = count & signpos;
+ 	  operands[1] = dataop = adj_offsettable_operand (dataop, offset);
+ 	}
        if (count == signpos)
  	cc_status.flags = CC_NOT_POSITIVE | CC_Z_IN_NOT_N;
***************
*** 93,97 ****
    if (REG_P (operands[0]))
      optype0 = REGOP;
!   else if (offsetable_memref_p (operands[0]))
      optype0 = OFFSOP;
    else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
--- 100,104 ----
    if (REG_P (operands[0]))
      optype0 = REGOP;
!   else if (offsettable_memref_p (operands[0]))
      optype0 = OFFSOP;
    else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
***************
*** 109,113 ****
  	   || GET_CODE (operands[1]) == CONST_DOUBLE)
      optype1 = CNSTOP;
!   else if (offsetable_memref_p (operands[1]))
      optype1 = OFFSOP;
    else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
--- 116,120 ----
  	   || GET_CODE (operands[1]) == CONST_DOUBLE)
      optype1 = CNSTOP;
!   else if (offsettable_memref_p (operands[1]))
      optype1 = OFFSOP;
    else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
***************
*** 167,171 ****
      latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
    else if (optype0 == OFFSOP)
!     latehalf[0] = adj_offsetable_operand (operands[0], 4);
    else
      latehalf[0] = operands[0];
--- 174,178 ----
      latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
    else if (optype0 == OFFSOP)
!     latehalf[0] = adj_offsettable_operand (operands[0], 4);
    else
      latehalf[0] = operands[0];
***************
*** 174,178 ****
      latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
    else if (optype1 == OFFSOP)
!     latehalf[1] = adj_offsetable_operand (operands[1], 4);
    else if (optype1 == CNSTOP)
      {
--- 181,185 ----
      latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
    else if (optype1 == OFFSOP)
!     latehalf[1] = adj_offsettable_operand (operands[1], 4);
    else if (optype1 == CNSTOP)
      {
***************
*** 210,214 ****
  	  && REGNO (operands[0]) == REGNO (latehalf[1])))
      {
!       /* Make any unoffsetable addresses point at high-numbered word.  */
        if (addreg0)
  	output_asm_insn ("addql %#4,%0", &addreg0);
--- 217,221 ----
  	  && REGNO (operands[0]) == REGNO (latehalf[1])))
      {
!       /* Make any unoffsettable addresses point at high-numbered word.  */
        if (addreg0)
  	output_asm_insn ("addql %#4,%0", &addreg0);
***************
*** 233,237 ****
    output_asm_insn (singlemove_string (operands), operands);
  
!   /* Make any unoffsetable addresses point at high-numbered word.  */
    if (addreg0)
      output_asm_insn ("addql %#4,%0", &addreg0);
--- 240,244 ----
    output_asm_insn (singlemove_string (operands), operands);
  
!   /* Make any unoffsettable addresses point at high-numbered word.  */
    if (addreg0)
      output_asm_insn ("addql %#4,%0", &addreg0);
***************
*** 274,298 ****
      return addr;
    abort ();
- }
- \f


- char *
- output_move_const_double (operands)
-      rtx *operands;
- {
-   return "fmove%.d %1,%0";
- }
- 
- char *
- output_move_const_single (operands)
-      rtx *operands;
- {
-   return "fmove%.s %1,%0";
- }
- 
- int
- standard_68881_constant_p (x)
-      rtx x;
- {
-   return 0;
  }
  
--- 281,284 ----
diff -rc2N gcc-1.35/config/out-convex.c gcc-1.36/config/out-convex.c
*** gcc-1.35/config/out-convex.c	Wed Feb 22 12:22:24 1989
--- gcc-1.36/config/out-convex.c	Wed Jun  7 14:24:15 1989
***************
*** 90,146 ****
  \f


  /*
-  *  set_section -- arg is a section name, like ".text".  
-  *	Remembers it and returns it
-  *
-  *  align_section -- returns a string to align current section,
-  *	something like ".text 2" or ".align 8".  Arg is log2 of boundary.
-  */
- 
- static char *prevsect = "";
- static char *cursect = "";
- 
- char *
- set_section (p)
-      char *p;
- {
-   if (p == 0)
-     p = prevsect;
-   prevsect = cursect;
-   cursect = p;
-   return p;
- }
- 
- char *
- align_section (n)
-      int n;
- {
-   static char buf[20];
- 
-   if (n < 0)
-     {
-       /* -n is a size; align to that size */
-       if ((n & 7) == 0) n = 3;
-       else if ((n & 3) == 0) n = 2;
-       else if ((n & 1) == 0) n = 1;
-       else n = 0;
-     }
- 
-   if (!strcmp (cursect, ".text"))
-     {
-       if (n > 1)
- 	sprintf (buf, "%s %d\n", cursect, n);
-       else
- 	sprintf (buf, "%s\n.align %d\n", cursect, 1 << n);
-       return buf;
-     }
-   else
-     {
-       if (n == 0) return "";
-       sprintf (buf, ".align %d\n", 1 << n);
-       return buf;
-     }
- }
- \f


- /*
   *  pick target machine if not specified, the same as the host
   */
--- 90,93 ----
***************
*** 288,291 ****
    return d;
  }
- 
  
--- 235,237 ----
diff -rc2N gcc-1.35/config/out-i386.c gcc-1.36/config/out-i386.c
*** gcc-1.35/config/out-i386.c	Mon Apr 10 05:19:28 1989
--- gcc-1.36/config/out-i386.c	Thu Aug 17 15:55:08 1989
***************
*** 436,440 ****
    if (REG_P (operands[0]))
      optype0 = REGOP;
!   else if (offsetable_memref_p (operands[0]))
      optype0 = OFFSOP;
    else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
--- 436,440 ----
    if (REG_P (operands[0]))
      optype0 = REGOP;
!   else if (offsettable_memref_p (operands[0]))
      optype0 = OFFSOP;
    else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
***************
*** 452,456 ****
  	   || GET_CODE (operands[1]) == CONST_DOUBLE)
      optype1 = CNSTOP;
!   else if (offsetable_memref_p (operands[1]))
      optype1 = OFFSOP;
    else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
--- 452,456 ----
  	   || GET_CODE (operands[1]) == CONST_DOUBLE)
      optype1 = CNSTOP;
!   else if (offsettable_memref_p (operands[1]))
      optype1 = OFFSOP;
    else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
***************
*** 510,514 ****
      latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
    else if (optype0 == OFFSOP)
!     latehalf[0] = adj_offsetable_operand (operands[0], 4);
    else
      latehalf[0] = operands[0];
--- 510,514 ----
      latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
    else if (optype0 == OFFSOP)
!     latehalf[0] = adj_offsettable_operand (operands[0], 4);
    else
      latehalf[0] = operands[0];
***************
*** 517,521 ****
      latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
    else if (optype1 == OFFSOP)
!     latehalf[1] = adj_offsetable_operand (operands[1], 4);
    else if (optype1 == CNSTOP)
      {
--- 517,521 ----
      latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
    else if (optype1 == OFFSOP)
!     latehalf[1] = adj_offsettable_operand (operands[1], 4);
    else if (optype1 == CNSTOP)
      {
***************
*** 553,557 ****
  	  && REGNO (operands[0]) == REGNO (latehalf[1])))
      {
!       /* Make any unoffsetable addresses point at high-numbered word.  */
        if (addreg0)
  	asm_add (4, addreg0);
--- 553,557 ----
  	  && REGNO (operands[0]) == REGNO (latehalf[1])))
      {
!       /* Make any unoffsettable addresses point at high-numbered word.  */
        if (addreg0)
  	asm_add (4, addreg0);
***************
*** 576,580 ****
    output_asm_insn (singlemove_string (operands), operands);
  
!   /* Make any unoffsetable addresses point at high-numbered word.  */
    if (addreg0)
      asm_add (4, addreg0);
--- 576,580 ----
    output_asm_insn (singlemove_string (operands), operands);
  
!   /* Make any unoffsettable addresses point at high-numbered word.  */
    if (addreg0)
      asm_add (4, addreg0);
***************
*** 816,821 ****
      {
        rtx xops[2];
!       xops[0] = adj_offsetable_operand (AT_BP (Pmode),
! 					-size -(nregs*(UNITS_PER_WORD)));
        xops[1] = stack_pointer_rtx;
        output_asm_insn (AS2 (lea%L0,%0,%1), xops);
--- 816,821 ----
      {
        rtx xops[2];
!       xops[0] = adj_offsettable_operand (AT_BP (Pmode),
! 					 -size -(nregs*(UNITS_PER_WORD)));
        xops[1] = stack_pointer_rtx;
        output_asm_insn (AS2 (lea%L0,%0,%1), xops);
***************
*** 830,841 ****
      }
  
!   if (frame_pointer_needed)  fprintf (file, "\tleave\n");
    if (current_function_pops_args && current_function_args_size)
!     fprintf (file, "\tret %s%d\n", IP, current_function_args_size);
!   else fprintf (file, "\tret\n")
!     ;
!   /* the following should be 1 for a function returning a float and
!      0 otherwise */
!   /* fprintf (file, "%s At return: fp_pop_level= %d\n", COMMENT_BEGIN, fp_pop_level); */
  }
  
--- 830,843 ----
      }
  
!   if (frame_pointer_needed)
!     fprintf (file, "\tleave\n");
    if (current_function_pops_args && current_function_args_size)
!     fprintf (file, "\tret %s%d\n", IP,
! 	     (current_function_args_size
! 	      + (current_function_returns_struct ? 4 : 0)));
!   else if (current_function_returns_struct)
!     fprintf (file, "\tret %s4\n", IP);
!   else
!     fprintf (file, "\tret\n");
  }
  
***************
*** 1246,1249 ****
--- 1248,1255 ----
        if (insn == 0)
  	return 1;
+       if (GET_CODE (insn) == NOTE || GET_CODE (insn) == CODE_LABEL)
+ 	continue;
+       if (GET_CODE (insn) == BARRIER)
+ 	abort ();
        if (GET_CODE (PATTERN (insn)) == SET
  	  && SET_DEST (PATTERN (insn)) != stack_pointer_rtx)
diff -rc2N gcc-1.35/config/out-i860.c gcc-1.36/config/out-i860.c
*** gcc-1.35/config/out-i860.c	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config/out-i860.c	Sat Sep 16 05:03:50 1989
***************
*** 0 ****
--- 1,1444 ----
+ /* Subroutines for insn-output.c for Intel 860
+    Copyright (C) 1989 Free Software Foundation, Inc.
+    Derived from out-sparc.c.
+ 
+ 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+ 
+ 
+ /* Global variables for machine-dependend things.  */
+ 
+ /* This should go away if we pass floats to regs via
+    the stack instead of the frame, and if we learn how
+    to renumber all the registers when we don't do a save (hard!).  */
+ extern int frame_pointer_needed;
+ 
+ static rtx find_addr_reg ();
+ \f


+ /* Return non-zero only if OP is a register of mode MODE,
+    or const0_rtx.  */
+ int
+ reg_or_0_operand (op, mode)
+      rtx op;
+      enum machine_mode mode;
+ {
+   return (op == const0_rtx || register_operand (op, mode)
+ 	  || op == CONST0_RTX (mode));
+ }
+ 
+ /* Return non-zero if this pattern, can be evaluated safely, even if it
+    was not asked for.  */
+ int
+ safe_insn_src_p (op, mode)
+      rtx op;
+      enum machine_mode mode;
+ {
+   /* Just experimenting.  */
+ 
+   /* No floating point src is safe if it contains an arithmetic
+      operation, since that operation may trap.  */
+   switch (GET_CODE (op))
+     {
+     case CONST_INT:
+     case LABEL_REF:
+     case SYMBOL_REF:
+     case CONST:
+       return 1;
+ 
+     case REG:
+       return 1;
+ 
+     case MEM:
+       return CONSTANT_ADDRESS_P (XEXP (op, 0));
+ 
+       /* We never need to negate or complement constants.  */
+     case NEG:
+       return (mode != SFmode && mode != DFmode);
+     case NOT:
+     case ZERO_EXTEND:
+       return 1;
+ 
+     case EQ:
+     case NE:
+     case LT:
+     case GT:
+     case LE:
+     case GE:
+     case LTU:
+     case GTU:
+     case LEU:
+     case GEU:
+     case MINUS:
+     case PLUS:
+       return (mode != SFmode && mode != DFmode);
+     case AND:
+     case IOR:
+     case XOR:
+     case LSHIFT:
+     case ASHIFT:
+     case ASHIFTRT:
+     case LSHIFTRT:
+       if ((GET_CODE (XEXP (op, 0)) == CONST_INT && ! SMALL_INT (XEXP (op, 0)))
+ 	  || (GET_CODE (XEXP (op, 1)) == CONST_INT && ! SMALL_INT (XEXP (op, 1))))
+ 	return 0;
+       return 1;
+ 
+     default:
+       return 0;
+     }
+ }
+ 
+ /* Return 1 if REG is clobbered in IN.
+    Return 2 if REG is used in IN. 
+    Return 3 if REG is both used and clobbered in IN.
+    Return 0 if neither.  */
+ 
+ static int
+ reg_clobbered_p (reg, in)
+      rtx reg;
+      rtx in;
+ {
+   register enum rtx_code code;
+ 
+   if (in == 0)
+     return 0;
+ 
+   code = GET_CODE (in);
+ 
+   if (code == SET || code == CLOBBER)
+     {
+       rtx dest = SET_DEST (in);
+       int set = 0;
+       int used = 0;
+ 
+       while (GET_CODE (dest) == STRICT_LOW_PART
+ 	     || GET_CODE (dest) == SUBREG
+ 	     || GET_CODE (dest) == SIGN_EXTRACT
+ 	     || GET_CODE (dest) == ZERO_EXTRACT)
+ 	dest = XEXP (dest, 0);
+ 
+       if (dest == reg)
+ 	set = 1;
+       else if (GET_CODE (dest) == REG
+ 	       && refers_to_regno_p (REGNO (reg),
+ 				     REGNO (reg) + HARD_REGNO_NREGS (reg, GET_MODE (reg)),
+ 				     SET_DEST (in), 0))
+ 	{
+ 	  set = 1;
+ 	  /* Anything that sets just part of the register
+ 	     is considered using as well as setting it.
+ 	     But note that a straight SUBREG of a single-word value
+ 	     clobbers the entire value.   */
+ 	  if (dest != SET_DEST (in)
+ 	      && ! (GET_CODE (SET_DEST (in)) == SUBREG
+ 		    || UNITS_PER_WORD >= GET_MODE_SIZE (GET_MODE (dest))))
+ 	    used = 1;
+ 	}
+ 
+       if (code == SET)
+ 	{
+ 	  if (set)
+ 	    used = refers_to_regno_p (REGNO (reg),
+ 				      REGNO (reg) + HARD_REGNO_NREGS (reg, GET_MODE (reg)),
+ 				      SET_SRC (in), 0);
+ 	  else
+ 	    used = refers_to_regno_p (REGNO (reg),
+ 				      REGNO (reg) + HARD_REGNO_NREGS (reg, GET_MODE (reg)),
+ 				      in, 0);
+ 	}
+ 
+       return set + used * 2;
+     }
+ 
+   if (refers_to_regno_p (REGNO (reg),
+ 			 REGNO (reg) + HARD_REGNO_NREGS (reg, GET_MODE (reg)),
+ 			 in, 0))
+     return 2;
+   return 0;
+ }
+ 
+ /* Return non-zero if OP can be written to without screwing up
+    GCC's model of what's going on.  It is assumed that this operand
+    appears in the dest position of a SET insn in a conditional
+    branch's delay slot.  AFTER is the label to start looking from.  */
+ int
+ operand_clobbered_before_used_after (op, after)
+      rtx op;
+      rtx after;
+ {
+   extern char call_used_regs[];
+ 
+   /* Just experimenting.  */
+   if (GET_CODE (op) == CC0)
+     return 1;
+   if (GET_CODE (op) == REG)
+     {
+       rtx insn;
+ 
+       if (op == stack_pointer_rtx)
+ 	return 0;
+ 
+       /* Scan forward from the label, to see if the value of OP
+ 	 is clobbered before the first use.  */
+ 
+       for (insn = NEXT_INSN (after); insn; insn = NEXT_INSN (insn))
+ 	{
+ 	  if (GET_CODE (insn) == NOTE)
+ 	    continue;
+ 	  if (GET_CODE (insn) == INSN
+ 	      || GET_CODE (insn) == JUMP_INSN
+ 	      || GET_CODE (insn) == CALL_INSN)
+ 	    {
+ 	      switch (reg_clobbered_p (op, PATTERN (insn)))
+ 		{
+ 		default:
+ 		  return 0;
+ 		case 1:
+ 		  return 1;
+ 		case 0:
+ 		  break;
+ 		}
+ 	    }
+ 	  /* If we reach another label without clobbering OP,
+ 	     then we cannot safely write it here.  */
+ 	  else if (GET_CODE (insn) == CODE_LABEL)
+ 	    return 0;
+ 	  if (GET_CODE (insn) == JUMP_INSN)
+ 	    {
+ 	      if (condjump_p (insn))
+ 		return 0;
+ 	      /* This is a jump insn which has already
+ 		 been mangled.  We can't tell what it does.  */
+ 	      if (GET_CODE (PATTERN (insn)) == PARALLEL)
+ 		return 0;
+ 	      if (! JUMP_LABEL (insn))
+ 		return 0;
+ 	      /* Keep following jumps.  */
+ 	      insn = JUMP_LABEL (insn);
+ 	    }
+ 	}
+       return 1;
+     }
+ 
+   /* In both of these cases, the first insn executed
+      for this op will be a orh whatever%h,r0,r31,
+      which is tolerable.  */
+   if (GET_CODE (op) == MEM)
+     return (CONSTANT_ADDRESS_P (XEXP (op, 0)));
+ 
+   return 0;
+ }
+ 
+ /* Return non-zero if this pattern, as a source to a "SET",
+    is known to yield an instruction of unit size.  */
+ int
+ single_insn_src_p (op, mode)
+      rtx op;
+      enum machine_mode mode;
+ {
+   switch (GET_CODE (op))
+     {
+     case CONST_INT:
+       /* This is not always a single insn src, technically,
+ 	 but output_delayed_branch knows how to deal with it.  */
+       return 1;
+ 
+     case SYMBOL_REF:
+     case CONST:
+       /* This is not a single insn src, technically,
+ 	 but output_delayed_branch knows how to deal with it.  */
+       return 1;
+ 
+     case REG:
+       return 1;
+ 
+     case MEM:
+       return 1;
+ 
+       /* We never need to negate or complement constants.  */
+     case NEG:
+       return (mode != DFmode);
+     case NOT:
+     case ZERO_EXTEND:
+       return 1;
+ 
+     case EQ:
+     case NE:
+     case LT:
+     case GT:
+     case LE:
+     case GE:
+     case LTU:
+     case GTU:
+     case LEU:
+     case GEU:
+     case MINUS:
+     case PLUS:
+       /* Not doing floating point, since they probably
+ 	 take longer than the branch slot they might fill.  */
+       return (mode != SFmode && mode != DFmode);
+     case AND:
+     case IOR:
+     case XOR:
+     case LSHIFT:
+     case ASHIFT:
+     case ASHIFTRT:
+     case LSHIFTRT:
+       if ((GET_CODE (XEXP (op, 0)) == CONST_INT && ! SMALL_INT (XEXP (op, 0)))
+ 	  || (GET_CODE (XEXP (op, 1)) == CONST_INT && ! SMALL_INT (XEXP (op, 1))))
+ 	return 0;
+       return 1;
+ 
+     case SUBREG:
+       if (SUBREG_WORD (op) != 0)
+ 	return 0;
+       return single_insn_src_p (SUBREG_REG (op), mode);
+ 
+       /* Not doing floating point, since they probably
+ 	 take longer than the branch slot they might fill.  */
+     case FLOAT_EXTEND:
+     case FLOAT_TRUNCATE:
+     case FLOAT:
+     case FIX:
+     case UNSIGNED_FLOAT:
+     case UNSIGNED_FIX:
+       return 0;
+ 
+     default:
+       return 0;
+     }
+ }
+ 
+ /* Nonzero only if this *really* is a single insn operand.  */
+ int
+ strict_single_insn_op_p (op, mode)
+      rtx op;
+      enum machine_mode mode;
+ {
+   if (mode == VOIDmode)
+     mode = GET_MODE (op);
+ 
+   switch (GET_CODE (op))
+     {
+     case CC0:
+       return 1;
+ 
+     case CONST_INT:
+       if (SMALL_INT (op))
+ 	return 1;
+       /* We can put this set insn into delay slot, because this is one
+ 	 insn; 'sethi'.  */
+       if ((INTVAL (op) & 0x3ff) == 0)
+ 	return 1;
+       return 0;
+ 
+     case SYMBOL_REF:
+       return 0;
+ 
+     case REG:
+ #if 0
+       /* This loses when moving an freg to a general reg.  */
+       return HARD_REGNO_NREGS (REGNO (op), mode) == 1;
+ #endif
+       return (mode != DFmode && mode != DImode);
+ 
+     case MEM:
+       if (! CONSTANT_ADDRESS_P (XEXP (op, 0)))
+ 	return (mode != DFmode && mode != DImode);
+       return 0;
+ 
+       /* We never need to negate or complement constants.  */
+     case NEG:
+       return (mode != DFmode);
+     case NOT:
+     case ZERO_EXTEND:
+       return 1;
+ 
+     case EQ:
+     case NE:
+     case LT:
+     case GT:
+     case LE:
+     case GE:
+     case LTU:
+     case GTU:
+     case LEU:
+     case GEU:
+     case MINUS:
+     case PLUS:
+     case AND:
+     case IOR:
+     case XOR:
+     case LSHIFT:
+     case ASHIFT:
+     case ASHIFTRT:
+     case LSHIFTRT:
+       if ((GET_CODE (XEXP (op, 0)) == CONST_INT && ! SMALL_INT (XEXP (op, 0)))
+ 	  || (GET_CODE (XEXP (op, 1)) == CONST_INT && ! SMALL_INT (XEXP (op, 1))))
+ 	return 0;
+       return 1;
+ 
+     case SUBREG:
+       if (SUBREG_WORD (op) != 0)
+ 	return 0;
+       return strict_single_insn_op_p (SUBREG_REG (op), mode);
+ 
+     case SIGN_EXTEND:
+       if (GET_CODE (XEXP (op, 0)) == MEM
+ 	  && ! CONSTANT_ADDRESS_P (XEXP (XEXP (op, 0), 0)))
+ 	return 1;
+       return 0;
+ 
+       /* Not doing floating point, since they probably
+ 	 take longer than the branch slot they might fill.  */
+     case FLOAT_EXTEND:
+     case FLOAT_TRUNCATE:
+     case FLOAT:
+     case FIX:
+     case UNSIGNED_FLOAT:
+     case UNSIGNED_FIX:
+       return 0;
+ 
+     default:
+       return 0;
+     }
+ }
+ \f


+ /* Return truth value of whether OP is a relational operator.  */
+ int
+ relop (op, mode)
+      rtx op;
+      enum machine_mode mode;
+ {
+   switch (GET_CODE (op))
+     {
+     case EQ:
+     case NE:
+     case GT:
+     case GE:
+     case LT:
+     case LE:
+     case GTU:
+     case GEU:
+     case LTU:
+     case LEU:
+       return 1;
+     }
+   return 0;
+ }
+ \f


+ /* Return truth value of whether OP can be used as an operands in a three
+    address add/subtract insn (such as add %o1,7,%l2) of mode MODE.  */
+ 
+ int
+ arith_operand (op, mode)
+      rtx op;
+      enum machine_mode mode;
+ {
+   return (register_operand (op, mode)
+ 	  || (GET_CODE (op) == CONST_INT && SMALL_INT (op)));
+ }
+ 
+ /* Return 1 if OP is a valid first operand for a logical insn of mode MODE.  */
+ 
+ int
+ logic_operand (op, mode)
+      rtx op;
+      enum machine_mode mode;
+ {
+   return (register_operand (op, mode)
+ 	  || (GET_CODE (op) == CONST_INT && LOGIC_INT (op)));
+ }
+ 
+ /* Return 1 if OP is a valid first operand for either a logical insn
+    or an add insn of mode MODE.  */
+ 
+ int
+ compare_operand (op, mode)
+      rtx op;
+      enum machine_mode mode;
+ {
+   return (register_operand (op, mode)
+ 	  || (GET_CODE (op) == CONST_INT && SMALL_INT (op) && LOGIC_INT (op)));
+ }
+ 
+ /* Return truth value of whether OP can be used as an operand
+    of a bte insn.  */
+ 
+ int
+ bte_operand (op, mode)
+      rtx op;
+      enum machine_mode mode;
+ {
+   return (register_operand (op, mode)
+ 	  || (GET_CODE (op) == CONST_INT
+ 	      && (unsigned) INTVAL (op) < 0x20));
+ }
+ 
+ /* Return 1 if OP is an indexed memory reference of mode MODE.  */
+ 
+ int
+ indexed_operand (op, mode)
+      rtx op;
+      enum machine_mode mode;
+ {
+   return (GET_CODE (op) == MEM && GET_MODE (op) == mode
+ 	  && GET_CODE (XEXP (op, 0)) == PLUS
+ 	  && GET_MODE (XEXP (op, 0)) == SImode
+ 	  && register_operand (XEXP (XEXP (op, 0), 0), SImode)
+ 	  && register_operand (XEXP (XEXP (op, 0), 1), SImode));
+ }
+ 
+ /* Return 1 if OP is a suitable source operand for a load insn
+    with mode MODE.  */
+ 
+ int
+ load_operand (op, mode)
+      rtx op;
+      enum machine_mode mode;
+ {
+   return (memory_operand (op, mode) || indexed_operand (op, mode));
+ }
+ 
+ /* Return truth value of whether OP is a integer which fits the
+    range constraining immediate operands in add/subtract insns.  */
+ 
+ int
+ small_int (op, mode)
+      rtx op;
+      enum machine_mode mode;
+ {
+   return (GET_CODE (op) == CONST_INT && SMALL_INT (op));
+ }
+ 
+ /* Return truth value of whether OP is a integer which fits the
+    range constraining immediate operands in logic insns.  */
+ 
+ int
+ logic_int (op, mode)
+      rtx op;
+      enum machine_mode mode;
+ {
+   return (GET_CODE (op) == CONST_INT && LOGIC_INT (op));
+ }
+ \f


+ /* Return the best assembler insn template
+    for moving operands[1] into operands[0] as a fullword.  */
+ 
+ static char *
+ singlemove_string (operands)
+      rtx *operands;
+ {
+   if (GET_CODE (operands[0]) == MEM)
+     {
+       if (GET_CODE (operands[1]) != MEM)
+ 	if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
+ 	  {
+ 	    if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
+ 		   && (cc_prev_status.flags & CC_HI_R31_ADJ)
+ 		   && cc_prev_status.mdep == XEXP (operands[0], 0)))
+ 	      output_asm_insn ("orh ha%%%m0,r0,r31", operands);
+ 	    cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
+ 	    cc_status.mdep = XEXP (operands[0], 0);
+ 	    return "st.l %r1,l%%%m0(r31)";
+ 	  }
+ 	else
+ 	  return "st.l %r1,%0";
+       else
+ 	abort ();
+ #if 0
+ 	{
+ 	  rtx xoperands[2];
+ 
+ 	  cc_status.flags &= ~CC_F0_IS_0;
+ 	  xoperands[0] = gen_rtx (REG, SFmode, 32);
+ 	  xoperands[1] = operands[1];
+ 	  output_asm_insn (singlemove_string (xoperands), xoperands);
+ 	  xoperands[1] = xoperands[0];
+ 	  xoperands[0] = operands[0];
+ 	  output_asm_insn (singlemove_string (xoperands), xoperands);
+ 	  return "";
+ 	}
+ #endif
+     }
+   if (GET_CODE (operands[1]) == MEM)
+     {
+       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
+ 	{
+ 	  if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
+ 		 && (cc_prev_status.flags & CC_HI_R31_ADJ)
+ 		 && cc_prev_status.mdep == XEXP (operands[1], 0)))
+ 	    output_asm_insn ("orh ha%%%m1,r0,r31", operands);
+ 	  cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
+ 	  cc_status.mdep = XEXP (operands[1], 0);
+ 	  return "ld.l l%%%m1(r31),%0";
+ 	}
+       return "ld.l %1,%0";
+     }
+   return "mov %1,%0";
+ }
+ \f


+ /* Output assembler code to perform a doubleword move insn
+    with operands OPERANDS.  */
+ 
+ char *
+ output_move_double (operands)
+      rtx *operands;
+ {
+   enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
+   rtx latehalf[2];
+   rtx addreg0 = 0, addreg1 = 0;
+ 
+   /* First classify both operands.  */
+ 
+   if (REG_P (operands[0]))
+     optype0 = REGOP;
+   else if (offsettable_memref_p (operands[0]))
+     optype0 = OFFSOP;
+   else if (GET_CODE (operands[0]) == MEM)
+     optype0 = MEMOP;
+   else
+     optype0 = RNDOP;
+ 
+   if (REG_P (operands[1]))
+     optype1 = REGOP;
+   else if (CONSTANT_P (operands[1])
+ 	   || GET_CODE (operands[1]) == CONST_DOUBLE)
+     optype1 = CNSTOP;
+   else if (offsettable_memref_p (operands[1]))
+     optype1 = OFFSOP;
+   else if (GET_CODE (operands[1]) == MEM)
+     optype1 = MEMOP;
+   else
+     optype1 = RNDOP;
+ 
+   /* Check for the cases that the operand constraints are not
+      supposed to allow to happen.  Abort if we get one,
+      because generating code for these cases is painful.  */
+ 
+   if (optype0 == RNDOP || optype1 == RNDOP)
+     abort ();
+ 
+   /* If an operand is an unoffsettable memory ref, find a register
+      we can increment temporarily to make it refer to the second word.  */
+ 
+   if (optype0 == MEMOP)
+     addreg0 = find_addr_reg (XEXP (operands[0], 0));
+ 
+   if (optype1 == MEMOP)
+     addreg1 = find_addr_reg (XEXP (operands[1], 0));
+ 
+ /* ??? Perhaps in some cases move double words
+    if there is a spare pair of floating regs.  */
+ 
+   /* Ok, we can do one word at a time.
+      Normally we do the low-numbered word first,
+      but if either operand is autodecrementing then we
+      do the high-numbered word first.
+ 
+      In either case, set up in LATEHALF the operands to use
+      for the high-numbered word and in some cases alter the
+      operands in OPERANDS to be suitable for the low-numbered word.  */
+ 
+   if (optype0 == REGOP)
+     latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+   else if (optype0 == OFFSOP)
+     latehalf[0] = adj_offsettable_operand (operands[0], 4);
+   else
+     latehalf[0] = operands[0];
+ 
+   if (optype1 == REGOP)
+     latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
+   else if (optype1 == OFFSOP)
+     latehalf[1] = adj_offsettable_operand (operands[1], 4);
+   else if (optype1 == CNSTOP)
+     {
+       if (CONSTANT_P (operands[1]))
+ 	latehalf[1] = const0_rtx;
+       else if (GET_CODE (operands[1]) == CONST_DOUBLE)
+ 	{
+ 	  latehalf[1] = gen_rtx (CONST_INT, VOIDmode,
+ 				 CONST_DOUBLE_HIGH (operands[1]));
+ 	  operands[1] = gen_rtx (CONST_INT, VOIDmode,
+ 				 CONST_DOUBLE_LOW (operands[1]));
+ 	}
+     }
+   else
+     latehalf[1] = operands[1];
+ 
+   /* If the first move would clobber the source of the second one,
+      do them in the other order.
+ 
+      RMS says "This happens only for registers;
+      such overlap can't happen in memory unless the user explicitly
+      sets it up, and that is an undefined circumstance."
+ 
+      but it happens on the sparc when loading parameter registers,
+      so I am going to define that circumstance, and make it work
+      as expected.  */
+ 
+   if (optype0 == REGOP && optype1 == REGOP
+       && REGNO (operands[0]) == REGNO (latehalf[1]))
+     {
+       /* Make any unoffsettable addresses point at high-numbered word.  */
+       if (addreg0)
+ 	output_asm_insn ("adds 0x4,%0,%0", &addreg0);
+       if (addreg1)
+ 	output_asm_insn ("adds 0x4,%0,%0", &addreg1);
+ 
+       /* Do that word.  */
+       output_asm_insn (singlemove_string (latehalf), latehalf);
+ 
+       /* Undo the adds we just did.  */
+       if (addreg0)
+ 	output_asm_insn ("adds -0x4,%0,%0", &addreg0);
+       if (addreg1)
+ 	output_asm_insn ("adds -0x4,%0,%0", &addreg1);
+ 
+       /* Do low-numbered word.  */
+       return singlemove_string (operands);
+     }
+   else if (optype0 == REGOP && optype1 != REGOP
+ 	   && reg_overlap_mentioned_p (operands[0], operands[1]))
+     {
+       /* Do the late half first.  */
+       output_asm_insn (singlemove_string (latehalf), latehalf);
+       /* Then clobber.  */
+       return singlemove_string (operands);
+     }
+ 
+   /* Normal case: do the two words, low-numbered first.  */
+ 
+   output_asm_insn (singlemove_string (operands), operands);
+ 
+   /* Make any unoffsettable addresses point at high-numbered word.  */
+   if (addreg0)
+     output_asm_insn ("adds 0x4,%0,%0", &addreg0);
+   if (addreg1)
+     output_asm_insn ("adds 0x4,%0,%0", &addreg1);
+ 
+   /* Do that word.  */
+   output_asm_insn (singlemove_string (latehalf), latehalf);
+ 
+   /* Undo the adds we just did.  */
+   if (addreg0)
+     output_asm_insn ("adds -0x4,%0,%0", &addreg0);
+   if (addreg1)
+     output_asm_insn ("adds -0x4,%0,%0", &addreg1);
+ 
+   return "";
+ }
+ \f


+ static char *
+ output_fp_move_double (operands)
+      rtx *operands;
+ {
+   if (FP_REG_P (operands[0]))
+     {
+       if (FP_REG_P (operands[1]))
+ 	return "fmov.dd %1,%0";
+       if (GET_CODE (operands[1]) == REG)
+ 	{
+ 	  output_asm_insn ("ixfr %1,%0", operands);
+ 	  operands[0] = gen_rtx (REG, VOIDmode, REGNO (operands[0]) + 1);
+ 	  operands[1] = gen_rtx (REG, VOIDmode, REGNO (operands[1]) + 1);
+ 	  return "ixfr %1,%0";
+ 	}
+       if (operands[1] == dconst0_rtx)
+ 	return "fmov.dd f0,%0";
+       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
+ 	{
+ 	  if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
+ 		 && (cc_prev_status.flags & CC_HI_R31_ADJ)
+ 		 && cc_prev_status.mdep == XEXP (operands[1], 0)))
+ 	    output_asm_insn ("orh ha%%%m1,r0,r31", operands);
+ 	  cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
+ 	  cc_status.mdep = XEXP (operands[1], 0);
+ 	  return "fld.d l%%%m1(r31),%0";
+ 	}
+       return "fld.d %1,%0";
+     }
+   else if (FP_REG_P (operands[1]))
+     {
+       if (GET_CODE (operands[0]) == REG)
+ 	{
+ 	  output_asm_insn ("fxfr %1,%0", operands);
+ 	  operands[0] = gen_rtx (REG, VOIDmode, REGNO (operands[0]) + 1);
+ 	  operands[1] = gen_rtx (REG, VOIDmode, REGNO (operands[1]) + 1);
+ 	  return "fxfr %1,%0";
+ 	}
+       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
+ 	{
+ 	  if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
+ 		 && (cc_prev_status.flags & CC_HI_R31_ADJ)
+ 		 && cc_prev_status.mdep == XEXP (operands[0], 0)))
+ 	    output_asm_insn ("orh ha%%%m0,r0,r31", operands);
+ 	  cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
+ 	  cc_status.mdep = XEXP (operands[0], 0);
+ 	  return "fst.d %1,l%%%m0(r31)";
+ 	}
+       return "fst.d %1,%0";
+     }
+   else abort ();
+ }
+ \f


+ /* Return a REG that occurs in ADDR with coefficient 1.
+    ADDR can be effectively incremented by incrementing REG.  */
+ 
+ static rtx
+ find_addr_reg (addr)
+      rtx addr;
+ {
+   while (GET_CODE (addr) == PLUS)
+     {
+       if (GET_CODE (XEXP (addr, 0)) == REG)
+ 	addr = XEXP (addr, 0);
+       else if (GET_CODE (XEXP (addr, 1)) == REG)
+ 	addr = XEXP (addr, 1);
+       else if (CONSTANT_P (XEXP (addr, 0)))
+ 	addr = XEXP (addr, 1);
+       else if (CONSTANT_P (XEXP (addr, 1)))
+ 	addr = XEXP (addr, 0);
+       else
+ 	abort ();
+     }
+   if (GET_CODE (addr) == REG)
+     return addr;
+   abort ();
+ }
+ 
+ /* Return a template for a load instruction with mode MODE and
+    arguments from the string ARGS.
+ 
+    This string is in static storage.   */
+ 
+ static char *
+ load_opcode (mode, args, reg)
+      enum machine_mode mode;
+      char *args;
+      rtx reg;
+ {
+   static char buf[30];
+   char *opcode;
+ 
+   switch (mode)
+     {
+     case QImode:
+       opcode = "ld.b";
+       break;
+ 
+     case HImode:
+       opcode = "ld.s";
+       break;
+ 
+     case SImode:
+     case SFmode:
+       if (FP_REG_P (reg))
+ 	opcode = "fld.l";
+       else
+ 	opcode = "ld.l";
+       break;
+ 
+     case DFmode:
+       opcode = "fld.d";
+       break;
+ 
+     default:
+       abort ();
+     }
+ 
+   sprintf (buf, "%s %s", opcode, args);
+   return buf;
+ }
+ 
+ /* Return a template for a store instruction with mode MODE and
+    arguments from the string ARGS.
+ 
+    This string is in static storage.   */
+ 
+ static char *
+ store_opcode (mode, args, reg)
+      enum machine_mode mode;
+      char *args;
+      rtx reg;
+ {
+   static char buf[30];
+   char *opcode;
+ 
+   switch (mode)
+     {
+     case QImode:
+       opcode = "st.b";
+       break;
+ 
+     case HImode:
+       opcode = "st.s";
+       break;
+ 
+     case SImode:
+     case SFmode:
+       if (FP_REG_P (reg))
+ 	opcode = "fst.l";
+       else
+ 	opcode = "st.l";
+       break;
+ 
+     case DFmode:
+       opcode = "fst.d";
+       break;
+ 
+     default:
+       abort ();
+     }
+ 
+   sprintf (buf, "%s %s", opcode, args);
+   return buf;
+ }
+ \f


+ /* Output a store-in-memory whose operands are OPERANDS[0,1].
+    OPERANDS[0] is a MEM, and OPERANDS[1] is a reg or zero.
+ 
+    This function returns a template for an insn.
+    This is in static storage.
+ 
+    It may also output some insns directly.
+    It may alter the values of operands[0] and operands[1].  */
+ 
+ char *
+ output_store (operands)
+      rtx *operands;
+ {
+   enum machine_mode mode = GET_MODE (operands[0]);
+   rtx address = XEXP (operands[0], 0);
+   char *string;
+ 
+   cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
+   cc_status.mdep = address;
+ 
+   if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
+ 	 && (cc_prev_status.flags & CC_HI_R31_ADJ)
+ 	 && address == cc_prev_status.mdep))
+     {
+       output_asm_insn ("orh ha%%%m0,r0,r31", operands);
+       cc_prev_status.mdep = address;
+     }
+ 
+   /* Store zero in two parts when appropriate.  */
+   if (mode == DFmode && operands[1] == dconst0_rtx)
+     return store_opcode (DFmode, "%r1,l%%%m0(r31)", operands[1]);
+ 
+   /* Code below isn't smart enough to move a doubleword in two parts,
+      so use output_move_double to do that in the cases that require it.  */
+   if ((mode == DImode || mode == DFmode)
+       && ! FP_REG_P (operands[1]))
+     return output_move_double (operands);
+ 
+   return store_opcode (mode, "%r1,l%%%m0(r31)", operands[1]);
+ }
+ 
+ /* Output a load-from-memory whose operands are OPERANDS[0,1].
+    OPERANDS[0] is a reg, and OPERANDS[1] is a mem.
+ 
+    This function returns a template for an insn.
+    This is in static storage.
+ 
+    It may also output some insns directly.
+    It may alter the values of operands[0] and operands[1].  */
+ 
+ char *
+ output_load (operands)
+      rtx *operands;
+ {
+   enum machine_mode mode = GET_MODE (operands[0]);
+   rtx address = XEXP (operands[1], 0);
+ 
+   /* We don't bother trying to see if we know %hi(address).
+      This is because we are doing a load, and if we know the
+      %hi value, we probably also know that value in memory.  */
+   cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
+   cc_status.mdep = address;
+ 
+   if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
+ 	 && (cc_prev_status.flags & CC_HI_R31_ADJ)
+ 	 && address == cc_prev_status.mdep
+ 	 && cc_prev_status.mdep == cc_status.mdep))
+     {
+       output_asm_insn ("orh ha%%%m1,r0,r31", operands);
+       cc_prev_status.mdep = address;
+     }
+ 
+   /* Code below isn't smart enough to move a doubleword in two parts,
+      so use output_move_double to do that in the cases that require it.  */
+   if ((mode == DImode || mode == DFmode)
+       && ! FP_REG_P (operands[0]))
+     return output_move_double (operands);
+ 
+   return load_opcode (mode, "l%%%m1(r31),%0", operands[0]);
+ }
+ \f


+ /* Load the address specified by OPERANDS[3] into the register
+    specified by OPERANDS[0].
+ 
+    OPERANDS[3] may be the result of a sum, hence it could either be:
+ 
+    (1) CONST
+    (2) REG
+    (2) REG + CONST_INT
+    (3) REG + REG + CONST_INT
+    (4) REG + REG  (special case of 3).
+ 
+    Note that (3) is not a legitimate address.
+    All cases are handled here.  */
+ 
+ void
+ output_load_address (operands)
+      rtx *operands;
+ {
+   rtx base, offset;
+ 
+   if (CONSTANT_P (operands[3]))
+     {
+       output_asm_insn ("mov %3,%0", operands);
+       return;
+     }
+ 
+   if (REG_P (operands[3]))
+     {
+       if (REGNO (operands[0]) != REGNO (operands[3]))
+ 	output_asm_insn ("mov %3,%0", operands);
+       return;
+     }
+ 
+   if (GET_CODE (operands[3]) != PLUS)
+     abort ();
+ 
+   base = XEXP (operands[3], 0);
+   offset = XEXP (operands[3], 1);
+ 
+   if (GET_CODE (base) == CONST_INT)
+     {
+       rtx tmp = base;
+       base = offset;
+       offset = tmp;
+     }
+ 
+   if (GET_CODE (offset) != CONST_INT)
+     {
+       /* Operand is (PLUS (REG) (REG)).  */
+       base = operands[3];
+       offset = const0_rtx;
+     }
+ 
+   if (REG_P (base))
+     {
+       operands[6] = base;
+       operands[7] = offset;
+       if (SMALL_INT (offset))
+ 	output_asm_insn ("adds %7,%6,%0", operands);
+       else
+ 	output_asm_insn ("mov %7,%0\n\tadds %0,%6,%0", operands);
+     }
+   else if (GET_CODE (base) == PLUS)
+     {
+       operands[6] = XEXP (base, 0);
+       operands[7] = XEXP (base, 1);
+       operands[8] = offset;
+ 
+       if (SMALL_INT (offset))
+ 	output_asm_insn ("adds %6,%7,%0\n\tadds %8,%0,%0", operands);
+       else
+ 	output_asm_insn ("mov %8,%0\n\tadds %0,%6,%0\n\tadds %0,%7,%0", operands);
+     }
+   else
+     abort ();
+ }
+ 
+ /* Output code to place a size count SIZE in register REG.
+    Because block moves are pipelined, we don't include the
+    first element in the transfer of SIZE to REG.
+    For this, we subtract ALIGN.  (Actually, I think it is not
+    right to subtract on this machine, so right now we don't.)  */
+ 
+ static void
+ output_size_for_block_move (size, reg, align)
+      rtx size, reg, align;
+ {
+   rtx xoperands[3];
+ 
+   xoperands[0] = reg;
+   xoperands[1] = size;
+   xoperands[2] = align;
+ 
+ #if 1
+   cc_status.flags &= ~ CC_KNOW_HI_R31;
+   output_asm_insn ("mov %1,%0", xoperands);
+ #else
+   if (GET_CODE (size) == REG)
+     output_asm_insn ("sub %2,%1,%0", xoperands);
+   else
+     {
+       xoperands[1]
+ 	= gen_rtx (CONST_INT, VOIDmode, INTVAL (size) - INTVAL (align));
+       cc_status.flags &= ~ CC_KNOW_HI_R31;
+       output_asm_insn ("mov %1,%0", xoperands);
+     }
+ #endif
+ }
+ 
+ /* Emit code to perform a block move.
+ 
+    OPERANDS[0] is the destination.
+    OPERANDS[1] is the source.
+    OPERANDS[2] is the size.
+    OPERANDS[3] is the known safe alignment.
+    OPERANDS[4..6] are pseudos we can safely clobber as temps.  */
+ 
+ char *
+ output_block_move (operands)
+      rtx *operands;
+ {
+   /* A vector for our computed operands.  Note that load_output_address
+      makes use of (and can clobber) up to the 8th element of this vector.  */
+   rtx xoperands[10];
+   rtx zoperands[10];
+   static int movstrsi_label = 0;
+   int i, j;
+   rtx temp1 = operands[4];
+   rtx alignrtx = operands[3];
+   int align = INTVAL (alignrtx);
+ 
+   xoperands[0] = operands[0];
+   xoperands[1] = operands[1];
+   xoperands[2] = temp1;
+ 
+   /* We can't move more than four bytes at a time
+      because we have only one register to move them through.  */
+   if (align > 4)
+     {
+       align = 4;
+       alignrtx = gen_rtx (CONST_INT, VOIDmode, 4);
+     }
+ 
+   /* Since we clobber untold things, nix the condition codes.  */
+   CC_STATUS_INIT;
+ 
+   /* Recognize special cases of block moves.  These occur
+      when GNU C++ is forced to treat something as BLKmode
+      to keep it in memory, when its mode could be represented
+      with something smaller.
+ 
+      We cannot do this for global variables, since we don't know
+      what pages they don't cross.  Sigh.  */
+   if (GET_CODE (operands[2]) == CONST_INT
+       && INTVAL (operands[2]) <= 16
+       && ! CONSTANT_ADDRESS_P (operands[0])
+       && ! CONSTANT_ADDRESS_P (operands[1]))
+     {
+       int size = INTVAL (operands[2]);
+       rtx op0 = xoperands[0];
+       rtx op1 = xoperands[1];
+ 
+       cc_status.flags &= ~CC_KNOW_HI_R31;
+       if (align == 1)
+ 	{
+ 	  if (memory_address_p (QImode, plus_constant (op0, size))
+ 	      && memory_address_p (QImode, plus_constant (op1, size)))
+ 	    {
+ 	      for (i = size-1; i >= 0; i--)
+ 		{
+ 		  xoperands[0] = plus_constant (op0, i);
+ 		  xoperands[1] = plus_constant (op1, i);
+ 		  output_asm_insn ("ld.b %a1,r31\n\tst.b r31,%a0",
+ 				   xoperands);
+ 		}
+ 	      return "";
+ 	    }
+ 	}
+       else if (align == 2)
+ 	{
+ 	  if (memory_address_p (HImode, plus_constant (op0, size))
+ 	      && memory_address_p (HImode, plus_constant (op1, size)))
+ 	    {
+ 	      for (i = (size>>1)-1; i >= 0; i--)
+ 		{
+ 		  xoperands[0] = plus_constant (op0, i * 2);
+ 		  xoperands[1] = plus_constant (op1, i * 2);
+ 		  output_asm_insn ("ld.s %a1,r31\n\tst.s r31,%a0",
+ 				   xoperands);
+ 		}
+ 	      return "";
+ 	    }
+ 	}
+       else
+ 	{
+ 	  if (memory_address_p (SImode, plus_constant (op0, size))
+ 	      && memory_address_p (SImode, plus_constant (op1, size)))
+ 	    {
+ 	      for (i = (size>>2)-1; i >= 0; i--)
+ 		{
+ 		  xoperands[0] = plus_constant (op0, i * 4);
+ 		  xoperands[1] = plus_constant (op1, i * 4);
+ 		  output_asm_insn ("ld.l %a1,r31\n\tst.l r31,%a0",
+ 				   xoperands);
+ 		}
+ 	      return "";
+ 	    }
+ 	}
+     }
+ 
+   /* This is the size of the transfer.
+      Either use the register which already contains the size,
+      or use a free register (used by no operands).  */
+   output_size_for_block_move (operands[2], operands[4], alignrtx);
+ 
+ #if 0
+   /* Also emit code to decrement the size value by ALIGN.  */
+   zoperands[0] = operands[0];
+   zoperands[3] = plus_constant (operands[0], align);
+   output_load_address (zoperands);
+ #endif
+ 
+   /* Generate number for unique label.  */
+ 
+   xoperands[3] = gen_rtx (CONST_INT, VOIDmode, movstrsi_label++);
+ 
+   /* Copy the increment (negative) to a register for bla insn.  */
+ 
+   xoperands[4] = gen_rtx (CONST_INT, VOIDmode, - align);
+   xoperands[5] = operands[5];
+   output_asm_insn ("mov %4,%5", xoperands);
+ 
+   xoperands[6] = operands[6];
+   output_asm_insn ("adds %0,%2,%6", xoperands);
+ 
+   /* Now the actual loop.
+      In xoperands, elements 1 and 0 are the input and output vectors.
+      Element 2 is the loop index.  Element 5 is the increment.  */
+ 
+   if (align == 1)
+     {
+       output_asm_insn ("bla %5,%2,.Lm%3\n\tnop\n.Lm%3:", xoperands);
+       output_asm_insn ("ld.b %1(%2),r31", xoperands);
+       output_asm_insn ("adds %5,%6,%6", xoperands);
+       output_asm_insn ("bla %5,%2,.Lm%3", xoperands);
+       output_asm_insn ("st.b r31,0(%6)", xoperands);
+     }
+   if (align == 2)
+     {
+       output_asm_insn ("bla %5,%2,.Lm%3\n\tnop\n.Lm%3:", xoperands);
+       output_asm_insn ("ld.s %1(%2),r31", xoperands);
+       output_asm_insn ("adds %5,%6,%6", xoperands);
+       output_asm_insn ("bla %5,%2,.Lm%3", xoperands);
+       output_asm_insn ("st.s r31,0(%6)", xoperands);
+     }
+   if (align == 4)
+     {
+       output_asm_insn ("bla %5,%2,.Lm%3\n\tnop\n.Lm%3:", xoperands);
+       output_asm_insn ("ld.l %1(%2),r31", xoperands);
+       output_asm_insn ("adds %5,%6,%6", xoperands);
+       output_asm_insn ("bla %5,%2,.Lm%3", xoperands);
+       output_asm_insn ("st.l r31,0(%6)", xoperands);
+     }
+ 
+   return "";
+ }
+ \f


+ /* Output a delayed branch insn with the delay insn in its
+    branch slot.  The delayed branch insn template is in TEMPLATE,
+    with operands OPERANDS.  The insn in its delay slot is INSN.
+ 
+    As a special case, since we know that all memory transfers are via
+    ld/st insns, if we see a (MEM (SYMBOL_REF ...)) we divide the memory
+    reference around the branch as
+ 
+ 	orh ha%x,r0,r31
+ 	b ...
+ 	ld/st l%x(r31),...
+ 
+    As another special case, we handle loading (SYMBOL_REF ...) and
+    other large constants around branches as well:
+ 
+ 	orh h%x,r0,%0
+ 	b ...
+ 	or l%x,%0,%1
+ 
+    */
+ 
+ char *
+ output_delayed_branch (template, operands, insn)
+      char *template;
+      rtx *operands;
+      rtx insn;
+ {
+   extern rtx recog_operand[];
+   rtx src = XVECEXP (PATTERN (insn), 0, 1);
+   rtx dest = XVECEXP (PATTERN (insn), 0, 0);
+ 
+   if (GET_CODE (src) == SYMBOL_REF || GET_CODE (src) == CONST
+       || (GET_CODE (src) == CONST_INT
+ 	  && !(SMALL_INT (src) || (INTVAL (src) & 0x3ff) == 0)))
+     {
+       rtx xoperands[2];
+       xoperands[0] = dest;
+       xoperands[1] = src;
+ 
+       /* Output the `orh' insn.  */
+       output_asm_insn ("orh h%%%1,r0,%0", xoperands);
+ 
+       /* Output the branch instruction next.  */
+       output_asm_insn (template, operands);
+ 
+       /* Now output the `or' insn.  */
+       output_asm_insn ("or l%%%1,%0,%0", xoperands);
+     }
+   else if ((GET_CODE (src) == MEM
+ 	    && CONSTANT_ADDRESS_P (XEXP (src, 0)))
+ 	   || (GET_CODE (dest) == MEM
+ 	       && CONSTANT_ADDRESS_P (XEXP (dest, 0))))
+     {
+       rtx xoperands[2];
+       char *split_template;
+       xoperands[0] = dest;
+       xoperands[1] = src;
+ 
+       /* Output the `orh' insn.  */
+       if (GET_CODE (src) == MEM)
+ 	{
+ 	  if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
+ 		 && (cc_prev_status.flags & CC_HI_R31_ADJ)
+ 		 && cc_prev_status.mdep == XEXP (operands[1], 0)))
+ 	    output_asm_insn ("orh ha%%%m1,r0,r31", xoperands);
+ 	  split_template = load_opcode (GET_MODE (dest),
+ 					"l%%%m1(r31),%0", src);
+ 	}
+       else
+ 	{
+ 	  if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
+ 		 && (cc_prev_status.flags & CC_HI_R31_ADJ)
+ 		 && cc_prev_status.mdep == XEXP (operands[0], 0)))
+ 	    output_asm_insn ("orh ha%%%m0,r0,r31", xoperands);
+ 	  split_template = store_opcode (GET_MODE (dest),
+ 					 "%r1,l%%%m0(r31)", src);
+ 	}
+ 
+       /* Output the branch instruction next.  */
+       output_asm_insn (template, operands);
+ 
+       /* Now output the load or store.
+ 	 No need to do a CC_STATUS_INIT, because we are branching anyway.  */
+       output_asm_insn (split_template, xoperands);
+     }
+   else
+     {
+       extern char *insn_template[];
+       extern char *(*insn_outfun[])();
+       extern int insn_n_operands[];
+       extern rtx alter_subreg();
+       int insn_code_number;
+       rtx pat = gen_rtx (SET, VOIDmode, dest, src);
+       rtx delay_insn = gen_rtx (INSN, VOIDmode, 0, 0, 0, pat, -1, 0, 0);
+       int i;
+ 
+       /* Output the branch instruction first.  */
+       output_asm_insn (template, operands);
+ 
+       /* Now recognize the insn which we put in its delay slot.
+ 	 We must do this after outputing the branch insn,
+ 	 since operands may just be a pointer to `recog_operand'.  */
+       insn_code_number = recog (pat, delay_insn);
+       if (insn_code_number == -1)
+ 	abort ();
+ 
+       for (i = 0; i < insn_n_operands[insn_code_number]; i++)
+ 	{
+ 	  if (GET_CODE (recog_operand[i]) == SUBREG)
+ 	    recog_operand[i] = alter_subreg (recog_operand[i]);
+ 	}
+ 
+       /* Now get the template for what this insn would
+ 	 have been, without the branch.  Its operands are
+ 	 exactly the same as they would be, so we don't
+ 	 need to do an insn_extract.  */
+       template = insn_template[insn_code_number];
+       if (template == 0)
+ 	template = (*insn_outfun[insn_code_number]) (recog_operand, delay_insn);
+       output_asm_insn (template, recog_operand);
+     }
+   CC_STATUS_INIT;
+   return "";
+ }
+ 
+ /* Output a newly constructed insn DELAY_INSN.  */
+ char *
+ output_delay_insn (delay_insn)
+      rtx delay_insn;
+ {
+   char *template;
+   extern rtx recog_operand[];
+   extern char call_used_regs[];
+   extern char *insn_template[];
+   extern int insn_n_operands[];
+   extern char *(*insn_outfun[])();
+   extern rtx alter_subreg();
+   int insn_code_number;
+   extern int insn_n_operands[];
+   int i;
+ 
+   /* Now recognize the insn which we put in its delay slot.
+      We must do this after outputing the branch insn,
+      since operands may just be a pointer to `recog_operand'.  */
+   insn_code_number = recog_memoized (delay_insn);
+   if (insn_code_number == -1)
+     abort ();
+ 
+   /* Extract the operands of this delay insn.  */
+   INSN_CODE (delay_insn) = insn_code_number;
+   insn_extract (delay_insn);
+ 
+   /* It is possible that this insn has not been properly scaned by final
+      yet.  If this insn's operands don't appear in the peephole's
+      actual operands, then they won't be fixed up by final, so we
+      make sure they get fixed up here.  -- This is a kludge.  */
+   for (i = 0; i < insn_n_operands[insn_code_number]; i++)
+     {
+       if (GET_CODE (recog_operand[i]) == SUBREG)
+ 	recog_operand[i] = alter_subreg (recog_operand[i]);
+     }
+ 
+ #ifdef REGISTER_CONSTRAINTS
+   if (! constrain_operands (insn_code_number))
+     abort ();
+ #endif
+ 
+   cc_prev_status = cc_status;
+ 
+   /* Update `cc_status' for this instruction.
+      The instruction's output routine may change it further.
+      If the output routine for a jump insn needs to depend
+      on the cc status, it should look at cc_prev_status.  */
+ 
+   NOTICE_UPDATE_CC (PATTERN (delay_insn), delay_insn);
+ 
+   /* Now get the template for what this insn would
+      have been, without the branch.  */
+ 
+   template = insn_template[insn_code_number];
+   if (template == 0)
+     template = (*insn_outfun[insn_code_number]) (recog_operand, delay_insn);
+   output_asm_insn (template, recog_operand);
+   return "";
+ }
+ 
diff -rc2N gcc-1.35/config/out-m68k.c gcc-1.36/config/out-m68k.c
*** gcc-1.35/config/out-m68k.c	Wed Mar 29 15:26:22 1989
--- gcc-1.36/config/out-m68k.c	Fri Jun  9 12:55:02 1989
***************
*** 40,46 ****
--- 40,55 ----
    operands[0] = countop;
    operands[1] = dataop;
+ 
    if (GET_CODE (countop) == CONST_INT)
      {
        register int count = INTVAL (countop);
+       /* If COUNT is bigger than size of storage unit in use,
+ 	 advance to the containing unit of same size.  */
+       if (count > signpos)
+ 	{
+ 	  int offset = (count & ~signpos) / 8;
+ 	  count = count & signpos;
+ 	  operands[1] = dataop = adj_offsettable_operand (dataop, offset);
+ 	}
        if (count == signpos)
  	cc_status.flags = CC_NOT_POSITIVE | CC_Z_IN_NOT_N;
***************
*** 94,98 ****
    if (REG_P (operands[0]))
      optype0 = REGOP;
!   else if (offsetable_memref_p (operands[0]))
      optype0 = OFFSOP;
    else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
--- 103,107 ----
    if (REG_P (operands[0]))
      optype0 = REGOP;
!   else if (offsettable_memref_p (operands[0]))
      optype0 = OFFSOP;
    else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
***************
*** 110,114 ****
  	   || GET_CODE (operands[1]) == CONST_DOUBLE)
      optype1 = CNSTOP;
!   else if (offsetable_memref_p (operands[1]))
      optype1 = OFFSOP;
    else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
--- 119,123 ----
  	   || GET_CODE (operands[1]) == CONST_DOUBLE)
      optype1 = CNSTOP;
!   else if (offsettable_memref_p (operands[1]))
      optype1 = OFFSOP;
    else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
***************
*** 168,172 ****
      latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
    else if (optype0 == OFFSOP)
!     latehalf[0] = adj_offsetable_operand (operands[0], 4);
    else
      latehalf[0] = operands[0];
--- 177,181 ----
      latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
    else if (optype0 == OFFSOP)
!     latehalf[0] = adj_offsettable_operand (operands[0], 4);
    else
      latehalf[0] = operands[0];
***************
*** 175,179 ****
      latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
    else if (optype1 == OFFSOP)
!     latehalf[1] = adj_offsetable_operand (operands[1], 4);
    else if (optype1 == CNSTOP)
      {
--- 184,188 ----
      latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
    else if (optype1 == OFFSOP)
!     latehalf[1] = adj_offsettable_operand (operands[1], 4);
    else if (optype1 == CNSTOP)
      {
***************
*** 211,215 ****
  	  && REGNO (operands[0]) == REGNO (latehalf[1])))
      {
!       /* Make any unoffsetable addresses point at high-numbered word.  */
        if (addreg0)
  	output_asm_insn ("addql %#4,%0", &addreg0);
--- 220,224 ----
  	  && REGNO (operands[0]) == REGNO (latehalf[1])))
      {
!       /* Make any unoffsettable addresses point at high-numbered word.  */
        if (addreg0)
  	output_asm_insn ("addql %#4,%0", &addreg0);
***************
*** 234,238 ****
    output_asm_insn (singlemove_string (operands), operands);
  
!   /* Make any unoffsetable addresses point at high-numbered word.  */
    if (addreg0)
      output_asm_insn ("addql %#4,%0", &addreg0);
--- 243,247 ----
    output_asm_insn (singlemove_string (operands), operands);
  
!   /* Make any unoffsettable addresses point at high-numbered word.  */
    if (addreg0)
      output_asm_insn ("addql %#4,%0", &addreg0);
diff -rc2N gcc-1.35/config/out-m88k.c gcc-1.36/config/out-m88k.c
*** gcc-1.35/config/out-m88k.c	Wed Feb 22 11:56:16 1989
--- gcc-1.36/config/out-m88k.c	Wed May 10 17:20:10 1989
***************
*** 192,196 ****
    if (REG_P (operands[0]))
      optype0 = REGOP;
!   else if (offsetable_memref_p (operands[0]))
      optype0 = OFFSOP;
    else if (GET_CODE (operands[0]) == MEM)
--- 192,196 ----
    if (REG_P (operands[0]))
      optype0 = REGOP;
!   else if (offsettable_memref_p (operands[0]))
      optype0 = OFFSOP;
    else if (GET_CODE (operands[0]) == MEM)
***************
*** 204,208 ****
  	   || GET_CODE (operands[1]) == CONST_DOUBLE)
      optype1 = CNSTOP;
!   else if (offsetable_memref_p (operands[1]))
      optype1 = OFFSOP;
    else if (GET_CODE (operands[1]) == MEM)
--- 204,208 ----
  	   || GET_CODE (operands[1]) == CONST_DOUBLE)
      optype1 = CNSTOP;
!   else if (offsettable_memref_p (operands[1]))
      optype1 = OFFSOP;
    else if (GET_CODE (operands[1]) == MEM)
***************
*** 239,243 ****
      latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
    else if (optype0 == OFFSOP)
!     latehalf[0] = adj_offsetable_operand (operands[0], 4);
    else
      latehalf[0] = operands[0];
--- 239,243 ----
      latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
    else if (optype0 == OFFSOP)
!     latehalf[0] = adj_offsettable_operand (operands[0], 4);
    else
      latehalf[0] = operands[0];
***************
*** 246,250 ****
      latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
    else if (optype1 == OFFSOP)
!     latehalf[1] = adj_offsetable_operand (operands[1], 4);
    else if (optype1 == CNSTOP)
      {
--- 246,250 ----
      latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
    else if (optype1 == OFFSOP)
!     latehalf[1] = adj_offsettable_operand (operands[1], 4);
    else if (optype1 == CNSTOP)
      {
***************
*** 270,274 ****
        && REGNO (operands[0]) == REGNO (latehalf[1]))
      {
!       /* Make any unoffsetable addresses point at high-numbered word.  */
        if (addreg0)
  	output_asm_insn ("addu %0,%0,4", &addreg0);
--- 270,274 ----
        && REGNO (operands[0]) == REGNO (latehalf[1]))
      {
!       /* Make any unoffsettable addresses point at high-numbered word.  */
        if (addreg0)
  	output_asm_insn ("addu %0,%0,4", &addreg0);
***************
*** 293,297 ****
    output_asm_insn (singlemove_string (operands), operands);
  
!   /* Make any unoffsetable addresses point at high-numbered word.  */
    if (addreg0)
      output_asm_insn ("addu %0,%0,4", &addreg0);
--- 293,297 ----
    output_asm_insn (singlemove_string (operands), operands);
  
!   /* Make any unoffsettable addresses point at high-numbered word.  */
    if (addreg0)
      output_asm_insn ("addu %0,%0,4", &addreg0);
diff -rc2N gcc-1.35/config/out-mips.c gcc-1.36/config/out-mips.c
*** gcc-1.35/config/out-mips.c	Wed Apr  5 17:22:43 1989
--- gcc-1.36/config/out-mips.c	Sat Sep  9 16:04:51 1989
***************
*** 21,33 ****
  
  #include <stdio.h>
! extern void  my_print_rtx();
! 
  
  /* Global variables for machine-dependent things.  */
  
! char *reg_numchar[]= REGISTER_NUMCHAR;
  
  
! /* Return truth value of whether OP can be used as an operands 
     where a 16 bit integer is needed  */
  
--- 21,34 ----
  
  #include <stdio.h>
! extern void  my_print_rtx ();
! extern void  abort_with_insn ();
  
+ 
  /* Global variables for machine-dependent things.  */
  
! char *reg_numchar[] = REGISTER_NUMCHAR;
  
  
! /* Return truth value of whether OP can be used as an operands
     where a 16 bit integer is needed  */
  
***************
*** 62,66 ****
--- 63,129 ----
  }
  
+ \f


+ #if 0
+ 				/* Used to allow constant expression known
+ 				** only at assembly time
+ 				*/
+ int
+ legitimize_constant_expr(expr)
+      rtx expr;
+ {
+   if (GET_CODE (expr) == PLUS
+       ||
+       GET_CODE (expr) == MINUS)
+     return (BASIC_CONSTANT_P (XEXP (expr, 0))
+ 	    && BASIC_CONSTANT_P (XEXP (expr, 1)));
+   return 0;
+ }
+ #endif
+ \f


+ char *
+ output_load_immediate (operands)
+      rtx *operands;
+ {
+   rtx xops[3];
+   xops[0] = operands[0];
+   xops[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]));
  
+   if ((INTVAL (operands[1]) >> 16)
+       && (INTVAL (operands[1]) & 0xffff))
+     {
+       if (!((-INTVAL (operands[1])) >> 16))
+ 	{
+ 	  xops[1] = gen_rtx (CONST_INT, VOIDmode,
+ 			     (INTVAL (operands[1])) & 0xffff);
+ 	  output_asm_insn ("addi%:\t%0,$0,%x1\t#movsi low part of %2",
+ 			   xops);
+ 	}
+       else
+ 	{
+ 	  xops[1] = gen_rtx (CONST_INT, VOIDmode,
+ 			     (INTVAL (operands[1]))>>16);
+ 	  output_asm_insn ("lui\t%0,%x1\t#movsi high part of %2", xops);
+ 	  xops[1] = gen_rtx (CONST_INT, VOIDmode,
+ 			     (INTVAL (operands[1])) & 0xffff);
+ 	  output_asm_insn ("ori\t%0,%x1\t#movsi low part of %2", xops);
+ 	}
+     }
+   else if (INTVAL (operands[1]) >> 16)
+     {
+       xops[1] = gen_rtx (CONST_INT, VOIDmode,
+ 			 (INTVAL (operands[1]))>>16);
+       output_asm_insn ("lui\t%0,%x1\t#movsi high part of %2", xops);
+       xops[1] = gen_rtx (CONST_INT, VOIDmode,
+ 			 (INTVAL (operands[1])) & 0xffff);
+     }
+   else
+     {
+       xops[1] = gen_rtx (CONST_INT, VOIDmode,
+ 			 (INTVAL (operands[1])) & 0xffff);
+       output_asm_insn ("ori\t%0,$0,%x1\t#movsi low part of %2",
+ 		       xops);
+     }
+   return "";
+ }
  \f


  				/* Used to obtain address of subregs      */
***************
*** 68,76 ****
  				/* subreg number into account             */
  
- 				/* So far only QI subregs of SI mode have */
- 				/* been found necessary and implemented.  */
- 
  rtx
! addr_compensate(addr,submode,origmode,subnum)
       rtx addr;
       enum machine_mode submode;
--- 131,136 ----
  				/* subreg number into account             */
  
  rtx
! addr_compensate (addr, submode, origmode, subnum)
       rtx addr;
       enum machine_mode submode;
***************
*** 78,96 ****
       int subnum;
  {
!   extern rtx change_address();
!   extern void  abort_with_insn();
!   extern rtx plus_constant( );
!      
!   if((submode == QImode) && (origmode == SImode))
      {
  #ifdef BYTES_BIG_ENDIAN
!       return    change_address(addr,QImode,
! 			       plus_constant(XEXP(addr,0),3 - subnum));      
  #else
!       return    change_address(addr,QImode,
! 			       plus_constant(XEXP(addr,0), subnum));      
  #endif
      }
!   else abort_with_insn(addr,"addr_compensate does not support mode");
  }
  
--- 138,166 ----
       int subnum;
  {
!   extern rtx change_address ();
!   extern rtx plus_constant ();
! 
!   if (submode == QImode && origmode == SImode)
!     {
! #ifdef BYTES_BIG_ENDIAN
!       return change_address (addr, QImode,
! 			     plus_constant (XEXP (addr, 0), 3 - subnum));
! #else
!       return change_address (addr, QImode,
! 			     plus_constant (XEXP (addr, 0), subnum));
! #endif
!     }
!   else if (submode == HImode && origmode == SImode)
      {
  #ifdef BYTES_BIG_ENDIAN
!       return change_address (addr, HImode,
! 			     plus_constant (XEXP (addr, 0), 2 - 2*subnum));
  #else
!       return change_address (addr, HImode,
! 			     plus_constant (XEXP (addr, 0), subnum));
  #endif
      }
!   else
!     abort_with_insn (addr, "addr_compensate does not support mode");
  }
  
***************
*** 100,104 ****
  				/* VARARGS */
  int function_suspect;
! int varargs_suspect=0; 
  int this_varargs_suspect;
  
--- 170,174 ----
  				/* VARARGS */
  int function_suspect;
! int varargs_suspect = 0;
  int this_varargs_suspect;
  
***************
*** 106,114 ****
  
  
! static struct 
! {  enum arg_state nxs_if_f, nxs_if_g;
!    short reg_if_f, reg_if_g;
! } 
!   arg_state_table[(int) ( ARG_STA_GGGG + 1)]  = ARG_STA_AUTOMA;
  
  
--- 176,185 ----
  
  
! static struct
! {
!   enum arg_state nxs_if_f, nxs_if_g;
!   short reg_if_f, reg_if_g;
! }
!   arg_state_table[(int) (ARG_STA_GGGG + 1)]  = ARG_STA_AUTOMA;
  
  
***************
*** 120,124 ****
  
  enum arg_state
! function_arg_advance(cum,mode,type)
       CUMULATIVE_ARGS *cum;
       enum machine_mode mode;
--- 191,195 ----
  
  enum arg_state
! function_arg_advance (cum, mode, type)
       CUMULATIVE_ARGS *cum;
       enum machine_mode mode;
***************
*** 125,149 ****
       int type;
  {
!   if(TARGET_DEBUGA_MODE) 
!     fprintf(stderr,"Function_arg_advance entered cum.arg_state=%d,mode=%d\n",
! 	    cum->arg_rec_state,mode);
  
-   (cum->arg_rec_state) = (FP_REGS == PREFERRED_RELOAD_CLASS_FM(mode,GR_REGS))? 
-     arg_state_table[(int)((cum->arg_rec_state))].nxs_if_f:
-   arg_state_table[(int)((cum->arg_rec_state))].nxs_if_g;
-   
    (cum->arg_num)++;
- 
-   if(TARGET_DEBUGA_MODE) 
-     fprintf(stderr,
- 	    "Function_arg_advance exited cum.arg_state=%d,mode=%d,num=%d\n",
- 	    cum->arg_rec_state,mode,cum->arg_num);
-   
  }
  
- 
- 
  rtx
! function_arg(cum,mode,type,named)
       CUMULATIVE_ARGS *cum;
       enum machine_mode mode;
--- 196,209 ----
       int type;
  {
!   cum->arg_rec_state
!     = (FP_REGS == PREFERRED_RELOAD_CLASS_FM (mode, GR_REGS)
!        ? arg_state_table[(int)((cum->arg_rec_state))].nxs_if_f
!        : arg_state_table[(int)((cum->arg_rec_state))].nxs_if_g);
  
    (cum->arg_num)++;
  }
  
  rtx
! function_arg (cum, mode, type, named)
       CUMULATIVE_ARGS *cum;
       enum machine_mode mode;
***************
*** 153,202 ****
    int regnum;
  
!   if(TARGET_DEBUGA_MODE) 
!     fprintf(stderr,"Function_arg entered cum.arg_state=%d,mode=%d\n",
! 	    cum->arg_rec_state,mode);
  
!   regnum = (FP_REGS == PREFERRED_RELOAD_CLASS_FM(mode,GR_REGS))
!     ? 
!       arg_state_table[(int)((cum->arg_rec_state))].reg_if_f
! 	:
!   arg_state_table[(int)((cum->arg_rec_state))].reg_if_g;
!   if(TARGET_DEBUGA_MODE) 
!     fprintf(stderr,"Fnarg, MODE=%d, REGNUM=%d\n",mode,regnum);
! 
!   return (( regnum >= 0 ) ? gen_rtx(REG,mode,regnum)
! 	  :(regnum == -2) ?  gen_rtx(REG,DFmode,6)
! 	  : 0); 
! 
  }
  
  
- rtx function_inarg(cum,mode,type,named)
-      CUMULATIVE_ARGS *cum;
-      enum machine_mode mode;
-      int type;
-      int named;
- { 
-   int regnum;
-   if(TARGET_DEBUGA_MODE) 
-     fprintf(stderr,"Function_inarg entered cum.arg_state=%d,mode=%d\n",
- 	    cum->arg_rec_state,mode);
- 
-   regnum = (FP_REGS == PREFERRED_RELOAD_CLASS_FM(mode,GR_REGS))
-     ? 
-       arg_state_table[(int)((cum->arg_rec_state))].reg_if_f
- 	:
-   arg_state_table[(int)((cum->arg_rec_state))].reg_if_g;
-   
-   if(TARGET_DEBUGA_MODE) 
-     fprintf(stderr,"Inarg, MODE=%d, REGNUM=%d",mode,regnum);
-   
- 
-   return (( regnum >= 0) ? gen_rtx(REG,mode,regnum)
- 	  :(regnum == -2) ?  gen_rtx(REG,DFmode,6)
- 	  : 0); 
- 
- }
- 
  \f


  static  rtx branch_cmp_op[2];
--- 213,230 ----
    int regnum;
  
!   regnum
!     = (FP_REGS == PREFERRED_RELOAD_CLASS_FM (mode, GR_REGS)
!        ? arg_state_table[(int)((cum->arg_rec_state))].reg_if_f
!        : arg_state_table[(int)((cum->arg_rec_state))].reg_if_g);
  
!   if (mode == BLKmode)
!     return 0;
!   else
!     return (regnum >= 0 ? gen_rtx (REG, mode, regnum)
! 	    : regnum == -2 ? gen_rtx (REG, DFmode, 6)
! 	    : 0);
  }
  
  
  \f


  static  rtx branch_cmp_op[2];
***************
*** 203,207 ****
  static  enum machine_mode branch_cmp_mode;
  
! compare_collect(mode,op0,op1)
       enum machine_mode mode;
       rtx op0;
--- 231,235 ----
  static  enum machine_mode branch_cmp_mode;
  
! compare_collect (mode, op0, op1)
       enum machine_mode mode;
       rtx op0;
***************
*** 208,216 ****
       rtx op1;
  {
!   if(TARGET_DEBUGD_MODE)
!     { 
!       fprintf(stderr,"compare_collect mode = %d, operands::",mode);
!       my_print_rtx(op0);
!       my_print_rtx(op1);
      }
    branch_cmp_op[0] = op0;
--- 236,244 ----
       rtx op1;
  {
!   if (TARGET_DEBUGD_MODE)
!     {
!       fprintf (stderr, "compare_collect mode = %d, operands::", mode);
!       my_print_rtx (op0);
!       my_print_rtx (op1);
      }
    branch_cmp_op[0] = op0;
***************
*** 217,226 ****
    branch_cmp_op[1] = op1;
    branch_cmp_mode = mode;
-   
-   
  }
  
  
! compare_restore(operands,mode,insn)
       rtx *operands;
       enum machine_mode *mode;
--- 245,252 ----
    branch_cmp_op[1] = op1;
    branch_cmp_mode = mode;
  }
  
  
! compare_restore (operands, mode, insn)
       rtx *operands;
       enum machine_mode *mode;
***************
*** 229,259 ****
    rtx  previous;
    rtx  prev_par;
!   if(TARGET_DEBUGD_MODE)
      {
!       fprintf(stderr, "compare_restore returning mode =%d, operands:%X,%X:"
! 	      , branch_cmp_mode ,branch_cmp_op[0],branch_cmp_op[1] );
!       my_print_rtx(branch_cmp_op[0]);
!       my_print_rtx(branch_cmp_op[1]);
      }
!   
!   if ( (! branch_cmp_op[0]) && (! branch_cmp_op[1]))
      {
        /*  Signal that multiple branches following */
        /* a comparison have been found             */
!       if(TARGET_DEBUGD_MODE)
! 	{ fprintf(stderr,"Not at ease in compare_restore\n");
! 	  my_print_rtx(insn);
! 	  my_print_rtx(PREV_INSN(insn));
  	}
        /*  Find the previous comparison */
! 
!       while( (GET_CODE(PREV_INSN(insn))) == JUMP_INSN) 
! 	{ insn = PREV_INSN(insn);
! 	  if(TARGET_DEBUGD_MODE)
! 	    my_print_rtx(PREV_INSN(insn));
  	}
!       previous =  PATTERN(PREV_INSN(insn));
  
!       if((GET_CODE(previous)) == PARALLEL)
  	{
  	  /*  Signal  that we have a very strange */
--- 255,287 ----
    rtx  previous;
    rtx  prev_par;
!   if (TARGET_DEBUGD_MODE)
      {
!       fprintf (stderr, "compare_restore returning mode = %d, operands:%X,%X:",
! 	       branch_cmp_mode, branch_cmp_op[0], branch_cmp_op[1]);
!       my_print_rtx (branch_cmp_op[0]);
!       my_print_rtx (branch_cmp_op[1]);
      }
! 
!   if ((! branch_cmp_op[0]) && (! branch_cmp_op[1]))
      {
        /*  Signal that multiple branches following */
        /* a comparison have been found             */
!       if (TARGET_DEBUGD_MODE)
! 	{
! 	  fprintf (stderr, "Not at ease in compare_restore\n");
! 	  my_print_rtx (insn);
! 	  my_print_rtx (PREV_INSN (insn));
  	}
        /*  Find the previous comparison */
!       while ((GET_CODE (PREV_INSN (insn))) == JUMP_INSN)
! 	{
! 	  insn = PREV_INSN (insn);
! 	  if (TARGET_DEBUGD_MODE)
! 	    my_print_rtx (PREV_INSN (insn));
  	}
! 
!       previous =  PATTERN (PREV_INSN (insn));
  
!       if ((GET_CODE (previous)) == PARALLEL)
  	{
  	  /*  Signal  that we have a very strange */
***************
*** 266,303 ****
  	  /* way */
  
! 	  branch_cmp_op[0] = XVECEXP(previous,0,0);
! 	  branch_cmp_op[1] = XVECEXP(previous,0,1);
! 	  /*	   warning("Check branch optimization with -mdebugd"); 
  	   */
  	}
        else
! 	if (  ((GET_CODE(previous)) == SET)
  	    &&
! 	    ((GET_CODE(XEXP(previous,0)))== CC0)
  	    &&
! 	    ((GET_CODE(XEXP(previous,1)))== MINUS)
! 	    )
  	  {			/* Here we find the comparison info    */
  	    /* in a more classical format          */
  
! 	    previous = XEXP(previous,1);
! 	    branch_cmp_op[0] = XEXP(previous,0);
! 	    branch_cmp_op[1] = XEXP(previous,1);	    
  	  }
        	else
  	  {			/* Be prepared for other things popping out */
! 	    /* of optimization ....                     */
! 	    fprintf(stderr,"Unexpected PATTERN Found in compare restore:\n");
! 	    my_print_rtx(previous);
! 	    abort();
  	  }
      }
!   
!   
!   
!   if (!  branch_cmp_op[0]) operands[0] =gen_rtx(REG,VOIDmode,0);  
!   else operands[0]= branch_cmp_op[0];
!   if (!  branch_cmp_op[1]) operands[1] =gen_rtx(REG,VOIDmode,0);  
!   else operands[1]= branch_cmp_op[1];
    *mode = branch_cmp_mode;
  
--- 294,331 ----
  	  /* way */
  
! 	  branch_cmp_op[0] = XVECEXP (previous, 0, 0);
! 	  branch_cmp_op[1] = XVECEXP (previous, 0, 1);
! 	  /*	   warning ("Check branch optimization with -mdebugd");
  	   */
  	}
        else
! 	if (((GET_CODE (previous)) == SET)
  	    &&
! 	    ((GET_CODE (XEXP (previous, 0))) == CC0)
  	    &&
! 	    ((GET_CODE (XEXP (previous, 1))) == COMPARE))
  	  {			/* Here we find the comparison info    */
  	    /* in a more classical format          */
  
! 	    previous = XEXP (previous, 1);
! 	    branch_cmp_op[0] = XEXP (previous, 0);
! 	    branch_cmp_op[1] = XEXP (previous, 1);
  	  }
        	else
  	  {			/* Be prepared for other things popping out */
! 	    abort ();
  	  }
      }
! 
! 
! 
!   if (!  branch_cmp_op[0])
!     operands[0] = gen_rtx (REG, VOIDmode, 0);
!   else
!     operands[0] = branch_cmp_op[0];
!   if (!  branch_cmp_op[1])
!     operands[1] = gen_rtx (REG, VOIDmode, 0);
!   else
!     operands[1] = branch_cmp_op[1];
    *mode = branch_cmp_mode;
  
***************
*** 304,312 ****
    branch_cmp_op[0] = NULL;
    branch_cmp_op[1] = NULL;
-   
- }
- 
  
  \f


  extern int optimize;
  extern int flag_combine_regs;
--- 332,340 ----
    branch_cmp_op[0] = NULL;
    branch_cmp_op[1] = NULL;
  
+ }
  \f


+ #if 0
+ 				/* See flags.h and toplev.c */
  extern int optimize;
  extern int flag_combine_regs;
***************
*** 316,319 ****
--- 344,350 ----
  extern int flag_omit_frame_pointer;
  extern char *main_input_filename;
+ extern char *asm_file_name;
+ 				/* See c-tree.h  and c-decl.c */
+ extern int flag_signed_char;
  
  #include <time.h>
***************
*** 320,324 ****
  #include <sys/types.h>
  #include <sys/timeb.h>
!  
  void
  print_options (out)
--- 351,355 ----
  #include <sys/types.h>
  #include <sys/timeb.h>
! 
  void
  print_options (out)
***************
*** 327,344 ****
    char *a_time;
    long c_time;
!   
!   fprintf(out," #OPTIONS:%s%s%s%s%s%s%s\n",
!           (TARGET_NOFIXED_OVFL ? " -dnofixed-ovfl":" -dfixed-ovfl"),
!           (optimize ? " optimize" : ""),
!           (flag_combine_regs ? " -fcombine-regs" : " !combine-regs"),
!           (flag_strength_reduce ? "" : " !strength_reduce"),
!           (flag_omit_frame_pointer ?"" :" !omit_frame_pointer"),
!           (flag_no_peephole ? "" : " peephole"),
!           (flag_inline_functions ?" inline-functions":"")
! 	  );
!   fprintf(out," #Source:%s\n",main_input_filename);
!   c_time=time(0);
!   a_time = ctime(&c_time);
!   fprintf(out," #Compiled:%s",a_time);
  #ifdef __GNUC__
  #ifndef __VERSION__
--- 358,378 ----
    char *a_time;
    long c_time;
! 
!   fprintf (out, " #OPTIONS:\t%s%s%s%s%s%s%s\n",
! 	   (TARGET_NOFIXED_OVFL ? " -dnofixed-ovfl":" -dfixed-ovfl"),
! 	   (optimize ? " optimize" : ""),
! 	   (flag_combine_regs ? " -fcombine-regs" : " !combine-regs"),
! 	   (flag_strength_reduce ? "" : " !strength_reduce"),
! 	   (flag_omit_frame_pointer ?"" :" !omit_frame_pointer"),
! 	   (flag_no_peephole ? "" : " peephole"),
! 	   (flag_inline_functions ?" inline-functions":""));
!   fprintf (out, " #OPTIONS:\t%s%s\n",
! 	   (flag_signed_char ? " signed-char" : " !signed-char"),
! 	   (TARGET_GP_OPT    ? " gpOPT"      : " !gpOPT"));
!   fprintf (out, " #Source:\t%s\n", main_input_filename);
!   fprintf (out, " #Destination:\t%s\n", asm_file_name);
!   c_time = time (0);
!   a_time = ctime (&c_time);
!   fprintf (out, " #Compiled:\t%s", a_time);
  #ifdef __GNUC__
  #ifndef __VERSION__
***************
*** 350,354 ****
  #endif
  }
! \f


  				/* DEBUGGING UTILITIES */
  rtx al_log_insn_debug;
--- 384,388 ----
  #endif
  }
! 
  				/* DEBUGGING UTILITIES */
  rtx al_log_insn_debug;
***************
*** 356,362 ****
  abort_show_logged ()
  {
!   if(al_log_insn_debug)
!     my_print_rtx(al_log_insn_debug);
!   abort();
  }
  
--- 390,396 ----
  abort_show_logged ()
  {
!   if (al_log_insn_debug)
!     my_print_rtx (al_log_insn_debug);
!   abort ();
  }
  
***************
*** 369,385 ****
    FILE *old;
    old = outfile;
!   
    outfile = stderr;
!   print_rtx(in_rtx);
!   fprintf(outfile,"\n");
!   
!   outfile=old;
!   
!   }
  
! extern FILE *outfile;
  
! void 
! my_print_insncode(insn)
       rtx insn;
  {
--- 403,416 ----
    FILE *old;
    old = outfile;
! 
    outfile = stderr;
!   print_rtx (in_rtx);
!   fprintf (outfile, "\n");
  
!   outfile = old;
! }
  
! void
! my_print_insncode (insn)
       rtx insn;
  {
***************
*** 386,407 ****
    FILE *old;
    old = outfile;
!   
    outfile = stderr;
!   print_rtx(insn);
!   fprintf(outfile,"\n");
!   fprintf(outfile,"INSN_CODE(insn) = %X\n", INSN_CODE(insn))  ;
!   
    outfile = old;
  }
  
- 
  void
! abort_with_insn (insn,reason)
       rtx insn;
!      char *reason;     
  {
!   fprintf(stderr,"About to Abort::%s\n",reason);
!   my_print_rtx(insn);
!   abort(); 
! }     
  
--- 417,512 ----
    FILE *old;
    old = outfile;
! 
    outfile = stderr;
!   print_rtx (insn);
!   fprintf (outfile, "\n");
!   fprintf (outfile, "INSN_CODE (insn) = %X\n", INSN_CODE (insn));
! 
    outfile = old;
  }
  
  void
! abort_with_insn (insn, reason)
       rtx insn;
!      char *reason;
! {
!   fprintf (stderr, "About to Abort::%s\n", reason);
!   my_print_rtx (insn);
!   abort ();
! }
! #endif
! 
! void
! abort_with_insn ()
! {
!   abort ();
! }
! 
! void
! my_print_rtx (in_rtx)
!      register rtx in_rtx;
! 
! {
!   abort();
! }
! \f


! #include "tree.h"
! 				/* GET SECTION (DATA/SDATA) THRESHOLD */
! int mips_section_threshold = -1;
! 
! extern char *tree_code_name[];
! 
! int
! mips_section_get ()
! {
!   register int i;
!   if (mips_section_threshold == -1)
!     {
!       i = TARGET_GVALUE;
!       if (i >= 6) i += 3;
!       if ((1 << i) != MIPS_GVALUE_DEFAULT)
! 	warning ("G value this run == %d\n", 1 << i);
!       mips_section_threshold = 1 << i;
!     }
! 
!   return mips_section_threshold;
! }
! 
! int
! mips_output_external (file, tree_exp, name)
!      FILE *file;
!      tree tree_exp;
!      char *name;
  {
!   register int i;
!   if (TARGET_GP_OPT
!       && ((TREE_CODE (tree_exp)) != FUNCTION_DECL)
!       &&
!       ((i = int_size_in_bytes (TREE_TYPE (tree_exp))) > 0))
!     {
!       fputs ("\n#ifndef _gccx__", file);
!       assemble_name (file, name);
!       fputs ("\n.extern\t", (file));
!       assemble_name ((file), (name));
!       fprintf ((file), ", %d", i, (TREE_TYPE (tree_exp)));
!       fputs ("\n#define _gccx__", file);
!       assemble_name (file, name);
!       fputs ("\n#endif\n ", file);
!     }
!   return 0;
! }
  
+ extern char *asm_file_name;
+ 
+ int
+ mips_asm_file_end (file)
+      FILE *file;
+ {
+   if (TARGET_GP_OPT)
+     {
+       fprintf (file, "\n#else\n#ifndef %sRESCAN_GCC", "__x_");
+       fprintf (file, "\n#define %sRESCAN_GCC\n#include \"%s\"", "__x_",
+ 	       asm_file_name);
+       fprintf (file, "\n#endif\n#endif\n");
+     }
+ }
diff -rc2N gcc-1.35/config/out-ns32k.c gcc-1.36/config/out-ns32k.c
*** gcc-1.35/config/out-ns32k.c	Wed Mar 29 17:48:15 1989
--- gcc-1.36/config/out-ns32k.c	Wed May 10 17:20:08 1989
***************
*** 97,101 ****
    if (REG_P (operands[0]))
      optype0 = REGOP;
!   else if (offsetable_memref_p (operands[0]))
      optype0 = OFFSOP;
    else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
--- 97,101 ----
    if (REG_P (operands[0]))
      optype0 = REGOP;
!   else if (offsettable_memref_p (operands[0]))
      optype0 = OFFSOP;
    else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
***************
*** 109,113 ****
  	   || GET_CODE (operands[1]) == CONST_DOUBLE)
      optype1 = CNSTOP;
!   else if (offsetable_memref_p (operands[1]))
      optype1 = OFFSOP;
    else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
--- 109,113 ----
  	   || GET_CODE (operands[1]) == CONST_DOUBLE)
      optype1 = CNSTOP;
!   else if (offsettable_memref_p (operands[1]))
      optype1 = OFFSOP;
    else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
***************
*** 135,139 ****
      latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
    else if (optype0 == OFFSOP)
!     latehalf[0] = adj_offsetable_operand (operands[0], 4);
    else
      latehalf[0] = operands[0];
--- 135,139 ----
      latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
    else if (optype0 == OFFSOP)
!     latehalf[0] = adj_offsettable_operand (operands[0], 4);
    else
      latehalf[0] = operands[0];
***************
*** 142,146 ****
      latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
    else if (optype1 == OFFSOP)
!     latehalf[1] = adj_offsetable_operand (operands[1], 4);
    else if (optype1 == CNSTOP)
      {
--- 142,146 ----
      latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
    else if (optype1 == OFFSOP)
!     latehalf[1] = adj_offsettable_operand (operands[1], 4);
    else if (optype1 == CNSTOP)
      {
diff -rc2N gcc-1.35/config/out-pyr.c gcc-1.36/config/out-pyr.c
*** gcc-1.35/config/out-pyr.c	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config/out-pyr.c	Sun Sep 17 03:31:31 1989
***************
*** 0 ****
--- 1,591 ----
+ /* Subroutines for insn-output.c for Pyramid 90 Series.
+    Copyright (C) 1989 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+ 
+ /* Some output-actions in pyr.md need these.  */
+ #include <stdio.h>
+ extern FILE *asm_out_file;
+ #include "tree.h"
+ 
+ /*
+  * Do FUNCTION_ARG.
+  * This cannot be defined as a macro on pyramids, because Pyramid Technology's
+  * C compiler dies on (several equivalent definitions of) this macro.
+  * The only way around this cc bug was to make this a function.
+  * While it would be possible to use a macro version for gcc, it seems
+  * more reliable to have a single version of the code.
+  */
+ void *
+ pyr_function_arg(cum, mode, type, named)
+   CUMULATIVE_ARGS cum;
+   enum machine_mode mode;
+   tree type;
+ {
+   return (void *)(FUNCTION_ARG_HELPER (cum, mode,type,named));
+ }
+ \f


+ /* Do the hard part of PARAM_SAFE_FOR_REG_P.
+  * This cannot be defined as a macro on pyramids, because Pyramid Technology's
+  * C compiler dies on (several equivalent definitions of) this macro.
+  * The only way around this cc bug was to make this a function.
+  */
+ int
+ inner_param_safe_helper (type)
+     tree type;
+ {
+   return (INNER_PARAM_SAFE_HELPER(type));
+ }
+ \f


+ 
+ /* Return 1 if OP is a non-indexed operand of mode MODE.
+    This is either a register reference, a memory reference,
+    or a constant.  In the case of a memory reference, the address
+    is checked to make sure it isn't indexed.
+ 
+    Register and memory references must have mode MODE in order to be valid,
+    but some constants have no machine mode and are valid for any mode.
+ 
+    If MODE is VOIDmode, OP is checked for validity for whatever mode
+    it has.
+ 
+    The main use of this function is as a predicate in match_operand
+    expressions in the machine description.
+ 
+    It is  useful to compare this with general_operand().  They should
+    be identical except for one line.
+ 
+    This function seems necessary because of the non-orthogonality of
+    Pyramid insns.
+    For any 2-operand insn, and any combination of operand modes,
+    if indexing is valid for the isn's second operand, it is invalid
+    for the first operand to be indexed. */
+ 
+ extern int volatile_ok;
+ 
+ int
+ nonindexed_operand(op, mode)
+     register rtx op;
+     enum machine_mode mode;
+ {
+   register enum rtx_code code = GET_CODE (op);
+   int mode_altering_drug = 0;
+ 
+   if (mode == VOIDmode)
+     mode = GET_MODE (op);
+ 
+   if (CONSTANT_P (op))
+     return ((GET_MODE (op) == VOIDmode || GET_MODE (op) == mode)
+ 	    && LEGITIMATE_CONSTANT_P (op));
+ 
+   /* Except for certain constants with VOIDmode, already checked for,
+      OP's mode must match MODE if MODE specifies a mode.  */
+ 
+   if (GET_MODE (op) != mode)
+     return 0;
+ 
+   while (code == SUBREG)
+     {
+       op = SUBREG_REG (op);
+       code = GET_CODE (op);
+ #if 0
+       /* No longer needed, since (SUBREG (MEM...))
+ 	 will load the MEM into a reload reg in the MEM's own mode.  */
+       mode_altering_drug = 1;
+ #endif
+     }
+   if (code == REG)
+     return 1;
+   if (code == CONST_DOUBLE)
+     return LEGITIMATE_CONSTANT_P (op);
+   if (code == MEM)
+     {
+       register rtx y = XEXP (op, 0);
+       if (! volatile_ok && MEM_VOLATILE_P (op))
+ 	return 0;
+     GO_IF_NONINDEXED_ADDRESS (y, win);
+     }
+   return 0;
+ 
+  win:
+   if (mode_altering_drug)
+     return ! mode_dependent_address_p (XEXP (op, 0));
+   return 1;
+ }
+ 
+ int
+ has_direct_base (op)
+      rtx op;
+ {
+   if ((GET_CODE (op) == PLUS
+        && (CONSTANT_ADDRESS_P (XEXP (op, 1))
+ 	   || CONSTANT_ADDRESS_P (XEXP (op, 0))))
+       || CONSTANT_ADDRESS_P (op))
+     return 1;
+ 
+   return 0;
+ }
+ 
+ int
+ has_index (op)
+      rtx op;
+ {
+   if (GET_CODE (op) == PLUS
+       && (GET_CODE (XEXP (op, 0)) == MULT
+ 	  || (GET_CODE (XEXP (op, 1)) == MULT)))
+     return 1;
+   else
+     return 0;
+ }
+ 
+ int swap_operands;
+ 
+ /* weird_memory_memory -- return 1 if OP1 and OP2 can be compared (or
+    exchanged with xchw) with one instruction.  If the operands need to
+    be swapped, set the global variable SWAP_OPERANDS.  This function
+    silently assumes that both OP0 and OP1 are valid memory references.
+    */
+ 
+ int
+ weird_memory_memory (op0, op1)
+      rtx op0, op1;
+ {
+   int ret;
+   int c;
+   enum rtx_code code0, code1;
+ 
+   op0 = XEXP (op0, 0);
+   op1 = XEXP (op1, 0);
+   code0 = GET_CODE (op0);
+   code1 = GET_CODE (op1);
+ 
+   swap_operands = 0;
+ 
+   if (code1 == REG)
+     {
+       return 1;
+     }
+   if (code0 == REG)
+     {
+       swap_operands = 1;
+       return 1;
+     }
+   if (has_direct_base (op0) && has_direct_base (op1))
+     {
+       if (has_index (op1))
+ 	{
+ 	  if (has_index (op0))
+ 	    return 0;
+ 	  swap_operands = 1;
+ 	}
+ 
+       return 1;
+     }
+   return 0;
+ }
+ 
+ int
+ signed_comparison (x, mode)
+      rtx x;
+      enum machine_mode mode;
+ {
+   enum rtx_code code = GET_CODE (x);
+ 
+   return (code == NE || code == EQ || code == GE || code == GT || code == LE
+ 	 || code == LT);
+ }
+ 
+ char *
+ output_branch (code)
+      enum rtx_code code;
+ {
+   switch (code)
+     {
+     case NE:  return "bne %l4";
+     case EQ:  return "beq %l4";
+     case GE:  return "bge %l4";
+     case GT:  return "bgt %l4";
+     case LE:  return "ble %l4";
+     case LT:  return "blt %l4";
+     }
+ }
+ 
+ char *
+ output_inv_branch (code)
+      enum rtx_code code;
+ {
+   switch (code)
+     {
+     case NE:  return "beq %l4";
+     case EQ:  return "bne %l4";
+     case GE:  return "ble %l4";
+     case GT:  return "blt %l4";
+     case LE:  return "bge %l4";
+     case LT:  return "bgt %l4";
+     }
+ }
+ 
+ extern rtx force_reg ();
+ rtx test_op0, test_op1;
+ 
+ rtx
+ ensure_extended (op, extop)
+      rtx op;
+      enum rtx_code extop;
+ {
+   if (GET_MODE (op) == HImode || GET_MODE (op) == QImode)
+     op = gen_rtx (extop, SImode, op);
+   op = force_reg (SImode, op);
+   return op;
+ }
+ 
+ /* Sign-extend or zero-extend constant X from FROM_MODE to TO_MODE.  */
+ 
+ rtx
+ extend_const (x, extop, from_mode, to_mode)
+     rtx x;
+     enum rtx_code extop;
+     enum machine_mode from_mode, to_mode;
+ {
+   int val = INTVAL (x);
+   int negative = val & (1 << (GET_MODE_BITSIZE (from_mode) - 1));
+   if (from_mode == to_mode)
+     return x;
+   if (GET_MODE_BITSIZE (from_mode) == HOST_BITS_PER_INT)
+     abort ();
+   if (negative && extop == SIGN_EXTEND)
+     val = val | ((-1) << (GET_MODE_BITSIZE (from_mode)));
+   else
+     val = val & ~((-1) << (GET_MODE_BITSIZE (from_mode)));
+   if (GET_MODE_BITSIZE (to_mode) == HOST_BITS_PER_INT)
+     return gen_rtx (CONST_INT, VOIDmode, val);
+   return gen_rtx (CONST_INT, VOIDmode,
+ 		  val & ~((-1) << (GET_MODE_BITSIZE (to_mode))));
+ }
+ 
+ /* Emit rtl for a branch, as well as any delayed (integer) compare insns.
+    The compare insn to perform is determined by the global variables
+    test_op0 and test_op1.  */
+ 
+ void
+ extend_and_branch (extop)
+      enum rtx_code extop;
+ {
+   rtx op0, op1;
+   enum rtx_code code0, code1;
+ 
+   op0 = test_op0, op1 = test_op1;
+   if (op0 == 0)
+     return;
+ 
+   code0 = GET_CODE (op0);
+   if (op1 != 0)
+     code1 = GET_CODE (op1);
+   test_op0 = test_op1 = 0;
+ 
+   if (op1 == 0)
+     {
+       op0 = ensure_extended (op0, extop);
+       emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx, op0));
+     }
+   else
+     {
+       if (CONSTANT_P (op0) && CONSTANT_P (op1))
+ 	{
+ 	  op0 = force_reg (SImode, op0);
+ 	  op1 = force_reg (SImode, op1);
+ 	}
+       else if (extop == ZERO_EXTEND && GET_MODE (op0) == HImode)
+ 	{
+ 	  /* Pyramids have no unsigned "cmphi" instructions.  We need to
+ 	     zero extend unsigned halfwords into temporary registers. */
+ 	  op0 = ensure_extended (op0, extop);
+ 	  op1 = ensure_extended (op1, extop);
+ 	}
+       else if (CONSTANT_P (op0))
+ 	{
+ 	  op0 = extend_const (op0, extop, GET_MODE (op1), SImode);
+ 	  op1 = ensure_extended (op1, extop);
+ 	}
+       else if (CONSTANT_P (op1))
+ 	{
+ 	  op1 = extend_const (op1, extop, GET_MODE (op0), SImode);
+ 	  op0 = ensure_extended (op0, extop);
+ 	}
+       else if (code0 == REG && code1 == REG)
+ 	{
+ 	  /* I could do this case without extension, by using the virtual
+ 	     register address (but that would lose for global regs).  */
+ 	  op0 = ensure_extended (op0, extop);
+ 	  op1 = ensure_extended (op1, extop);
+ 	}
+       else if (code0 == MEM && code1 == MEM)
+ 	{
+ 	  /* Load into a reg if the address combination can't be handled
+ 	     directly.  */
+ 	  if (! weird_memory_memory (op0, op1))
+ 	    op0 = force_reg (GET_MODE (op0), op0);
+ 	}
+ 
+       emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx,
+ 			  gen_rtx (COMPARE, VOIDmode, op0, op1)));
+     }
+ }
+ 
+ /* Return non-zero if the two single-word operations with operands[0]
+    and operands[1] for the first single-word operation, and operands[2]
+    and operands[3] for the second single-word operation, is possible to
+    combine to a double word operation.
+ 
+    The criterion is whether the operands are in consecutive memory cells,
+    registers, etc.  */
+ 
+ int
+ movdi_possible (operands)
+      rtx operands[];
+ {
+   int cnst_diff0, cnst_diff1;
+ 
+   cnst_diff0 = consecutive_operands (operands[0], operands[2]);
+   if (cnst_diff0 == 0)
+     return 0;
+ 
+   cnst_diff1 = consecutive_operands (operands[1], operands[3]);
+   if (cnst_diff0 & cnst_diff1)
+     {
+       if (cnst_diff0 & 1)
+ 	swap_operands = 0;
+       else
+ 	swap_operands = 1;
+       return 1;
+     }
+   return 0;
+ }
+ 
+ /* Return +1 of OP0 is a consecutive operand to OP1, -1 if OP1 is a
+    consecutive operand to OP0.
+ 
+    This function is used to determine if addresses are consecutive,
+    and therefore possible to combine to fewer instructions.  */
+ 
+ int
+ consecutive_operands (op0, op1)
+      rtx op0, op1;
+ {
+   enum rtx_code code0, code1;
+   int cnst_diff;
+ 
+   code0 = GET_CODE (op0);
+   code1 = GET_CODE (op1);
+ 
+   if (CONSTANT_P (op0) && CONSTANT_P (op1))
+     {
+       if (op0 == const0_rtx)
+ 	if (op1 == const0_rtx)
+ 	  return 3;
+ 	else
+ 	  return 2;
+       if (op1 == const0_rtx)
+ 	return 1;
+     }
+ 
+   if (code0 != code1)
+     return 0;
+ 
+   if (code0 == REG)
+     {
+       cnst_diff = REGNO (op0) - REGNO (op1);
+       if (cnst_diff == 1)
+ 	return 1;
+       else if (cnst_diff == -1)
+ 	return 2;
+     }
+   else if (code0 == MEM)
+     {
+       cnst_diff = radr_diff (XEXP (op0, 0), XEXP (op1, 0));
+       if (cnst_diff)
+ 	if (cnst_diff == 4)
+ 	  return 1;
+ 	else if (cnst_diff == -4)
+ 	  return 2;
+     }
+   return 0;
+ }
+ 
+ /* Return the constant difference of the rtx expressions OP0 and OP1,
+    or 0 if the y don't have a constant difference.
+ 
+    This function is used to determine if addresses are consecutive,
+    and therefore possible to combine to fewer instructions.  */
+ 
+ int
+ radr_diff (op0, op1)
+      rtx op0, op1;
+ {
+   enum rtx_code code0, code1;
+   int cnst_diff;
+ 
+   code0 = GET_CODE (op0);
+   code1 = GET_CODE (op1);
+ 
+   if (code0 != code1)
+     {
+       if (code0 == PLUS)
+ 	{
+ 	  if (GET_CODE (XEXP (op0, 1)) == CONST_INT
+ 	      && rtx_equal_p (op1, XEXP (op0, 0)))
+ 	    return INTVAL (XEXP (op0, 1));
+ 	}
+       else if (code1 == PLUS)
+ 	{
+ 	  if (GET_CODE (XEXP (op1, 1)) == CONST_INT
+ 	      && rtx_equal_p (op0, XEXP (op1, 0)))
+ 	    return -INTVAL (XEXP (op1, 1));
+ 	}
+       return 0;
+     }
+ 
+   if (code0 == CONST_INT)
+     return INTVAL (op0) - INTVAL (op1);
+ 
+   if (code0 == PLUS)
+     {
+       cnst_diff = radr_diff (XEXP (op0, 0), XEXP (op1, 0));
+       if (cnst_diff)
+ 	return (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1)))
+ 	  ? cnst_diff : 0;
+       cnst_diff = radr_diff (XEXP (op0, 1), XEXP (op1, 1));
+       if (cnst_diff)
+ 	return (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0)))
+ 	  ? cnst_diff : 0;
+     }
+ 
+   return 0;
+ }
+ 
+ int
+ already_sign_extended (insn, from_mode, op)
+      rtx insn;
+      enum machine_mode from_mode;
+      rtx op;
+ {
+   rtx xinsn;
+ 
+   return 0;
+ 
+ #if 0
+   for (;;)
+     {
+       insn = PREV_INSN (insn);
+       if (insn == 0)
+ 	return 0;
+       if (GET_CODE (insn) == NOTE)
+ 	continue;
+       if (GET_CODE (insn) != INSN)
+ 	return 0;
+       xinsn = PATTERN (insn);
+ 
+       if (GET_CODE (xinsn) != SET)
+ 	return 0;
+ 
+       /* Is it another register that is set in this insn?  */
+       if (GET_CODE (SET_DEST (xinsn)) != REG
+ 	  || REGNO (SET_DEST (xinsn)) != REGNO (op))
+ 	continue;
+ 
+       if (GET_CODE (SET_SRC (xinsn)) == SIGN_EXTEND
+ 	  || (GET_CODE (SET_SRC (xinsn)) == MEM
+ 	      && GET_MODE (SET_SRC (xinsn)) == from_mode))
+ 	return 1;
+ 
+       /* Is the register modified by another operation?  */
+       if (REGNO (SET_DEST (xinsn)) == REGNO (op))
+ 	return 0;
+     }
+ #endif
+ }
+ 
+ char *
+ output_move_double (operands)
+      rtx *operands;
+ {
+   CC_STATUS_INIT;
+   if (GET_CODE (operands[1]) == CONST_DOUBLE)
+     {
+       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT)
+ 	{
+ 	  /* In an integer, the low-order word is in CONST_DOUBLE_LOW.  */
+ 	  rtx const_op = operands[1];
+ 	  if (CONST_DOUBLE_HIGH (const_op) == 0)
+ 	    {
+ 	      operands[1] = gen_rtx (CONST_INT, VOIDmode,
+ 				     CONST_DOUBLE_LOW (const_op));
+ 	      return "movl %1,%0";
+ 	    }
+ 	  operands[1] = gen_rtx (CONST_INT, VOIDmode,
+ 				 CONST_DOUBLE_HIGH (const_op));
+ 	  output_asm_insn ("movw %1,%0", operands);
+ 	  operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+ 	  operands[1] = gen_rtx (CONST_INT, VOIDmode,
+ 				 CONST_DOUBLE_LOW (const_op));
+ 	  return "movw %1,%0";
+ 	}
+       else
+ 	{
+ 	  /* In a real, the low-address word is in CONST_DOUBLE_LOW.  */
+ 	  rtx const_op = operands[1];
+ 	  if (CONST_DOUBLE_LOW (const_op) == 0)
+ 	    {
+ 	      operands[1] = gen_rtx (CONST_INT, VOIDmode,
+ 				     CONST_DOUBLE_HIGH (const_op));
+ 	      return "movl %1,%0";
+ 	    }
+ 	  operands[1] = gen_rtx (CONST_INT, VOIDmode,
+ 				 CONST_DOUBLE_LOW (const_op));
+ 	  output_asm_insn ("movw %1,%0", operands);
+ 	  operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+ 	  operands[1] = gen_rtx (CONST_INT, VOIDmode,
+ 				 CONST_DOUBLE_HIGH (const_op));
+ 	  return "movw %1,%0";
+ 	}
+     }
+ 
+   return "movl %1,%0";
+ }
+ 
+ /* Return non-zero if the code of this rtx pattern is a relop.  */
+ int
+ relop (op, mode)
+      rtx op;
+      enum machine_mode mode;
+ {
+   switch (GET_CODE (op))
+     {
+     case EQ:
+     case NE:
+     case LT:
+     case LE:
+     case GE:
+     case GT:
+     case LTU:
+     case LEU:
+     case GEU:
+     case GTU:
+       return 1;
+     }
+   return 0;
+ }
diff -rc2N gcc-1.35/config/out-sparc.c gcc-1.36/config/out-sparc.c
*** gcc-1.35/config/out-sparc.c	Wed Mar 29 15:28:23 1989
--- gcc-1.36/config/out-sparc.c	Wed Sep  6 03:54:34 1989
***************
*** 601,605 ****
    if (REG_P (operands[0]))
      optype0 = REGOP;
!   else if (offsetable_memref_p (operands[0]))
      optype0 = OFFSOP;
    else if (GET_CODE (operands[0]) == MEM)
--- 601,605 ----
    if (REG_P (operands[0]))
      optype0 = REGOP;
!   else if (offsettable_memref_p (operands[0]))
      optype0 = OFFSOP;
    else if (GET_CODE (operands[0]) == MEM)
***************
*** 613,617 ****
  	   || GET_CODE (operands[1]) == CONST_DOUBLE)
      optype1 = CNSTOP;
!   else if (offsetable_memref_p (operands[1]))
      optype1 = OFFSOP;
    else if (GET_CODE (operands[1]) == MEM)
--- 613,617 ----
  	   || GET_CODE (operands[1]) == CONST_DOUBLE)
      optype1 = CNSTOP;
!   else if (offsettable_memref_p (operands[1]))
      optype1 = OFFSOP;
    else if (GET_CODE (operands[1]) == MEM)
***************
*** 648,652 ****
      latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
    else if (optype0 == OFFSOP)
!     latehalf[0] = adj_offsetable_operand (operands[0], 4);
    else
      latehalf[0] = operands[0];
--- 648,652 ----
      latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
    else if (optype0 == OFFSOP)
!     latehalf[0] = adj_offsettable_operand (operands[0], 4);
    else
      latehalf[0] = operands[0];
***************
*** 655,659 ****
      latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
    else if (optype1 == OFFSOP)
!     latehalf[1] = adj_offsetable_operand (operands[1], 4);
    else if (optype1 == CNSTOP)
      {
--- 655,659 ----
      latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
    else if (optype1 == OFFSOP)
!     latehalf[1] = adj_offsettable_operand (operands[1], 4);
    else if (optype1 == CNSTOP)
      {
***************
*** 765,769 ****
        && REGNO (operands[0]) == REGNO (latehalf[1]))
      {
!       /* Make any unoffsetable addresses point at high-numbered word.  */
        if (addreg0)
  	output_asm_insn ("add %0,0x4,%0", &addreg0);
--- 765,769 ----
        && REGNO (operands[0]) == REGNO (latehalf[1]))
      {
!       /* Make any unoffsettable addresses point at high-numbered word.  */
        if (addreg0)
  	output_asm_insn ("add %0,0x4,%0", &addreg0);
***************
*** 796,800 ****
    output_asm_insn (singlemove_string (operands), operands);
  
!   /* Make any unoffsetable addresses point at high-numbered word.  */
    if (addreg0)
      output_asm_insn ("add %0,0x4,%0", &addreg0);
--- 796,800 ----
    output_asm_insn (singlemove_string (operands), operands);
  
!   /* Make any unoffsettable addresses point at high-numbered word.  */
    if (addreg0)
      output_asm_insn ("add %0,0x4,%0", &addreg0);
***************
*** 883,901 ****
  	    }
  	}
        if (GET_CODE (XEXP (operands[0], 0)) == PLUS
! 	  && (XEXP (XEXP (operands[0], 0), 0) == frame_pointer_rtx
! 	      || XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx)
! 	  && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT
! 	  && (INTVAL (XEXP (XEXP (operands[0], 0), 1)) & 0x7) != 0)
! 	{
! 	  rtx xoperands[2];
! 	  output_asm_insn ("st %r1,%0", operands);
! 	  xoperands[1] = gen_rtx (REG, GET_MODE (operands[1]),
! 				  REGNO (operands[1]) + 1);
! 	  xoperands[0] = gen_rtx (MEM, GET_MODE (operands[0]),
! 				  plus_constant (XEXP (operands[0], 0), 4));
! 	  output_asm_insn ("st %r1,%0", xoperands);
! 	  return "";
! 	}
        if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  	{
--- 883,898 ----
  	    }
  	}
+       /* Use std if we can be sure it is well-aligned.  */
        if (GET_CODE (XEXP (operands[0], 0)) == PLUS
! 	  && (((XEXP (XEXP (operands[0], 0), 0) == frame_pointer_rtx
! 		|| XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx)
! 	       && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT
! 	       && (INTVAL (XEXP (XEXP (operands[0], 0), 1)) & 0x7) == 0)
! 	      /* Arrays are known to be aligned,
! 		 and reg+reg addresses are used (on this machine)
! 		 only for array accesses.  */
! 	      || (REG_P (XEXP (XEXP (operands[0], 0), 0))
! 		  && REG_P (XEXP (XEXP (operands[0], 0), 1)))))
! 	return "std %1,%0";
        if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  	{
***************
*** 907,911 ****
  	  return "std %1,[%%lo(%m0)+%%g1]";
  	}
!       return "std %1,%0";
      }
    else abort ();
--- 904,918 ----
  	  return "std %1,[%%lo(%m0)+%%g1]";
  	}
!       /* Otherwise use two st insns.  */
!       {
! 	rtx xoperands[2];
! 	output_asm_insn ("st %r1,%0", operands);
! 	xoperands[1] = gen_rtx (REG, GET_MODE (operands[1]),
! 				REGNO (operands[1]) + 1);
! 	xoperands[0] = gen_rtx (MEM, GET_MODE (operands[0]),
! 				plus_constant (XEXP (operands[0], 0), 4));
! 	output_asm_insn ("st %r1,%0", xoperands);
! 	return "";
!       }
      }
    else abort ();
***************
*** 1165,1171 ****
  
  /* Output code to place a size count SIZE in register REG.
!    If SIZE is round, then assume that we can use alignment
!    based on that roundness, and return an integer saying
!    what alignment (roundness, transfer size) we will be using.
  
     Because block moves are pipelined, we don't include the
--- 1172,1176 ----
  
  /* Output code to place a size count SIZE in register REG.
!    ALIGN is the size of the unit of transfer.
  
     Because block moves are pipelined, we don't include the
***************
*** 1172,1210 ****
     first element in the transfer of SIZE to REG.  */
  
! static int
! output_size_for_block_move (size, reg)
       rtx size, reg;
  {
!   int align;
!   rtx xoperands[2];
!   xoperands[0] = reg;
  
!   /* First, figure out best alignment we may assume.  */
!   if (REG_P (size))
      {
!       xoperands[1] = size;
!       output_asm_insn ("sub %1,1,%0", xoperands);
!       align = 1;
!     }
!   else
!     {
!       int i = INTVAL (size);
! 
!       if (i & 1)
! 	align = 1;
!       else if (i & 3)
! 	align = 2;
!       else
! 	align = 4;
! 
!       /* predecrement count.  */
!       i -= align;
!       if (i < 0) abort ();
! 
!       xoperands[1] = gen_rtx (CONST_INT, VOIDmode, i);
! 
        output_asm_insn ("set %1,%0", xoperands);
      }
-   return align;
  }
  
--- 1177,1199 ----
     first element in the transfer of SIZE to REG.  */
  
! static void
! output_size_for_block_move (size, reg, align)
       rtx size, reg;
+      rtx align;
  {
!   rtx xoperands[3];
  
!   xoperands[0] = reg;
!   xoperands[1] = size;
!   xoperands[2] = align;
!   if (GET_CODE (size) == REG)
!     output_asm_insn ("sub %1,%2,%0", xoperands);
!   else
      {
!       xoperands[1]
! 	= gen_rtx (CONST_INT, VOIDmode, INTVAL (size) - INTVAL (align));
!       cc_status.flags &= ~ CC_KNOW_HI_G1;
        output_asm_insn ("set %1,%0", xoperands);
      }
  }
  
***************
*** 1214,1218 ****
     OPERANDS[1] is the source.
     OPERANDS[2] is the size.
!    OPERANDS[3..5] are pseudos we can safely clobber as temps.  */
  
  char *
--- 1203,1208 ----
     OPERANDS[1] is the source.
     OPERANDS[2] is the size.
!    OPERANDS[3] is the alignment safe to use.
!    OPERANDS[4] is a register we can safely clobber as a temp.  */
  
  char *
***************
*** 1225,1235 ****
    rtx zoperands[10];
    static int movstrsi_label = 0;
-   int align = -1;		/* not yet known */
    int i, j;
  
    xoperands[0] = operands[0];
    xoperands[1] = operands[1];
!   xoperands[2] = operands[3];
  
    /* Since we clobber untold things, nix the condition codes.  */
    CC_STATUS_INIT;
--- 1215,1235 ----
    rtx zoperands[10];
    static int movstrsi_label = 0;
    int i, j;
+   rtx temp1 = operands[4];
+   rtx alignrtx = operands[3];
+   int align = INTVAL (alignrtx);
  
    xoperands[0] = operands[0];
    xoperands[1] = operands[1];
!   xoperands[2] = temp1;
  
+   /* We can't move more than four bytes at a time
+      because we have only one register to move them through.  */
+   if (align > 4)
+     {
+       align = 4;
+       alignrtx = gen_rtx (CONST_INT, VOIDmode, 4);
+     }
+ 
    /* Since we clobber untold things, nix the condition codes.  */
    CC_STATUS_INIT;
***************
*** 1250,1254 ****
  
        cc_status.flags &= ~CC_KNOW_HI_G1;
!       if (size & 1)
  	{
  	  if (memory_address_p (QImode, plus_constant (xoperands[0], size))
--- 1250,1254 ----
  
        cc_status.flags &= ~CC_KNOW_HI_G1;
!       if (align == 1)
  	{
  	  if (memory_address_p (QImode, plus_constant (xoperands[0], size))
***************
*** 1266,1270 ****
  	    }
  	}
!       else if (size & 2)
  	{
  	  if (memory_address_p (HImode, plus_constant (xoperands[0], size))
--- 1266,1270 ----
  	    }
  	}
!       else if (align == 2)
  	{
  	  if (memory_address_p (HImode, plus_constant (xoperands[0], size))
***************
*** 1304,1308 ****
       or use a free register (used by no operands).
       Also emit code to decrement the size value by ALIGN.  */
!   align = output_size_for_block_move (operands[2], operands[3]);
       
    zoperands[0] = operands[0];
--- 1304,1308 ----
       or use a free register (used by no operands).
       Also emit code to decrement the size value by ALIGN.  */
!   output_size_for_block_move (operands[2], temp1, alignrtx);
       
    zoperands[0] = operands[0];
***************
*** 1520,1529 ****
    extern rtx sequence_stack;
    rtx last_insn = XEXP (XEXP (sequence_stack, 1), 0);
!   rtx last_pat = PATTERN (last_insn);
    if (GET_CODE (last_pat) != SET
        || GET_CODE (SET_DEST (last_pat)) != CC0)
      abort ();
!   SET_DEST (last_pat) = operands[0];
!   SET_SRC (last_pat) = gen_rtx (code, mode, SET_SRC (last_pat), const0_rtx);
  }
  
--- 1520,1544 ----
    extern rtx sequence_stack;
    rtx last_insn = XEXP (XEXP (sequence_stack, 1), 0);
!   rtx last_pat;
! 
!   /* Skip back over the CLOBBERs that may precede this insn.  */
!   while (last_insn && GET_CODE (last_insn) == INSN
! 	 && GET_CODE (PATTERN (last_insn)) == CLOBBER)
!     last_insn = PREV_INSN (last_insn);
!   /* We should have found the preceding compare.  */
!   if (last_insn == 0 || GET_CODE (last_insn) != INSN)
!     abort ();
!   last_pat = PATTERN (last_insn);
    if (GET_CODE (last_pat) != SET
        || GET_CODE (SET_DEST (last_pat)) != CC0)
      abort ();
! 
!   /* Turn off that previous insn, now that we have got the data out of it.  */
!   PUT_CODE (last_insn, NOTE);
!   NOTE_LINE_NUMBER (last_insn) = NOTE_INSN_DELETED;
! 
!   /* Emit one replacement insn to compare operands and store result.  */
!   emit_insn (gen_rtx (SET, VOIDmode, operands[0],
! 		      gen_rtx (code, mode, SET_SRC (last_pat), const0_rtx)));
  }
  
***************
*** 1541,1544 ****
--- 1556,1560 ----
    rtx label = gen_label_rtx ();
    int cc_in_fccr = cc_status.flags & CC_IN_FCCR;
+   int antisymmetric = 0;
  
    xoperands[0] = operand;
***************
*** 1564,1567 ****
--- 1580,1584 ----
        else
  	output_asm_insn ("bge,a %l0", &label);
+       antisymmetric = 1;
        break;
      case GT:
***************
*** 1570,1573 ****
--- 1587,1591 ----
        else
  	output_asm_insn ("bg,a %l0", &label);
+       antisymmetric = 1;
        break;
      case LE:
***************
*** 1576,1579 ****
--- 1594,1598 ----
        else
  	output_asm_insn ("ble,a %l0", &label);
+       antisymmetric = 1;
        break;
      case LT:
***************
*** 1582,1585 ****
--- 1601,1605 ----
        else
  	output_asm_insn ("bl,a %l0", &label);
+       antisymmetric = 1;
        break;
      case GEU:
***************
*** 1588,1591 ****
--- 1608,1612 ----
        else
  	output_asm_insn ("bgeu,a %l0", &label);
+       antisymmetric = 1;
        break;
      case GTU:
***************
*** 1594,1597 ****
--- 1615,1619 ----
        else
  	output_asm_insn ("bgu,a %l0", &label);
+       antisymmetric = 1;
        break;
      case LEU:
***************
*** 1600,1603 ****
--- 1622,1626 ----
        else
  	output_asm_insn ("bleu,a %l0", &label);
+       antisymmetric = 1;
        break;
      case LTU:
***************
*** 1606,1609 ****
--- 1629,1633 ----
        else
  	output_asm_insn ("blu,a %l0", &label);
+       antisymmetric = 1;
        break;
      default:
***************
*** 1610,1614 ****
        abort ();
      }
!   output_asm_insn ("mov 1,%0\n\tmov 0,%0\n%l1:", xoperands);
    return "";
  }
--- 1634,1642 ----
        abort ();
      }
!   if (antisymmetric
!       && (cc_status.flags & CC_REVERSED))
!     output_asm_insn ("orcc %%g0,0,%0\n\torcc %%g0,1,%0\n%l1:", xoperands);
!   else
!     output_asm_insn ("orcc %%g0,1,%0\n\torcc %%g0,0,%0\n%l1:", xoperands);
    return "";
  }
***************
*** 1702,1705 ****
--- 1730,1736 ----
        rtx pat = gen_rtx (SET, VOIDmode, dest, src);
        rtx delay_insn = gen_rtx (INSN, VOIDmode, 0, 0, 0, pat, -1, 0, 0);
+       int i;
+       extern rtx alter_subreg();
+       extern int insn_n_operands[];
  
        /* Output the branch instruction first.  */
***************
*** 1712,1715 ****
--- 1743,1752 ----
        if (insn_code_number == -1)
  	abort ();
+ 
+       for (i = 0; i < insn_n_operands[insn_code_number]; i++)
+ 	{
+ 	  if (GET_CODE (recog_operand[i]) == SUBREG)
+ 	    recog_operand[i] = alter_subreg (recog_operand[i]);
+ 	}
  
        /* Now get the template for what this insn would
diff -rc2N gcc-1.35/config/out-spur.c gcc-1.36/config/out-spur.c
*** gcc-1.35/config/out-spur.c	Wed Mar 29 15:26:05 1989
--- gcc-1.36/config/out-spur.c	Wed May 10 17:20:04 1989
***************
*** 83,87 ****
    if (REG_P (operands[0]))
      optype0 = REGOP;
!   else if (offsetable_memref_p (operands[0]))
      optype0 = OFFSOP;
    else if (GET_CODE (operands[0]) == MEM)
--- 83,87 ----
    if (REG_P (operands[0]))
      optype0 = REGOP;
!   else if (offsettable_memref_p (operands[0]))
      optype0 = OFFSOP;
    else if (GET_CODE (operands[0]) == MEM)
***************
*** 95,99 ****
  	   || GET_CODE (operands[1]) == CONST_DOUBLE)
      optype1 = CNSTOP;
!   else if (offsetable_memref_p (operands[1]))
      optype1 = OFFSOP;
    else if (GET_CODE (operands[1]) == MEM)
--- 95,99 ----
  	   || GET_CODE (operands[1]) == CONST_DOUBLE)
      optype1 = CNSTOP;
!   else if (offsettable_memref_p (operands[1]))
      optype1 = OFFSOP;
    else if (GET_CODE (operands[1]) == MEM)
***************
*** 130,134 ****
      latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
    else if (optype0 == OFFSOP)
!     latehalf[0] = adj_offsetable_operand (operands[0], 4);
    else
      latehalf[0] = operands[0];
--- 130,134 ----
      latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
    else if (optype0 == OFFSOP)
!     latehalf[0] = adj_offsettable_operand (operands[0], 4);
    else
      latehalf[0] = operands[0];
***************
*** 137,141 ****
      latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
    else if (optype1 == OFFSOP)
!     latehalf[1] = adj_offsetable_operand (operands[1], 4);
    else if (optype1 == CNSTOP)
      {
--- 137,141 ----
      latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
    else if (optype1 == OFFSOP)
!     latehalf[1] = adj_offsettable_operand (operands[1], 4);
    else if (optype1 == CNSTOP)
      {
***************
*** 161,165 ****
        && REGNO (operands[0]) == REGNO (latehalf[1]))
      {
!       /* Make any unoffsetable addresses point at high-numbered word.  */
        if (addreg0)
  	output_asm_insn ("add_nt %0,%0,$4", &addreg0);
--- 161,165 ----
        && REGNO (operands[0]) == REGNO (latehalf[1]))
      {
!       /* Make any unoffsettable addresses point at high-numbered word.  */
        if (addreg0)
  	output_asm_insn ("add_nt %0,%0,$4", &addreg0);
***************
*** 184,188 ****
    output_asm_insn (singlemove_string (operands), operands);
  
!   /* Make any unoffsetable addresses point at high-numbered word.  */
    if (addreg0)
      output_asm_insn ("add_nt %0,%0,$4", &addreg0);
--- 184,188 ----
    output_asm_insn (singlemove_string (operands), operands);
  
!   /* Make any unoffsettable addresses point at high-numbered word.  */
    if (addreg0)
      output_asm_insn ("add_nt %0,%0,$4", &addreg0);
diff -rc2N gcc-1.35/config/out-tahoe.c gcc-1.36/config/out-tahoe.c
*** gcc-1.35/config/out-tahoe.c	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config/out-tahoe.c	Sat Sep 16 20:54:56 1989
***************
*** 0 ****
--- 1,550 ----
+ /* Subroutines for insn-output.c for Tahoe.
+    Copyright (C) 1989 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+ 
+ 
+ /*
+  * File: output-tahoe.c
+  *
+  * This port made at the University of Buffalo by Devon Bowen,
+  * Dale Wiles and Kevin Zachmann.
+  *
+  * Mail bugs reports or fixes to:	gcc@cs.buffalo.edu
+  */
+ 
+ 
+ /* most of the print_operand_address function was taken from the vax	*/
+ /* since the modes are basically the same. I had to add a special case,	*/
+ /* though, for symbol references with offsets.				*/
+ 
+ #include <stdio.h>
+ 
+ print_operand_address (file, addr)
+      FILE *file;
+      register rtx addr;
+ {
+   register rtx reg1, reg2, breg, ireg;
+   rtx offset;
+   static char *reg_name[] = REGISTER_NAMES;
+ 
+  retry:
+   switch (GET_CODE (addr))
+     {
+     case MEM:
+       fprintf (file, "*");
+       addr = XEXP (addr, 0);
+       goto retry;
+ 
+     case REG:
+       fprintf (file, "(%s)", reg_name [REGNO (addr)]);
+       break;
+ 
+     case PRE_DEC:
+       fprintf (file, "-(%s)", reg_name [REGNO (XEXP (addr, 0))]);
+       break;
+ 
+     case POST_INC:
+       fprintf (file, "(%s)+", reg_name [REGNO (XEXP (addr, 0))]);
+       break;
+ 
+     case PLUS:
+       reg1 = 0;	reg2 = 0;
+       ireg = 0;	breg = 0;
+       offset = 0;
+ 
+       if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
+ 	  && GET_CODE (XEXP (addr, 1)) == CONST_INT)
+ 	output_addr_const (file, addr);
+ 
+       if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
+ 	  && GET_CODE (XEXP (addr, 0)) == CONST_INT)
+ 	output_addr_const (file, addr);
+ 
+       if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
+ 	  || GET_CODE (XEXP (addr, 0)) == MEM)
+ 	{
+ 	  offset = XEXP (addr, 0);
+ 	  addr = XEXP (addr, 1);
+ 	}
+       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
+ 	       || GET_CODE (XEXP (addr, 1)) == MEM)
+ 	{
+ 	  offset = XEXP (addr, 1);
+ 	  addr = XEXP (addr, 0);
+ 	}
+       if (GET_CODE (addr) != PLUS)
+ 	;
+       else if (GET_CODE (XEXP (addr, 0)) == MULT)
+ 	{
+ 	  reg1 = XEXP (addr, 0);
+ 	  addr = XEXP (addr, 1);
+ 	}
+       else if (GET_CODE (XEXP (addr, 1)) == MULT)
+ 	{
+ 	  reg1 = XEXP (addr, 1);
+ 	  addr = XEXP (addr, 0);
+ 	}
+       else if (GET_CODE (XEXP (addr, 0)) == REG)
+ 	{
+ 	  reg1 = XEXP (addr, 0);
+ 	  addr = XEXP (addr, 1);
+ 	}
+       else if (GET_CODE (XEXP (addr, 1)) == REG)
+ 	{
+ 	  reg1 = XEXP (addr, 1);
+ 	  addr = XEXP (addr, 0);
+ 	}
+       if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
+ 	{
+ 	  if (reg1 == 0)
+ 	    reg1 = addr;
+ 	  else
+ 	    reg2 = addr;
+ 	  addr = 0;
+ 	}
+       if (offset != 0)
+ 	{
+ 	  if (addr != 0) abort ();
+ 	  addr = offset;
+ 	}
+       if (reg1 != 0 && GET_CODE (reg1) == MULT)
+ 	{
+ 	  breg = reg2;
+ 	  ireg = reg1;
+ 	}
+       else if (reg2 != 0 && GET_CODE (reg2) == MULT)
+ 	{
+ 	  breg = reg1;
+ 	  ireg = reg2;
+ 	}
+       else if (reg2 != 0 || GET_CODE (addr) == MEM)
+ 	{
+ 	  breg = reg2;
+ 	  ireg = reg1;
+ 	}
+       else
+ 	{
+ 	  breg = reg1;
+ 	  ireg = reg2;
+ 	}
+       if (addr != 0)
+ 	output_address (offset);
+       if (breg != 0)
+ 	{
+ 	  if (GET_CODE (breg) != REG)
+ 	    abort ();
+ 	  fprintf (file, "(%s)", reg_name[REGNO (breg)]);
+ 	}
+       if (ireg != 0)
+ 	{
+ 	  if (GET_CODE (ireg) == MULT)
+ 	    ireg = XEXP (ireg, 0);
+ 	  if (GET_CODE (ireg) != REG)
+ 	    abort ();
+ 	  fprintf (file, "[%s]", reg_name[REGNO (ireg)]);
+ 	}
+       break;
+ 
+     default:
+       output_addr_const (file, addr);
+     }
+ }
+ 
+ 
+ /* Do a quick check and find out what the best way to do the */
+ /* mini-move is. Could be a push or a move.....		     */
+ 
+ static char *
+ singlemove_string (operands)
+      rtx *operands;
+ {
+   if (GET_CODE (operands[0]) == MEM
+       && GET_CODE (XEXP (operands[0],0)) == PRE_DEC)
+     return "pushl %1";
+   return "movl %1,%0";
+ }
+ 
+ 
+ /* given the rtx for an address, return true if the given */
+ /* register number is used in the address somewhere.	  */
+ 
+ int
+ regisused (addr,regnum)
+      rtx addr;
+      int regnum;
+ {
+   if (GET_CODE (addr) == REG)
+     {
+       if (REGNO (addr) == regnum)
+ 	return (1);
+       else
+ 	return (0);
+     }
+ 
+   if (GET_CODE (addr) == MEM)
+     return regisused (XEXP (addr,0),regnum);
+ 
+   if (GET_CODE (addr) == MULT || GET_CODE (addr) == PLUS)
+     return (regisused (XEXP (addr,0),regnum)
+ 	    || regisused (XEXP (addr,1),regnum));
+ 
+   return 0;
+ }
+ 
+ 
+ /* Given some rtx, traverse it and return the register used in a */
+ /* index. If no index is found, return 0.			 */
+ 
+ rtx
+ index_reg (addr)
+      rtx addr;
+ {
+   rtx temp;
+ 
+   if (GET_CODE (addr) == MEM)
+     return index_reg (XEXP (addr,0));
+ 
+   if (GET_CODE (addr) == MULT)
+     {
+       if (GET_CODE (XEXP (addr,0)) == REG)
+ 	return XEXP (addr,0);
+       else
+ 	return XEXP (addr,1);
+     }
+ 
+   if (GET_CODE (addr) == PLUS)
+     {
+       if (temp = index_reg (XEXP (addr,0)))
+ 	return temp;
+       else
+ 	return index_reg (XEXP (addr,1));
+     }
+ 
+   return 0;
+ }
+ 
+ 
+ /* simulate the move double by generating two movl's. You have */
+ /* to be careful about mixing modes here. A future improvement */
+ /* would be to allow immediate doubles.			       */
+ 
+ char *
+ output_move_double (operands)
+      rtx *operands;
+ {
+   enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, INDOP, CNSTOP, RNDOP } optype0, optype1;
+   rtx latehalf[2];
+   rtx shftreg0 = 0, shftreg1 = 0;
+   rtx temp0 = 0, temp1 = 0;
+   rtx addreg0 = 0, addreg1 = 0;
+   int dohighfirst = 0;
+ 
+   /* First classify both operands. */
+ 
+   if (REG_P (operands[0]))
+     optype0 = REGOP;
+   else if ((GET_CODE (operands[0])==MEM) && (shftreg0=index_reg (operands[0])))
+     optype0 = INDOP;
+   else if (offsettable_memref_p (operands[0]))
+     optype0 = OFFSOP;
+   else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
+     {
+       optype0 = PUSHOP;
+       dohighfirst++;
+     }
+   else if (GET_CODE (operands[0]) == MEM)
+     optype0 = MEMOP;
+   else
+     optype0 = RNDOP;
+ 
+   if (REG_P (operands[1]))
+     optype1 = REGOP;
+   else if ((GET_CODE (operands[1])==MEM) && (shftreg1=index_reg (operands[1])))
+     optype1 = INDOP;
+   else if (offsettable_memref_p (operands[1]))
+     optype1 = OFFSOP;
+   else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
+     optype1 = POPOP; 
+   else if (GET_CODE (operands[1]) == MEM)
+     optype1 = MEMOP;
+   else if (GET_CODE (operands[1]) == CONST_DOUBLE || CONSTANT_P (operands[1]))
+     optype1 = CNSTOP;
+   else
+     optype1 = RNDOP;
+ 
+   /* set up for the high byte move for operand zero */
+ 
+   switch (optype0)
+     {
+ 
+       /* if it's a register, just use the next highest in the */
+       /* high address move.					*/
+ 
+     case REGOP:
+       latehalf[0] = gen_rtx (REG,SImode,REGNO (operands[0])+1);
+       break;
+ 
+       /* for an offsettable address, use the gcc function to  */
+       /* modify the operand to get an offset of 4 higher for  */
+       /* the second move.					*/
+ 
+     case OFFSOP:
+       latehalf[0] = adj_offsettable_operand (operands[0], 4);
+       break;
+ 
+       /* if the operand is MEMOP type, it must be a pointer	*/
+       /* to a pointer. So just remember to increase the mem	*/
+       /* location and use the same operand.			*/
+ 
+     case MEMOP:
+       latehalf[0] = operands[0];
+       addreg0 = XEXP (operands[0],0);
+       break;
+ 
+       /* if we're dealing with a push instruction, just leave */
+       /* the operand alone since it auto-increments.		*/
+ 
+     case PUSHOP:
+       latehalf[0] = operands[0];
+       break;
+ 
+       /* YUCK! Indexed addressing!! If the address is considered   */
+       /* offsettable, go use the offset in the high part. Otherwise */
+       /* find what exactly is being added to the mutiplication. If */
+       /* it's a mem reference, increment that with the high part   */
+       /* being unchanged to cause the shift. If it's a reg, do the */
+       /* same. If you can't identify it, abort. Remember that the  */
+       /* shift register was already set during identification.     */
+ 
+     case INDOP:
+       if (offsettable_memref_p (operands[0]))
+ 	{
+ 	  latehalf[0] = adj_offsettable_operand (operands[0],4);
+ 	  break;
+ 	}
+ 
+       latehalf[0] = operands[0];
+ 
+       temp0 = XEXP (XEXP (operands[0],0),0);
+       if (GET_CODE (temp0) == MULT)
+ 	{
+ 	  temp1 = temp0;
+ 	  temp0 = XEXP (XEXP (operands[0],0),1);
+ 	}
+       else
+ 	{
+ 	  temp1 = XEXP (XEXP (operands[0],0),1);
+ 	  if (GET_CODE (temp1) != MULT)
+ 	    abort ();
+ 	}
+ 
+       if (GET_CODE (temp0) == MEM)
+ 	addreg0 = temp0;
+       else if (GET_CODE (temp0) == REG)
+ 	addreg0 = temp0;
+       else
+ 	abort ();
+ 
+       break;
+ 
+       /* if we don't know the operand type, print a friendly  */
+       /* little error message...   8-)			*/
+ 
+     case RNDOP:
+       default:
+       abort ();
+     }
+ 
+   /* do the same setup for operand one */
+ 
+   switch (optype1)
+     {
+ 
+     case REGOP:
+       latehalf[1] = gen_rtx (REG,SImode,REGNO (operands[1])+1);
+       break;
+ 
+     case OFFSOP:
+       latehalf[1] = adj_offsettable_operand (operands[1], 4);
+       break;
+ 
+     case MEMOP:
+       latehalf[1] = operands[1];
+       addreg1 = XEXP (operands[1],0);
+       break;
+ 
+     case POPOP:
+       latehalf[1] = operands[1];
+       break;
+ 
+     case INDOP:
+       if (offsettable_memref_p (operands[1]))
+ 	{
+ 	  latehalf[1] = adj_offsettable_operand (operands[1],4);
+ 	  break;
+ 	}
+ 
+       latehalf[1] = operands[1];
+ 
+       temp0 = XEXP (XEXP (operands[1],0),0);
+       if (GET_CODE (temp0) == MULT)
+ 	{
+ 	  temp1 = temp0;
+ 	  temp0 = XEXP (XEXP (operands[1],0),1);
+ 	}
+       else
+ 	{
+ 	  temp1 = XEXP (XEXP (operands[1],0),1);
+ 	  if (GET_CODE (temp1) != MULT)
+ 	    abort ();
+ 	}
+ 
+       if (GET_CODE (temp0) == MEM)
+ 	addreg1 = temp0;
+       else if (GET_CODE (temp0) == REG)
+ 	addreg1 = temp0;
+       else
+ 	abort ();
+ 
+       break;
+ 
+     case CNSTOP:
+       /* Since this machine is big-endian,
+ 	 the late half must be the low-order word for an integer,
+ 	 or the latter word for a float.  */
+       if (GET_CODE (operands[1]) == CONST_DOUBLE)
+ 	{
+ 	  if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_FLOAT)
+ 	    {
+ 	      latehalf[1] = gen_rtx (CONST_INT, VOIDmode,
+ 				     CONST_DOUBLE_HIGH (operands[1]));
+ 	      operands[1] = gen_rtx (CONST_INT, VOIDmode,
+ 				     CONST_DOUBLE_LOW (operands[1]));
+ 	    }
+ 	  else
+ 	    {
+ 	      latehalf[1] = gen_rtx (CONST_INT, VOIDmode,
+ 				     CONST_DOUBLE_LOW (operands[1]));
+ 	      operands[1] = gen_rtx (CONST_INT, VOIDmode,
+ 				     CONST_DOUBLE_HIGH (operands[1]));
+ 	    }
+ 	}
+       else
+ 	{
+ 	  latehalf[1] = operands[1];
+ 	  operands[1] = const0_rtx;
+ 	}
+       break;
+ 
+     case RNDOP:
+     default:
+       abort ();
+     }
+ 
+ 
+   /* double the register used for shifting in both of the operands */
+   /* but make sure the same register isn't doubled twice!	   */
+ 
+   if (shftreg0 && shftreg1 && rtx_equal_p (shftreg0, shftreg1))
+     output_asm_insn ("addl2 %0,%0", &shftreg0);
+   else
+     {
+       if (shftreg0)
+ 	output_asm_insn ("addl2 %0,%0", &shftreg0);
+       if (shftreg1)
+ 	output_asm_insn ("addl2 %0,%0", &shftreg1);
+     }
+ 
+   /* if the destination is a register and that register is needed in  */
+   /* the source addressing mode, swap the order of the moves since we */
+   /* don't want this destroyed til last. If both regs are used, not   */
+   /* much we can do, so abort. If these becomes a problem, maybe we   */
+   /* can do it on the stack?					      */
+ 
+   if (GET_CODE (operands[0])==REG && regisused (operands[1],REGNO (operands[0])))
+     if (regisused (latehalf[1],REGNO (latehalf[0])))
+       8;
+     else
+       dohighfirst++;
+ 
+   /* if we're pushing, do the high address part first. */
+ 
+   if (dohighfirst)
+     {
+ 
+       if (addreg0 && addreg1 && (rtx_equal_p (addreg0,addreg1)))
+ 	output_asm_insn ("addl2 $4,%0", &addreg0);
+       else
+ 	{
+ 	  if (addreg0)
+ 	    output_asm_insn ("addl2 $4,%0", &addreg0);
+ 	  if (addreg1)
+ 	    output_asm_insn ("addl2 $4,%0", &addreg1);
+ 	}
+ 
+       output_asm_insn (singlemove_string (latehalf), latehalf);
+ 
+       if (addreg0 && addreg1 && (rtx_equal_p (addreg0,addreg1)))
+ 	output_asm_insn ("subl2 $4,%0", &addreg0);
+       else
+ 	{
+ 	  if (addreg0)
+ 	    output_asm_insn ("subl2 $4,%0", &addreg0);
+ 	  if (addreg1)
+ 	    output_asm_insn ("subl2 $4,%0", &addreg1);
+ 	}
+ 
+       return singlemove_string (operands);
+     }
+ 
+   output_asm_insn (singlemove_string (operands), operands);
+ 
+   if (addreg0 && addreg1 && (rtx_equal_p (addreg0,addreg1)))
+     output_asm_insn ("addl2 $4,%0", &addreg0);
+   else
+     {
+       if (addreg0)
+ 	output_asm_insn ("addl2 $4,%0", &addreg0);
+       if (addreg1)
+ 	output_asm_insn ("addl2 $4,%0", &addreg1);
+     }
+ 
+   output_asm_insn (singlemove_string (latehalf), latehalf);
+ 
+   if (addreg0 && addreg1 && (rtx_equal_p (addreg0,addreg1)))
+     output_asm_insn ("subl2 $4,%0", &addreg0);
+   else
+     {
+       if (addreg0)
+ 	output_asm_insn ("subl2 $4,%0", &addreg0);
+       if (addreg1)
+ 	output_asm_insn ("subl2 $4,%0", &addreg1);
+     }
+ 
+   if (shftreg0 && shftreg1 && (rtx_equal_p (shftreg0,shftreg1)))
+     output_asm_insn ("shar $1,%0,%0", &shftreg0);
+   else
+     {
+       if (shftreg0)
+ 	output_asm_insn ("shar $1,%0,%0", &shftreg0);
+       if (shftreg1)
+ 	output_asm_insn ("shar $1,%0,%0", &shftreg1);
+     }
+ 
+   return "";
+ }
diff -rc2N gcc-1.35/config/pyr.md gcc-1.36/config/pyr.md
*** gcc-1.35/config/pyr.md	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config/pyr.md	Fri Sep 22 17:47:50 1989
***************
*** 0 ****
--- 1,1461 ----
+ ;; Machine description for Pyramid 90 Series for GNU C compiler
+ ;; Copyright (C) 1989 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+ 
+ ;; Instruction patterns.  When multiple patterns apply,
+ ;; the first one in the file is chosen.
+ ;;
+ ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
+ ;;
+ ;; cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
+ ;; updates for most instructions.
+ \f


+ ;; * Should we check for SUBREG as well as REG, in some places???
+ ;; * Make the jump tables contain branches, not addresses!  This would
+ ;;   save us one instruction.
+ ;; * Could the compilcated scheme for compares be simplyfied, if we had
+ ;;   no named cmpqi or cmphi patterns, and instead anonymous patterns for
+ ;;   the less-than-word compare cases pyr can handle???
+ ;; * The jump insn seems to accept more than just IR addressing.  Would
+ ;;   we win by telling GCC?
+ ;; * More DImode patterns.
+ ;; * Expansion of "cmpsi" is not necessary.  Also, some define_insn could
+ ;;   be taken away if constraints were used.
+ ;; * Scan backwards in "zero_extendhisi2", "zero_extendqisi2" to find out
+ ;;   if the extension can be omitted.  Also improve the scan (now in the sign
+ ;;   extenstion patterns), to handle more cases than extension regx->regx.
+ ;; * Enhance NOTICE_UPDATE_CC.  1) Should not be reset by insn that don't
+ ;;   modify cc.  2) cc is preserved by CALL.
+ ;; * "divmodsi" with Pyramid "ediv" insn.  Is it possible in rtl??
+ ;; * Would "rcsp tmpreg; u?cmp[bh] op1_regdispl(tmpreg),op2" win in
+ ;;   comparison with the two extensions and single test generated now?
+ ;;   The rcsp insn could be expanded, and moved out of loops by the
+ ;;   optimizer, making 1 (64 bit) insn of 3 (32 bit) insns in loops.
+ ;;   The rcsp insn could be followed by an add insn, making non-displacement
+ ;;   IR addressing sufficient.
+ 
+ ;______________________________________________________________________
+ ;
+ ;	Test and Compare Patterns.
+ ;______________________________________________________________________
+ 
+ (define_expand "cmpsi"
+   [(set (cc0)
+ 	(compare (match_operand:SI 0 "general_operand" "")
+ 		 (match_operand:SI 1 "general_operand" "")))]
+   ""
+   "
+ {
+   extern rtx test_op0, test_op1;
+   test_op0 = copy_rtx (operands[0]);
+   test_op1 = copy_rtx (operands[1]);
+   DONE;
+ }")
+ 
+ (define_expand "tstsi"
+   [(set (cc0)
+ 	(match_operand:SI 0 "general_operand" ""))]
+   ""
+   "
+ {
+   extern rtx test_op0, test_op1;
+   test_op0 = copy_rtx (operands[0]);
+   DONE;
+ }")
+ 
+ (define_insn ""
+   [(set (cc0)
+ 	(compare (match_operand:SI 0 "memory_operand" "m")
+ 		 (match_operand:SI 1 "memory_operand" "m")))]
+   "weird_memory_memory (operands[0], operands[1])"
+   "*
+ {
+   rtx br_insn = NEXT_INSN (insn);
+   RTX_CODE br_code;
+ 
+   if (GET_CODE (br_insn) != JUMP_INSN)
+     abort();
+   br_code =  GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
+ 
+   weird_memory_memory (operands[0], operands[1]);
+ 
+   if (swap_operands == 0)
+     return (br_code >= GEU && br_code <= LTU
+ 	    ? \"ucmpw %1,%0\" : \"cmpw %1,%0\");
+   else
+     {
+       cc_status.flags |= CC_REVERSED;
+       return (br_code >= GEU && br_code <= LTU
+ 	      ? \"ucmpw %0,%1\" : \"cmpw %0,%1\");
+     }
+ }")
+ 
+ (define_insn ""
+   [(set (cc0)
+ 	(compare (match_operand:SI 0 "general_operand" "r,g")
+ 		 (match_operand:SI 1 "general_operand" "g,r")))]
+   ""
+   "*
+ {
+   rtx br_insn = NEXT_INSN (insn);
+   RTX_CODE br_code;
+ 
+   if (GET_CODE (br_insn) != JUMP_INSN)
+     abort();
+   br_code =  GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
+ 
+   if (which_alternative == 0)
+     return (br_code >= GEU && br_code <= LTU)
+       ? \"ucmpw %1,%0\" : \"cmpw %1,%0\";
+   else
+     {
+       cc_status.flags |= CC_REVERSED;
+       return (br_code >= GEU && br_code <= LTU)
+ 	? \"ucmpw %0,%1\" : \"cmpw %0,%1\";
+     }
+ }")
+ 
+ (define_insn ""
+   [(set (cc0)
+ 	(match_operand:SI 0 "register_operand" "r"))]
+   ""
+   "mtstw %0,%0")
+ 
+ (define_expand "cmphi"
+   [(set (cc0)
+ 	(compare (match_operand:HI 0 "general_operand" "")
+ 		 (match_operand:HI 1 "general_operand" "")))]
+   ""
+   "
+ {
+   extern rtx test_op0, test_op1;
+   test_op0 = copy_rtx (operands[0]);
+   test_op1 = copy_rtx (operands[1]);
+   DONE;
+ }")
+ 
+ (define_expand "tsthi"
+   [(set (cc0)
+ 	(match_operand:HI 0 "general_operand" ""))]
+   ""
+   "
+ {
+   extern rtx test_op0, test_op1;
+   test_op0 = copy_rtx (operands[0]);
+   DONE;
+ }")
+ 
+ (define_insn ""
+   [(set (cc0)
+ 	(compare (match_operand:HI 0 "memory_operand" "m")
+ 		 (match_operand:HI 1 "memory_operand" "m")))]
+   "weird_memory_memory (operands[0], operands[1])"
+   "*
+ {
+   rtx br_insn = NEXT_INSN (insn);
+ 
+   if (GET_CODE (br_insn) != JUMP_INSN)
+     abort();
+ 
+   weird_memory_memory (operands[0], operands[1]);
+ 
+   if (swap_operands == 0)
+     return \"cmph %1,%0\";
+   else
+     {
+       cc_status.flags |= CC_REVERSED;
+       return \"cmph %0,%1\";
+     }
+ }")
+ 
+ (define_insn ""
+   [(set (cc0)
+ 	(compare (match_operand:HI 0 "nonimmediate_operand" "r,m")
+ 		 (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
+   ""
+   "*
+ {
+   rtx br_insn = NEXT_INSN (insn);
+ 
+   if (GET_CODE (br_insn) != JUMP_INSN)
+     abort();
+ 
+   if (which_alternative == 0)
+     return \"cmph %1,%0\";
+   else
+     {
+       cc_status.flags |= CC_REVERSED;
+       return \"cmph %0,%1\";
+     }
+ }")
+ 
+ (define_expand "cmpqi"
+   [(set (cc0)
+ 	(compare (match_operand:QI 0 "general_operand" "")
+ 		 (match_operand:QI 1 "general_operand" "")))]
+   ""
+   "
+ {
+   extern rtx test_op0, test_op1;
+   test_op0 = copy_rtx (operands[0]);
+   test_op1 = copy_rtx (operands[1]);
+   DONE;
+ }")
+ 
+ (define_expand "tstqi"
+   [(set (cc0)
+ 	(match_operand:QI 0 "general_operand" ""))]
+   ""
+   "
+ {
+   extern rtx test_op0, test_op1;
+   test_op0 = copy_rtx (operands[0]);
+   DONE;
+ }")
+ 
+ (define_insn ""
+   [(set (cc0)
+ 	(compare (match_operand:QI 0 "memory_operand" "m")
+ 		 (match_operand:QI 1 "memory_operand" "m")))]
+   "weird_memory_memory (operands[0], operands[1])"
+   "*
+ {
+   rtx br_insn = NEXT_INSN (insn);
+   RTX_CODE br_code;
+ 
+   if (GET_CODE (br_insn) != JUMP_INSN)
+     abort();
+   br_code =  GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
+ 
+   weird_memory_memory (operands[0], operands[1]);
+ 
+   if (swap_operands == 0)
+     return (br_code >= GEU && br_code <= LTU
+ 	    ? \"ucmpb %1,%0\" : \"cmpb %1,%0\");
+   else
+     {
+       cc_status.flags |= CC_REVERSED;
+       return (br_code >= GEU && br_code <= LTU
+ 	      ? \"ucmpb %0,%1\" : \"cmpb %0,%1\");
+     }
+ }")
+ 
+ (define_insn ""
+   [(set (cc0)
+ 	(compare (match_operand:QI 0 "nonimmediate_operand" "r,m")
+ 		 (match_operand:QI 1 "nonimmediate_operand" "m,r")))]
+   ""
+   "*
+ {
+   rtx br_insn = NEXT_INSN (insn);
+   RTX_CODE br_code;
+ 
+   if (GET_CODE (br_insn) != JUMP_INSN)
+     abort();
+   br_code =  GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
+ 
+   if (which_alternative == 0)
+     return (br_code >= GEU && br_code <= LTU)
+       ? \"ucmpb %1,%0\" : \"cmpb %1,%0\";
+   else
+     {
+       cc_status.flags |= CC_REVERSED;
+       return (br_code >= GEU && br_code <= LTU)
+ 	? \"ucmpb %0,%1\" : \"cmpb %0,%1\";
+     }
+ }")
+ 
+ (define_expand "bgt"
+   [(set (pc) (if_then_else (gt (cc0) (const_int 0))
+ 			   (label_ref (match_operand 0 "" "")) (pc)))]
+   "" "extend_and_branch (SIGN_EXTEND);")
+ 
+ (define_expand "blt"
+   [(set (pc) (if_then_else (lt (cc0) (const_int 0))
+ 			   (label_ref (match_operand 0 "" "")) (pc)))]
+   "" "extend_and_branch (SIGN_EXTEND);")
+ 
+ (define_expand "bge"
+   [(set (pc) (if_then_else (ge (cc0) (const_int 0))
+ 			   (label_ref (match_operand 0 "" "")) (pc)))]
+   "" "extend_and_branch (SIGN_EXTEND);")
+ 
+ (define_expand "ble"
+   [(set (pc) (if_then_else (le (cc0) (const_int 0))
+ 			   (label_ref (match_operand 0 "" "")) (pc)))]
+   "" "extend_and_branch (SIGN_EXTEND);")
+ 
+ (define_expand "beq"
+   [(set (pc) (if_then_else (eq (cc0) (const_int 0))
+ 			   (label_ref (match_operand 0 "" "")) (pc)))]
+   "" "extend_and_branch (SIGN_EXTEND);")
+ 
+ (define_expand "bne"
+   [(set (pc) (if_then_else (ne (cc0) (const_int 0))
+ 			   (label_ref (match_operand 0 "" "")) (pc)))]
+   "" "extend_and_branch (SIGN_EXTEND);")
+ 
+ (define_expand "bgtu"
+   [(set (pc) (if_then_else (gtu (cc0) (const_int 0))
+ 			   (label_ref (match_operand 0 "" "")) (pc)))]
+   "" "extend_and_branch (ZERO_EXTEND);")
+ 
+ (define_expand "bltu"
+   [(set (pc) (if_then_else (ltu (cc0) (const_int 0))
+ 			   (label_ref (match_operand 0 "" "")) (pc)))]
+   "" "extend_and_branch (ZERO_EXTEND);")
+ 
+ (define_expand "bgeu"
+   [(set (pc) (if_then_else (geu (cc0) (const_int 0))
+ 			   (label_ref (match_operand 0 "" "")) (pc)))]
+   "" "extend_and_branch (ZERO_EXTEND);")
+ 
+ (define_expand "bleu"
+   [(set (pc) (if_then_else (leu (cc0) (const_int 0))
+ 			   (label_ref (match_operand 0 "" "")) (pc)))]
+   "" "extend_and_branch (ZERO_EXTEND);")
+ 
+ (define_insn "cmpdf"
+   [(set (cc0)
+ 	(compare (match_operand:DF 0 "register_operand" "r")
+ 		 (match_operand:DF 1 "register_operand" "r")))]
+   ""
+   "cmpd %1,%0")
+ 
+ (define_insn "cmpsf"
+   [(set (cc0)
+ 	(compare (match_operand:SF 0 "register_operand" "r")
+ 		 (match_operand:SF 1 "register_operand" "r")))]
+   ""
+   "cmpf %1,%0")
+ 
+ (define_insn "tstdf"
+   [(set (cc0)
+        	(match_operand:DF 0 "register_operand" "r"))]
+   ""
+   "mtstd %0,%0")
+ 
+ (define_insn "tstsf"
+   [(set (cc0)
+        	(match_operand:SF 0 "register_operand" "r"))]
+   ""
+   "mtstf %0,%0")
+ \f


+ ;______________________________________________________________________
+ ;
+ ;	Fixed-point Arithmetic.
+ ;______________________________________________________________________
+ 
+ (define_insn "addsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r,!r")
+ 	(plus:SI (match_operand:SI 1 "register_operand" "%0,r")
+ 		 (match_operand:SI 2 "general_operand" "g,rJ")))]
+   ""
+   "*
+ {
+   if (which_alternative == 0)
+     return \"addw %2,%0\";
+   else
+     {
+       CC_STATUS_INIT;
+       if (REG_P (operands[2]))
+ 	return \"mova (%2)[%1*1],%0\";
+       else
+ 	return \"mova %a2[%1*1],%0\";
+     }
+ }")
+ 
+ (define_insn "subsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r,r")
+ 	(minus:SI (match_operand:SI 1 "general_operand" "0,g")
+ 		  (match_operand:SI 2 "general_operand" "g,0")))]
+   ""
+   "*
+ {
+   if (which_alternative == 0)
+     return \"subw %2,%0\";
+   else
+     return \"rsubw %1,%0\";
+ }")
+ 
+ (define_insn "mulsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(mult:SI (match_operand:SI 1 "register_operand" "%0")
+ 		 (match_operand:SI 2 "general_operand" "g")))]
+   ""
+   "mulw %2,%0")
+ 
+ (define_insn "umulsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(umult:SI (match_operand:SI 1 "register_operand" "%0")
+ 		  (match_operand:SI 2 "general_operand" "g")))]
+   ""
+   "umulw %2,%0")
+ 
+ (define_insn "divsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r,r")
+ 	(div:SI (match_operand:SI 1 "general_operand" "0,g")
+ 		(match_operand:SI 2 "general_operand" "g,0")))]
+   ""
+   "*
+ {
+   if (which_alternative == 0)
+     return \"divw %2,%0\";
+   else
+     return \"rdivw %1,%0\";
+ }")
+ 
+ (define_insn "udivsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(udiv:SI (match_operand:SI 1 "register_operand" "0")
+ 		 (match_operand:SI 2 "general_operand" "g")))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   return \"udivw %2,%0\";
+ }")
+ 
+ (define_insn "modsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(mod:SI (match_operand:SI 1 "register_operand" "0")
+ 		(match_operand:SI 2 "general_operand" "g")))]
+   ""
+   "modw %2,%0")
+ 
+ (define_insn "umodsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(umod:SI (match_operand:SI 1 "register_operand" "0")
+ 		 (match_operand:SI 2 "general_operand" "g")))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   return \"umodw %2,%0\";
+ }")
+ 
+ (define_insn "negsi2"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(neg:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
+   ""
+   "mnegw %1,%0")
+ 
+ (define_insn "one_cmplsi2"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(not:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
+   ""
+   "mcomw %1,%0")
+ 
+ (define_insn "abssi2"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(abs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
+   ""
+   "mabsw %1,%0")
+ \f


+ ;______________________________________________________________________
+ ;
+ ;	Floating-point Arithmetic.
+ ;______________________________________________________________________
+ 
+ (define_insn "adddf3"
+   [(set (match_operand:DF 0 "register_operand" "=r")
+ 	(plus:DF (match_operand:DF 1 "register_operand" "%0")
+ 		 (match_operand:DF 2 "register_operand" "r")))]
+   ""
+   "addd %2,%0")
+ 
+ (define_insn "addsf3"
+   [(set (match_operand:SF 0 "register_operand" "=r")
+ 	(plus:SF (match_operand:SF 1 "register_operand" "%0")
+ 		 (match_operand:SF 2 "register_operand" "r")))]
+   ""
+   "addf %2,%0")
+ 
+ (define_insn "subdf3"
+   [(set (match_operand:DF 0 "register_operand" "=r")
+ 	(minus:DF (match_operand:DF 1 "register_operand" "0")
+ 		  (match_operand:DF 2 "register_operand" "r")))]
+   ""
+   "subd %2,%0")
+ 
+ (define_insn "subsf3"
+   [(set (match_operand:SF 0 "register_operand" "=r")
+ 	(minus:SF (match_operand:SF 1 "register_operand" "0")
+ 		  (match_operand:SF 2 "register_operand" "r")))]
+   ""
+   "subf %2,%0")
+ 
+ (define_insn "muldf3"
+   [(set (match_operand:DF 0 "register_operand" "=r")
+ 	(mult:DF (match_operand:DF 1 "register_operand" "%0")
+ 		 (match_operand:DF 2 "register_operand" "r")))]
+   ""
+   "muld %2,%0")
+ 
+ (define_insn "mulsf3"
+   [(set (match_operand:SF 0 "register_operand" "=r")
+ 	(mult:SF (match_operand:SF 1 "register_operand" "%0")
+ 		 (match_operand:SF 2 "register_operand" "r")))]
+   ""
+   "mulf %2,%0")
+ 
+ (define_insn "divdf3"
+   [(set (match_operand:DF 0 "register_operand" "=r")
+ 	(div:DF (match_operand:DF 1 "register_operand" "0")
+ 		(match_operand:DF 2 "register_operand" "r")))]
+   ""
+   "divd %2,%0")
+ 
+ (define_insn "divsf3"
+   [(set (match_operand:SF 0 "register_operand" "=r")
+ 	(div:SF (match_operand:SF 1 "register_operand" "0")
+ 		(match_operand:SF 2 "register_operand" "r")))]
+   ""
+   "divf %2,%0")
+ 
+ (define_insn "negdf2"
+   [(set (match_operand:DF 0 "register_operand" "=r")
+ 	(neg:DF (match_operand:DF 1 "register_operand" "r")))]
+   ""
+   "mnegd %1,%0")
+ 
+ (define_insn "negsf2"
+   [(set (match_operand:SF 0 "register_operand" "=r")
+ 	(neg:SF (match_operand:SF 1 "register_operand" "r")))]
+   ""
+   "mnegf %1,%0")
+ 
+ (define_insn "absdf2"
+   [(set (match_operand:DF 0 "register_operand" "=r")
+ 	(abs:DF (match_operand:DF 1 "register_operand" "r")))]
+   ""
+   "mabsd %1,%0")
+ 
+ (define_insn "abssf2"
+   [(set (match_operand:SF 0 "register_operand" "=r")
+ 	(abs:SF (match_operand:SF 1 "register_operand" "r")))]
+   ""
+   "mabsf %1,%0")
+ \f


+ ;______________________________________________________________________
+ ;
+ ;	Logical and Shift Instructions.
+ ;______________________________________________________________________
+ 
+ (define_insn ""
+   [(set (cc0)
+ 	(and:SI (match_operand:SI 0 "register_operand" "%r")
+ 		(match_operand:SI 1 "general_operand" "g")))]
+   ""
+   "bitw %1,%0");
+ 
+ (define_insn "andsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r,r")
+ 	(and:SI (match_operand:SI 1 "register_operand" "%0,r")
+ 		(match_operand:SI 2 "general_operand" "g,K")))]
+   ""
+   "*
+ {
+   if (which_alternative == 0)
+     return \"andw %2,%0\";
+   else
+     {
+       CC_STATUS_INIT;
+       return (INTVAL (operands[2]) == 255
+ 	      ? \"movzbw %1,%0\" : \"movzhw %1,%0\");
+     }
+ }")
+ 
+ (define_insn "andcbsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(and:SI (match_operand:SI 1 "register_operand" "0")
+ 		(not:SI (match_operand:SI 2 "general_operand" "g"))))]
+   ""
+   "bicw %2,%0")
+ 
+ (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(and:SI (not:SI (match_operand:SI 1 "general_operand" "g"))
+ 		(match_operand:SI 2 "register_operand" "0")))]
+   ""
+   "bicw %1,%0")
+ 
+ (define_insn "iorsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(ior:SI (match_operand:SI 1 "register_operand" "%0")
+ 		(match_operand:SI 2 "general_operand" "g")))]
+   ""
+   "orw %2,%0")
+ 
+ (define_insn "xorsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(xor:SI (match_operand:SI 1 "register_operand" "%0")
+ 		(match_operand:SI 2 "general_operand" "g")))]
+   ""
+   "xorw %2,%0")
+ 
+ ; Some patterns using De Morgan law.
+ ;
+ ;(define_insn ""
+ ;  [(set (match_operand:SI 0 "register_operand" "=r")
+ ;	(not:SI (and:SI (not:SI (match_operand:SI 1 "register_operand" "%0"))
+ ;			(not:SI (match_operand:SI 2 "general_operand" "g")))))]
+ ;  ""
+ ;  "orw %2,%0")
+ ;
+ ;(define_insn ""
+ ;  [(set (match_operand:SI 0 "register_operand" "=r")
+ ;	(not:SI (ior:SI (not:SI (match_operand:SI 1 "register_operand" "%0"))
+ ;			(not:SI (match_operand:SI 2 "general_operand" "g")))))]
+ ;  ""
+ ;  "andw %2,%0")
+ ;
+ ;(define_insn ""
+ ;  [(set (match_operand:SI 0 "register_operand" "=r")
+ ;	(not:SI (and:SI (not:SI (match_operand:SI 1 "register_operand" "0"))
+ ;			(match_operand:SI 2 "immediate_operand" "n"))))]
+ ;  ""
+ ;  "*
+ ;  operands[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
+ ;  return \"orw %2,%0\";
+ ;")
+ ;
+ ;(define_insn ""
+ ;  [(set (match_operand:SI 0 "register_operand" "=r")
+ ;	(not:SI (ior:SI (not:SI (match_operand:SI 1 "register_operand" "0"))
+ ;			(match_operand:SI 2 "immediate_operand" "n"))))]
+ ;  ""
+ ;  "*
+ ;  operands[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
+ ;  return \"andw %2,%0\";
+ ;")
+ 
+ (define_insn "ashlsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(ashift:SI (match_operand:SI 1 "register_operand" "0")
+ 		   (match_operand:SI 2 "general_operand" "rnm")))]
+   ""
+   "*
+ {
+   if (GET_CODE (operands[2]) == CONST_INT)
+     {
+       int cnt = INTVAL (operands[2]) % 32;
+       if (cnt == 0)
+ 	  return \"\";
+       operands[2] = gen_rtx (CONST_INT, VOIDmode, cnt);
+     }
+   /* Use lshlw, not ashlw, since arithmetic shifts work strangely on pyr.  */
+   return \"lshlw %2,%0\";
+ }")
+ 
+ ; The arithmetic left shift instructions work strange on pyramids.
+ ; They fail to modify the sign bit.
+ ;(define_insn "ashldi3"
+ ;  [(set (match_operand:DI 0 "register_operand" "=r")
+ ;	(ashift:DI (match_operand:DI 1 "register_operand" "0")
+ ;		   (match_operand:SI 2 "general_operand" "rnm")))]
+ ;  ""
+ ;  "*
+ ;{
+ ;  if (GET_CODE (operands[2]) == CONST_INT)
+ ;    {
+ ;      int cnt = INTVAL (operands[2]) % 64;
+ ;      if (cnt == 0)
+ ;	  return \"\";
+ ;      operands[2] = gen_rtx (CONST_INT, VOIDmode, cnt);
+ ;    }
+ ;  return \"ashll %2,%0\";
+ ;}")
+ 
+ (define_insn "ashrsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
+ 		     (match_operand:SI 2 "general_operand" "rnm")))]
+   ""
+   "*
+ {
+   if (GET_CODE (operands[2]) == CONST_INT)
+     {
+       int cnt = INTVAL (operands[2]) % 32;
+       if (cnt == 0)
+ 	  return \"\";
+       operands[2] = gen_rtx (CONST_INT, VOIDmode, cnt);
+     }
+   return \"ashrw %2,%0\";
+ }")
+ 
+ (define_insn "ashrdi3"
+   [(set (match_operand:DI 0 "register_operand" "=r")
+ 	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
+ 		     (match_operand:SI 2 "general_operand" "rnm")))]
+   ""
+   "*
+ {
+   if (GET_CODE (operands[2]) == CONST_INT)
+     {
+       int cnt = INTVAL (operands[2]) % 64;
+       if (cnt == 0)
+ 	return \"\";
+       operands[2] = gen_rtx (CONST_INT, VOIDmode, cnt);
+     }
+   return \"ashrl %2,%0\";
+ }")
+ 
+ (define_insn "lshrsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
+ 		     (match_operand:SI 2 "general_operand" "rnm")))]
+   ""
+   "*
+ {
+   if (GET_CODE (operands[2]) == CONST_INT)
+     {
+       int cnt = INTVAL (operands[2]) % 32;
+       if (cnt == 0)
+ 	  return \"\";
+       operands[2] = gen_rtx (CONST_INT, VOIDmode, cnt);
+     }
+   return \"lshrw %2,%0\";
+ }")
+ 
+ (define_insn "rotlsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(rotate:SI (match_operand:SI 1 "register_operand" "0")
+ 		   (match_operand:SI 2 "general_operand" "rnm")))]
+   ""
+   "*
+ {
+   if (GET_CODE (operands[2]) == CONST_INT)
+     {
+       int cnt = INTVAL (operands[2]) % 32;
+       if (cnt == 0)
+ 	  return \"\";
+       operands[2] = gen_rtx (CONST_INT, VOIDmode, cnt);
+     }
+   return \"rotlw %2,%0\";
+ }")
+ 
+ (define_insn "rotrsi3"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(rotatert:SI (match_operand:SI 1 "register_operand" "0")
+ 		     (match_operand:SI 2 "general_operand" "rnm")))]
+   ""
+   "*
+ {
+   if (GET_CODE (operands[2]) == CONST_INT)
+     {
+       int cnt = INTVAL (operands[2]) % 32;
+       if (cnt == 0)
+ 	  return \"\";
+       operands[2] = gen_rtx (CONST_INT, VOIDmode, cnt);
+     }
+   return \"rotrw %2,%0\";
+ }")
+ \f


+ ;______________________________________________________________________
+ ;
+ ;	Fixed and Floating Moves.
+ ;______________________________________________________________________
+ 
+ ;; If the destination is a memory address, indexed source operands are
+ ;; disallowed.  Big DImode constants are always loaded into a reg pair,
+ ;; although offsetable memory addresses really could be dealt with.
+ 
+ (define_insn ""
+   [(set (match_operand:DI 0 "memory_operand" "=m")
+ 	(match_operand:DI 1 "nonindexed_operand" "gF"))]
+   "(GET_CODE (operands[1]) == CONST_DOUBLE
+     ? CONST_DOUBLE_HIGH (operands[1]) == 0
+     : 1)"
+   "*
+ {
+   CC_STATUS_INIT;
+   if (GET_CODE (operands[1]) == CONST_DOUBLE)
+     operands[1] = gen_rtx (CONST_INT, VOIDmode,
+ 				      CONST_DOUBLE_LOW (operands[1]));
+   return \"movl %1,%0\";
+ }")
+ 
+ ;; Force the destination to a register, so all source operands are allowed.
+ 
+ (define_insn "movdi"
+   [(set (match_operand:DI 0 "general_operand" "=r")
+ 	(match_operand:DI 1 "general_operand" "gF"))]
+   ""
+   "* return output_move_double (operands); ")
+ 
+ ;; If the destination is a memory address, indexed operands are disallowed.
+ 
+ (define_insn ""
+   [(set (match_operand:SI 0 "memory_operand" "=m")
+ 	(match_operand:SI 1 "nonindexed_operand" "g"))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   return \"movw %1,%0\";
+ }")
+ 
+ ;; Force the destination to a register, so all source operands are allowed.
+ 
+ (define_insn "movsi"
+   [(set (match_operand:SI 0 "general_operand" "=r")
+ 	(match_operand:SI 1 "general_operand" "g"))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   return \"movw %1,%0\";
+ }")
+ 
+ ;; If the destination is a memory address, indexed operands are disallowed.
+ 
+ (define_insn ""
+   [(set (match_operand:HI 0 "memory_operand" "=m")
+ 	(match_operand:HI 1 "nonindexed_operand" "g"))]
+   ""
+   "*
+ {
+   if (REG_P (operands[1]))
+     return \"cvtwh %1,%0\";		/* reg -> mem */
+   else
+     {
+       CC_STATUS_INIT;
+       return \"movh %1,%0\";		/* mem imm -> mem */
+     }
+ }")
+ 
+ ;; Force the destination to a register, so all source operands are allowed.
+ 
+ (define_insn "movhi"
+   [(set (match_operand:HI 0 "general_operand" "=r")
+ 	(match_operand:HI 1 "general_operand" "g"))]
+   ""
+   "*
+ {
+   if (GET_CODE (operands[1]) != MEM)
+     {
+       CC_STATUS_INIT;
+       return \"movw %1,%0\";
+     }
+   return \"cvthw %1,%0\";
+ }")
+ 
+ ;; If the destination is a memory address, indexed operands are disallowed.
+ 
+ (define_insn ""
+   [(set (match_operand:QI 0 "memory_operand" "=m")
+ 	(match_operand:QI 1 "nonindexed_operand" "g"))]
+   ""
+   "*
+ {
+   if (REG_P (operands[1]))
+     return \"cvtwb %1,%0\";		/* reg -> mem */
+   else
+     {
+       CC_STATUS_INIT;
+       return \"movb %1,%0\";		/* mem imm -> mem */
+     }
+ }")
+ 
+ ;; Force the destination to a register, so all source operands are allowed.
+ 
+ (define_insn "movqi"
+   [(set (match_operand:QI 0 "general_operand" "=r")
+ 	(match_operand:QI 1 "general_operand" "g"))]
+   ""
+   "*
+ {
+   if (GET_CODE (operands[1]) != MEM)
+     {
+       CC_STATUS_INIT;
+       return \"movw %1,%0\";
+     }
+   return \"cvtbw %1,%0\";
+ }")
+ 
+ ;; If the destination is a memory address, indexed operands are disallowed, and
+ ;; so are immediate operands.  (Constants are always loaded into a reg pair,
+ ;; although offsetable memory addresses really doesn't need that.)
+ 
+ (define_insn ""
+   [(set (match_operand:DF 0 "memory_operand" "=m")
+ 	(match_operand:DF 1 "nonindexed_operand" "g"))]
+   "GET_CODE (operands[1]) != CONST_DOUBLE"
+   "*
+ {
+   CC_STATUS_INIT;
+   return \"movl %1,%0\";
+ }")
+ 
+ ;; Force the destination to a register, so all source operands are allowed.
+ 
+ (define_insn "movdf"
+   [(set (match_operand:DF 0 "general_operand" "=r")
+ 	(match_operand:DF 1 "general_operand" "gF"))]
+   ""
+   "* return output_move_double (operands); ")
+ 
+ ;; If the destination is a memory address, indexed operands are disallowed.
+ 
+ (define_insn ""
+   [(set (match_operand:SF 0 "memory_operand" "=m")
+ 	(match_operand:SF 1 "nonindexed_operand" "g"))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   return \"movw %1,%0\";
+ }")
+ 
+ ;; Force the destination to a register, so all source operands are allowed.
+ 
+ (define_insn "movsf"
+   [(set (match_operand:SF 0 "general_operand" "=r")
+ 	(match_operand:SF 1 "general_operand" "g"))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   return \"movw %1,%0\";
+ }")
+ 
+ (define_insn ""
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(match_operand:QI 1 "address_operand" "p"))]
+   ""
+   "*
+   CC_STATUS_INIT;
+   return \"mova %a1,%0\";
+ ")
+ \f


+ ;______________________________________________________________________
+ ;
+ ;	Conversion patterns.
+ ;______________________________________________________________________
+ 
+ ;; The trunc patterns are used only when non compile-time constants are used.
+ 
+ (define_insn "truncsiqi2"
+   [(set (match_operand:QI 0 "general_operand" "=r,m")
+ 	(truncate:QI (match_operand:SI 1 "nonimmediate_operand" "rm,r")))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   if (REGNO (operands[0]) == REGNO (operands[1]))
+     return \"\";
+   else
+     return \"movw %1,%0\";
+ }")
+ 
+ (define_insn "truncsihi2"
+   [(set (match_operand:HI 0 "general_operand" "=r,m")
+ 	(truncate:HI (match_operand:SI 1 "nonimmediate_operand" "rm,r")))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   if (REGNO (operands[0]) == REGNO (operands[1]))
+     return \"\";
+   else
+     return \"movw %1,%0\";
+ }")
+ 
+ (define_insn "extendhisi2"
+   [(set (match_operand:SI 0 "general_operand" "=r,m")
+ 	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm,r")))]
+   ""
+   "*
+ {
+   extern int optimize;
+   if (optimize && REG_P (operands[0]) && REG_P (operands[1])
+       && REGNO (operands[0]) == REGNO (operands[1])
+       && already_sign_extended (insn, HImode, operands[0]))
+     {
+       CC_STATUS_INIT;
+       return \"\";
+     }
+   return \"cvthw %1,%0\";
+ }")
+ 
+ (define_insn "extendqisi2"
+   [(set (match_operand:SI 0 "general_operand" "=r,m")
+ 	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm,r")))]
+   ""
+   "*
+ {
+   extern int optimize;
+   if (optimize && REG_P (operands[0]) && REG_P (operands[1])
+       && REGNO (operands[0]) == REGNO (operands[1])
+       && already_sign_extended (insn, QImode, operands[0]))
+     {
+       CC_STATUS_INIT;
+       return \"\";
+     }
+   return \"cvtbw %1,%0\";
+ }")
+ 
+ ; Pyramid doesn't have insns *called* "cvtbh" or "movzbh".
+ ; But we can cvtbw/movzbw into a register, where there is no distinction
+ ; between words and halfwords.
+ (define_insn "extendqihi2"
+   [(set (match_operand:HI 0 "register_operand" "=r")
+ 	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
+   ""
+   "cvtbw %1,%0")
+ 
+ (define_insn "zero_extendhisi2"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   return \"movzhw %1,%0\";
+ }")
+ 
+ (define_insn "zero_extendqisi2"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   return \"movzbw %1,%0\";
+ }")
+ 
+ (define_insn "zero_extendqihi2"
+   [(set (match_operand:HI 0 "register_operand" "=r")
+ 	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   return \"movzbw %1,%0\";
+ }")
+ 
+ (define_insn "extendsfdf2"
+   [(set (match_operand:DF 0 "general_operand" "=r,m")
+ 	(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "rm,r")))]
+   ""
+   "cvtfd %1,%0")
+ 
+ (define_insn "truncdfsf2"
+   [(set (match_operand:SF 0 "general_operand" "=r,m")
+ 	(float_truncate:SF (match_operand:DF 1 "nonimmediate_operand" "rm,r")))]
+   ""
+   "cvtdf %1,%0")
+ \f


+ ;;----------------------------------------------------------------------------
+ ;;
+ ;; Fix-to-Float and Float-to-Fix Conversion Patterns.
+ ;;
+ ;; Note that the ones that start with SImode come first.
+ ;; That is so that an operand that is a CONST_INT
+ ;; (and therefore lacks a specific machine mode).
+ ;; will be recognized as SImode (which is always valid)
+ ;; rather than as QImode or HImode.
+ ;;
+ ;;----------------------------------------------------------------------------
+ 
+ (define_insn "floatsisf2"
+   [(set (match_operand:SF 0 "general_operand" "=r,m")
+ 	(float:SF (match_operand:SI 1 "nonimmediate_operand" "rm,r")))]
+   ""
+   "cvtwf %1,%0")
+ 
+ (define_insn "floatsidf2"
+   [(set (match_operand:DF 0 "general_operand" "=r,m")
+ 	(float:DF (match_operand:SI 1 "nonimmediate_operand" "rm,r")))]
+   ""
+   "cvtwd %1,%0")
+ 
+ (define_insn "fix_truncsfsi2"
+   [(set (match_operand:SI 0 "general_operand" "=r,m")
+ 	(fix:SI (fix:SF (match_operand:SF 1 "nonimmediate_operand" "rm,r"))))]
+   ""
+   "cvtfw %1,%0")
+ 
+ (define_insn "fix_truncdfsi2"
+   [(set (match_operand:SI 0 "general_operand" "=r,m")
+ 	(fix:SI (fix:DF (match_operand:DF 1 "nonimmediate_operand" "rm,r"))))]
+   ""
+   "cvtdw %1,%0")
+ \f


+ ;______________________________________________________________________
+ ;
+ ;	Flow Control Patterns.
+ ;______________________________________________________________________
+ 
+ ;; Prefer "br" to "jump" for unconditional jumps, since it's faster.
+ ;; (The assembler can manage with out-of-range branches.)
+ 
+ (define_insn "jump"
+   [(set (pc)
+ 	(label_ref (match_operand 0 "" "")))]
+   ""
+   "br %l0")
+ 
+ (define_insn ""
+   [(set (pc)
+ 	(if_then_else (match_operator 0 "relop" [(cc0) (const_int 0)])
+ 		      (label_ref (match_operand 1 "" ""))
+ 		      (pc)))]
+   ""
+   "b%N0 %l1")
+ 
+ (define_insn ""
+   [(set (pc)
+ 	(if_then_else (match_operator 0 "relop" [(cc0) (const_int 0)])
+ 		      (pc)
+ 		      (label_ref (match_operand 1 "" ""))))]
+   ""
+   "b%C0 %l1")
+ 
+ (define_insn "call"
+   [(call (match_operand:QI 0 "memory_operand" "m")
+ 	 (match_operand:QI 1 "immediate_operand" "n"))]
+   ""
+   "call %0")
+ 
+ (define_insn "call_value"
+   [(set (match_operand 0 "" "=r")
+ 	(call (match_operand:QI 1 "memory_operand" "m")
+ 	      (match_operand:SI 2 "immediate_operand" "n")))]
+   ;; Operand 2 not really used on Pyramid architecture.
+   ""
+   "call %1")
+ 
+ (define_insn ""
+   [(return)]
+   ""
+   "ret")
+ 
+ (define_insn "tablejump"
+   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
+    (use (label_ref (match_operand 1 "" "")))]
+   ""
+   "jump (%0)")
+ \f


+ ;______________________________________________________________________
+ ;
+ ;	Peep-hole Optimization Patterns.
+ ;______________________________________________________________________
+ 
+ ;; Optimize fullword move followed by a test of the moved value.
+ 
+ ;(define_peephole
+ ;  [(set (match_operand:SI 0 "register_operand" "=r")
+ ;	(match_operand:SI 1 "nonimmediate_operand" "rm"))
+ ;   (set (cc0) (match_operand:SI 2 "nonimmediate_operand" "rm"))]
+ ;  "rtx_equal_p (operands[2], operands[0])
+ ;   || rtx_equal_p (operands[2], operands[1])"
+ ;  "mtstw %1,%0")
+ ;
+ ;;; Optimize loops with a incremented/decremented variable.
+ ;
+ ;(define_peephole
+ ;  [(set (match_operand:SI 0 "register_operand" "=r")
+ ;	(plus:SI (match_dup 0)
+ ;		 (const_int -1)))
+ ;   (set (cc0)
+ ;	(compare (match_operand:SI 1 "register_operand" "r")
+ ;		 (match_operand:SI 2 "nonmemory_operand" "ri")))
+ ;   (set (pc)
+ ;	(if_then_else (match_operator:SI 3 "signed_comparison"
+ ;			 [(cc0) (const_int 0)])
+ ;		      (label_ref (match_operand 4 "" ""))
+ ;		      (pc)))]
+ ;  "rtx_equal_p (operands[0], operands[1])
+ ;     || rtx_equal_p (operands[0], operands[2])"
+ ;  "*
+ ;  if (rtx_equal_p (operands[0], operands[1]))
+ ;    {
+ ;      output_asm_insn (\"dcmpw %2,%0\", operands);
+ ;      return output_branch (GET_CODE (operands[3]));
+ ;    }
+ ;  else
+ ;    {
+ ;      output_asm_insn (\"dcmpw %1,%0\", operands);
+ ;      return output_inv_branch (GET_CODE (operands[3]));
+ ;    }
+ ;")
+ ;
+ ;(define_peephole
+ ;  [(set (match_operand:SI 0 "register_operand" "=r")
+ ;	(plus:SI (match_dup 0)
+ ;		 (const_int 1)))
+ ;   (set (cc0)
+ ;	(compare (match_operand:SI 1 "register_operand" "r")
+ ;		 (match_operand:SI 2 "nonmemory_operand" "ri")))
+ ;   (set (pc)
+ ;	(if_then_else (match_operator:SI 3 "signed_comparison"
+ ;			 [(cc0) (const_int 0)])
+ ;		      (label_ref (match_operand 4 "" ""))
+ ;		      (pc)))]
+ ;  "rtx_equal_p (operands[0], operands[1])
+ ;     || rtx_equal_p (operands[0], operands[2])"
+ ;  "*
+ ;  if (rtx_equal_p (operands[0], operands[1]))
+ ;    {
+ ;      output_asm_insn (\"icmpw %2,%0\", operands);
+ ;      return output_branch (GET_CODE (operands[3]));
+ ;    }
+ ;  else
+ ;    {
+ ;      output_asm_insn (\"icmpw %1,%0\", operands);
+ ;      return output_inv_branch (GET_CODE (operands[3]));
+ ;    }
+ ;")
+ ;
+ ;(define_peephole
+ ;  [(set (match_operand:SI 0 "register_operand" "=r")
+ ;	(plus:SI (match_dup 0) (const_int -1)))
+ ;   (set (cc0) (match_dup 0))
+ ;   (set (pc) (if_then_else (match_operator:SI 1 "signed_comparison"
+ ;					      [(cc0) (const_int 0)])
+ ;			   (label_ref (match_operand 4 "" ""))
+ ;			   (pc)))]
+ ;  ""
+ ;  "*
+ ;    output_asm_insn (\"dcmpw $0,%0\", operands);
+ ;    return output_branch (GET_CODE (operands[1]));
+ ;")
+ ;
+ ;(define_peephole
+ ;  [(set (match_operand:SI 0 "register_operand" "=r")
+ ;	(plus:SI (match_dup 0) (const_int 1)))
+ ;   (set (cc0) (match_dup 0))
+ ;   (set (pc) (if_then_else (match_operator:SI 1 "signed_comparison"
+ ;					      [(cc0) (const_int 0)])
+ ;			   (label_ref (match_operand 4 "" ""))
+ ;			   (pc)))]
+ ;  ""
+ ;  "*
+ ;    output_asm_insn (\"icmpw $0,%0\", operands);
+ ;    return output_branch (GET_CODE (operands[1]));
+ ;")
+ ;
+ ;;; Combine word moves with consequtive operands into a long move.
+ ;;; Also combines immediate moves, if the high-order destination operand
+ ;;; is loaded with zero.
+ ;
+ ;(define_peephole
+ ;  [(set (match_operand:SI 0 "general_operand" "=g")
+ ;	(match_operand:SI 1 "general_operand" "g"))
+ ;   (set (match_operand:SI 2 "general_operand" "=g")
+ ;	(match_operand:SI 3 "general_operand" "g"))]
+ ;  "movdi_possible (operands)"
+ ;  "*
+ ;  CC_STATUS_INIT;
+ ;  movdi_possible (operands);
+ ;  if (CONSTANT_P (operands[1]))
+ ;    /* Also operand 3 is guarranteed to be CONSTANT by movdi_possible.  */
+ ;    return (swap_operands) ? \"movl %3,%0\" : \"movl %1,%2\";
+ ;
+ ;  return (swap_operands) ? \"movl %1,%0\" : \"movl %3,%2\";
+ ;")
+ ;
+ ;;; Optimize certain tests after memory stores.
+ ;
+ ;(define_peephole
+ ;  [(set (match_operand 0 "memory_operand" "=m")
+ ;	(match_operand 1 "register_operand" "r"))
+ ;   (set (match_operand:SI 2 "register_operand" "=r")
+ ;	(sign_extend:SI (match_dup 1)))
+ ;   (set (cc0)
+ ;	(match_dup 2))]
+ ;  "dead_or_set_p (insn, operands[2])"
+ ;  "*
+ ;  if (GET_MODE (operands[0]) == QImode)
+ ;    return \"cvtwb %1,%0\";
+ ;  else
+ ;    return \"cvtwh %1,%0\";
+ ;")
+ \f


+ ;______________________________________________________________________
+ ;
+ ;	DImode Patterns.
+ ;______________________________________________________________________
+ 
+ (define_expand "extendsidi2"
+   [(set (subreg:SI (match_operand:DI 0 "register_operand" "=r") 1)
+ 	(match_operand:SI 1 "register_operand" "r"))
+    (set (subreg:SI (match_dup 0) 0)
+ 	(subreg:SI (match_dup 0) 1))
+    (set (subreg:SI (match_dup 0) 0)
+ 	(ashiftrt:SI (subreg:SI (match_dup 0) 0)
+ 		     (const_int 31)))]
+   ""
+   "")
+ 
+ ;; I need to debug these.
+ 
+ ;(define_expand "cmpdi"
+ ;  [(set (cc0)
+ ;	(compare (subreg:SI (match_operand:DI 0 "register_operand" "r") 0)
+ ;		 (subreg:SI (match_operand:DI 1 "register_operand" "r") 0)))
+ ;   (set (pc) (if_then_else (ne (cc0) (const_int 0))
+ ;			   (label_ref (match_dup 2))
+ ;			   (pc)))
+ ;   (set (cc0)
+ ;	(compare (subreg:SI (match_dup 0) 1)
+ ;		 (subreg:SI (match_dup 1) 1)))
+ ;   (match_dup 2)]
+ ;  ""
+ ;  "operands[2] = gen_label_rtx ();")
+ ;
+ ;(define_expand "tstdi"
+ ;  [(set (cc0) (subreg:SI (match_operand:DI 0 "register_operand" "r") 0))
+ ;   (set (pc) (if_then_else (ne (cc0) (const_int 0))
+ ;			   (label_ref (match_dup 1))
+ ;			   (pc)))
+ ;   (set (cc0) (subreg:SI (match_dup 0) 1))
+ ;   (match_dup 1)]
+ ;  ""
+ ;  "operands[1] = gen_label_rtx ();")
+ 
+ (define_insn "adddi3"
+   [(set (match_operand:DI 0 "register_operand" "=r")
+ 	(plus:DI (match_operand:DI 1 "register_operand" "%0")
+ 		 (match_operand:DI 2 "nonmemory_operand" "rF")))]
+   ""
+   "*
+ {
+   rtx xoperands[2];
+   CC_STATUS_INIT;
+   xoperands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+   if (REG_P (operands[2]))
+     xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
+   else
+     {
+       xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
+ 			      CONST_DOUBLE_LOW (operands[2]));
+       operands[2] = gen_rtx (CONST_INT, VOIDmode,
+ 			     CONST_DOUBLE_HIGH (operands[2]));
+     }
+   output_asm_insn (\"addw %1,%0\", xoperands);
+   return \"addwc %2,%0\";
+ }")
+ 
+ (define_insn "subdi3"
+   [(set (match_operand:DI 0 "register_operand" "=r")
+ 	(minus:DI (match_operand:DI 1 "register_operand" "0")
+ 		  (match_operand:DI 2 "nonmemory_operand" "rF")))]
+   ""
+   "*
+ {
+   rtx xoperands[2];
+   CC_STATUS_INIT;
+   xoperands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+   if (REG_P (operands[2]))
+     xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
+   else
+     {
+       xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
+ 			      CONST_DOUBLE_LOW (operands[2]));
+       operands[2] = gen_rtx (CONST_INT, VOIDmode,
+ 			     CONST_DOUBLE_HIGH (operands[2]));
+     }
+   output_asm_insn (\"subw %1,%0\", xoperands);
+   return \"subwb %2,%0\";
+ }")
+ 
+ (define_insn "iordi3"
+   [(set (match_operand:DI 0 "register_operand" "=r")
+ 	(ior:DI (match_operand:DI 1 "register_operand" "%0")
+ 		(match_operand:DI 2 "nonmemory_operand" "rF")))]
+   ""
+   "*
+ {
+   rtx xoperands[2];
+   CC_STATUS_INIT;
+   xoperands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+   if (REG_P (operands[2]))
+     xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
+   else
+     {
+       xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
+ 			      CONST_DOUBLE_LOW (operands[2]));
+       operands[2] = gen_rtx (CONST_INT, VOIDmode,
+ 			     CONST_DOUBLE_HIGH (operands[2]));
+     }
+   output_asm_insn (\"orw %1,%0\", xoperands);
+   return \"orw %2,%0\";
+ }")
+ 
+ (define_insn "anddi3"
+   [(set (match_operand:DI 0 "register_operand" "=r")
+ 	(and:DI (match_operand:DI 1 "register_operand" "%0")
+ 		(match_operand:DI 2 "nonmemory_operand" "rF")))]
+   ""
+   "*
+ {
+   rtx xoperands[2];
+   CC_STATUS_INIT;
+   xoperands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+   if (REG_P (operands[2]))
+     xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
+   else
+     {
+       xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
+ 			      CONST_DOUBLE_LOW (operands[2]));
+       operands[2] = gen_rtx (CONST_INT, VOIDmode,
+ 			     CONST_DOUBLE_HIGH (operands[2]));
+     }
+   output_asm_insn (\"andw %1,%0\", xoperands);
+   return \"andw %2,%0\";
+ }")
+ 
+ (define_insn "xordi3"
+   [(set (match_operand:DI 0 "register_operand" "=r")
+ 	(xor:DI (match_operand:DI 1 "register_operand" "%0")
+ 		(match_operand:DI 2 "nonmemory_operand" "rF")))]
+   ""
+   "*
+ {
+   rtx xoperands[2];
+   CC_STATUS_INIT;
+   xoperands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+   if (REG_P (operands[2]))
+     xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
+   else
+     {
+       xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
+ 			      CONST_DOUBLE_LOW (operands[2]));
+       operands[2] = gen_rtx (CONST_INT, VOIDmode,
+ 			     CONST_DOUBLE_HIGH (operands[2]));
+     }
+   output_asm_insn (\"xorw %1,%0\", xoperands);
+   return \"xorw %2,%0\";
+ }")
+ 
+ (define_insn "nop"
+   [(const_int 0)]
+   ""
+   "movw gr0,gr0  # nop")
+ \f


+ ;;- Local variables:
+ ;;- mode:emacs-lisp
+ ;;- comment-start: ";;- "
+ ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
+ ;;- eval: (modify-syntax-entry ?] ")[")
+ ;;- eval: (modify-syntax-entry ?{ "(}")
+ ;;- eval: (modify-syntax-entry ?} "){")
+ ;;- End:
diff -rc2N gcc-1.35/config/sparc.md gcc-1.36/config/sparc.md
*** gcc-1.35/config/sparc.md	Sat Apr 15 17:30:58 1989
--- gcc-1.36/config/sparc.md	Fri Sep  1 20:46:40 1989
***************
*** 29,32 ****
--- 29,35 ----
  ;; Compare instructions.
  ;; This controls RTL generation and register allocation.
+ 
+ ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
+ 
  (define_insn "cmpsi"
    [(set (cc0)
***************
*** 96,101 ****
  }")
  
! ;; We have to have these because cse can optimize the previous patterns
! ;; into this one.
  
  (define_insn "tstsi"
--- 99,103 ----
  }")
  
! ;; Put tstsi first among test insns so it matches a CONST_INT operand.
  
  (define_insn "tstsi"
***************
*** 128,189 ****
  ;; before conditional branches.
  
! (define_peephole
!   [(set (match_operand:SI 0 "register_operand" "=r")
! 	(match_operand:SI 1 "general_operand" "g"))
!    (set (match_operand:SI 2 "register_operand" "=r")
! 	(match_operand:SI 3 "reg_or_0_operand" "rJ"))
!    (set (cc0) (match_operand:SI 4 "register_operand" "r"))
!    (set (pc) (match_operand 5 "" ""))]
!   "GET_CODE (operands[5]) == IF_THEN_ELSE
!    && operands[0] != operands[3]
!    && ! reg_mentioned_p (operands[2], operands[1])
!    && (operands[4] == operands[0]
!        || operands[4] == operands[2]
!        || operands[4] == operands[3])"
!   "*
! {
!   rtx xoperands[2];
!   int parity;
!   xoperands[0] = XEXP (operands[5], 0);
!   if (GET_CODE (XEXP (operands[5], 1)) == PC)
!     {
!       parity = 1;
!       xoperands[1] = XEXP (XEXP (operands[5], 2), 0);
!     }
!   else
!     {
!       parity = 0;
!       xoperands[1] = XEXP (XEXP (operands[5], 1), 0);
!     }
! 
!   if (operands[4] == operands[0])
!     {
!       /* Although the constraints for operands[1] permit a general
! 	 operand (and hence possibly a const_int), we know that
! 	 in this branch it cannot be a CONST_INT, since that would give
! 	 us a fixed condition, and those should have been optimized away.  */
!       if (REG_P (operands[1]))
! 	output_asm_insn (\"orcc %1,%%g0,%0 ! 3-insn reorder\", operands);
!       else if (GET_CODE (operands[1]) != MEM)
! 	abort ();
!       else
! 	{
! 	  if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
! 	    output_asm_insn (\"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\;tst %0 ! 4-insn reorder\", operands);
! 	  else
! 	    output_asm_insn (\"ld %1,%0\;tst %0 ! 3.5-insn reorder\", operands);
! 	}
!       XVECEXP (PATTERN (insn), 0, 0) = XVECEXP (PATTERN (insn), 0, 2);
!       XVECEXP (PATTERN (insn), 0, 1) = XVECEXP (PATTERN (insn), 0, 3);
!     }
!   else
!     {
!       output_asm_insn (\"orcc %3,%%g0,%2 ! 3-insn reorder\", operands);
!     }
!   if (parity)
!     return output_delayed_branch (\"b%N0 %l1\", xoperands, insn);
!   else
!     return output_delayed_branch (\"b%C0 %l1\", xoperands, insn);
! }")
  
  ;; By default, operations don't set the condition codes.
--- 130,199 ----
  ;; before conditional branches.
  
! ;; Turned off because (1) this case is rarely encounted
! ;; (2) to be correct, more conditions must be checked
! ;; (3) the conditions must be checked with rtx_equal_p, not ==
! ;; (4) when branch scheduling is added to the compiler,
! ;;     this optimization will be performed by the branch scheduler
! ;; Bottom line: it is not worth the trouble of fixing or
! ;; maintaining it.
! 
! ;(define_peephole
! ;  [(set (match_operand:SI 0 "register_operand" "=r")
! ;	(match_operand:SI 1 "general_operand" "g"))
! ;   (set (match_operand:SI 2 "register_operand" "=r")
! ;	(match_operand:SI 3 "reg_or_0_operand" "rJ"))
! ;   (set (cc0) (match_operand:SI 4 "register_operand" "r"))
! ;   (set (pc) (match_operand 5 "" ""))]
! ;  "GET_CODE (operands[5]) == IF_THEN_ELSE
! ;   && operands[0] != operands[3]
! ;   && ! reg_mentioned_p (operands[2], operands[1])
! ;   && (operands[4] == operands[0]
! ;       || operands[4] == operands[2]
! ;       || operands[4] == operands[3])"
! ;  "*
! ;{
! ;  rtx xoperands[2];
! ;  int parity;
! ;  xoperands[0] = XEXP (operands[5], 0);
! ;  if (GET_CODE (XEXP (operands[5], 1)) == PC)
! ;    {
! ;      parity = 1;
! ;      xoperands[1] = XEXP (XEXP (operands[5], 2), 0);
! ;    }
! ;  else
! ;    {
! ;      parity = 0;
! ;      xoperands[1] = XEXP (XEXP (operands[5], 1), 0);
! ;    }
! ;
! ;  if (operands[4] == operands[0])
! ;    {
! ;      /* Although the constraints for operands[1] permit a general
! ;	 operand (and hence possibly a const_int), we know that
! ;	 in this branch it cannot be a CONST_INT, since that would give
! ;	 us a fixed condition, and those should have been optimized away.  */
! ;      if (REG_P (operands[1]))
! ;	output_asm_insn (\"orcc %1,%%g0,%0 ! 3-insn reorder\", operands);
! ;      else if (GET_CODE (operands[1]) != MEM)
! ;	abort ();
! ;      else
! ;	{
! ;	  if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
! ;	    output_asm_insn (\"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\;tst %0 ! 4-insn reorder\", operands);
! ;	  else
! ;	    output_asm_insn (\"ld %1,%0\;tst %0 ! 3.5-insn reorder\", operands);
! ;	}
! ;      XVECEXP (PATTERN (insn), 0, 0) = XVECEXP (PATTERN (insn), 0, 2);
! ;      XVECEXP (PATTERN (insn), 0, 1) = XVECEXP (PATTERN (insn), 0, 3);
! ;    }
! ;  else
! ;    {
! ;      output_asm_insn (\"orcc %3,%%g0,%2 ! 3-insn reorder\", operands);
! ;    }
! ;  if (parity)
! ;    return output_delayed_branch (\"b%N0 %l1\", xoperands, insn);
! ;  else
! ;    return output_delayed_branch (\"b%C0 %l1\", xoperands, insn);
! ;}")
  
  ;; By default, operations don't set the condition codes.
***************
*** 192,196 ****
  (define_insn ""
    [(set (cc0)
! 	(zero_extend:SI (subreg:QI (match_operand:SI 0 "register_operand" "r"))))]
    ""
    "andcc %0,0xff,%%g0")
--- 202,206 ----
  (define_insn ""
    [(set (cc0)
! 	(zero_extend:SI (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)))]
    ""
    "andcc %0,0xff,%%g0")
***************
*** 379,382 ****
--- 389,394 ----
    "*
  {
+   CC_STATUS_INIT;
+   cc_status.value1 = operands[0];
    if (! REG_P (operands[2]))
      {
***************
*** 395,400 ****
  			 (const_int 0)]))]
    ""
!   "* output_asm_insn (\"tst %2\", operands);
!      return output_scc_insn (GET_CODE (operands[1]), operands[0]);")
  
  (define_insn ""
--- 407,417 ----
  			 (const_int 0)]))]
    ""
!   "*
! {
!   CC_STATUS_INIT;
!   cc_status.value1 = operands[0];
!   output_asm_insn (\"tst %2\", operands);
!   return output_scc_insn (GET_CODE (operands[1]), operands[0]);
! }")
  
  (define_insn ""
***************
*** 407,410 ****
--- 424,431 ----
    "*
  {
+   CC_STATUS_INIT;
+   cc_status.value1 = operands[0];
+   cc_status.flags |= CC_IN_FCCR;
+ 
    if (GET_CODE (operands[2]) == CONST_DOUBLE
        || GET_CODE (operands[3]) == CONST_DOUBLE)
***************
*** 411,415 ****
      make_f0_contain_0 (2);
  
-   cc_status.flags |= CC_IN_FCCR;
    if (GET_CODE (operands[2]) == CONST_DOUBLE)
      output_asm_insn (\"fcmped %%f0,%3\;nop\", operands);
--- 432,435 ----
***************
*** 428,433 ****
    "*
  {
!   make_f0_contain_0 (2);
    cc_status.flags |= CC_IN_FCCR;
    output_asm_insn (\"fcmped %2,%%f0\;nop\", operands);
    return output_scc_insn (GET_CODE (operands[1]), operands[0]);
--- 448,456 ----
    "*
  {
!   CC_STATUS_INIT;
!   cc_status.value1 = operands[0];
    cc_status.flags |= CC_IN_FCCR;
+ 
+   make_f0_contain_0 (2);
    output_asm_insn (\"fcmped %2,%%f0\;nop\", operands);
    return output_scc_insn (GET_CODE (operands[1]), operands[0]);
***************
*** 443,446 ****
--- 466,473 ----
    "*
  {
+   CC_STATUS_INIT;
+   cc_status.value1 = operands[0];
+   cc_status.flags |= CC_IN_FCCR;
+ 
    if (GET_CODE (operands[2]) == CONST_DOUBLE
        || GET_CODE (operands[3]) == CONST_DOUBLE)
***************
*** 447,451 ****
      make_f0_contain_0 (1);
  
-   cc_status.flags |= CC_IN_FCCR;
    if (GET_CODE (operands[2]) == CONST_DOUBLE)
      output_asm_insn (\"fcmpes %%f0,%3\;nop\", operands);
--- 474,477 ----
***************
*** 464,469 ****
    "*
  {
!   make_f0_contain_0 (1);
    cc_status.flags |= CC_IN_FCCR;
    output_asm_insn (\"fcmpes %2,%%f0\;nop\", operands);
    return output_scc_insn (GET_CODE (operands[1]), operands[0]);
--- 490,498 ----
    "*
  {
!   CC_STATUS_INIT;
!   cc_status.value1 = operands[0];
    cc_status.flags |= CC_IN_FCCR;
+ 
+   make_f0_contain_0 (1);
    output_asm_insn (\"fcmpes %2,%%f0\;nop\", operands);
    return output_scc_insn (GET_CODE (operands[1]), operands[0]);
***************
*** 748,752 ****
  		   (mem:BLK (match_operand:BLK 1 "general_operand" "")))
  	      (use (match_operand:SI 2 "arith32_operand" ""))
! 	      (clobber (match_dup 3))
  	      (clobber (match_dup 0))
  	      (clobber (match_dup 1))])]
--- 777,782 ----
  		   (mem:BLK (match_operand:BLK 1 "general_operand" "")))
  	      (use (match_operand:SI 2 "arith32_operand" ""))
! 	      (use (match_operand:SI 3 "immediate_operand" ""))
! 	      (clobber (match_dup 4))
  	      (clobber (match_dup 0))
  	      (clobber (match_dup 1))])]
***************
*** 756,760 ****
    operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
    operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
!   operands[3] = gen_reg_rtx (SImode);
  }")
  
--- 786,790 ----
    operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
    operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
!   operands[4] = gen_reg_rtx (SImode);
  }")
  
***************
*** 763,769 ****
  	(mem:BLK (match_operand:SI 1 "register_operand" "r")))
     (use (match_operand:SI 2 "arith32_operand" "rn"))
!    (clobber (match_operand:SI 3 "register_operand" "=r"))
!    (clobber (match_operand:SI 4 "register_operand" "=0"))
!    (clobber (match_operand:SI 5 "register_operand" "=1"))]
    ""
    "* return output_block_move (operands);")
--- 793,800 ----
  	(mem:BLK (match_operand:SI 1 "register_operand" "r")))
     (use (match_operand:SI 2 "arith32_operand" "rn"))
!    (use (match_operand:SI 3 "immediate_operand" "i"))
!    (clobber (match_operand:SI 4 "register_operand" "=r"))
!    (clobber (match_operand:SI 5 "register_operand" "=0"))
!    (clobber (match_operand:SI 6 "register_operand" "=1"))]
    ""
    "* return output_block_move (operands);")
***************
*** 800,804 ****
  	  return \"st %%g0,[%%g1+%%lo(%%m0)]\;st %%g0,[%%g1+%%lo(%%m0)+4]\";
  	}
!       operands[1] = adj_offsetable_operand (operands[0], 4);
        return \"st %%g0,%0\;st %%g0,%1\";
      }
--- 831,835 ----
  	  return \"st %%g0,[%%g1+%%lo(%%m0)]\;st %%g0,[%%g1+%%lo(%%m0)+4]\";
  	}
!       operands[1] = adj_offsettable_operand (operands[0], 4);
        return \"st %%g0,%0\;st %%g0,%1\";
      }
***************
*** 1524,1528 ****
  (define_insn "andcbsi3"
    [(set (match_operand:SI 0 "register_operand" "=r")
! 	(and:SI (match_operand:SI 1 "register_operand" "%r")
  		(not:SI (match_operand:SI 2 "register_operand" "r"))))]
    ""
--- 1555,1559 ----
  (define_insn "andcbsi3"
    [(set (match_operand:SI 0 "register_operand" "=r")
! 	(and:SI (match_operand:SI 1 "register_operand" "r")
  		(not:SI (match_operand:SI 2 "register_operand" "r"))))]
    ""
***************
*** 1544,1548 ****
  (define_insn "iorcbsi3"
    [(set (match_operand:SI 0 "register_operand" "=r")
! 	(ior:SI (match_operand:SI 1 "register_operand" "%r")
  		(not:SI (match_operand:SI 2 "register_operand" "r"))))]
    ""
--- 1575,1579 ----
  (define_insn "iorcbsi3"
    [(set (match_operand:SI 0 "register_operand" "=r")
! 	(ior:SI (match_operand:SI 1 "register_operand" "r")
  		(not:SI (match_operand:SI 2 "register_operand" "r"))))]
    ""
***************
*** 1564,1568 ****
  (define_insn "xorcbsi3"
    [(set (match_operand:SI 0 "register_operand" "=r")
! 	(xor:SI (match_operand:SI 1 "register_operand" "%r")
  		(not:SI (match_operand:SI 2 "register_operand" "r"))))]
    ""
--- 1595,1599 ----
  (define_insn "xorcbsi3"
    [(set (match_operand:SI 0 "register_operand" "=r")
! 	(xor:SI (match_operand:SI 1 "register_operand" "r")
  		(not:SI (match_operand:SI 2 "register_operand" "r"))))]
    ""
***************
*** 1734,1738 ****
    if (GET_CODE (operands[2]) == CONST_INT
        && INTVAL (operands[2]) >= 32)
!     return \"mov %%g0,%0\";
    return \"sll %1,%2,%0\";
  }")
--- 1765,1769 ----
    if (GET_CODE (operands[2]) == CONST_INT
        && INTVAL (operands[2]) >= 32)
!     operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 31);
    return \"sll %1,%2,%0\";
  }")
***************
*** 1747,1751 ****
    if (GET_CODE (operands[2]) == CONST_INT
        && INTVAL (operands[2]) >= 32)
!     return \"sra %1,31,%0\";
    return \"sra %1,%2,%0\";
  }")
--- 1778,1782 ----
    if (GET_CODE (operands[2]) == CONST_INT
        && INTVAL (operands[2]) >= 32)
!     operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 31);
    return \"sra %1,%2,%0\";
  }")
***************
*** 1760,1764 ****
    if (GET_CODE (operands[2]) == CONST_INT
        && INTVAL (operands[2]) >= 32)
!     return \"mov %%g0,%0\";
    return \"srl %1,%2,%0\";
  }")
--- 1791,1795 ----
    if (GET_CODE (operands[2]) == CONST_INT
        && INTVAL (operands[2]) >= 32)
!     operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 31);
    return \"srl %1,%2,%0\";
  }")
***************
*** 2103,2107 ****
  
  (define_expand "call_value"
!   [(set (match_operand 0 "register_operand" "rf")
  	(call (match_operand:SI 1 "memory_operand" "m")
  	      (match_operand 2 "" "i")))]
--- 2134,2138 ----
  
  (define_expand "call_value"
!   [(set (match_operand 0 "register_operand" "=rf")
  	(call (match_operand:SI 1 "memory_operand" "m")
  	      (match_operand 2 "" "i")))]
***************
*** 2141,2145 ****
  
  (define_insn ""
!   [(set (match_operand 0 "" "rf")
  	(call (match_operand:SI 1 "memory_operand" "m")
  	      (match_operand 2 "" "i")))
--- 2172,2176 ----
  
  (define_insn ""
!   [(set (match_operand 0 "" "=rf")
  	(call (match_operand:SI 1 "memory_operand" "m")
  	      (match_operand 2 "" "i")))
***************
*** 2160,2164 ****
    [(set (match_operand:SI 0 "register_operand" "=r")
  	(match_operand:SI 1 "single_insn_src_p" "p"))
!    (parallel [(set (match_operand 2 "" "rf")
  		   (call (match_operand:SI 3 "memory_operand" "m")
  			 (match_operand 4 "" "i")))
--- 2191,2195 ----
    [(set (match_operand:SI 0 "register_operand" "=r")
  	(match_operand:SI 1 "single_insn_src_p" "p"))
!    (parallel [(set (match_operand 2 "" "=rf")
  		   (call (match_operand:SI 3 "memory_operand" "m")
  			 (match_operand 4 "" "i")))
***************
*** 2178,2182 ****
    [(set (match_operand:SI 0 "memory_operand" "=m")
  	(match_operand:SI 1 "reg_or_0_operand" "rJ"))
!    (parallel [(set (match_operand 2 "" "rf")
  		   (call (match_operand:SI 3 "memory_operand" "m")
  			 (match_operand 4 "" "i")))
--- 2209,2213 ----
    [(set (match_operand:SI 0 "memory_operand" "=m")
  	(match_operand:SI 1 "reg_or_0_operand" "rJ"))
!    (parallel [(set (match_operand 2 "" "=rf")
  		   (call (match_operand:SI 3 "memory_operand" "m")
  			 (match_operand 4 "" "i")))
***************
*** 2220,2223 ****
--- 2251,2259 ----
    "! TARGET_EPILOGUE"
    "ret\;restore %0,-(%1),%%o0")
+ 
+ (define_insn "nop"
+   [(const_int 0)]
+   ""
+   "nop")
  \f


  ;;- Local variables:
diff -rc2N gcc-1.35/config/spur.md gcc-1.36/config/spur.md
*** gcc-1.35/config/spur.md	Tue Apr  4 20:09:35 1989
--- gcc-1.36/config/spur.md	Fri Aug 18 22:22:50 1989
***************
*** 34,37 ****
--- 34,39 ----
  ;; compares and jumps, and output each pair as a single assembler insn.
  
+ ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
+ 
  ;; This controls RTL generation and register allocation.
  (define_insn "cmpsi"
***************
*** 46,49 ****
--- 48,53 ----
  }")
  
+ ;; Put tstsi first among test insns so it matches a CONST_INT operand.
+ 
  ;; We have to have this because cse can optimize the previous pattern
  ;; into this one.
***************
*** 585,589 ****
    if (operands[1] == dconst0_rtx && GET_CODE (operands[0]) == MEM)
      {
!       operands[1] = adj_offsetable_operand (operands[0], 4);
        return \"st_32 r0,%0\;st_32 r0,%1\";
      }
--- 589,593 ----
    if (operands[1] == dconst0_rtx && GET_CODE (operands[0]) == MEM)
      {
!       operands[1] = adj_offsettable_operand (operands[0], 4);
        return \"st_32 r0,%0\;st_32 r0,%1\";
      }
***************
*** 1074,1078 ****
  
  (define_insn "call_value"
!   [(set (match_operand 0 "" "g")
  	(call (match_operand:SI 1 "memory_operand" "m")
  	      (match_operand:SI 2 "general_operand" "g")))]
--- 1078,1082 ----
  
  (define_insn "call_value"
!   [(set (match_operand 0 "" "=g")
  	(call (match_operand:SI 1 "memory_operand" "m")
  	      (match_operand:SI 2 "general_operand" "g")))]
***************
*** 1092,1096 ****
  
  (define_insn ""
!   [(set (match_operand 0 "" "g")
  	(call (mem:SI (match_operand:SI 1 "" "i"))
  	      (match_operand:SI 2 "general_operand" "g")))]
--- 1096,1100 ----
  
  (define_insn ""
!   [(set (match_operand 0 "" "=g")
  	(call (mem:SI (match_operand:SI 1 "" "i"))
  	      (match_operand:SI 2 "general_operand" "g")))]
***************
*** 1098,1101 ****
--- 1102,1110 ----
    "GET_CODE (operands[1]) == SYMBOL_REF"
    "call %1\;nop")
+ 
+ (define_insn "nop"
+   [(const_int 0)]
+   ""
+   "nop")
  \f


  ;;- Local variables:
diff -rc2N gcc-1.35/config/tahoe.md gcc-1.36/config/tahoe.md
*** gcc-1.35/config/tahoe.md	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config/tahoe.md	Sun Sep 24 00:23:10 1989
***************
*** 0 ****
--- 1,1497 ----
+ ;;- Machine description for GNU compiler
+ ;;- Tahoe version
+ ;;   Copyright (C) 1989 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+ 
+ 
+ ; File: tahoe.md
+ ;
+ ; This port made at the University of Buffalo by Devon Bowen,
+ ; Dale Wiles and Kevin Zachmann.
+ ;
+ ; Mail bugs reports or fixes to:	gcc@cs.buffalo.edu
+ 
+ 
+ ; movdi must call the output_move_double routine to move it around since
+ ; the tahoe doesn't efficiently support 8 bit moves.
+ 
+ (define_insn "movdi"
+   [(set (match_operand:DI 0 "general_operand" "=g")
+ 	(match_operand:DI 1 "general_operand" "g"))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   return output_move_double (operands);
+ }")
+ 
+ 
+ ; The trick in the movsi is accessing the contents of the sp register.  The
+ ; tahoe doesn't allow you to access it directly so you have to access the
+ ; address of the top of the stack instead.
+ 
+ (define_insn "movsi"
+   [(set (match_operand:SI 0 "general_operand" "=g")
+ 	(match_operand:SI 1 "general_operand" "g"))]
+   ""
+   "*
+ {
+   rtx link;
+   if (operands[1] == const1_rtx
+       && (link = find_reg_note (insn, REG_WAS_0, 0))
+       && ! XEXP (link, 0)->volatil
+       && GET_CODE (XEXP (link, 0)) != NOTE
+       && no_labels_between_p (XEXP (link, 0), insn))
+     return \"incl %0\";
+   if (GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == CONST)
+     {
+       if (push_operand (operands[0], SImode))
+ 	return \"pushab %a1\";
+       return \"movab %a1,%0\";
+     }
+   if (operands[1] == const0_rtx)
+     return \"clrl %0\";
+   if (push_operand (operands[0], SImode))
+     return \"pushl %1\";
+   if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 14)
+     return \"moval (sp),%0\";
+   return \"movl %1,%0\";
+ }")
+ 
+ 
+ (define_insn "movhi"
+   [(set (match_operand:HI 0 "general_operand" "=g")
+ 	(match_operand:HI 1 "general_operand" "g"))]
+   ""
+   "*
+ {
+   rtx link;
+   if (operands[1] == const1_rtx
+       && (link = find_reg_note (insn, REG_WAS_0, 0))
+       && ! XEXP (link, 0)->volatil
+       && GET_CODE (XEXP (link, 0)) != NOTE
+       && no_labels_between_p (XEXP (link, 0), insn))
+     return \"incw %0\";
+   if (operands[1] == const0_rtx)
+     return \"clrw %0\";
+   return \"movw %1,%0\";
+ }")
+ 
+ 
+ (define_insn "movqi"
+   [(set (match_operand:QI 0 "general_operand" "=g")
+ 	(match_operand:QI 1 "general_operand" "g"))]
+   ""
+   "*
+ {
+   if (operands[1] == const0_rtx)
+     return \"clrb %0\";
+   return \"movb %1,%0\";
+ }")
+ 
+ 
+ ; movsf has three cases since they can move from one place to another
+ ; or to/from the fpp and since different instructions are needed for
+ ; each case.  The fpp related instructions don't set the flags properly.
+ 
+ (define_insn "movsf"
+   [(set (match_operand:SF 0 "general_operand" "=g,=a,=g")
+ 	(match_operand:SF 1 "general_operand" "g,g,a"))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   switch (which_alternative)
+     {
+     case 0:
+       return \"movl %1,%0\";
+     case 1:
+       return \"ldf %1\";
+     case 2:
+       return \"stf %0\";
+     }
+ }")
+ 
+ 
+ ; movdf has a number of different cases.  If it's going to or from
+ ; the fpp, use the special instructions to do it.  If not, use the
+ ; output_move_double function.
+ 
+ (define_insn "movdf"
+   [(set (match_operand:DF 0 "general_operand" "=a,=g,?=g")
+ 	(match_operand:DF 1 "general_operand" "g,a,g"))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   switch (which_alternative)
+     {
+     case 0:
+       return \"ldd %1\";
+     case 1:
+       if (push_operand (operands[0], DFmode))
+ 	return \"pushd\";
+       else
+ 	return \"std %0\";
+     case 2:
+       return output_move_double (operands);
+     }
+ }")
+ 
+ 
+ (define_insn "addsi3"
+   [(set (match_operand:SI 0 "general_operand" "=g")
+ 	(plus:SI (match_operand:SI 1 "general_operand" "g")
+ 		 (match_operand:SI 2 "general_operand" "g")))]
+   ""
+   "*
+ {
+   if (rtx_equal_p (operands[0], operands[1]))
+     {
+       if (operands[2] == const1_rtx)
+ 	return \"incl %0\";
+       if (GET_CODE (operands[2]) == CONST_INT
+ 	  && INTVAL (operands[2]) == -1)
+ 	return \"decl %0\";
+       if (GET_CODE (operands[2]) == CONST_INT
+ 	  && (unsigned) (- INTVAL (operands[2])) < 64)
+ 	return \"subl2 $%n2,%0\";
+       return \"addl2 %2,%0\";
+     }
+   if (rtx_equal_p (operands[0], operands[2]))
+     return \"addl2 %1,%0\";
+   if (GET_CODE (operands[2]) == CONST_INT
+       && GET_CODE (operands[1]) == REG)
+     {
+       if (push_operand (operands[0], SImode))
+         return \"pushab %c2(%1)\";
+       return \"movab %c2(%1),%0\";
+     }
+   if (GET_CODE (operands[2]) == CONST_INT
+       && (unsigned) (- INTVAL (operands[2])) < 64)
+     return \"subl3 $%n2,%1,%0\";
+   return \"addl3 %1,%2,%0\";
+ }")
+ 
+ 
+ (define_insn "addhi3"
+   [(set (match_operand:HI 0 "general_operand" "=g")
+ 	(plus:HI (match_operand:HI 1 "general_operand" "g")
+ 		 (match_operand:HI 2 "general_operand" "g")))]
+   ""
+   "*
+ {
+   if (rtx_equal_p (operands[0], operands[1]))
+     {
+       if (operands[2] == const1_rtx)
+ 	return \"incw %0\";
+       if (GET_CODE (operands[1]) == CONST_INT
+ 	  && INTVAL (operands[1]) == -1)
+ 	return \"decw %0\";
+       if (GET_CODE (operands[2]) == CONST_INT
+ 	  && (unsigned) (- INTVAL (operands[2])) < 64)
+ 	return \"subw2 $%n2,%0\";
+       return \"addw2 %2,%0\";
+     }
+   if (rtx_equal_p (operands[0], operands[2]))
+     return \"addw2 %1,%0\";
+   if (GET_CODE (operands[2]) == CONST_INT
+       && (unsigned) (- INTVAL (operands[2])) < 64)
+     return \"subw3 $%n2,%1,%0\";
+   return \"addw3 %1,%2,%0\";
+ }")
+ 
+ 
+ (define_insn "addqi3"
+   [(set (match_operand:QI 0 "general_operand" "=g")
+ 	(plus:QI (match_operand:QI 1 "general_operand" "g")
+ 		 (match_operand:QI 2 "general_operand" "g")))]
+   ""
+   "*
+ {
+   if (rtx_equal_p (operands[0], operands[1]))
+     {
+       if (operands[2] == const1_rtx)
+ 	return \"incb %0\";
+       if (GET_CODE (operands[1]) == CONST_INT
+ 	  && INTVAL (operands[1]) == -1)
+ 	return \"decb %0\";
+       if (GET_CODE (operands[2]) == CONST_INT
+ 	  && (unsigned) (- INTVAL (operands[2])) < 64)
+ 	return \"subb2 $%n2,%0\";
+       return \"addb2 %2,%0\";
+     }
+   if (rtx_equal_p (operands[0], operands[2]))
+     return \"addb2 %1,%0\";
+   if (GET_CODE (operands[2]) == CONST_INT
+       && (unsigned) (- INTVAL (operands[2])) < 64)
+     return \"subb3 $%n2,%1,%0\";
+   return \"addb3 %1,%2,%0\";
+ }")
+ 
+ 
+ ; addsf3 can only add into the fpp register since the fpp is treated
+ ; as a separate unit in the machine.  It also doesn't set the flags at
+ ; all.
+ 
+ (define_insn "addsf3"
+   [(set (match_operand:SF 0 "register_operand" "=a")
+ 	(plus:SF (match_operand:SF 1 "register_operand" "%0")
+ 		 (match_operand:SF 2 "general_operand" "g")))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   return \"addf %2\";
+ }")
+ 
+ 
+ ; adddf3 can only add into the fpp reg since the fpp is treated as a
+ ; separate entity.  Doubles can only be read from a register or memory
+ ; since a double is not an immediate mode.  Flags are not set by this
+ ; instruction.
+ 
+ (define_insn "adddf3"
+   [(set (match_operand:DF 0 "register_operand" "=a")
+ 	(plus:DF (match_operand:DF 1 "register_operand" "%0")
+ 		 (match_operand:DF 2 "general_operand" "rm")))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   return \"addd %2\";
+ }")
+ 
+ 
+ ; Subtraction from the sp (needed by the built in alloc funtion) needs
+ ; to be different since the sp cannot be directly read on the tahoe.
+ ; If it's a simple constant, you just use displacment.  Otherwise, you
+ ; push the sp, and then do the subtraction off the stack.
+ 
+ (define_insn "subsi3"
+   [(set (match_operand:SI 0 "general_operand" "=g")
+ 	(minus:SI (match_operand:SI 1 "general_operand" "g")
+ 		  (match_operand:SI 2 "general_operand" "g")))]
+   ""
+   "*
+ {
+   if (rtx_equal_p (operands[0], operands[1]))
+     {
+       if (operands[2] == const1_rtx)
+ 	return \"decl %0\";
+       if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 14)
+ 	if (GET_CODE (operands[2]) == CONST_INT)
+ 	  return \"movab %n2(sp),sp\";
+ 	else
+ 	  return \"pushab (sp)\;subl3 %2,(sp),sp\";
+       return \"subl2 %2,%0\";
+     }
+   if (rtx_equal_p (operands[1], operands[2]))
+     return \"clrl %0\";
+   return \"subl3 %2,%1,%0\";
+ }")
+ 
+ 
+ (define_insn "subhi3"
+   [(set (match_operand:HI 0 "general_operand" "=g")
+ 	(minus:HI (match_operand:HI 1 "general_operand" "g")
+ 		  (match_operand:HI 2 "general_operand" "g")))]
+   ""
+   "*
+ {
+   if (rtx_equal_p (operands[0], operands[1]))
+     {
+       if (operands[2] == const1_rtx)
+ 	return \"decw %0\";
+       return \"subw2 %2,%0\";
+     }
+   if (rtx_equal_p (operands[1], operands[2]))
+     return \"clrw %0\";
+   return \"subw3 %2,%1,%0\";
+ }")
+ 
+ 
+ (define_insn "subqi3"
+   [(set (match_operand:QI 0 "general_operand" "=g")
+ 	(minus:QI (match_operand:QI 1 "general_operand" "g")
+ 		  (match_operand:QI 2 "general_operand" "g")))]
+   ""
+   "*
+ {
+   if (rtx_equal_p (operands[0], operands[1]))
+     {
+       if (operands[2] == const1_rtx)
+ 	return \"decb %0\";
+       return \"subb2 %2,%0\";
+     }
+   if (rtx_equal_p (operands[1], operands[2]))
+     return \"clrb %0\";
+   return \"subb3 %2,%1,%0\";
+ }")
+ 
+ 
+ ; subsf3 can only subtract into the fpp accumulator due to the way
+ ; the fpp reg is limited by the instruction set.  This also doesn't
+ ; bother setting up flags.
+ 
+ (define_insn "subsf3"
+   [(set (match_operand:SF 0 "register_operand" "=a")
+ 	(minus:SF (match_operand:SF 1 "register_operand" "0")
+ 		  (match_operand:SF 2 "general_operand" "g")))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   return \"subf %2\";
+ }")
+ 
+ 
+ ; subdf3 is set up to subtract into the fpp reg due to limitations
+ ; of the fpp instruction set.  Doubles can not be immediate.  This
+ ; instruction does not set the flags.
+ 
+ (define_insn "subdf3"
+   [(set (match_operand:DF 0 "register_operand" "=a")
+ 	(minus:DF (match_operand:DF 1 "register_operand" "0")
+ 		  (match_operand:DF 2 "general_operand" "rm")))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   return \"subd %2\";
+ }")
+ 
+ 
+ (define_insn "mulsi3"
+   [(set (match_operand:SI 0 "general_operand" "=g")
+ 	(mult:SI (match_operand:SI 1 "general_operand" "g")
+ 		 (match_operand:SI 2 "general_operand" "g")))]
+   ""
+   "*
+ {
+   if (rtx_equal_p (operands[0], operands[1]))
+     return \"mull2 %2,%0\";
+   if (rtx_equal_p (operands[0], operands[2]))
+     return \"mull2 %1,%0\";
+   return \"mull3 %1,%2,%0\";
+ }")
+ 
+ 
+ ; mulsf3 can only multiply into the fpp accumulator due to limitations
+ ; of the fpp.  It also does not set the condition codes properly.
+ 
+ (define_insn "mulsf3"
+   [(set (match_operand:SF 0 "register_operand" "=a")
+ 	(mult:SF (match_operand:SF 1 "register_operand" "%0")
+ 		 (match_operand:SF 2 "general_operand" "g")))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   return \"mulf %2\";
+ }")
+ 
+ 
+ ; muldf3 can only multiply into the fpp reg since the fpp is limited
+ ; from the rest.  Doubles may not be immediate mode.  This does not set
+ ; the flags like GCC would expect.
+ 
+ (define_insn "muldf3"
+   [(set (match_operand:DF 0 "register_operand" "=a")
+ 	(mult:DF (match_operand:DF 1 "register_operand" "%0")
+ 		 (match_operand:DF 2 "general_operand" "rm")))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   return \"muld %2\";
+ }")
+ 
+ 
+ (define_insn "divsi3"
+   [(set (match_operand:SI 0 "general_operand" "=g")
+ 	(div:SI (match_operand:SI 1 "general_operand" "g")
+ 		(match_operand:SI 2 "general_operand" "g")))]
+   ""
+   "*
+ {
+   if (rtx_equal_p (operands[1], operands[2]))
+     return \"movl $1,%0\";
+   if (operands[1] == const0_rtx)
+     return \"clrl %0\";
+   if (GET_CODE (operands[2]) == CONST_INT
+       && INTVAL (operands[2]) == -1)
+     return \"mnegl %1,%0\";
+   if (rtx_equal_p (operands[0], operands[1]))
+     return \"divl2 %2,%0\";
+   return \"divl3 %2,%1,%0\";
+ }")
+ 
+ 
+ ; divsf3 must divide into the fpp accumulator.  Flags are not set by
+ ; this instruction, so they are cleared.
+ 
+ (define_insn "divsf3"
+   [(set (match_operand:SF 0 "register_operand" "=a")
+ 	(div:SF (match_operand:SF 1 "register_operand" "0")
+ 		(match_operand:SF 2 "general_operand" "g")))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   return \"divf %2\";
+ }")
+ 
+ 
+ ; divdf3 also must divide into the fpp reg so optimization isn't
+ ; possible.  Note that doubles cannot be immediate.  The flags here
+ ; are not set correctly so they must be ignored.
+ 
+ (define_insn "divdf3"
+   [(set (match_operand:DF 0 "register_operand" "=a")
+ 	(div:DF (match_operand:DF 1 "register_operand" "0")
+ 		(match_operand:DF 2 "general_operand" "rm")))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   return \"divd %2\";
+ }")
+ 
+ 
+ (define_insn "andsi3"
+   [(set (match_operand:SI 0 "general_operand" "=g")
+ 	(and:SI (match_operand:SI 1 "general_operand" "g")
+ 		(match_operand:SI 2 "general_operand" "g")))]
+   ""
+   "andl3 %2,%1,%0")
+ 
+ 
+ (define_insn "andhi3"
+   [(set (match_operand:HI 0 "general_operand" "=g")
+ 	(and:HI (match_operand:HI 1 "general_operand" "g")
+ 		(match_operand:HI 2 "general_operand" "g")))]
+   ""
+   "andw3 %1,%2,%0")
+ 
+ 
+ (define_insn "andqi3"
+   [(set (match_operand:QI 0 "general_operand" "=g")
+ 	(and:QI (match_operand:QI 1 "general_operand" "g")
+ 		(match_operand:QI 2 "general_operand" "g")))]
+   ""
+   "andb3 %1,%2,%0")
+ 
+ 
+ (define_insn "iorsi3"
+   [(set (match_operand:SI 0 "general_operand" "=g")
+ 	(ior:SI (match_operand:SI 1 "general_operand" "g")
+ 		(match_operand:SI 2 "general_operand" "g")))]
+   ""
+   "orl3 %2,%1,%0")
+ 
+ 
+ (define_insn "iorhi3"
+   [(set (match_operand:HI 0 "general_operand" "=g")
+ 	(ior:HI (match_operand:HI 1 "general_operand" "g")
+ 		(match_operand:HI 2 "general_operand" "g")))]
+   ""
+   "orw3 %2,%1,%0")
+ 
+ 
+ (define_insn "iorqi3"
+   [(set (match_operand:QI 0 "general_operand" "=g")
+ 	(ior:QI (match_operand:QI 1 "general_operand" "g")
+ 		(match_operand:QI 2 "general_operand" "g")))]
+   ""
+   "orb3 %2,%1,%0")
+ 
+ 
+ (define_insn "xorsi3"
+   [(set (match_operand:SI 0 "general_operand" "=g")
+ 	(xor:SI (match_operand:SI 1 "general_operand" "g")
+ 		(match_operand:SI 2 "general_operand" "g")))]
+   ""
+   "xorl3 %1,%2,%0")
+ 
+ 
+ (define_insn "xorhi3"
+   [(set (match_operand:HI 0 "general_operand" "=g")
+ 	(xor:HI (match_operand:HI 1 "general_operand" "g")
+ 		(match_operand:HI 2 "general_operand" "g")))]
+   ""
+   "xorw3 %1,%2,%0")
+ 
+ 
+ (define_insn "xorqi3"
+   [(set (match_operand:QI 0 "general_operand" "=g")
+ 	(xor:QI (match_operand:QI 1 "general_operand" "g")
+ 		(match_operand:QI 2 "general_operand" "g")))]
+   ""
+   "xorb3 %1,%2,%0")
+ 
+ 
+ ; Shifts on the tahoe are expensive, so try to do an add instead.
+ 
+ (define_insn "ashlsi3"
+   [(set (match_operand:SI 0 "general_operand" "=g")
+ 	(ashift:SI (match_operand:SI 1 "general_operand" "g")
+ 		   (match_operand:QI 2 "general_operand" "g")))]
+   ""
+   "*
+ {
+   if (operands[2] == const1_rtx && rtx_equal_p (operands[0], operands[1]))
+     {
+       CC_STATUS_INIT;
+       return \"addl2 %0,%0\";
+     }
+   return \"shal %2,%1,%0\";
+ }")
+ 
+ 
+ (define_insn "ashrsi3"
+   [(set (match_operand:SI 0 "general_operand" "=g")
+ 	(ashiftrt:SI (match_operand:SI 1 "general_operand" "g")
+ 		   (match_operand:QI 2 "general_operand" "g")))]
+   ""
+   "shar %2,%1,%0")
+ 
+ 
+ ; Shifts are very expensive, so try to do an add if possible.
+ 
+ (define_insn "lshlsi3"
+   [(set (match_operand:SI 0 "general_operand" "=g")
+ 	(lshift:SI (match_operand:SI 1 "general_operand" "g")
+ 		   (match_operand:QI 2 "general_operand" "g")))]
+   ""
+   "*
+ {
+   if (operands[2] == const1_rtx && rtx_equal_p (operands[0], operands[1]))
+     {
+       CC_STATUS_INIT;
+       return \"addl2 %0,%0\";
+     }
+   return \"shll %2,%1,%0\";
+ }")
+ 
+ 
+ (define_insn "lshrsi3"
+   [(set (match_operand:SI 0 "general_operand" "=g")
+ 	(lshiftrt:SI (match_operand:SI 1 "general_operand" "g")
+ 		   (match_operand:QI 2 "general_operand" "g")))]
+   ""
+   "shrl %2,%1,%0")
+ 
+ 
+ (define_insn "negsi2"
+   [(set (match_operand:SI 0 "general_operand" "=g")
+ 	(neg:SI (match_operand:SI 1 "general_operand" "g")))]
+   ""
+   "mnegl %1,%0")
+ 
+ 
+ (define_insn "neghi2"
+   [(set (match_operand:HI 0 "general_operand" "=g")
+ 	(neg:HI (match_operand:HI 1 "general_operand" "g")))]
+   ""
+   "mnegw %1,%0")
+ 
+ 
+ (define_insn "negqi2"
+   [(set (match_operand:QI 0 "general_operand" "=g")
+ 	(neg:QI (match_operand:QI 1 "general_operand" "g")))]
+   ""
+   "mnegb %1,%0")
+ 
+ 
+ ; negsf2 can only negate the value already in the fpp accumulator.
+ ; The value remains in the fpp accumulator.  No flags are set.
+ 
+ (define_insn "negsf2"
+   [(set (match_operand:SF 0 "register_operand" "=a,=a")
+ 	(neg:SF (match_operand:SF 1 "register_operand" "a,g")))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   switch (which_alternative)
+     {
+     case 0:
+       return \"negf\";
+     case 1:
+       return \"lnf %1\";
+     }
+ }")
+ 
+ 
+ ; negdf2 can only negate the value already in the fpp accumulator.
+ ; The value remains in the fpp accumulator.  No flags are set.
+ 
+ (define_insn "negdf2"
+   [(set (match_operand:DF 0 "register_operand" "=a,=a")
+ 	(neg:DF (match_operand:DF 1 "register_operand" "a,g")))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   switch (which_alternative)
+     {
+     case 0:
+       return \"negd\";
+     case 1:
+       return \"lnd %1\";
+     }
+ }")
+ 
+ 
+ ; sqrtsf2 tahoe can calculate the square root of a float in the
+ ; fpp accumulator.  The answer remains in the fpp accumulator.  No
+ ; flags are set by this function.
+ 
+ (define_insn "sqrtsf2"
+   [(set (match_operand:SF 0 "register_operand" "=a")
+ 	(sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   return \"sqrtf\";
+ }")
+ 
+ 
+ ; ffssi2 tahoe instruction gives one less than GCC desired result for
+ ; any given input.  So the increment is necessary here.
+ 
+ (define_insn "ffssi2"
+   [(set (match_operand:SI 0 "general_operand" "=g")
+ 	(ffs:SI (match_operand:SI 1 "general_operand" "g")))]
+   ""
+   "ffs %1,%0\;incl %0")
+ 
+ 
+ (define_insn "one_cmplsi2"
+   [(set (match_operand:SI 0 "general_operand" "=g")
+ 	(not:SI (match_operand:SI 1 "general_operand" "g")))]
+   ""
+   "mcoml %1,%0")
+ 
+ 
+ (define_insn "one_cmplhi2"
+   [(set (match_operand:HI 0 "general_operand" "=g")
+ 	(not:HI (match_operand:HI 1 "general_operand" "g")))]
+   ""
+   "mcomw %1,%0")
+ 
+ 
+ (define_insn "one_cmplqi2"
+   [(set (match_operand:QI 0 "general_operand" "=g")
+ 	(not:QI (match_operand:QI 1 "general_operand" "g")))]
+   ""
+   "mcomb %1,%0")
+ 
+ 
+ ; cmpsi works fine, but due to microcode problems, the tahoe doesn't
+ ; properly compare hi's and qi's.  Leaving them out seems to be acceptable
+ ; to the compiler, so they were left out.  Compares of the stack are
+ ; possible, though.
+ 
+ ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
+ 
+ (define_insn "cmpsi"
+   [(set (cc0)
+ 	(compare (match_operand:SI 0 "general_operand" "g")
+ 	         (match_operand:SI 1 "general_operand" "g")))]
+   ""
+   "cmpl %0,%1")
+ 
+ 
+ ; cmpsf similar to vax, but first operand is expected to be in the
+ ; fpp accumulator.
+ 
+ (define_insn "cmpsf"
+   [(set (cc0)
+ 	(compare (match_operand:SF 0 "register_operand" "a")
+ 	         (match_operand:SF 1 "general_operand" "g")))]
+   ""
+   "cmpf %1")
+ 
+ 
+ ; cmpdf similar to vax, but first operand is expected to be in the
+ ; fpp accumulator.  Immediate doubles not allowed.
+ 
+ (define_insn "cmpdf"
+   [(set (cc0)
+ 	(compare (match_operand:DF 0 "register_operand" "a")
+ 	         (match_operand:DF 1 "general_operand" "rm")))]
+   ""
+   "cmpd %1")
+ 
+ 
+ ;; Put tstsi first among test insns so it matches a CONST_INT operand.
+ 
+ (define_insn "tstsi"
+   [(set (cc0)
+ 	(match_operand:SI 0 "general_operand" "g"))]
+   ""
+   "tstl %0")
+ 
+ 
+ ; Small tests from memory are normal, but testing from registers don't
+ ; expand the data properly.  So test in this case does a convert and tests
+ ; the new register data from the stack.
+ 
+ (define_insn "tsthi"
+   [(set (cc0)
+ 	(match_operand:HI 0 "general_operand" "m,?r"))]
+   ""
+   "*
+ {
+   switch (which_alternative)
+     {
+     case 0:
+       return \"tstw %0\";
+     case 1:
+       return \"pushl %0\;cvtwl 2(sp),(sp)\;tstl (sp)+\";
+     }
+ }")
+ 
+ 
+ ; Small tests from memory are normal, but testing from registers don't
+ ; expand the data properly.  So test in this case does a convert and tests
+ ; the new register data from the stack.
+ 
+ (define_insn "tstqi"
+   [(set (cc0)
+ 	(match_operand:QI 0 "general_operand" "m,?r"))]
+   ""
+   "*
+ {
+   switch (which_alternative)
+     {
+     case 0:
+       return \"tstb %0\";
+     case 1:
+       return \"pushl %0\;cvtbl 3(sp),(sp)\;tstl (sp)+\";
+     }
+ }")
+ 
+ 
+ ; tstsf compares a given value to a value already in the fpp accumulator.
+ ; No flags are set by this so ignore them.
+ 
+ (define_insn "tstsf"
+   [(set (cc0)
+ 	(match_operand:SF 0 "register_operand" "a"))]
+   ""
+   "tstf")
+ 
+ 
+ ; tstdf compares a given value to a value already in the fpp accumulator.
+ ; immediate doubles not allowed.  Flags are ignored after this.
+ 
+ (define_insn "tstdf"
+   [(set (cc0)
+ 	(match_operand:DF 0 "register_operand" "a"))]
+   ""
+   "tstd")
+ 
+ 
+ ; movstrhi tahoe instruction does not load registers by itself like
+ ; the vax counterpart does.  registers 0-2 must be primed by hand.
+ ; we have loaded the registers in the order: dst, src, count.
+ 
+ (define_insn "movstrhi"
+   [(set (match_operand:BLK 0 "general_operand" "p")
+ 	 (match_operand:BLK 1 "general_operand" "p"))
+    (use (match_operand:HI 2 "general_operand" "g"))
+    (clobber (reg:SI 0))
+    (clobber (reg:SI 1))
+    (clobber (reg:SI 2))]
+   ""
+   "movab %0,r1\;movab %1,r0\;movl %2,r2\;movblk")
+ 
+ 
+ ; floatsisf2 on tahoe converts the long from reg/mem into the fpp
+ ; accumulator.  There are no hi and qi counterparts.  Flags are not
+ ; set correctly here.
+ 
+ (define_insn "floatsisf2"
+   [(set (match_operand:SF 0 "register_operand" "=a")
+ 	(float:SF (match_operand:SI 1 "general_operand" "g")))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   return \"cvlf %1\";
+ }")
+ 
+ 
+ ; floatsidf2 on tahoe converts the long from reg/mem into the fpp
+ ; accumulator.  There are no hi and qi counterparts.  Flags are not
+ ; set correctly here.
+ 
+ (define_insn "floatsidf2"
+   [(set (match_operand:DF 0 "register_operand" "=a")
+ 	(float:DF (match_operand:SI 1 "general_operand" "g")))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   return \"cvld %1\";
+ }")
+ 
+ 
+ ; fix_truncsfsi2 to convert a float to long, tahoe must have the float
+ ; in the fpp accumulator.  Flags are not set here.
+ 
+ (define_insn "fix_truncsfsi2"
+   [(set (match_operand:SI 0 "general_operand" "=g")
+ 	(fix:SI (fix:SF (match_operand:SF 1 "register_operand" "a"))))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   return \"cvfl %0\";
+ }")
+ 
+ 
+ ; fix_truncsfsi2 to convert a double to long, tahoe must have the double
+ ; in the fpp accumulator.  Flags are not set here.
+ 
+ (define_insn "fix_truncdfsi2"
+   [(set (match_operand:SI 0 "general_operand" "=g")
+ 	(fix:SI (fix:DF (match_operand:DF 1 "register_operand" "a"))))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   return \"cvdl %0\";
+ }")
+ 
+ 
+ (define_insn "truncsihi2"
+   [(set (match_operand:HI 0 "general_operand" "=g")
+ 	(truncate:HI (match_operand:SI 1 "general_operand" "g")))]
+   ""
+   "cvtlw %1,%0")
+ 
+ 
+ (define_insn "truncsiqi2"
+   [(set (match_operand:QI 0 "general_operand" "=g")
+ 	(truncate:QI (match_operand:SI 1 "general_operand" "g")))]
+   ""
+   "cvtlb %1,%0")
+ 
+ 
+ (define_insn "trunchiqi2"
+   [(set (match_operand:QI 0 "general_operand" "=g")
+ 	(truncate:QI (match_operand:HI 1 "general_operand" "g")))]
+   ""
+   "cvtwb %1,%0")
+ 
+ 
+ ; The fpp related instructions don't set flags, so ignore them
+ ; after this instruction.
+ 
+ (define_insn "truncdfsf2"
+   [(set (match_operand:SF 0 "register_operand" "=a")
+ 	(float_truncate:SF (match_operand:DF 1 "register_operand" "0")))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   return \"cvdf\";
+ }")
+ 
+ 
+ ; This monster is to cover for the Tahoe's nasty habit of not extending
+ ; a number if the source is in a register.  (It just moves it!)  Case 0 is
+ ; a normal extend from memory.  Case 1 does the extension from the top of
+ ; the stack.  Extension from the stack doesn't set the flags right since
+ ; the moval changes them.
+ 
+ (define_insn "extendhisi2"
+   [(set (match_operand:SI 0 "general_operand" "=g,?=g")
+ 	(sign_extend:SI (match_operand:HI 1 "general_operand" "m,r")))]
+   ""
+   "*
+ {
+   switch (which_alternative)
+     {
+     case 0:
+       return \"cvtwl %1,%0\";
+     case 1:
+       if (push_operand(operands[0], SImode))
+ 	return \"pushl %1\;cvtwl 2(sp),(sp)\";
+       else
+ 	{
+ 	  CC_STATUS_INIT;
+ 	  return \"pushl %1\;cvtwl 2(sp),%0\;moval 4(sp),sp\";
+ 	}
+     }
+ }")
+ 
+ 
+ ; This monster is to cover for the Tahoe's nasty habit of not extending
+ ; a number if the source is in a register.  (It just moves it!)  Case 0 is
+ ; a normal extend from memory.  Case 1 does the extension from the top of
+ ; the stack.  Extension from the stack doesn't set the flags right since
+ ; the moval changes them.
+ 
+ (define_insn "extendqisi2"
+   [(set (match_operand:SI 0 "general_operand" "=g,?=g")
+ 	(sign_extend:SI (match_operand:QI 1 "general_operand" "m,r")))]
+   ""
+   "*
+ {
+   switch (which_alternative)
+     {
+     case 0:
+       return \"cvtbl %1,%0\";
+     case 1:
+       if (push_operand(operands[0], SImode))
+ 	return \"pushl %1\;cvtbl 3(sp),(sp)\";
+       else
+ 	{
+ 	  CC_STATUS_INIT;
+ 	  return \"pushl %1\;cvtbl 3(sp),%0\;moval 4(sp),sp\";
+ 	}
+     }
+ }")
+ 
+ 
+ ; This monster is to cover for the Tahoe's nasty habit of not extending
+ ; a number if the source is in a register.  (It just moves it!)  Case 0 is
+ ; a normal extend from memory.  Case 1 does the extension from the top of
+ ; the stack.  Extension from the stack doesn't set the flags right since
+ ; the moval changes them.
+ 
+ (define_insn "extendqihi2"
+   [(set (match_operand:HI 0 "general_operand" "=g,?=g")
+ 	(sign_extend:HI (match_operand:QI 1 "general_operand" "m,r")))]
+   ""
+   "*
+ {
+   switch (which_alternative)
+     {
+     case 0:
+       return \"cvtbw %1,%0\";
+     case 1:
+       if (push_operand(operands[0], SImode))
+ 	return \"pushl %1\;cvtbw 3(sp),2(sp)\";
+       else {
+ 	CC_STATUS_INIT;
+ 	return \"pushl %1\;cvtbw 3(sp),%0\;moval 4(sp),sp\";
+       }
+     }
+ }")
+ 
+ 
+ ; extendsfdf2 tahoe uses the fpp accumulator to do the extension.
+ ; It takes a float and loads it up directly as a double.
+ 
+ (define_insn "extendsfdf2"
+   [(set (match_operand:DF 0 "register_operand" "=a")
+ 	(float_extend:DF (match_operand:SF 1 "general_operand" "g")))]
+   ""
+   "*
+ {
+   CC_STATUS_INIT;
+   return \"ldfd %1\";
+ }")
+ 
+ 
+ ; movz works fine from memory but not from register for the same reasons
+ ; the cvt instructions don't work right.  So we use the normal instruction
+ ; from memory and we use an and to simulate it from register.  This is faster
+ ; than pulling it off the stack.
+ 
+ (define_insn "zero_extendhisi2"
+   [(set (match_operand:SI 0 "general_operand" "=g,?=g")
+ 	(zero_extend:SI (match_operand:HI 1 "general_operand" "m,r")))]
+   ""
+   "*
+ {
+   switch (which_alternative)
+     {
+     case 0:
+       return \"movzwl %1,%0\";
+     case 1:
+       return \"andl3 $0xffff,%1,%0\";
+     }
+ }")
+ 
+ 
+ ; movz works fine from memory but not from register for the same reasons
+ ; the cvt instructions don't work right.  So we use the normal instruction
+ ; from memory and we use an and to simulate it from register.  This is faster
+ ; than pulling it off the stack.
+ 
+ (define_insn "zero_extendqihi2"
+   [(set (match_operand:HI 0 "general_operand" "=g,?=g")
+ 	(zero_extend:HI (match_operand:QI 1 "general_operand" "m,r")))]
+   ""
+   "*
+ {
+   switch (which_alternative)
+     {
+     case 0:
+       return \"movzbw %1,%0\";
+     case 1:
+       return \"andw3 $0xff,%1,%0\";
+     }
+ }")
+ 
+ 
+ ; movz works fine from memory but not from register for the same reasons
+ ; the cvt instructions don't work right.  So we use the normal instruction
+ ; from memory and we use an and to simulate it from register.  This is faster
+ ; than pulling it off the stack.
+ 
+ (define_insn "zero_extendqisi2"
+   [(set (match_operand:SI 0 "general_operand" "=g,?=g")
+ 	(zero_extend:SI (match_operand:QI 1 "general_operand" "m,r")))]
+   ""
+   "*
+ {
+   switch (which_alternative)
+     {
+     case 0:
+       return \"movzbl %1,%0\";
+     case 1:
+       return \"andl3 $0xff,%1,%0\";
+     }
+ }")
+ 
+ 
+ (define_insn "beq"
+   [(set (pc)
+ 	(if_then_else (eq (cc0)
+ 			  (const_int 0))
+ 		      (label_ref (match_operand 0 "" ""))
+ 		      (pc)))]
+   ""
+   "jeql %l0")
+ 
+ 
+ (define_insn "bne"
+   [(set (pc)
+ 	(if_then_else (ne (cc0)
+ 			  (const_int 0))
+ 		      (label_ref (match_operand 0 "" ""))
+ 		      (pc)))]
+   ""
+   "jneq %l0")
+ 
+ 
+ (define_insn "bgt"
+   [(set (pc)
+ 	(if_then_else (gt (cc0)
+ 			  (const_int 0))
+ 		      (label_ref (match_operand 0 "" ""))
+ 		      (pc)))]
+   ""
+   "jgtr %l0")
+ 
+ 
+ (define_insn "bgtu"
+   [(set (pc)
+ 	(if_then_else (gtu (cc0)
+ 			   (const_int 0))
+ 		      (label_ref (match_operand 0 "" ""))
+ 		      (pc)))]
+   ""
+   "jgtru %l0")
+ 
+ 
+ (define_insn "blt"
+   [(set (pc)
+ 	(if_then_else (lt (cc0)
+ 			  (const_int 0))
+ 		      (label_ref (match_operand 0 "" ""))
+ 		      (pc)))]
+   ""
+   "jlss %l0")
+ 
+ 
+ (define_insn "bltu"
+   [(set (pc)
+ 	(if_then_else (ltu (cc0)
+ 			   (const_int 0))
+ 		      (label_ref (match_operand 0 "" ""))
+ 		      (pc)))]
+   ""
+   "jlssu %l0")
+ 
+ 
+ (define_insn "bge"
+   [(set (pc)
+ 	(if_then_else (ge (cc0)
+ 			  (const_int 0))
+ 		      (label_ref (match_operand 0 "" ""))
+ 		      (pc)))]
+   ""
+   "jgeq %l0")
+ 
+ 
+ (define_insn "bgeu"
+   [(set (pc)
+ 	(if_then_else (geu (cc0)
+ 			   (const_int 0))
+ 		      (label_ref (match_operand 0 "" ""))
+ 		      (pc)))]
+   ""
+   "jgequ %l0")
+ 
+ 
+ (define_insn "ble"
+   [(set (pc)
+ 	(if_then_else (le (cc0)
+ 			  (const_int 0))
+ 		      (label_ref (match_operand 0 "" ""))
+ 		      (pc)))]
+   ""
+   "jleq %l0")
+ 
+ 
+ (define_insn "bleu"
+   [(set (pc)
+ 	(if_then_else (leu (cc0)
+ 			   (const_int 0))
+ 		      (label_ref (match_operand 0 "" ""))
+ 		      (pc)))]
+   ""
+   "jlequ %l0")
+ 
+ 
+ ; GCC does not account for register mask/argc longword.  Thus the number
+ ; for the call = number bytes for args + 4
+ 
+ (define_insn "call"
+   [(call (match_operand:QI 0 "general_operand" "g")
+ 	 (match_operand:QI 1 "general_operand" "g"))]
+   ""
+   "*
+ {
+   operands[1] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[1]) + 4));
+   return \"calls %1,%0\";
+ }")
+ 
+ 
+ ; GCC does not account for register mask/argc longword.  Thus the number
+ ; for the call = number bytes for args + 4
+ 
+ (define_insn "call_value"
+   [(set (match_operand 0 "" "=g")
+ 	(call (match_operand:QI 1 "general_operand" "g")
+ 	      (match_operand:QI 2 "general_operand" "g")))]
+   ""
+   "*
+ {
+   operands[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) + 4));
+   return \"calls %2,%1\";
+ }")
+ 
+ 
+ (define_insn "nop"
+   [(const_int 0)]
+   ""
+   "nop")
+ 
+ 
+ (define_insn "return"
+   [(return)]
+   ""
+   "ret")
+ 
+ 
+ ; casesi, extracted from the vax code.  The instructions are
+ ; very similar.  Tahoe requires that the table be word aligned.  GCC
+ ; places the table immediately after, thus the alignment directive.
+ 
+ (define_insn "casesi"
+   [(set (pc)
+ 	(if_then_else (le (minus:SI (match_operand:SI 0 "general_operand" "g")
+ 				    (match_operand:SI 1 "general_operand" "g"))
+ 			  (match_operand:SI 2 "general_operand" "g"))
+ 		      (plus:SI (sign_extend:SI
+ 				(mem:HI (plus:SI (pc)
+ 						 (minus:SI (match_dup 0)
+ 							   (match_dup 1)))))
+ 			       (label_ref:SI (match_operand 3 "" "")))
+ 		      (pc)))]
+   ""
+   "casel %0,%1,%2\;.align %@")
+ 
+ 
+ (define_insn "jump"
+   [(set (pc)
+ 	(label_ref (match_operand 0 "" "")))]
+   ""
+   "jbr %l0")
+ 
+ 
+ ;; This is the list of all the non-standard insn patterns
+ 
+ 
+ ; This is used to access the address of a byte.  This is similar to
+ ; movqi, but the second operand had to be "address_operand" type, so
+ ; it had to be an unnamed one.
+ 
+ (define_insn ""
+   [(set (match_operand:SI 0 "general_operand" "=g")
+ 	(match_operand:QI 1 "address_operand" "p"))]
+   ""
+   "*
+ {
+   if (push_operand (operands[0], SImode))
+     return \"pushab %a1\";
+   return \"movab %a1,%0\";
+ }")
+ 
+ ; This is used to access the address of a word.  This is similar to
+ ; movhi, but the second operand had to be "address_operand" type, so
+ ; it had to be an unnamed one.
+ 
+ (define_insn ""
+   [(set (match_operand:SI 0 "general_operand" "=g")
+ 	(match_operand:HI 1 "address_operand" "p"))]
+   ""
+   "*
+ {
+   if (push_operand (operands[0], SImode))
+     return \"pushaw %a1\";
+   return \"movaw %a1,%0\";
+ }")
+ 
+ ; This is used to access the address of a long.  This is similar to
+ ; movsi, but the second operand had to be "address_operand" type, so
+ ; it had to be an unnamed one.
+ 
+ (define_insn ""
+   [(set (match_operand:SI 0 "general_operand" "=g")
+ 	(match_operand:SI 1 "address_operand" "p"))]
+   ""
+   "*
+ {
+   if (push_operand (operands[0], SImode))
+     return \"pushal %a1\";
+   return \"moval %a1,%0\";
+ }")
+ 
+ ; The tahoe doesn't have an 8 byte indexed move address command
+ ; and GCC needs it.  To work around it, double the index (%2) and
+ ; then use the 4 byte indexed move address command.
+ ;
+ ;(define_insn ""
+ ;  [(set (match_operand:SI 0 "general_operand" "=g")
+ ;	(plus:SI (match_operand:SI 1 "general_operand" "g")
+ ;		 (mult:SI (match_operand:SI 2 "register_operand" "r")
+ ;			  (const_int 8))))]
+ ;  ""
+ ;  "*
+ ;{
+ ;  if (GET_CODE (operands[0]) == REG &&
+ ;      REGNO (operands[0]) == REGNO (operands[2])) {
+ ;	return \"shll $3,%2,%2\;addl3 %1,%2,%0\";
+ ;  } else {
+ ;	return \"shll $3,%2,%2\;addl3 %1,%2,%0\;shrl $3,%2,%2\"; }
+ ;}")
+ 
+ 
+ ; Bit test longword instruction, same as vax.
+ 
+ (define_insn ""
+   [(set (cc0)
+ 	(and:SI (match_operand:SI 0 "general_operand" "g")
+ 		(match_operand:SI 1 "general_operand" "g")))]
+   ""
+   "bitl %0,%1")
+ 
+ 
+ ; Bit test word instructions, same as vax.
+ 
+ (define_insn ""
+   [(set (cc0)
+ 	(and:HI (match_operand:HI 0 "general_operand" "g")
+ 		(match_operand:HI 1 "general_operand" "g")))]
+   ""
+   "bitw %0,%1")
+ 
+ 
+ ; Bit test instructions, same as vax.
+ 
+ (define_insn ""
+   [(set (cc0)
+ 	(and:QI (match_operand:QI 0 "general_operand" "g")
+ 		(match_operand:QI 1 "general_operand" "g")))]
+   ""
+   "bitb %0,%1")
+ 
+ 
+ ; bne counterpart.  In case GCC reverses the conditional.
+ 
+ (define_insn ""
+   [(set (pc)
+ 	(if_then_else (eq (cc0)
+ 			  (const_int 0))
+ 		      (pc)
+ 		      (label_ref (match_operand 0 "" ""))))]
+   ""
+   "jneq %l0")
+ 
+ 
+ ; beq counterpart.  In case GCC reverses the conditional.
+ 
+ (define_insn ""
+   [(set (pc)
+ 	(if_then_else (ne (cc0)
+ 			  (const_int 0))
+ 		      (pc)
+ 		      (label_ref (match_operand 0 "" ""))))]
+   ""
+   "jeql %l0")
+ 
+ 
+ ; ble counterpart.  In case GCC reverses the conditional.
+ 
+ (define_insn ""
+   [(set (pc)
+ 	(if_then_else (gt (cc0)
+ 			  (const_int 0))
+ 		      (pc)
+ 		      (label_ref (match_operand 0 "" ""))))]
+   ""
+   "jleq %l0")
+ 
+ 
+ ; bleu counterpart.  In case GCC reverses the conditional.
+ 
+ (define_insn ""
+   [(set (pc)
+ 	(if_then_else (gtu (cc0)
+ 			   (const_int 0))
+ 		      (pc)
+ 		      (label_ref (match_operand 0 "" ""))))]
+   ""
+   "jlequ %l0")
+ 
+ 
+ ; bge counterpart.  In case GCC reverses the conditional.
+ 
+ (define_insn ""
+   [(set (pc)
+ 	(if_then_else (lt (cc0)
+ 			  (const_int 0))
+ 		      (pc)
+ 		      (label_ref (match_operand 0 "" ""))))]
+   ""
+   "jgeq %l0")
+ 
+ 
+ ; bgeu counterpart.  In case GCC reverses the conditional.
+ 
+ (define_insn ""
+   [(set (pc)
+ 	(if_then_else (ltu (cc0)
+ 			   (const_int 0))
+ 		      (pc)
+ 		      (label_ref (match_operand 0 "" ""))))]
+   ""
+   "jgequ %l0")
+ 
+ 
+ ; blt counterpart.  In case GCC reverses the conditional.
+ 
+ (define_insn ""
+   [(set (pc)
+ 	(if_then_else (ge (cc0)
+ 			  (const_int 0))
+ 		      (pc)
+ 		      (label_ref (match_operand 0 "" ""))))]
+   ""
+   "jlss %l0")
+ 
+ 
+ ; bltu counterpart.  In case GCC reverses the conditional.
+ 
+ (define_insn ""
+   [(set (pc)
+ 	(if_then_else (geu (cc0)
+ 			   (const_int 0))
+ 		      (pc)
+ 		      (label_ref (match_operand 0 "" ""))))]
+   ""
+   "jlssu %l0")
+ 
+ 
+ ; bgt counterpart.  In case GCC reverses the conditional.
+ 
+ (define_insn ""
+   [(set (pc)
+ 	(if_then_else (le (cc0)
+ 			  (const_int 0))
+ 		      (pc)
+ 		      (label_ref (match_operand 0 "" ""))))]
+   ""
+   "jgtr %l0")
+ 
+ 
+ ; bgtu counterpart.  In case GCC reverses the conditional.
+ 
+ (define_insn ""
+   [(set (pc)
+ 	(if_then_else (leu (cc0)
+ 			   (const_int 0))
+ 		      (pc)
+ 		      (label_ref (match_operand 0 "" ""))))]
+   ""
+   "jgtru %l0")
+ 
+ 
+ ; casesi alternate form as found in vax code.  This form is to
+ ; compensate for the table's offset being no distance (0 displacement)
+ 
+ (define_insn ""
+   [(set (pc)
+ 	(if_then_else (le (match_operand:SI 0 "general_operand" "g")
+ 			  (match_operand:SI 1 "general_operand" "g"))
+ 		      (plus:SI (sign_extend:SI
+ 				(mem:HI (plus:SI (pc)
+ 						 (minus:SI (match_dup 0)
+ 							   (const_int 0)))))
+ 			       (label_ref:SI (match_operand 3 "" "")))
+ 		      (pc)))]
+   ""
+   "casel %0,$0,%1\;.align %@")
+ 
+ 
+ ; casesi alternate form as found in vax code.  Another form to
+ ; compensate for the table's offset being no distance (0 displacement)
+ 
+ (define_insn ""
+   [(set (pc)
+ 	(if_then_else (le (match_operand:SI 0 "general_operand" "g")
+ 			  (match_operand:SI 1 "general_operand" "g"))
+ 		      (plus:SI (sign_extend:SI
+ 				(mem:HI (plus:SI (pc)
+ 						 (match_dup 0))))
+ 			       (label_ref:SI (match_operand 3 "" "")))
+ 		      (pc)))]
+   ""
+   "casel %0,$0,%1 \;.align %@")
diff -rc2N gcc-1.35/config/tm-3b1.h gcc-1.36/config/tm-3b1.h
*** gcc-1.35/config/tm-3b1.h	Wed Mar 29 17:36:38 1989
--- gcc-1.36/config/tm-3b1.h	Sat Sep  9 02:12:01 1989
***************
*** 1,3 ****
! /* Definitions of target machine for GNU compiler.  
     AT&T UNIX PC version (pc7300, 3b1)
  
--- 1,3 ----
! /* Definitions of target machine for GNU compiler.
     AT&T UNIX PC version (pc7300, 3b1)
  
***************
*** 143,146 ****
--- 143,167 ----
    else if ((LOG) != 0)			\
      abort ();
+ 
+ /* The `space' pseudo in the text segment outputs nop insns rather than 0s,
+    so we must output 0s explicitly in the text segment.  */
+ #undef ASM_OUTPUT_SKIP
+ #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
+   if (in_section == text_section)                                           \
+     {									    \
+       int i;								    \
+       for (i = 0; i < (SIZE); i += 20)					    \
+ 	fprintf (FILE, "\tbyte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n"); \
+       if (i < (SIZE))							    \
+         {								    \
+ 	  fprintf (FILE, "\tbyte 0");					    \
+ 	  i++;								    \
+ 	  for (; i < (SIZE); i++)					    \
+ 	    fprintf (FILE, ",0");					    \
+ 	  fprintf (FILE, "\n");						    \
+ 	}								    \
+     }									    \
+   else									    \
+     fprintf (FILE, "\tspace %d\n", (SIZE))
  
  /* The beginnings of sdb support... */
diff -rc2N gcc-1.35/config/tm-aix386.h gcc-1.36/config/tm-aix386.h
*** gcc-1.35/config/tm-aix386.h	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config/tm-aix386.h	Fri Aug  4 17:32:50 1989
***************
*** 0 ****
--- 1,98 ----
+ /* Definitions for IBM PS2 running AIX/386.
+    From: Minh Tran-Le <TRANLE@intellicorp.com>
+    Copyright (C) 1988 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+ 
+ 
+ #include "tm-i386.h"
+ 
+ /* Use the ATT assembler syntax.  */
+ 
+ #include "tm-att386.h"
+ 
+ /* By default, target has a 80387.  */
+ 
+ #define TARGET_DEFAULT 1
+ 
+ /* Use crt1.o as a startup file and crtn.o as a closing file.  */
+ 
+ #define STARTFILE_SPEC  \
+   "%{pg:gcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}"
+ 
+ #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} crtn.o%s"
+ 
+ /* Special flags for the linker.  I don't know what they do.  */
+ 
+ #define LINK_SPEC "%{!K:-K} %{!T*:-T0x00400000} %{lg} %{g} %{z:-lm}"
+ 
+ /* Specify predefined symbols in preprocessor.  */
+ 
+ #define CPP_PREDEFINES "-Dunix -Di386 -DAIX"
+ 
+ /* special flags for the aix assembler to generate the short form for all
+    qualifying forward reference */
+ 
+ #define ASM_SPEC "-s2"
+ 
+ /* Allow #sccs in preprocessor.  */
+ 
+ #define SCCS_DIRECTIVE
+ 
+ /* Output #ident as a .ident.  */
+ 
+ #define ASM_OUTPUT_IDENT(FILE, NAME) fprintf (FILE, "\t.ident \"%s\"\n", NAME);
+ 
+ /* We don't want to output SDB debugging information. */
+ 
+ #undef SDB_DEBUGGING_INFO
+ #undef ASM_FILE_START
+ #define ASM_FILE_START(FILE) 					\
+   do { fprintf (FILE, "\t.file\t\"%s\"\n", dump_base_name);	\
+        if (optimize) ASM_FILE_START_1 (FILE);			\
+      } while (0)
+ 
+ /* This was suggested, but it shouldn't be right for DBX output. -- RMS
+    #define ASM_OUTPUT_SOURCE_FILENAME(FILE, NAME) */
+ 
+ /* This is IBM AIX, it has a DBX debugger */
+ 
+ #define DBX_DEBUGGING_INFO
+ 
+ /* Implicit library calls should use memcpy, not bcopy, etc.  */
+ 
+ #define TARGET_MEM_FUNCTIONS
+ 
+ /* Don't write a `.optim' pseudo; this assembler
+    is said to have a bug when .optim is used.  */
+ 
+ #undef ASM_FILE_START_1
+ #define ASM_FILE_START_1(FILE) fprintf (FILE, "\t.noopt\n");
+ \f


+ /* Machines that use the AT&T assembler syntax
+    also return floating point values in an FP register.  */
+ /* Define how to find the value returned by a function.
+    VALTYPE is the data type of the value (as a tree).
+    If the precise function being called is known, FUNC is its FUNCTION_DECL;
+    otherwise, FUNC is 0.  */
+ 
+ #define VALUE_REGNO(MODE) \
+   (((MODE)==SFmode || (MODE)==DFmode) ? FIRST_FLOAT_REG : 0)
+ 
+ /* 1 if N is a possible register number for a function value. */
+ 
+ #define FUNCTION_VALUE_REGNO_P(N) ((N) == 0 || (N)== FIRST_FLOAT_REG)
diff -rc2N gcc-1.35/config/tm-alliant.h gcc-1.36/config/tm-alliant.h
*** gcc-1.35/config/tm-alliant.h	Wed Mar 29 17:37:45 1989
--- gcc-1.36/config/tm-alliant.h	Sun Jul  2 01:11:46 1989
***************
*** 1,4 ****
! /* Definitions of target machine for GNU compiler.  Alliant FX/8 version.
!    Copyright (C) 1987, 1989 Free Software Foundation, Inc.
  
  This file is part of GNU CC.
--- 1,6 ----
! /* Definitions of target machine for GNU compiler.  Alliant FX version.
!    Copyright (C) 1989 Free Software Foundation, Inc.
!    Adapted from tm-m68k.h by Paul Petersen (petersen@uicsrd.csrd.uiuc.edu)
!    and Joe Weening (weening@gang-of-four.stanford.edu).
  
  This file is part of GNU CC.
***************
*** 19,39 ****
  
  
! /* Note that some other tm- files include this one and then override
!    many of the definitions that relate to assembler syntax.  */
  
- 
  /* Names to predefine in the preprocessor for this target machine.  */
  
! /* See tm-sun3.h, tm-sun2.h, tm-isi68.h for different CPP_PREDEFINES.  */
  
  /* Print subsidiary information on the compiler version in use.  */
- #ifdef MOTOROLA
- #define TARGET_VERSION printf (" (68k, Motorola syntax)");
- #else
- #define TARGET_VERSION printf (" (68k, MIT syntax)");
- #endif
  
! /* Run-time compilation parameters selecting different hardware subsets.  */
  
  extern int target_flags;
  
--- 21,49 ----
  
  
! /* This file is based on tm-m68k.h, simplified by removing support for
!    the Sun FPA and other things not applicable to the Alliant.  Some
!    remnants of these features remain.  */
  
  /* Names to predefine in the preprocessor for this target machine.  */
  
! #define CPP_PREDEFINES "-Dmc68000 -Dalliant -Dunix"
  
  /* Print subsidiary information on the compiler version in use.  */
  
! #define TARGET_VERSION fprintf (stderr, " (Alliant)");
  
+ /* Run-time compilation parameters selecting different hardware
+    subsets.  The Alliant IP is an mc68020.  (Older mc68010-based IPs
+    are no longer supported.)  The Alliant CE is 68020-compatible, and
+    also has floating point, vector and concurrency instructions.
+ 
+    Although the IP doesn't have floating point, it emulates it in the
+    operating system.  Using this generally is faster than running code
+    compiled with -msoft-float, because the soft-float code still uses
+    (simulated) FP registers and ends up emulating several fmove{s,d}
+    instructions per call.  So I don't recommend using soft-float for
+    any Alliant code.  -- JSW
+ */
+ 
  extern int target_flags;
  
***************
*** 42,63 ****
  /* Compile for a 68020 (not a 68000 or 68010).  */
  #define TARGET_68020 (target_flags & 1)
! /* Compile 68881 insns for floating point (not library calls).  */
! #define TARGET_68881 (target_flags & 2)
  /* Compile using 68020 bitfield insns.  */
  #define TARGET_BITFIELD (target_flags & 4)
- /* Compile using rtd insn calling sequence.
-    This will not work unless you use prototypes at least
-    for all functions that can take varying numbers of args.  */
- #define TARGET_RTD (target_flags & 8)
- /* Compile passing first two args in regs 0 and 1.
-    This exists only to test compiler features that will
-    be needed for RISC chips.  It is not usable
-    and is not intended to be usable on this cpu.  */
- #define TARGET_REGPARM (target_flags & 020)
  /* Compile with 16-bit `int'.  */
  #define TARGET_SHORT (target_flags & 040)
  
! /* Compile with special insns for Sun FPA.  */
! #define TARGET_FPA (target_flags & 0100)
  
  /* Macro to define tables used to set the flags.
--- 52,95 ----
  /* Compile for a 68020 (not a 68000 or 68010).  */
  #define TARGET_68020 (target_flags & 1)
! /* Compile CE insns for floating point (not library calls).  */
! #define TARGET_CE (target_flags & 2)
  /* Compile using 68020 bitfield insns.  */
  #define TARGET_BITFIELD (target_flags & 4)
  /* Compile with 16-bit `int'.  */
  #define TARGET_SHORT (target_flags & 040)
  
! /* Default 3 means compile 68020 and CE instructions.  We don't use
!    bitfield instructions because there appears to be a bug in the
!    implementation of bfins on the CE.  */
! 
! #define TARGET_DEFAULT 3
! 
! /* Define __HAVE_CE__ in preprocessor according to the -m flags.
!    This will control the use of inline FP insns in certain macros.
!    Also inform the program which CPU this is for.  */
! 
! #if TARGET_DEFAULT & 02
! 
! /* -mce is the default */
! #define CPP_SPEC \
! "%{!msoft-float:-D__HAVE_CE__ }\
! %{m68000:-Dmc68010}%{mc68000:-Dmc68010}%{!mc68000:%{!m68000:-Dmc68020}}"
! 
! #else
! 
! /* -msoft-float is the default */
! #define CPP_SPEC \
! "%{mce:-D__HAVE_CE__ }\
! %{m68000:-Dmc68010}%{mc68000:-Dmc68010}%{!mc68000:%{!m68000:-Dmc68020}}"
! 
! #endif
! 
! /* Every structure or union's size must be a multiple of 2 bytes.  */
! 
! #define STRUCTURE_SIZE_BOUNDARY 16
! 
! /* This is BSD, so it wants DBX format.  */
! 
! #define DBX_DEBUGGING_INFO
  
  /* Macro to define tables used to set the flags.
***************
*** 70,95 ****
    { { "68020", 5},				\
      { "c68020", 5},				\
-     { "68881", 2},				\
      { "bitfield", 4},				\
!     { "68000", -5},				\
!     { "c68000", -5},				\
!     { "soft-float", -0102},			\
      { "nobitfield", -4},			\
-     { "rtd", 8},				\
-     { "nortd", -8},				\
      { "short", 040},				\
      { "noshort", -040},				\
-     { "fpa", 0100},				\
-     { "nofpa", -0100},				\
      { "", TARGET_DEFAULT}}
- 
- /* TARGET_DEFAULT is defined in tm-sun*.h and tm-isi68.h, etc.  */
- 
- /* Blow away 68881 flag silently on TARGET_FPA (since we can't clear
-    any bits in TARGET_SWITCHES above) */
- #define OVERRIDE_OPTIONS		\
- {					\
-   if (TARGET_FPA) target_flags &= ~2;	\
- }
  \f


  /* target machine storage layout */
--- 102,113 ----
    { { "68020", 5},				\
      { "c68020", 5},				\
      { "bitfield", 4},				\
!     { "68000", -7},				\
!     { "c68000", -7},				\
!     { "soft-float", -2},			\
      { "nobitfield", -4},			\
      { "short", 040},				\
      { "noshort", -040},				\
      { "", TARGET_DEFAULT}}
  \f


  /* target machine storage layout */
***************
*** 161,174 ****
     All registers that the compiler knows about must be given numbers,
     even those that are not normally considered general registers.
!    For the 68000, we give the data registers numbers 0-7,
     the address registers numbers 010-017,
!    and the 68881 floating point registers numbers 020-027.  */
! #define FIRST_PSEUDO_REGISTER 56 
  
  /* 1 for registers that have pervasive standard uses
     and are not available for the register allocator.
!    On the 68000, only the stack pointer is such.  */
! /* fpa0 is also reserved so that it can be used to move shit back and
!    forth between high fpa regs and everything else. */
  #define FIXED_REGISTERS  \
   {0, 0, 0, 0, 0, 0, 0, 0, \
--- 179,191 ----
     All registers that the compiler knows about must be given numbers,
     even those that are not normally considered general registers.
!    For the Alliant, we give the data registers numbers 0-7,
     the address registers numbers 010-017,
!    and the floating point registers numbers 020-027.  */
! #define FIRST_PSEUDO_REGISTER 24
  
  /* 1 for registers that have pervasive standard uses
     and are not available for the register allocator.
!    On the Alliant, these are a0 (argument pointer),
!    a6 (frame pointer) and a7 (stack pointer).  */
  #define FIXED_REGISTERS  \
   {0, 0, 0, 0, 0, 0, 0, 0, \
***************
*** 181,185 ****
     The latter must include the registers where values are returned
     and the register where structure-value addresses are passed.
!    Aside from that, you can include as many other registers as you like.  */
  
  #define CALL_USED_REGISTERS \
--- 198,204 ----
     The latter must include the registers where values are returned
     and the register where structure-value addresses are passed.
!    Aside from that, you can include as many other registers as you like.
!    The Alliant calling sequence allows a function to use any register,
!    so we include them all here.  */
  
  #define CALL_USED_REGISTERS \
***************
*** 188,210 ****
    1, 1, 1, 1, 1, 1, 1, 1  }
  
- /* Make sure everything's fine if we *don't* have a given processor.
-    This assumes that putting a register in fixed_regs will keep the
-    compilers mitt's completely off it.  We don't bother to zero it out
-    of register classes.  If neither TARGET_FPA or TARGET_68881 is set,
-    the compiler won't touch since no instructions that use these
-    registers will be valid.  */
- #define CONDITIONAL_REGISTER_USAGE \
- { 						\
-   int i; 					\
-   HARD_REG_SET x; 				\
-   if (!TARGET_FPA)				\
-     { 						\
-       COPY_HARD_REG_SET (x, reg_class_contents[(int)FPA_REGS]); \
-       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++ ) \
-        if (TEST_HARD_REG_BIT (x, i)) 		\
- 	fixed_regs[i] = call_used_regs[i] = 1; 	\
-     } 						\
- }
- 
  /* Return number of consecutive hard regs needed starting at reg REGNO
     to hold something of mode MODE.
--- 207,210 ----
***************
*** 212,217 ****
     but can be less for certain modes in special long registers.
  
!    On the 68000, ordinary registers hold 32 bits worth;
!    for the 68881 registers, a single register is always enough for
     anything that can be stored in them at all.  */
  #define HARD_REGNO_NREGS(REGNO, MODE)   \
--- 212,217 ----
     but can be less for certain modes in special long registers.
  
!    On the Alliant, ordinary registers hold 32 bits worth;
!    for the FP registers, a single register is always enough for
     anything that can be stored in them at all.  */
  #define HARD_REGNO_NREGS(REGNO, MODE)   \
***************
*** 220,233 ****
  
  /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
!    On the 68000, the cpu registers can hold any mode but the 68881 registers
!    can hold only SFmode or DFmode.  And the 68881 registers can't hold anything
!    if 68881 use is disabled.  However, the Sun FPA register can
!    (apparently) hold whatever you feel like putting in them.  */
! #define HARD_REGNO_MODE_OK(REGNO, MODE) \
!   ((REGNO) < 16								\
!    || ((REGNO) < 24							\
!        ? TARGET_68881 && ((MODE) == SFmode || (MODE) == DFmode)		\
!        : ((REGNO) < 56							\
! 	  ? TARGET_FPA : 0)))
  
  /* Value is 1 if it is a good idea to tie two pseudo registers
--- 220,227 ----
  
  /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
!    On the Alliant, the cpu registers can hold any mode but the FP registers
!    can hold only SFmode or DFmode.  */
! #define HARD_REGNO_MODE_OK(REGNO, MODE)		\
!   ((REGNO) < 16 || (MODE) == SFmode || (MODE) == DFmode)
  
  /* Value is 1 if it is a good idea to tie two pseudo registers
***************
*** 236,242 ****
     for any hard reg, then this must be 0 for correct output.  */
  #define MODES_TIEABLE_P(MODE1, MODE2)			\
!   (! TARGET_68881					\
!    || (((MODE1) == SFmode || (MODE1) == DFmode)		\
!        == ((MODE2) == SFmode || (MODE2) == DFmode)))
  
  /* Specify the registers used for certain standard purposes.
--- 230,235 ----
     for any hard reg, then this must be 0 for correct output.  */
  #define MODES_TIEABLE_P(MODE1, MODE2)			\
!    (((MODE1) == SFmode || (MODE1) == DFmode)		\
!        == ((MODE2) == SFmode || (MODE2) == DFmode))
  
  /* Specify the registers used for certain standard purposes.
***************
*** 256,259 ****
--- 249,254 ----
     may be accessed via the stack pointer) in functions that seem suitable.
     This is computed in `reload', in reload1.c.  */
+ /* Set for now on Alliant until we find a way to make this work with
+    their calling sequence.  */
  #define FRAME_POINTER_REQUIRED 1
  
***************
*** 288,311 ****
     class that represents their union.  */
  
! /* The 68000 has three kinds of registers, so eight classes would be
     a complete set.  One of them is not needed.  */
  
! /*
!  * Notes on final choices:
!  *
!  *   1) Didn't feel any need to union-ize LOW_FPA_REGS with anything
!  * else.
!  *   2) Removed all unions that involve address registers with
!  * floating point registers (left in unions of address and data with
!  * floating point).
!  *   3) Defined GENERAL_REGS as ADDR_OR_DATA_REGS.
!  *   4) Defined ALL_REGS as FPA_OR_FP_OR_GENERAL_REGS.
!  *   4) Left in everything else.
!  */
! enum reg_class { NO_REGS, LO_FPA_REGS, FPA_REGS, FP_REGS, 
!   FP_OR_FPA_REGS, DATA_REGS, DATA_OR_FPA_REGS, DATA_OR_FP_REGS, 
!   DATA_OR_FP_OR_FPA_REGS, ADDR_REGS, GENERAL_REGS, 
!   GENERAL_OR_FPA_REGS, GENERAL_OR_FP_REGS, ALL_REGS,
!   LIM_REG_CLASSES };
  
  #define N_REG_CLASSES (int) LIM_REG_CLASSES
--- 283,291 ----
     class that represents their union.  */
  
! /* The Alliant has three kinds of registers, so eight classes would be
     a complete set.  One of them is not needed.  */
  
! enum reg_class { NO_REGS, FP_REGS, DATA_REGS, DATA_OR_FP_REGS,
!   ADDR_REGS, GENERAL_REGS, ALL_REGS, LIM_REG_CLASSES };
  
  #define N_REG_CLASSES (int) LIM_REG_CLASSES
***************
*** 314,321 ****
  
  #define REG_CLASS_NAMES \
!  { "NO_REGS", "LO_FPA_REGS", "FPA_REGS", "FP_REGS",  \
!    "FP_OR_FPA_REGS", "DATA_REGS", "DATA_OR_FPA_REGS", "DATA_OR_FP_REGS",  \
!    "DATA_OR_FP_OR_FPA_REGS", "ADDR_REGS", "GENERAL_REGS",  \
!    "GENERAL_OR_FPA_REGS", "GENERAL_OR_FP_REGS", "ALL_REGS" }
  
  /* Define which registers fit in which classes.
--- 294,299 ----
  
  #define REG_CLASS_NAMES \
!  { "NO_REGS", "FP_REGS", "DATA_REGS", "DATA_OR_FP_REGS",  \
!    "ADDR_REGS", "GENERAL_REGS", "ALL_REGS" }
  
  /* Define which registers fit in which classes.
***************
*** 324,342 ****
  
  #define REG_CLASS_CONTENTS \
! {							\
!  {0, 0},			/* NO_REGS */		\
!  {0xff000000, 0x000000ff},	/* LO_FPA_REGS */	\
!  {0xff000000, 0x00ffffff},	/* FPA_REGS */		\
!  {0x00ff0000, 0x00000000},	/* FP_REGS */		\
!  {0xffff0000, 0x00ffffff},	/* FP_OR_FPA_REGS */	\
!  {0x000000ff, 0x00000000},	/* DATA_REGS */		\
!  {0xff0000ff, 0x00ffffff},	/* DATA_OR_FPA_REGS */	\
!  {0x00ff00ff, 0x00000000},	/* DATA_OR_FP_REGS */	\
!  {0xffff00ff, 0x00ffffff},	/* DATA_OR_FP_OR_FPA_REGS */\
!  {0x0000ff00, 0x00000000},	/* ADDR_REGS */		\
!  {0x0000ffff, 0x00000000},	/* GENERAL_REGS */	\
!  {0xff00ffff, 0x00ffffff},	/* GENERAL_OR_FPA_REGS */\
!  {0x00ffffff, 0x00000000},	/* GENERAL_OR_FP_REGS */\
!  {0xffffffff, 0x00ffffff}	/* ALL_REGS */		\
  }
  
--- 302,313 ----
  
  #define REG_CLASS_CONTENTS \
! {					\
!  0,		/* NO_REGS */		\
!  0x00ff0000,	/* FP_REGS */		\
!  0x000000ff,	/* DATA_REGS */		\
!  0x00ff00ff,	/* DATA_OR_FP_REGS */	\
!  0x0000ff00,	/* ADDR_REGS */		\
!  0x0000ffff,	/* GENERAL_REGS */	\
!  0x00ffffff	/* ALL_REGS */		\
  }
  
***************
*** 353,363 ****
  #define INDEX_REG_CLASS GENERAL_REGS
  #define BASE_REG_CLASS ADDR_REGS
!   
! /* Get reg_class from a letter such as appears in the machine description.
!    We do a trick here to modify the effective constraints on the
!    machine description; we zorch the constraint letters that aren't
!    appropriate for a specific target.  This allows us to guarrantee
!    that a specific kind of register will not be used for a given taget
!    without fiddling with the register classes above. */
  
  #define REG_CLASS_FROM_LETTER(C) \
--- 324,329 ----
  #define INDEX_REG_CLASS GENERAL_REGS
  #define BASE_REG_CLASS ADDR_REGS
! 
! /* Get reg_class from a letter such as appears in the machine description.  */
  
  #define REG_CLASS_FROM_LETTER(C) \
***************
*** 364,374 ****
    ((C) == 'a' ? ADDR_REGS :			\
     ((C) == 'd' ? DATA_REGS :			\
!     ((C) == 'f' ? (TARGET_68881 ? FP_REGS :	\
! 		   NO_REGS) :			\
!      ((C) == 'x' ? (TARGET_FPA ? FPA_REGS :	\
! 		    NO_REGS) :			\
!       ((C) == 'y' ? (TARGET_FPA ? LO_FPA_REGS :	\
! 		     NO_REGS) :			\
!        NO_REGS)))))
  
  /* The letters I, J, K, L and M in a register constraint string
--- 330,335 ----
    ((C) == 'a' ? ADDR_REGS :			\
     ((C) == 'd' ? DATA_REGS :			\
!     ((C) == 'f' ? FP_REGS :			\
!      NO_REGS)))
  
  /* The letters I, J, K, L and M in a register constraint string
***************
*** 390,402 ****
     (C) == 'L' ? (VALUE) < 0 && (VALUE) >= -8 : 0)
  
- /*
-  * A small bit of explanation:
-  * "G" defines all of the floating constants that are *NOT* 68881
-  * constants.  this is so 68881 constants get reloaded and the
-  * fpmovecr is used.  "H" defines *only* the class of constants that
-  * the fpa can use, because these can be gotten at in any fpa
-  * instruction and there is no need to force reloads.
-  */
- 
  #define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C)  0
  
--- 351,354 ----
***************
*** 423,427 ****
     except in the FP regs, where a single reg is always enough.  */
  #define CLASS_MAX_NREGS(CLASS, MODE)	\
!  ((CLASS) == FP_REGS || (CLASS) == FPA_REGS || (CLASS) == LO_FPA_REGS ? 1 \
    : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
  \f


--- 375,379 ----
     except in the FP regs, where a single reg is always enough.  */
  #define CLASS_MAX_NREGS(CLASS, MODE)	\
!  ((CLASS) == FP_REGS ? 1 \
    : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
  \f


***************
*** 438,443 ****
  #define FRAME_GROWS_DOWNWARD
  
! /* Define this if should default to -fcaller-saves.  */
! 
  #define DEFAULT_CALLER_SAVES
  
--- 390,394 ----
  #define FRAME_GROWS_DOWNWARD
  
! /* The Alliant uses -fcaller-saves by default.  */
  #define DEFAULT_CALLER_SAVES
  
***************
*** 461,478 ****
     or for a library call it is an identifier node for the subroutine name.
  
!    On the 68000, the RTS insn cannot pop anything.
!    On the 68010, the RTD insn may be used to pop them if the number
!      of args is fixed, but if the number is variable then the caller
!      must pop them all.  RTD can't be used for library calls now
!      because the library is compiled with the Unix compiler.
!    Use of RTD is a selectable option, since it is incompatible with
!    standard Unix calling sequences.  If the option is not selected,
!    the caller must always pop the args.  */
! 
! #define RETURN_POPS_ARGS(FUNTYPE)   \
!   (TARGET_RTD && TREE_CODE (FUNTYPE) != IDENTIFIER_NODE		\
!    && (TYPE_ARG_TYPES (FUNTYPE) == 0				\
!        || TREE_VALUE (tree_last (TYPE_ARG_TYPES (FUNTYPE))) == void_type_node))
  
  /* Define how to find the value returned by a function.
     VALTYPE is the data type of the value (as a tree).
--- 412,422 ----
     or for a library call it is an identifier node for the subroutine name.
  
!    On the Alliant we define this as 1 and make the calling sequence
!    (in alliant.md) pop the args.  This wouldn't be necessary if we
!    could add to the pending stack adjustment the size of the argument
!    descriptors that are pushed after the arguments.  */
  
+ #define RETURN_POPS_ARGS(FUNTYPE) 1
+ 
  /* Define how to find the value returned by a function.
     VALTYPE is the data type of the value (as a tree).
***************
*** 480,487 ****
     otherwise, FUNC is 0.  */
  
! /* On the 68000 the return value is in D0 regardless.  */
  
  #define FUNCTION_VALUE(VALTYPE, FUNC)  \
!   gen_rtx (REG, TYPE_MODE (VALTYPE), 0)
  
  /* Define how to find the value returned by a library function
--- 424,433 ----
     otherwise, FUNC is 0.  */
  
! /* On the Alliant the return value is in FP0 if real, else D0.  */
  
  #define FUNCTION_VALUE(VALTYPE, FUNC)  \
!   (TREE_CODE (VALTYPE) == REAL_TYPE \
!    ? gen_rtx (REG, TYPE_MODE (VALTYPE), 16) \
!    : gen_rtx (REG, TYPE_MODE (VALTYPE), 0))
  
  /* Define how to find the value returned by a library function
***************
*** 488,494 ****
     assuming the value has mode MODE.  */
  
! /* On the 68000 the return value is in D0 regardless.  */
  
! #define LIBCALL_VALUE(MODE)  gen_rtx (REG, MODE, 0)
  
  /* Define this if PCC uses the nonreentrant convention for returning
--- 434,453 ----
     assuming the value has mode MODE.  */
  
! /* On the Alliant the return value is in FP0 if real, else D0.  The
!    Alliant library functions for floating-point emulation return their
!    values both in FP0 and in D0/D1.  But since not all gnulib functions
!    return the results of these directly, we cannot assume that D0/D1
!    contain the values we expect on return from a gnulib function.  */
! 
! #define LIBCALL_VALUE(MODE)  \
!   (((MODE) == DFmode || (MODE) == SFmode) \
!    ? gen_rtx (REG, MODE, 16) \
!    : gen_rtx (REG, MODE, 0))
! 
! /* 1 if N is a possible register number for a function value.
!    On the Alliant, D0 and FP0 are the only registers thus used.
!    (No need to mention D1 when used as a pair with D0.)  */
  
! #define FUNCTION_VALUE_REGNO_P(N) (((N) & ~16) == 0)
  
  /* Define this if PCC uses the nonreentrant convention for returning
***************
*** 497,507 ****
  #define PCC_STATIC_STRUCT_RETURN
  
- /* 1 if N is a possible register number for a function value.
-    On the 68000, d0 is the only register thus used.  */
- 
- #define FUNCTION_VALUE_REGNO_P(N) ((N) == 0)
- 
  /* 1 if N is a possible register number for function argument passing.
!    On the 68000, no registers are used in this way.  */
  
  #define FUNCTION_ARG_REGNO_P(N) 0
--- 456,461 ----
  #define PCC_STATIC_STRUCT_RETURN
  
  /* 1 if N is a possible register number for function argument passing.
!    On the Alliant, no registers are used in this way.  */
  
  #define FUNCTION_ARG_REGNO_P(N) 0
***************
*** 513,517 ****
     such as FUNCTION_ARG to determine where the next arg should go.
  
!    On the m68k, this is a single integer, which is a number of bytes
     of arguments scanned so far.  */
  
--- 467,471 ----
     such as FUNCTION_ARG to determine where the next arg should go.
  
!    On the Alliant, this is a single integer, which is a number of bytes
     of arguments scanned so far.  */
  
***************
*** 522,526 ****
     For a library call, FNTYPE is 0.
  
!    On the m68k, the offset starts at 0.  */
  
  #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE)	\
--- 476,480 ----
     For a library call, FNTYPE is 0.
  
!    On the Alliant, the offset starts at 0.  */
  
  #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE)	\
***************
*** 549,559 ****
      (otherwise it is an extra parameter matching an ellipsis).  */
  
! /* On the 68000 all args are pushed, except if -mregparm is specified
!    then the first two words of arguments are passed in d0, d1.
!    *NOTE* -mregparm does not work.
!    It exists only to test register calling conventions.  */
  
! #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
! ((TARGET_REGPARM && (CUM) < 8) ? gen_rtx(REG, (MODE), (CUM)/4) : 0)
  
  /* For an arg passed partly in registers and partly in memory,
--- 503,509 ----
      (otherwise it is an extra parameter matching an ellipsis).  */
  
! /* On the Alliant all args are pushed.  */
  
! #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) 0
  
  /* For an arg passed partly in registers and partly in memory,
***************
*** 561,570 ****
     For args passed entirely in registers or entirely in memory, zero.  */
  
! #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
! ((TARGET_REGPARM && (CUM) < 8				\
!   && 8 < ((CUM) + ((MODE) == BLKmode			\
! 		      ? int_size_in_bytes (TYPE)		\
! 		      : GET_MODE_SIZE (MODE))))  		\
!  ? 2 - (CUM) / 4 : 0)
  
  /* This macro generates the assembly code for function entry.
--- 511,515 ----
     For args passed entirely in registers or entirely in memory, zero.  */
  
! #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
  
  /* This macro generates the assembly code for function entry.
***************
*** 574,584 ****
     to save; `regs_ever_live[I]' is nonzero if register number I
     is ever used in the function.  This macro is responsible for
!    knowing which registers should not be saved even if used.  */
  
- /* Note that the order of the bit mask for fmovem is the opposite
-    of the order for movem!  */
- 
  #define FUNCTION_PROLOGUE(FILE, SIZE)     \
! { int fsize = ((SIZE) + 3) & -4;				\
    if (frame_pointer_needed) {					\
      if (TARGET_68020 || fsize < 0x8000)				\
--- 519,527 ----
     to save; `regs_ever_live[I]' is nonzero if register number I
     is ever used in the function.  This macro is responsible for
!    knowing which registers should not be saved even if used.
!    The Alliant uses caller-saves, so this macro is very simple.  */
  
  #define FUNCTION_PROLOGUE(FILE, SIZE)     \
! { int fsize = ((SIZE) - STARTING_FRAME_OFFSET + 3) & -4;	\
    if (frame_pointer_needed) {					\
      if (TARGET_68020 || fsize < 0x8000)				\
***************
*** 585,590 ****
        fprintf(FILE,"\tlink a6,#%d\n", -fsize);			\
      else							\
!       fprintf(FILE,"\tlink a6,#0\n\tsubl #%d,sp\n", fsize); }  	\
!   fprintf(FILE, "\tmovl a0,a6@(-4)\n" ); }
  
  /* Output assembler code to FILE to increment profiler label # LABELNO
--- 528,533 ----
        fprintf(FILE,"\tlink a6,#%d\n", -fsize);			\
      else							\
!       fprintf(FILE,"\tlink a6,#0\n\tsubl #%d,sp\n", fsize);  	\
!     fprintf(FILE, "\tmovl a0,a6@(-4)\n" ); }}
  
  /* Output assembler code to FILE to increment profiler label # LABELNO
***************
*** 592,596 ****
  
  #define FUNCTION_PROFILER(FILE, LABELNO)  \
!   fprintf (FILE, "\tlea LP%d,a0\n\tjsr mcount\n", (LABELNO))
  
  /* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
--- 535,539 ----
  
  #define FUNCTION_PROFILER(FILE, LABELNO)  \
!   fprintf (FILE, "\tjbsr __mcount_\n")
  
  /* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
***************
*** 612,622 ****
  
  #define FUNCTION_EPILOGUE(FILE, SIZE) \
! { extern int current_function_pops_args;			\
!   extern int current_function_args_size;			\
!   if (frame_pointer_needed)					\
      fprintf (FILE, "\tunlk a6\n");				\
!   if (current_function_pops_args && current_function_args_size)	\
!     fprintf (FILE, "\trtd #%d\n", current_function_args_size);	\
!   else fprintf (FILE, "\trts\n"); }
  
  /* If the memory address ADDR is relative to the frame pointer,
--- 555,561 ----
  
  #define FUNCTION_EPILOGUE(FILE, SIZE) \
! { if (frame_pointer_needed)					\
      fprintf (FILE, "\tunlk a6\n");				\
!   fprintf (FILE, "\trts\n"); }
  
  /* If the memory address ADDR is relative to the frame pointer,
***************
*** 692,697 ****
  (((REGNO) ^ 020) < 8 || (unsigned) (reg_renumber[REGNO] ^ 020) < 8)
  
- #define REGNO_OK_FOR_FPA_P(REGNO)	0 
- 
  /* Now macros that check whether X is a register and also,
     strictly, whether it is in a specified class.
--- 631,634 ----
***************
*** 712,718 ****
  
  #define ADDRESS_REG_P(X) (REG_P (X) && REGNO_OK_FOR_BASE_P (REGNO (X)))
- 
- /* 1 if X is a register in the Sun FPA.  */
- #define FPA_REG_P(X) 0
  \f


  /* Maximum number of registers that can appear in a valid memory address.  */
--- 649,652 ----
***************
*** 727,731 ****
     It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.  */
  
! #define LEGITIMATE_CONSTANT_P(X) 1
  
  /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
--- 661,667 ----
     It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.  */
  
! /* Alliant FP instructions don't take immediate operands, so this
!    forces them into memory.  */
! #define LEGITIMATE_CONSTANT_P(X) (GET_CODE (X) != CONST_DOUBLE)
  
  /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
***************
*** 962,966 ****
  /* Set if the cc value came from a floating point test, so a floating
     point conditional branch must be output.  */
! #define CC_IN_68881 04000
  
  /* Store in cc_status the expressions
--- 898,902 ----
  /* Set if the cc value came from a floating point test, so a floating
     point conditional branch must be output.  */
! #define CC_IN_FP 04000
  
  /* Store in cc_status the expressions
***************
*** 977,998 ****
  {								\
    if (GET_CODE (EXP) == SET)					\
!     { if (ADDRESS_REG_P (XEXP (EXP, 0)))			\
  	{ if (cc_status.value1					\
! 	      && reg_overlap_mentioned_p (XEXP (EXP, 0), cc_status.value1)) \
  	    cc_status.value1 = 0;				\
  	  if (cc_status.value2					\
! 	      && reg_overlap_mentioned_p (XEXP (EXP, 0), cc_status.value2)) \
  	    cc_status.value2 = 0; }				\
!       else if (FP_REG_P (XEXP (EXP,0))				\
! 	       || (FP_REG_P (XEXP (EXP,1))			\
! 		   && XEXP (EXP, 0) != cc0_rtx))		\
! 	{ }							\
!       else if (!FP_REG_P (XEXP (EXP, 0))			\
! 	       && XEXP (EXP, 0) != cc0_rtx			\
! 	       && (FP_REG_P (XEXP (EXP, 1))			\
! 		   || GET_CODE (XEXP (EXP, 1)) == FIX		\
! 		   || GET_CODE (XEXP (EXP, 1)) == FLOAT_TRUNCATE \
! 		   || GET_CODE (XEXP (EXP, 1)) == FLOAT_EXTEND)) \
  	{ CC_STATUS_INIT; }					\
        else if (GET_CODE (SET_SRC (EXP)) == CALL)		\
  	{ CC_STATUS_INIT; }					\
--- 913,937 ----
  {								\
    if (GET_CODE (EXP) == SET)					\
!     { if (ADDRESS_REG_P (SET_DEST (EXP)) || FP_REG_P (SET_DEST (EXP)))	    \
  	{ if (cc_status.value1					\
! 	      && reg_overlap_mentioned_p (SET_DEST (EXP), cc_status.value1)) \
  	    cc_status.value1 = 0;				\
  	  if (cc_status.value2					\
! 	      && reg_overlap_mentioned_p (SET_DEST (EXP), cc_status.value2)) \
  	    cc_status.value2 = 0; }				\
!       else if (SET_DEST (EXP) != cc0_rtx				\
! 	       && (FP_REG_P (SET_SRC (EXP))			\
! 		   || GET_CODE (SET_SRC (EXP)) == FIX		\
! 		   || GET_CODE (SET_SRC (EXP)) == FLOAT_TRUNCATE \
! 		   || GET_CODE (SET_SRC (EXP)) == FLOAT_EXTEND)) \
  	{ CC_STATUS_INIT; }					\
+       /* A pair of move insns doesn't produce a useful overall cc.  */ \
+       else if (!FP_REG_P (SET_DEST (EXP))			\
+ 	       && !FP_REG_P (SET_SRC (EXP))			\
+ 	       && GET_MODE_SIZE (GET_MODE (SET_SRC (EXP))) > 4	\
+ 	       && (GET_CODE (SET_SRC (EXP)) == REG		\
+ 		   || GET_CODE (SET_SRC (EXP)) == MEM		\
+ 		   || GET_CODE (SET_SRC (EXP)) == CONST_DOUBLE))\
+ 	{ CC_STATUS_INIT; }					\
        else if (GET_CODE (SET_SRC (EXP)) == CALL)		\
  	{ CC_STATUS_INIT; }					\
***************
*** 1015,1020 ****
        && GET_MODE (cc_status.value2) == QImode)			\
      CC_STATUS_INIT;						\
!   if (cc_status.value2 != 0					\
!       && !(cc_status.value1 && FPA_REG_P (cc_status.value1)))	\
      switch (GET_CODE (cc_status.value2))			\
        { case PLUS: case MINUS: case MULT: case UMULT:		\
--- 954,958 ----
        && GET_MODE (cc_status.value2) == QImode)			\
      CC_STATUS_INIT;						\
!   if (cc_status.value2 != 0)					\
      switch (GET_CODE (cc_status.value2))			\
        { case PLUS: case MINUS: case MULT: case UMULT:		\
***************
*** 1037,1044 ****
    if ((cc_status.value1 && FP_REG_P (cc_status.value1))		\
         || (cc_status.value2 && FP_REG_P (cc_status.value2)))	\
!     cc_status.flags = CC_IN_68881; }
  
  #define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV)  \
! { if (cc_prev_status.flags & CC_IN_68881)			\
      return FLOAT;						\
    if (cc_prev_status.flags & CC_NO_OVERFLOW)			\
--- 975,982 ----
    if ((cc_status.value1 && FP_REG_P (cc_status.value1))		\
         || (cc_status.value2 && FP_REG_P (cc_status.value2)))	\
!     cc_status.flags = CC_IN_FP; }
  
  #define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV)  \
! { if (cc_prev_status.flags & CC_IN_FP)			\
      return FLOAT;						\
    if (cc_prev_status.flags & CC_NO_OVERFLOW)			\
***************
*** 1050,1054 ****
  /* Output at beginning of assembler file.  */
  
! #define ASM_FILE_START(FILE) fprintf (FILE, "#NO_APP\n");
  
  /* Output to assembler file text saying following lines
--- 988,993 ----
  /* Output at beginning of assembler file.  */
  
! #define ASM_FILE_START(FILE)	\
!   fprintf (FILE, "#NO_APP\n");
  
  /* Output to assembler file text saying following lines
***************
*** 1081,1084 ****
--- 1020,1024 ----
     On the Sun-3, the floating point registers have numbers
     18 to 25, not 16 to 23 as they do in the compiler.  */
+ /* (On the Alliant, dbx isn't working yet at all.  */
  
  #define DBX_REGISTER_NUMBER(REGNO) ((REGNO) < 16 ? (REGNO) : (REGNO) + 2)
***************
*** 1246,1252 ****
     For `%' followed by punctuation, CODE is the punctuation and X is null.
  
!    On the 68000, we use several CODE characters:
!    'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)
!    'b' for byte insn (no effect, on the Sun; this is for the ISI).
     '.' for dot needed in Motorola-style opcode names.
     '-' for an operand pushing on the stack:
--- 1186,1190 ----
     For `%' followed by punctuation, CODE is the punctuation and X is null.
  
!    On the Alliant, we use several CODE characters:
     '.' for dot needed in Motorola-style opcode names.
     '-' for an operand pushing on the stack:
***************
*** 1260,1271 ****
     '!' for the cc register (used in an `and to cc' insn).
  
!    'w' for FPA insn (print a CONST_DOUBLE as a SunFPA constant rather
!        than directly).  Second part of 'y' below.
     'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),
!        or print pair of registers as rx:ry.
!    'y' for a FPA insn (print pair of registers as rx:ry).  This also outputs
!        CONST_DOUBLE's as SunFPA constant RAM registers if
!        possible, so it should not be used except for the SunFPA. */
  
  #define PRINT_OPERAND(FILE, X, CODE)  \
  { int i;								\
--- 1198,1211 ----
     '!' for the cc register (used in an `and to cc' insn).
  
!    'b' for byte insn (no effect, on the Sun; this is for the ISI).
!    'd' to force memory addressing to be absolute, not relative.
!    'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)
     'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),
!        or print pair of registers as rx:ry.  */
  
+ #define PRINT_OPERAND_PUNCT_VALID_P(CODE)				\
+   ((CODE) == '.' || (CODE) == '#' || (CODE) == '-'			\
+    || (CODE) == '+' || (CODE) == '@' || (CODE) == '!')
+ 
  #define PRINT_OPERAND(FILE, X, CODE)  \
  { int i;								\
***************
*** 1284,1292 ****
      }									\
    else if (GET_CODE (X) == MEM)						\
!     output_address (XEXP (X, 0));					\
!   else if ((CODE == 'y' || CODE == 'w')					\
! 	   && GET_CODE(X) == CONST_DOUBLE				\
! 	   && (i = standard_SunFPA_constant_p (X)))			\
!     fprintf(FILE, "%%%d", i & 0x1ff);					\
    else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode)	\
      { union { double d; int i[2]; } u;					\
--- 1224,1233 ----
      }									\
    else if (GET_CODE (X) == MEM)						\
!     {									\
!       output_address (XEXP (X, 0));					\
!       if (CODE == 'd' && ! TARGET_68020					\
! 	  && CONSTANT_ADDRESS_P (XEXP (X, 0)))				\
! 	fprintf (FILE, ":l");						\
!     }									\
    else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode)	\
      { union { double d; int i[2]; } u;					\
***************
*** 1401,1406 ****
  	  if (GET_CODE (ireg) == SIGN_EXTEND)				\
  	    fprintf (FILE, "pc@(L%d-LI%d-2:B)[%s:W",			\
- 		     CODE_LABEL_NUMBER (XEXP (addr, 0)),		\
  		     CODE_LABEL_NUMBER (XEXP (addr, 0)),		\
  		     reg_names[REGNO (XEXP (ireg, 0))]); 		\
  	  else								\
--- 1342,1347 ----
  	  if (GET_CODE (ireg) == SIGN_EXTEND)				\
  	    fprintf (FILE, "pc@(L%d-LI%d-2:B)[%s:W",			\
  		     CODE_LABEL_NUMBER (XEXP (addr, 0)),		\
+ 		     CODE_LABEL_NUMBER (XEXP (addr, 0)),		\
  		     reg_names[REGNO (XEXP (ireg, 0))]); 		\
  	  else								\
***************
*** 1414,1418 ****
        if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF)	\
          { fprintf (FILE, "pc@(L%d-LI%d-2:B)[%s:L:B]",			\
! 		   CODE_LABEL_NUMBER (XEXP (addr, 0)),			\
  		   CODE_LABEL_NUMBER (XEXP (addr, 0)),			\
  		   reg_names[REGNO (breg)]);				\
--- 1355,1359 ----
        if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF)	\
          { fprintf (FILE, "pc@(L%d-LI%d-2:B)[%s:L:B]",			\
! 		   CODE_LABEL_NUMBER (XEXP (addr, 0)),			\
  		   CODE_LABEL_NUMBER (XEXP (addr, 0)),			\
  		   reg_names[REGNO (breg)]);				\
***************
*** 1473,1519 ****
  End:
  */
- /* See tm-m68k.h.  3 means 68020 with 68881.  */
- 
- #define TARGET_DEFAULT 3
- 
- /* Define __HAVE_FPA__ or __HAVE_68881__ in preprocessor,
-    according to the -m flags.
-    This will control the use of inline 68881 insns in certain macros.
-    Also inform the program which CPU this is for.  */
- 
- #if TARGET_DEFAULT & 02
- 
- /* -m68881 is the default */
- #define CPP_SPEC \
- "%{!msoft-float:%{mfpa:-D__HAVE_FPA__ }%{!mfpa:-D__HAVE_68881__ }}\
- %{m68000:-Dmc68010}%{mc68000:-Dmc68010}%{!mc68000:%{!m68000:-Dmc68020}}"
- 
- #else
- #if TARGET_DEFAULT & 0100
- 
- /* -mfpa is the default */
- #define CPP_SPEC \
- "%{!msoft-float:%{m68881:-D__HAVE_68881__ }%{!m68881:-D__HAVE_FPA__ }}\
- %{m68000:-Dmc68010}%{mc68000:-Dmc68010}%{!mc68000:%{!m68000:-Dmc68020}}"
- 
- #else
- 
- /* -msoft-float is the default */
- #define CPP_SPEC \
- "%{m68881:-D__HAVE_68881__ }%{mfpa:-D__HAVE_FPA__ }\
- %{m68000:-Dmc68010}%{mc68000:-Dmc68010}%{!mc68000:%{!m68000:-Dmc68020}}"
- 
- #endif
- #endif
- 
- /* Names to predefine in the preprocessor for this target machine.  */
- 
- #define CPP_PREDEFINES "-Dmc68000 -Dalliant -Dunix"
- 
- /* Every structure or union's size must be a multiple of 2 bytes.  */
- 
- #define STRUCTURE_SIZE_BOUNDARY 16
  
- /* This is BSD, so it wants DBX format.  */
- 
- #define DBX_DEBUGGING_INFO
--- 1414,1416 ----
diff -rc2N gcc-1.35/config/tm-altos3068.h gcc-1.36/config/tm-altos3068.h
*** gcc-1.35/config/tm-altos3068.h	Fri Apr 14 11:37:00 1989
--- gcc-1.36/config/tm-altos3068.h	Sun Aug  6 14:28:17 1989
***************
*** 72,75 ****
--- 72,79 ----
  #define DBX_DEBUGGING_INFO
  
+ /* Tell some conditionals we will use GAS.  Is this really used?  */
+ 
+ #define USE_GAS
+ 
  /* This is how to output an assembler line defining a `double' constant.  */
  
***************
*** 92,94 ****
       fprintf (FILE, "#0r%.20g", (VALUE))
  
! #define USE_GAS
--- 96,107 ----
       fprintf (FILE, "#0r%.20g", (VALUE))
  
! /* Return pointer values in both d0 and a0.  */
! 
! #undef FUNCTION_EXTRA_EPILOGUE
! #define FUNCTION_EXTRA_EPILOGUE(FILE, SIZE)			\
! {								\
!   extern int current_function_returns_pointer;			\
!   if ((current_function_returns_pointer) && 			\
!       ! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode))\
!     fprintf (FILE, "\tmovel d0,a0\n");				\
! }
diff -rc2N gcc-1.35/config/tm-apollo68.h gcc-1.36/config/tm-apollo68.h
*** gcc-1.35/config/tm-apollo68.h	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config/tm-apollo68.h	Sun Aug 27 15:24:37 1989
***************
*** 0 ****
--- 1,178 ----
+ /* Definitions of target machine for GNU compiler.  Apollo 680X0 version.
+    Copyright (C) 1989 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+ 
+ #include "tm-m68k.h"
+ 
+ /* This symbol may be tested in other files for special Apollo handling */
+ 
+ #define TM_APOLLO
+ 
+ /* See tm-m68k.h.  7 means 68020 with 68881.  */
+ 
+ #ifndef TARGET_DEFAULT
+ #define TARGET_DEFAULT 7
+ #endif
+ 
+ /* Target switches for the Apollo is the same as in tm-m68k.h, except
+    there is no Sun FPA. */
+ 
+ #undef TARGET_SWITCHES
+ #define TARGET_SWITCHES  \
+   { { "68020", 5},				\
+     { "c68020", 5},				\
+     { "68881", 2},				\
+     { "bitfield", 4},				\
+     { "68000", -5},				\
+     { "c68000", -5},				\
+     { "soft-float", -0102},			\
+     { "nobitfield", -4},			\
+     { "rtd", 8},				\
+     { "nortd", -8},				\
+     { "short", 040},				\
+     { "noshort", -040},				\
+     { "", TARGET_DEFAULT}}
+ 
+ /* Define __HAVE_68881__ in preprocessor,
+    according to the -m flags.
+    This will control the use of inline 68881 insns in certain macros.
+    Also inform the program which CPU this is for.  */
+ 
+ #if TARGET_DEFAULT & 02
+ 
+ /* -m68881 is the default */
+ #define CPP_SPEC \
+ "%{!msoft-float:%{mfpa:-D__HAVE_FPA__ }%{!mfpa:-D__HAVE_68881__ }}\
+ %{!ansi:%{m68000:-Dmc68010}%{mc68000:-Dmc68010}%{!mc68000:%{!m68000:-Dmc68020}}}"
+ 
+ #else
+ 
+ /* -msoft-float is the default */
+ #define CPP_SPEC \
+ "%{m68881:-D__HAVE_68881__ }%{mfpa:-D__HAVE_FPA__ }\
+ %{!ansi:%{m68000:-Dmc68010}%{mc68000:-Dmc68010}%{!mc68000:%{!m68000:-Dmc68020}}}"
+ 
+ #endif
+ 
+ /* Names to predefine in the preprocessor for this target machine.  */
+ /* These are the ones defined by Apollo, plus mc68000 for uniformity with
+    GCC on other 68000 systems.  */
+ 
+ #define CPP_PREDEFINES "-Dapollo -Daegis -Dunix"
+ 
+ /* cpp has to support a #sccs directive for the /usr/include files */
+ 
+ #define SCCS_DIRECTIVE
+ 
+ /* Allow #ident but output nothing for it.  */
+ 
+ #define IDENT_DIRECTIVE
+ #define ASM_OUTPUT_IDENT(FILE, NAME)
+ 
+ /* Allow dollarsigns in identifiers */
+ 
+ #define DOLLARS_IN_IDENTIFIERS 1
+ 
+ /* -m68000 requires special flags to the assembler.
+    The -C flag is passed to a modified GNU assembler to cause COFF
+    modules to be produced. Remove it if you're not using this. */
+ 
+ #define ASM_SPEC \
+  "-C %{m68000:-mc68010}%{mc68000:-mc68010}%{!mc68000:%{!m68000:-mc68020}}"
+ 
+ /* STARTFILE_SPEC
+    Note that includes knowledge of the default specs for gcc, ie. no
+    args translates to the same effect as -m68881 */
+ 
+ #if TARGET_DEFAULT & 2
+ /* -m68881 is the default */
+ #define STARTFILE_SPEC					\
+   "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}"
+ #else
+ /* -msoft-float is the default */
+ #define STARTFILE_SPEC					\
+   "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}"
+ #endif
+ 
+ /* Specify library to handle `-a' basic block profiling.  */
+ 
+ #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} \
+ %{a:/usr/lib/bb_link.o} "
+ 
+ /* Debugging is not supported yet */
+ 
+ #undef DBX_DEBUGGING_INFO
+ #undef SDB_DEBUGGING_INFO
+ 
+ /* Every structure or union's size must be a multiple of 2 bytes.  */
+ 
+ #define STRUCTURE_SIZE_BOUNDARY 16
+ 
+ /* Functions which return large structures get the address
+    to place the wanted value at offset 8 from the frame.  */
+ 
+ #undef  PCC_STATIC_STRUCT_RETURN
+ #undef  STRUCT_VALUE_REGNUM
+ 
+ /* Caller treats address of return area like a parm.  */
+ #define STRUCT_VALUE 0
+ 
+ #define STRUCT_VALUE_INCOMING \
+   gen_rtx (MEM, Pmode,					\
+ 	   gen_rtx (PLUS, SImode, frame_pointer_rtx,	\
+ 		    gen_rtx (CONST_INT, VOIDmode, 8)))
+ 
+ /* Specify how to pad function arguments.
+    Arguments sizes < sizeof(int) are padded upward, and larger arguments
+    are not padded at all. */
+ 
+ #define FUNCTION_ARG_PADDING(mode, size)				\
+   (((mode) == BLKmode							\
+     ? (GET_CODE (size) == CONST_INT					\
+        && INTVAL (size) < PARM_BOUNDARY / BITS_PER_UNIT)		\
+     : GET_MODE_BITSIZE (mode) < PARM_BOUNDARY)				\
+    ? upward : none)
+ 
+ /* Short integral argument prototype promotion is not done */
+ 
+ #undef  PROMOTE_PROTOTYPES
+ 
+ /* The definition of this macro imposes a limit on the size of
+    an aggregate object which can be treated as if it were a scalar
+    object. */
+ 
+ #define MAX_FIXED_MODE_SIZE    BITS_PER_WORD
+ 
+ /* The definition of this macro implies that there are cases where
+    a scalar value cannot be returned in registers.
+    For Apollo, anything larger than one integer register is returned
+    using the structure-value mechanism, i.e. objects of DFmode are
+    returned that way. */
+ 
+ #define RETURN_IN_MEMORY(type) \
+   (GET_MODE_SIZE (TYPE_MODE (type)) > UNITS_PER_WORD)
+ 
+ /* This is how to output a reference to a user-level label named NAME.
+    In order to link to Apollo libraries, no underscore is prepended to names.
+    `assemble_name' uses this.  */
+ 
+ #undef  ASM_OUTPUT_LABELREF
+ #define ASM_OUTPUT_LABELREF(FILE,NAME)	\
+   fprintf (FILE, "%s", NAME)
+ 
+ 
diff -rc2N gcc-1.35/config/tm-convex.h gcc-1.36/config/tm-convex.h
*** gcc-1.35/config/tm-convex.h	Mon Apr 10 23:22:32 1989
--- gcc-1.36/config/tm-convex.h	Fri Aug 18 15:50:22 1989
***************
*** 712,738 ****
  
  /* Alignment with Convex's assembler goes like this:
!    .text will allow .align 1 or .align 2
!    .data allows 1,2,4,8 (at least; but those are all we need).
!    there is no .lcomm, must use explicit decls in .bss instead.
!    .text and .data have subsections, each starts on an 8-byte boundary.
!    So, since alignment is worth having, 
!    use ".text <n>" for 2**<n>-byte aligned text section --
!    this assumes that all lengths are multiples of their alignment.
!    use .align in .text if possible, and it's always possible in .data.
!    gcc arranges that everything in .bss is a multiple of 8, so it
!    stays aligned.
!    This is all handled in two routines in output-convex.c. */
  
! extern char *set_section ();
! extern char *align_section ();
  
  /* Output before read-only data.  */
  
! #define TEXT_SECTION_ASM_OP set_section (".text")
  
  /* Output before writable data.  */
  
! #define DATA_SECTION_ASM_OP set_section (".data")
  
  /* How to refer to registers in assembler output.
     This sequence is indexed by compiler's hard-register-number (see above).  */
--- 712,764 ----
  
  /* Alignment with Convex's assembler goes like this:
!    .text can be .aligned up to a halfword.
!    .data and .bss can be .aligned up to a longword.
!    .lcomm is not supported, explicit declarations in .bss must be used instead.
!    We get alignment for word and longword .text data by conventionally
!    using .text 2 for word-aligned data and .text 3 for longword-aligned
!    data.  This requires that this data's size be a multiple of its alignment,
!    which seems to be always true.  */
!    
! /* Boolean to keep track of whether the current section is .text or not.  */
  
! int current_section_is_text;
  
  /* Output before read-only data.  */
  
! #define TEXT_SECTION_ASM_OP (current_section_is_text = 1, ".text")
  
  /* Output before writable data.  */
  
! #define DATA_SECTION_ASM_OP (current_section_is_text = 0, ".data") 
  
+ /* Output before uninitialized data.  */
+ 
+ #define BSS_SECTION_ASM_OP (current_section_is_text = 0, ".bss") 
+ 
+ #define EXTRA_SECTIONS in_bss
+ 
+ #define EXTRA_SECTION_FUNCTIONS						\
+ void									\
+ bss_section ()								\
+ {									\
+   if (in_section != in_bss)						\
+     {									\
+       fprintf (asm_out_file, "%s\n", BSS_SECTION_ASM_OP);		\
+       in_section = in_bss;						\
+     }									\
+ }
+ 
+ /* This is how to output an assembler line
+    that says to advance the location counter
+    to a multiple of 2**LOG bytes.  */
+ 
+ #define ASM_OUTPUT_ALIGN(FILE,LOG)  \
+   if (current_section_is_text && (LOG) > 1)				\
+     fprintf (FILE, ".text %d\n", LOG);					\
+   else if (current_section_is_text)					\
+     fprintf (FILE, ".text\n.align %d\n", 1 << (LOG));			\
+   else									\
+     fprintf (FILE, ".align %d\n", 1 << (LOG))
+ 
  /* How to refer to registers in assembler output.
     This sequence is indexed by compiler's hard-register-number (see above).  */
***************
*** 790,798 ****
  
  #define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLE) \
!   fprintf (FILE, ".text 2\n"); \
    ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM)
  
  #define ASM_OUTPUT_CASE_END(FILE,NUM,TABLE) \
!   fprintf (FILE, ".text\n");
  
  /* This is how to store into the string LABEL
--- 816,824 ----
  
  #define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLE) \
!   ASM_OUTPUT_ALIGN (FILE, 2); \
    ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM)
  
  #define ASM_OUTPUT_CASE_END(FILE,NUM,TABLE) \
!   ASM_OUTPUT_ALIGN (FILE, 1)
  
  /* This is how to store into the string LABEL
***************
*** 879,891 ****
  
  /* This is how to output an assembler line
!    that says to advance the location counter
!    to a multiple of 2**LOG bytes.  */
  
- #define ASM_OUTPUT_ALIGN(FILE,LOG)  \
-   fprintf (FILE, align_section (LOG));
- 
-  /* This is how to output an assembler line
-     that says to advance the location counter by SIZE bytes.  */
- 
  #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
    fprintf (FILE, "\tds.b %d(0)\n", (SIZE))
--- 905,910 ----
  
  /* This is how to output an assembler line
!    that says to advance the location counter by SIZE bytes.  */
  
  #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
    fprintf (FILE, "\tds.b %d(0)\n", (SIZE))
***************
*** 903,910 ****
  
  #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)  \
! ( fprintf ((FILE), "%s\n", set_section (".bss")), \
    assemble_name ((FILE), (NAME)),		\
!   fprintf ((FILE), ":\tbs.b %d\n", (ROUNDED)),	\
!   fprintf ((FILE), "%s\n", set_section (0)))
  
  /* Store in OUTPUT a string (made with alloca) containing
--- 922,928 ----
  
  #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)  \
! ( bss_section (),				\
    assemble_name ((FILE), (NAME)),		\
!   fprintf ((FILE), ":\tbs.b %d\n", (ROUNDED)))
  
  /* Store in OUTPUT a string (made with alloca) containing
***************
*** 989,991 ****
--- 1007,1010 ----
      fprintf (FILE, "(%s)", reg_names[REGNO (index)]);			\
  }
+ 
  
diff -rc2N gcc-1.35/config/tm-decstatn.h gcc-1.36/config/tm-decstatn.h
*** gcc-1.35/config/tm-decstatn.h	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config/tm-decstatn.h	Sun Sep 24 00:52:34 1989
***************
*** 0 ****
--- 1,3 ----
+ #define DECSTATION
+ 
+ #include "tm-mips.h"
diff -rc2N gcc-1.35/config/tm-encore.h gcc-1.36/config/tm-encore.h
*** gcc-1.35/config/tm-encore.h	Wed Mar 29 17:41:26 1989
--- gcc-1.36/config/tm-encore.h	Fri Jun 23 21:41:40 1989
***************
*** 30,33 ****
--- 30,35 ----
  
  #define SDB_DEBUGGING_INFO
+ #undef DBX_REGISTER_NUMBER
+ #define DBX_REGISTER_NUMBER(REGNO) (REGNO)
  
  /* Cause long-jump assembler to be used,
diff -rc2N gcc-1.35/config/tm-genix.h gcc-1.36/config/tm-genix.h
*** gcc-1.35/config/tm-genix.h	Wed Mar 29 17:41:24 1989
--- gcc-1.36/config/tm-genix.h	Fri Apr 28 18:22:24 1989
***************
*** 20,23 ****
--- 20,26 ----
  #include "tm-encore.h"
  
+ /* We don't want the one Encore needs.  */
+ #undef ASM_SPEC
+ 
  /* The following defines override ones in tm-ns32k.h and prevent any attempts
     to explicitly or implicitly make references to the SB register in the GCC
diff -rc2N gcc-1.35/config/tm-harris.h gcc-1.36/config/tm-harris.h
*** gcc-1.35/config/tm-harris.h	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config/tm-harris.h	Sun Sep 24 00:22:39 1989
***************
*** 0 ****
--- 1,77 ----
+ /* Definitions of target machine for GNU compiler.  Harris tahoe version.
+    Copyright (C) 1989 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+ 
+ 
+ #include "tm-tahoe.h"
+ 
+ #undef CPP_PREDEFINES
+ #define CPP_PREDEFINES "-Dtahoe -Dunix -Dhcx"
+ 
+ #undef DBX_DEBUGGING_INFO
+ #define SDB_DEBUGGING_INFO
+ 
+ #undef TARGET_DEFAULT
+ #define TARGET_DEFAULT 1
+ 
+ /* urem and udiv don't exist on this system.  */
+ #undef UDIVSI3_LIBCALL
+ #undef UMODSI3_LIBCALL
+ 
+ /* Operand of .align is not logarithmic.  */
+ #undef ASM_OUTPUT_ALIGN
+ #define ASM_OUTPUT_ALIGN(FILE,LOG)  \
+   LOG ? fprintf (FILE, "\t.align %d\n", 1 << (LOG)) : 0
+ 
+ /* For the same reason, we need .align 2 after casesi.  */
+ #undef PRINT_OPERAND
+ #define PRINT_OPERAND(FILE, X, CODE)  \
+ { if (CODE == '@')							\
+     putc ('2', FILE);							\
+   else if (GET_CODE (X) == REG)						\
+     fprintf (FILE, "%s", reg_names[REGNO (X)]);				\
+   else if (GET_CODE (X) == MEM)						\
+     output_address (XEXP (X, 0));					\
+   else { putc ('$', FILE); output_addr_const (FILE, X); }}
+ 
+ #undef ASM_OUTPUT_LOCAL
+ #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)  \
+ ( fputs (".bss ", (FILE)),			\
+   assemble_name ((FILE), (NAME)),		\
+   fprintf ((FILE), ",%d,4\n", (ROUNDED)))
+ 
+ #define ASM_OUTPUT_ASCII(FILE, PTR, SIZE)		\
+ {							\
+   unsigned char *_p = (PTR);				\
+   int _thissize = (SIZE);				\
+   fprintf ((FILE), "\t.ascii \"");			\
+   for (i = 0; i < _thissize; i++)			\
+     {							\
+       register int c = _p[i];				\
+       if (c >= ' ' && c < 0177 && c != '\"' && c != '\\') \
+ 	putc (c, (FILE));				\
+       else						\
+ 	{						\
+ 	  fprintf ((FILE), "\\%o", c);			\
+ 	  if (i < _thissize - 1				\
+ 	      && _p[i + 1] >= '0' && _p[i + 1] <= '9')	\
+ 	    fprintf ((FILE), "\"\n\t.ascii \"");	\
+ 	}						\
+     }							\
+   fprintf ((FILE), "\"\n");				\
+ }
diff -rc2N gcc-1.35/config/tm-hp9k310g.h gcc-1.36/config/tm-hp9k310g.h
*** gcc-1.35/config/tm-hp9k310g.h	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config/tm-hp9k310g.h	Sun Aug  6 14:52:58 1989
***************
*** 0 ****
--- 1,12 ----
+ /* Definitions of target machine for GNU compiler.  HP-UX 68000/68020 version.
+    Use this file if GCC is supposed to work with the GNU assembler,
+    GNU linker and GNU debugger using DBX debugging information.
+    (In other words, much of HPUX has been cast aside.)  */
+ 
+ /* This wants DBX format.  */
+ 
+ #define DBX_DEBUGGING_INFO
+ 
+ #define USE_GAS
+ 
+ #include "tm-hp9k310.h"
diff -rc2N gcc-1.35/config/tm-hp9k320.h gcc-1.36/config/tm-hp9k320.h
*** gcc-1.35/config/tm-hp9k320.h	Fri Apr 14 11:11:14 1989
--- gcc-1.36/config/tm-hp9k320.h	Mon Aug 28 12:41:42 1989
***************
*** 44,70 ****
     This will control the use of inline 68881 insns in certain macros.  */
  
  #ifdef HPUX_ASM
! /* __HPUX_ASM__ is needed because some programs, particularly GDB, need to
     know which assembler is being used so that the correct `asm'
     instructions can be used. */
! #define CPP_SPEC "%{!msoft-float:-D__HAVE_68881__} -D__HPUX_ASM__"
! #define ASM_SPEC "%{m68000:+X}"
! #else
  
! #if TARGET_DEFAULT & 02
  
! /* -m68881 is the default */
  #define CPP_SPEC \
  "%{!msoft-float:-D__HAVE_68881__ }\
! %{!ansi:%{m68000:-Dmc68000}%{mc68000:-Dmc68000}%{!mc68000:%{!m68000:-Dmc68020}}}"
  
! #else
  
- /* -msoft-float is the default */
  #define CPP_SPEC \
  "%{m68881:-D__HAVE_68881__ }\
! %{!ansi:%{m68000:-Dmc68000}%{mc68000:-Dmc68000}%{!mc68000:%{!m68000:-Dmc68020}}}"
  
! #endif
  
  
--- 44,88 ----
     This will control the use of inline 68881 insns in certain macros.  */
  
+ /* For version 6.2 of HP-UX (or earlier), remove the "-V 3" from
+    ASM_SPEC below. */
+ 
  #ifdef HPUX_ASM
! 
! #define ASM_SPEC "%{m68000:+X} -V 3"
! 
! #if TARGET_DEFAULT & 02  /* -m68881 is the default */
! 
! /* These definitions differ from those used for GAS by defining __HPUX_ASM__.
!    This is needed because some programs, particularly GDB, need to
     know which assembler is being used so that the correct `asm'
     instructions can be used. */
! 
! #define CPP_SPEC \
! "%{!msoft-float:-D__HAVE_68881__ }\
! %{!ansi:%{!mc68000:%{!m68000:-Dmc68020}}} -D__HPUX_ASM__"
! 
! #else /* default is -msoft-float */
  
! #define CPP_SPEC \
! "%{m68881:-D__HAVE_68881__ }\
! %{!ansi:%{!mc68000:%{!m68000:-Dmc68020}}} -D__HPUX_ASM__"
! 
! #endif /* default is -msoft-float */
! 
! #else /* not HPUX_ASM */
  
! #if TARGET_DEFAULT & 02  /* -m68881 is the default */
! 
  #define CPP_SPEC \
  "%{!msoft-float:-D__HAVE_68881__ }\
! %{!ansi:%{!mc68000:%{!m68000:-Dmc68020}}}"
  
! #else /* default is -msoft-float */
  
  #define CPP_SPEC \
  "%{m68881:-D__HAVE_68881__ }\
! %{!ansi:%{!mc68000:%{!m68000:-Dmc68020}}}"
  
! #endif /* default is -msoft-float */
  
  
***************
*** 74,87 ****
  
  /* special directory for gnu libs on hp-ux system */
! #ifndef STANDARD_STARTFILE_PREFIX
  #define STANDARD_STARTFILE_PREFIX "/usr/local/lib/gnu/"
- #endif
  
! #endif
  
  /* Names to predefine in the preprocessor for this target machine
     (for non-strict-ANSI programs only).  */
  
! #define CPP_PREDEFINES "-Dhp9000s200 -Dhp9000s300 -DPWB -Dmc68k -Dhpux -Dunix"
  
  /* Every structure or union's size must be a multiple of 2 bytes.  */
--- 92,106 ----
  
  /* special directory for gnu libs on hp-ux system */
! #undef STANDARD_STARTFILE_PREFIX
  #define STANDARD_STARTFILE_PREFIX "/usr/local/lib/gnu/"
  
! #endif /* Not HPUX_ASM */
  
  /* Names to predefine in the preprocessor for this target machine
     (for non-strict-ANSI programs only).  */
+ /* These are the ones defined by HPUX cc, plus mc68000 for uniformity with
+    GCC on other 68000 systems.  */
  
! #define CPP_PREDEFINES "-Dhp9000s200 -Dhp9000s300 -DPWB -Dhpux -Dunix"
  
  /* Every structure or union's size must be a multiple of 2 bytes.  */
***************
*** 89,92 ****
--- 108,114 ----
  #define STRUCTURE_SIZE_BOUNDARY 16
  
+ /* hpux doesn't use static area for struct returns. */
+ #undef PCC_STATIC_STRUCT_RETURN
+ 
  /* Generate calls to memcpy, memcmp and memset.  */
  #define TARGET_MEM_FUNCTIONS
***************
*** 456,461 ****
  	  if (GET_CODE (ireg) == SIGN_EXTEND)				\
  	    fprintf (FILE, "L%d-LI%d(%%pc,%s.w",			\
- 		     CODE_LABEL_NUMBER (XEXP (addr, 0)),		\
  		     CODE_LABEL_NUMBER (XEXP (addr, 0)),		\
  		     reg_names[REGNO (XEXP (ireg, 0))]); 		\
  	  else								\
--- 478,483 ----
  	  if (GET_CODE (ireg) == SIGN_EXTEND)				\
  	    fprintf (FILE, "L%d-LI%d(%%pc,%s.w",			\
  		     CODE_LABEL_NUMBER (XEXP (addr, 0)),		\
+ 		     CODE_LABEL_NUMBER (XEXP (addr, 0)),		\
  		     reg_names[REGNO (XEXP (ireg, 0))]); 		\
  	  else								\
***************
*** 489,493 ****
        else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF)		\
  	{ fprintf (FILE, "L%d-LI%d(%%pc,%s.w)",				\
! 		   CODE_LABEL_NUMBER (XEXP (addr, 0)),			\
  		   CODE_LABEL_NUMBER (XEXP (addr, 0)),			\
  		   reg_names[REGNO (reg1)]);				\
--- 511,515 ----
        else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF)		\
  	{ fprintf (FILE, "L%d-LI%d(%%pc,%s.w)",				\
! 		   CODE_LABEL_NUMBER (XEXP (addr, 0)),			\
  		   CODE_LABEL_NUMBER (XEXP (addr, 0)),			\
  		   reg_names[REGNO (reg1)]);				\
***************
*** 562,566 ****
  }
  
! /* Prevent output of `gcc_compiled.:'.
  
  #define ASM_IDENTIFY_GCC(FILE)
--- 584,588 ----
  }
  
! /* Prevent output of `gcc_compiled.:'.  */
  
  #define ASM_IDENTIFY_GCC(FILE)
diff -rc2N gcc-1.35/config/tm-hp9k3bsd.h gcc-1.36/config/tm-hp9k3bsd.h
*** gcc-1.35/config/tm-hp9k3bsd.h	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config/tm-hp9k3bsd.h	Fri Jun 23 23:35:50 1989
***************
*** 0 ****
--- 1,36 ----
+ #include "tm-m68k.h"
+ 
+ /* See tm-m68k.h.  7 means 68020 with 68881.  */
+ 
+ #define TARGET_DEFAULT 7
+ 
+ /* Define __HAVE_FPU__ in preprocessor, unless -msoft-float is specified.
+    This will control the use of inline 68881 insns in certain macros.  */
+ 
+ #define CPP_SPEC "%{!msoft-float:-D__HAVE_FPU__}"
+ 
+ /* Names to predefine in the preprocessor for this target machine.  */
+ 
+ #define CPP_PREDEFINES "-Dmc68000 -Dmc68020 -Dhp300 -Dhp9000 -Dunix"
+ 
+ /* Every structure or union's size must be a multiple of 2 bytes.  */
+ 
+ #define STRUCTURE_SIZE_BOUNDARY 16
+ 
+ /* This is BSD, so it wants DBX format.  */
+ 
+ #define DBX_DEBUGGING_INFO
+ 
+ /* Do not break .stabs pseudos into continuations.  */
+ 
+ #define DBX_CONTIN_LENGTH 0
+ 
+ /* This is the char to use for continuation (in case we need to turn
+    continuation back on).  */
+ 
+ #define DBX_CONTIN_CHAR '?'
+ 
+ /* Don't use the `xsfoo;' construct in DBX output; this system
+    doesn't support it.  */
+ 
+ #define DBX_NO_XREFS
diff -rc2N gcc-1.35/config/tm-i386.h gcc-1.36/config/tm-i386.h
*** gcc-1.35/config/tm-i386.h	Wed Feb 22 12:27:48 1989
--- gcc-1.36/config/tm-i386.h	Sun Jun 25 00:00:48 1989
***************
*** 243,247 ****
  
  enum reg_class {
!   NO_REGS, AREG, DREG, ADREG, CREG, BREG, Q_REGS,
    INDEX_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS, LIM_REG_CLASSES };
  
--- 243,247 ----
  
  enum reg_class {
!   NO_REGS, AREG, DREG, ADREG, CREG, BREG, Q_REGS, SIREG, DIREG,
    INDEX_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS, LIM_REG_CLASSES };
  
***************
*** 252,255 ****
--- 252,256 ----
  #define REG_CLASS_NAMES \
  {  "NO_REGS", "AREG", "DREG", "ADREG", "CREG", "BREG","Q_REGS", \
+    "SIREG", "DIREG",						\
     "INDEX_REGS", "GENERAL_REGS", "FLOAT_REGS", "ALL_REGS"}
  /* Define which registers fit in which classes.
***************
*** 260,264 ****
  
  #define REG_CLASS_CONTENTS {0, 0x1, 0x2, 0x3, 0x4, 0x8, 0xf,\
! 			    0x7f, 0xff, 0x300, 0x3ff}
  
  /* The same information, inverted:
--- 261,265 ----
  
  #define REG_CLASS_CONTENTS {0, 0x1, 0x2, 0x3, 0x4, 0x8, 0xf,\
! 			    0x10, 0x20, 0x7f, 0xff, 0x300, 0x3ff}
  
  /* The same information, inverted:
***************
*** 272,275 ****
--- 273,278 ----
    (REGNO) == 2 ? CREG : \
    (REGNO) == 3 ? BREG : \
+   (REGNO) == 4 ? SIREG : \
+   (REGNO) == 5 ? DIREG : \
    (REGNO) == 7 ? GENERAL_REGS : \
    (REGNO) < 8 ? INDEX_REGS : \
***************
*** 301,311 ****
  /* Get reg_class from a letter such as appears in the machine description.  */
  
! #define REG_CLASS_FROM_LETTER(C) \
!   ((C) == 'r' ? GENERAL_REGS :		\
!    (C) == 'q' ? Q_REGS :		\
!    (C) == 'f' ? FLOAT_REGS :		\
     (C) == 'a' ? AREG : (C) == 'b' ? BREG :	\
     (C) == 'c' ? CREG : (C) == 'd' ? DREG :	\
!    (C) == 'A' ? ADREG : NO_REGS)
  
  /* The letters I, J, K, L and M in a register constraint string
--- 304,316 ----
  /* Get reg_class from a letter such as appears in the machine description.  */
  
! #define REG_CLASS_FROM_LETTER(C)		\
!   ((C) == 'r' ? GENERAL_REGS :			\
!    (C) == 'q' ? Q_REGS :			\
!    (C) == 'f' ? FLOAT_REGS :			\
     (C) == 'a' ? AREG : (C) == 'b' ? BREG :	\
     (C) == 'c' ? CREG : (C) == 'd' ? DREG :	\
!    (C) == 'A' ? ADREG :				\
!    (C) == 'S' ? SIREG :				\
!    (C) == 'D' ? DIREG : NO_REGS)
  
  /* The letters I, J, K, L and M in a register constraint string
***************
*** 492,501 ****
  
  /* Output assembler code to FILE to increment profiler label # LABELNO
!    for profiling a function entry.
  
-    THIS DEFINITION FOR THE 80386 IS A GUESS.  IT HAS NOT BEEN TESTED.  */
- 
  #define FUNCTION_PROFILER(FILE, LABELNO)  \
!    fprintf (FILE, "\tlea %sP%d,%%eax\n\tcall mcount\n", LPREFIX, (LABELNO));
  
  /* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
--- 497,504 ----
  
  /* Output assembler code to FILE to increment profiler label # LABELNO
!    for profiling a function entry.  */
  
  #define FUNCTION_PROFILER(FILE, LABELNO)  \
!    fprintf (FILE, "\tmovl $%sP%d,%%edx\n\tcall _mcount\n", LPREFIX, (LABELNO));
  
  /* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
***************
*** 1040,1043 ****
--- 1043,1049 ----
     w -- print the operand as if it's a "word" (HImode) even if it isn't.
     c -- don't print special prefixes before constant operands.  */
+ 
+ #define PRINT_OPERAND_PUNCT_VALID_P(CODE)				\
+   ((CODE) == '*')
  
  #define PRINT_OPERAND(FILE, X, CODE)  \
diff -rc2N gcc-1.35/config/tm-i386gas.h gcc-1.36/config/tm-i386gas.h
*** gcc-1.35/config/tm-i386gas.h	Wed Mar 29 17:31:07 1989
--- gcc-1.36/config/tm-i386gas.h	Fri Sep  1 18:13:01 1989
***************
*** 27,31 ****
   *  ASM_OUTPUT_LOCAL is done with .set .,.+N, but that can't be
   *   used to define bss static space
-  *  ASM_OUTPUT_ALIGN's arg is N instead of log(N) for att
   *
   * Next is the question of whether to uses underscores.  RMS didn't
--- 27,30 ----
***************
*** 71,74 ****
--- 70,83 ----
  #define TARGET_MEM_FUNCTIONS
  
+ /* When using gas, .align N aligns to an N-byte boundary.  */
+ 
+ #undef ASM_OUTPUT_ALIGN
+ #define ASM_OUTPUT_ALIGN(FILE,LOG)	\
+      if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", 1<<(LOG))
+ 
+ /* Align labels, etc. at 4-byte boundaries.  */
+ 
+ #define ASM_OUTPUT_ALIGN_CODE(FILE) \
+      fprintf ((FILE), "\t.align 4\n");
  \f


  /* Machines that use the AT&T assembler syntax
diff -rc2N gcc-1.35/config/tm-i386v.h gcc-1.36/config/tm-i386v.h
*** gcc-1.35/config/tm-i386v.h	Wed Mar 29 17:31:06 1989
--- gcc-1.36/config/tm-i386v.h	Fri Aug  4 00:39:41 1989
***************
*** 34,38 ****
    "%{pg:gcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}"
  
! #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} crtn.o%s"
  
  /* Specify predefined symbols in preprocessor.  */
--- 34,38 ----
    "%{pg:gcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}"
  
! #define LIB_SPEC "%{p:-L/usr/lib/libp}%{pg:-L/usr/lib/libp} -lc crtn.o%s"
  
  /* Specify predefined symbols in preprocessor.  */
***************
*** 59,62 ****
--- 59,66 ----
  
  #define TARGET_MEM_FUNCTIONS
+ 
+ /* Writing `int' for a bitfield forces int alignment for the structure.  */
+ 
+ #define PCC_BITFIELD_TYPE_MATTERS
  
  /* Don't write a `.optim' pseudo; this assembler doesn't handle them.  */
diff -rc2N gcc-1.35/config/tm-i860.h gcc-1.36/config/tm-i860.h
*** gcc-1.35/config/tm-i860.h	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config/tm-i860.h	Fri Sep  1 04:43:40 1989
***************
*** 0 ****
--- 1,1191 ----
+ /* Definitions of target machine for GNU compiler, for Intel 860.
+    Copyright (C) 1989 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+ 
+ 
+ /* Note that some other tm- files include this one and then override
+    many of the definitions that relate to assembler syntax.  */
+ 
+ 
+ /* Names to predefine in the preprocessor for this target machine.  */
+ 
+ #define CPP_PREDEFINES "-Di860 -Dunix"
+ 
+ /* Print subsidiary information on the compiler version in use.  */
+ #define TARGET_VERSION fprintf (stderr, " (i860)");
+ 
+ /* Run-time compilation parameters selecting different hardware subsets.
+ 
+    On the i860, we have one: TARGET_FPU.  */
+ 
+ extern int target_flags;
+ 
+ /* Nonzero if we should generate code to use the fpu.  */
+ #define TARGET_FPU (target_flags & 1)
+ 
+ /* Macro to define tables used to set the flags.
+    This is a list in braces of pairs in braces,
+    each pair being { "NAME", VALUE }
+    where VALUE is the bits to set or minus the bits to clear.
+    An empty string NAME is used to identify the default VALUE.  */
+ 
+ #define TARGET_SWITCHES  \
+   { {"fpu", 1},			\
+     {"soft-float", -1},		\
+     { "", TARGET_DEFAULT}}
+ 
+ #define TARGET_DEFAULT 1
+ \f


+ /* target machine storage layout */
+ 
+ /* Define this if most significant bit is lowest numbered
+    in instructions that operate on numbered bit-fields.
+    This is a moot question on the i860 due to the lack of bit-field insns.  */
+ /* #define BITS_BIG_ENDIAN */
+ 
+ /* Define this if most significant byte of a word is the lowest numbered.  */
+ /* That is not true on i860 in the mode we will use.  */
+ /* #define BYTES_BIG_ENDIAN */
+ 
+ /* Define this if most significant word of a multiword number is numbered.  */
+ /* For the i860 this goes with BYTES_BIG_ENDIAN.  */
+ /* #define WORDS_BIG_ENDIAN */
+ 
+ /* number of bits in an addressible 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 32
+ 
+ /* Width of a word, in units (bytes).  */
+ #define UNITS_PER_WORD 4
+ 
+ /* Width in bits of a pointer.
+    See also the macro `Pmode' defined below.  */
+ #define POINTER_SIZE 32
+ 
+ /* Allocation boundary (in *bits*) for storing pointers in memory.  */
+ #define POINTER_BOUNDARY 32
+ 
+ /* Allocation boundary (in *bits*) for storing arguments in argument list.  */
+ #define PARM_BOUNDARY 32
+ 
+ /* Boundary (in *bits*) on which stack pointer should be aligned.  */
+ #define STACK_BOUNDARY 128
+ 
+ /* Allocation boundary (in *bits*) for the code of a function.  */
+ #define FUNCTION_BOUNDARY 32
+ 
+ /* Alignment of field after `int : 0' in a structure.  */
+ #define EMPTY_FIELD_BOUNDARY 32
+ 
+ /* Every structure's size must be a multiple of this.  */
+ #define STRUCTURE_SIZE_BOUNDARY 8
+ 
+ /* No data type wants to be aligned rounder than this.  */
+ #define BIGGEST_ALIGNMENT 64
+ 
+ /* Define this if move instructions will actually fail to work
+    when given unaligned data.  */
+ #define STRICT_ALIGNMENT
+ 
+ /* If bit field type is int, dont let it cross an int,
+    and give entire struct the alignment of an int.  */
+ #define PCC_BITFIELD_TYPE_MATTERS
+ \f


+ /* Standard register usage.  */
+ 
+ /* Number of actual hardware registers.
+    The hardware registers are assigned numbers for the compiler
+    from 0 to just below FIRST_PSEUDO_REGISTER.
+    All registers that the compiler knows about must be given numbers,
+    even those that are not normally considered general registers.
+ 
+    i860 has 32 fullword registers and 32 floating point registers.  */
+ 
+ #define FIRST_PSEUDO_REGISTER 64
+ 
+ /* 1 for registers that have pervasive standard uses
+    and are not available for the register allocator.
+    On the i860, this includes the always-0 registers
+    and fp, sp, and the return address.
+    Also r31, used for special purposes for constant addresses.  */
+ #define FIXED_REGISTERS  \
+  {1, 1, 1, 1, 0, 0, 0, 0,	\
+   0, 0, 0, 0, 0, 0, 0, 0,	\
+   0, 0, 0, 0, 0, 0, 0, 0,	\
+   0, 0, 0, 0, 0, 0, 0, 1,	\
+   1, 1, 0, 0, 0, 0, 0, 0,	\
+   0, 0, 0, 0, 0, 0, 0, 0,	\
+   0, 0, 0, 0, 0, 0, 0, 0,	\
+   0, 0, 0, 0, 0, 0, 0, 0}
+ 
+ /* 1 for registers not available across function calls.
+    These must include the FIXED_REGISTERS and also any
+    registers that can be used without being saved.
+    On the i860, these are r0-r3, r16-r31, f0, f1, and f16-f31.  */
+ #define CALL_USED_REGISTERS  \
+  {1, 1, 1, 1, 0, 0, 0, 0,	\
+   0, 0, 0, 0, 0, 0, 0, 0,	\
+   1, 1, 1, 1, 1, 1, 1, 1,	\
+   1, 1, 1, 1, 1, 1, 1, 1,	\
+   1, 1, 0, 0, 0, 0, 0, 0,	\
+   1, 1, 1, 1, 1, 1, 1, 1,	\
+   1, 1, 1, 1, 1, 1, 1, 1,	\
+   1, 1, 1, 1, 1, 1, 1, 1}
+ 
+ #define REG_ALLOC_ORDER  \
+  {16, 17, 18, 19, 20, 21, 22, 23, 	\
+   24, 25, 26, 27, 28, 29, 30, 31,	\
+   0, 1, 2, 3, 4, 5, 6, 7,		\
+   8, 9, 10, 11, 12, 13, 14, 15,		\
+   40, 41, 42, 43, 44, 45, 46, 47,	\
+   48, 49, 50, 51, 52, 53, 54, 55,	\
+   56, 57, 58, 59, 60, 61, 62, 63,	\
+   32, 33, 34, 35, 36, 37, 38, 39}
+ 
+ /* Return number of consecutive hard regs needed starting at reg REGNO
+    to hold something of mode MODE.
+    This is ordinarily the length in words of a value of mode MODE
+    but can be less for certain modes in special long registers.
+ 
+    On the i860, all registers hold 32 bits worth.  */
+ #define HARD_REGNO_NREGS(REGNO, MODE)   \
+   (((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
+ 
+ /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
+    On the i860, any register can hold anything, provided it is properly
+    aligned.  */
+ #define HARD_REGNO_MODE_OK(REGNO, MODE) \
+   (((GET_MODE_SIZE ((MODE)) <= 4) || ((REGNO) & 1) == 0)	\
+    && ((REGNO) < 32 || TARGET_FPU))
+ 
+ /* Value is 1 if it is a good idea to tie two pseudo registers
+    when one has mode MODE1 and one has mode MODE2.
+    If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
+    for any hard reg, then this must be 0 for correct output.  */
+ /* I think that is not always true; alignment restrictions for doubles
+    should not prevent tying them with singles.  So try allowing that.
+    On the other hand, don't let fixed and floating be tied;
+    this restriction is not necessary, but may make better code.  */
+ #define MODES_TIEABLE_P(MODE1, MODE2) \
+   ((GET_MODE_CLASS ((MODE1)) == MODE_FLOAT)	\
+    == (GET_MODE_CLASS ((MODE2)) == MODE_FLOAT))
+ 
+ /* Specify the registers used for certain standard purposes.
+    The values of these macros are register numbers.  */
+ 
+ /* i860 pc isn't overloaded on a register that the compiler knows about.  */
+ /* #define PC_REGNUM  */
+ 
+ /* Register to use for pushing function arguments.  */
+ #define STACK_POINTER_REGNUM 2
+ 
+ /* Base register for access to local variables of the function.  */
+ #define FRAME_POINTER_REGNUM 3
+ 
+ /* Value should be nonzero if functions must have frame pointers.
+    Zero means the frame pointer need not be set up (and parms
+    may be accessed via the stack pointer) in functions that seem suitable.
+    This is computed in `reload', in reload1.c.  */
+ #define FRAME_POINTER_REQUIRED 1
+ 
+ /* Base register for access to arguments of the function.  */
+ #define ARG_POINTER_REGNUM 28
+ 
+ /* Register in which static-chain is passed to a function.  */
+ #define STATIC_CHAIN_REGNUM 29
+ 
+ /* Register in which address to store a structure value
+    is passed to a function.  */
+ #define STRUCT_VALUE_REGNUM 16
+ \f


+ /* Define the classes of registers for register constraints in the
+    machine description.  Also define ranges of constants.
+ 
+    One of the classes must always be named ALL_REGS and include all hard regs.
+    If there is more than one class, another class must be named NO_REGS
+    and contain no registers.
+ 
+    The name GENERAL_REGS must be the name of a class (or an alias for
+    another name such as ALL_REGS).  This is the class of registers
+    that is allowed by "g" or "r" in a register constraint.
+    Also, registers outside this class are allocated only when
+    instructions express preferences for them.
+ 
+    The classes must be numbered in nondecreasing order; that is,
+    a larger-numbered class must never be contained completely
+    in a smaller-numbered class.
+ 
+    For any two classes, it is very desirable that there be another
+    class that represents their union.  */
+    
+ /* The i860 has two kinds of registers, hence four classes.  */
+ 
+ enum reg_class { NO_REGS, GENERAL_REGS, FP_REGS, ALL_REGS, LIM_REG_CLASSES };
+ 
+ #define N_REG_CLASSES (int) LIM_REG_CLASSES
+ 
+ /* Give names of register classes as strings for dump file.   */
+ 
+ #define REG_CLASS_NAMES \
+  {"NO_REGS", "GENERAL_REGS", "FP_REGS", "ALL_REGS" }
+ 
+ /* Define which registers fit in which classes.
+    This is an initializer for a vector of HARD_REG_SET
+    of length N_REG_CLASSES.  */
+ 
+ #define REG_CLASS_CONTENTS	\
+  {{0, 0}, {0xffffffff, 0},	\
+   {0, 0xffffffff}, {0xffffffff, 0xffffffff}}
+ 
+ /* The same information, inverted:
+    Return the class number of the smallest class containing
+    reg number REGNO.  This could be a conditional expression
+    or could index an array.  */
+ 
+ #define REGNO_REG_CLASS(REGNO) \
+  ((REGNO) >= 32 ? FP_REGS : GENERAL_REGS)
+ 
+ /* The class value for index registers, and the one for base regs.  */
+ #define INDEX_REG_CLASS GENERAL_REGS
+ #define BASE_REG_CLASS GENERAL_REGS
+ 
+ /* Get reg_class from a letter such as appears in the machine description.  */
+ 
+ #define REG_CLASS_FROM_LETTER(C) \
+   ((C) == 'f' ? FP_REGS : NO_REGS)
+ 
+ /* The letters I, J, K, L and M in a register constraint string
+    can be used to stand for particular ranges of immediate operands.
+    This macro defines what the ranges are.
+    C is the letter, and VALUE is a constant value.
+    Return 1 if VALUE is in the range specified by C.
+ 
+    For the i860, `I' is used for the range of constants 
+    an add/subtract insn can actually contain.
+    But not including -0x8000, since we need
+    to negate the constant sometimes.
+    `J' is used for the range which is just zero (since that is R0).
+    `K' is used for the range allowed in bte.
+    `L' is used for the range allowed in logical insns.  */
+ 
+ #define SMALL_INT(X) ((unsigned) (INTVAL (X) + 0x7fff) < 0xffff)
+ 
+ #define LOGIC_INT(X) ((unsigned) INTVAL (X) < 0x10000)
+ 
+ #define SMALL_INTVAL(X) ((unsigned) ((X) + 0x7fff) < 0xffff)
+ 
+ #define LOGIC_INTVAL(X) ((unsigned) (X) < 0x10000)
+ 
+ #define CONST_OK_FOR_LETTER_P(VALUE, C)  \
+   ((C) == 'I' ? ((unsigned) (VALUE) + 0x7fff) < 0xffff	\
+    : (C) == 'J' ? (VALUE) == 0				\
+    : (C) == 'K' ? (unsigned) (VALUE) < 0x20	\
+    : (C) == 'L' ? (unsigned) (VALUE) < 0x10000	\
+    : 0)
+ 
+ /* Similar, but for floating constants, and defining letters G and H.
+    Here VALUE is the CONST_DOUBLE rtx itself.  */
+ 
+ #define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C)  	\
+   ((C) == 'G' && CONST_DOUBLE_LOW ((VALUE)) == 0	\
+    && CONST_DOUBLE_HIGH ((VALUE)) == 0)
+ 
+ /* Given an rtx X being reloaded into a reg required to be
+    in class CLASS, return the class of reg to actually use.
+    In general this is just CLASS; but on some machines
+    in some cases it is preferable to use a more restrictive class.  */
+ #define PREFERRED_RELOAD_CLASS(X,CLASS) (CLASS)
+ 
+ /* Return the maximum number of consecutive registers
+    needed to represent mode MODE in a register of class CLASS.  */
+ /* On the i860, this is the size of MODE in words.  */
+ #define CLASS_MAX_NREGS(CLASS, MODE)	\
+   ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+ \f


+ /* Stack layout; function entry, exit and calling.  */
+ 
+ /* Define this if pushing a word on the stack
+    makes the stack pointer a smaller address.  */
+ #define STACK_GROWS_DOWNWARD
+ 
+ /* Define this if the nominal address of the stack frame
+    is at the high-address end of the local variables;
+    that is, each additional local variable allocated
+    goes at a more negative offset in the frame.  */
+ #define FRAME_GROWS_DOWNWARD
+ 
+ /* Offset within stack frame to start allocating local variables at.
+    If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
+    first local allocated.  Otherwise, it is the offset to the BEGINNING
+    of the first local allocated.  */
+ #define STARTING_FRAME_OFFSET 0
+ 
+ /* If we generate an insn to push BYTES bytes,
+    this says how many the stack pointer really advances by.
+    On the i860, don't define this because there are no push insns.  */
+ /*  #define PUSH_ROUNDING(BYTES) */
+ 
+ /* Offset of first parameter from the argument pointer register value.  */
+ #define FIRST_PARM_OFFSET(FNDECL) 0
+ 
+ /* Value is 1 if returning from a function call automatically
+    pops the arguments described by the number-of-args field in the call.
+    FUNTYPE is the data type of the function (as a tree),
+    or for a library call it is an identifier node for the subroutine name.  */
+ 
+ #define RETURN_POPS_ARGS(FUNTYPE) 0
+ 
+ /* Define how to find the value returned by a function.
+    VALTYPE is the data type of the value (as a tree).
+    If the precise function being called is known, FUNC is its FUNCTION_DECL;
+    otherwise, FUNC is 0.  */
+ 
+ /* On the i860, the value register depends on the mode.  */
+ 
+ #define FUNCTION_VALUE(VALTYPE, FUNC)  \
+   gen_rtx (REG, TYPE_MODE (VALTYPE),				\
+ 	   (GET_MODE_CLASS (TYPE_MODE (VALTYPE)) == MODE_FLOAT	\
+ 	    ? 40 : 16))
+ 
+ /* Define how to find the value returned by a library function
+    assuming the value has mode MODE.  */
+ 
+ #define LIBCALL_VALUE(MODE)				\
+   gen_rtx (REG, MODE,					\
+ 	   (GET_MODE_CLASS ((MODE)) == MODE_FLOAT	\
+ 	    ? 40 : 16))
+ 
+ /* 1 if N is a possible register number for a function value
+    as seen by the caller.  */
+ 
+ #define FUNCTION_VALUE_REGNO_P(N) ((N) == 40 || (N) == 16)
+ 
+ /* 1 if N is a possible register number for function argument passing.
+    On the i860, these are r16-r27 and f8-f15.  */
+ 
+ #define FUNCTION_ARG_REGNO_P(N)		\
+   (((N) < 28 && (N) > 15) || ((N) < 48 && (N) >= 40))
+ \f


+ /* Define a data type for recording info about an argument list
+    during the scan of that argument list.  This data type should
+    hold all necessary information about the function itself
+    and about the args processed so far, enough to enable macros
+    such as FUNCTION_ARG to determine where the next arg should go.
+ 
+    On the i860, we must count separately the number of general registers used
+    and the number of float registers used.  */
+ 
+ #define CUMULATIVE_ARGS struct { int ints, floats; }
+ 
+ /* 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.
+ 
+    On the i860, the general-reg offset normally starts at 0,
+    but starts at 4 bytes
+    when the function gets a structure-value-address as an
+    invisible first argument.  */
+ 
+ #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE)	\
+  ((CUM).ints = ((FNTYPE) != 0 && TYPE_MODE (TREE_TYPE (FNTYPE)) == BLKmode \
+ 		? 4 : 0),			\
+   (CUM).floats = 0)
+ 
+ /* Machine-specific subroutines of the following macros.  */
+ #define CEILING(X,Y)  (((X) + (Y) - 1) / (Y))
+ #define ROUNDUP(X,Y)  (CEILING ((X), (Y)) * (Y))
+ 
+ /* Update the data in CUM to advance over an argument
+    of mode MODE and data type TYPE.
+    (TYPE is null for libcalls where that information may not be available.)
+    Floats, and doubleword ints, are returned in f regs;
+    other ints, in r regs.
+    Aggregates, even short ones, are passed in memory.  */
+ 
+ #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)		\
+  ((TYPE) != 0 && (TREE_CODE ((TYPE)) == RECORD_TYPE		\
+ 		  || TREE_CODE ((TYPE)) == UNION_TYPE)		\
+   ? 0								\
+   : GET_MODE_CLASS ((MODE)) == MODE_FLOAT || (MODE) == DImode	\
+   ? ((CUM).floats = (ROUNDUP ((CUM).floats, GET_MODE_SIZE ((MODE)))	\
+ 		     + ROUNDUP (GET_MODE_SIZE (MODE), 4)))	\
+   : GET_MODE_CLASS ((MODE)) == MODE_INT				\
+   ? ((CUM).ints = (ROUNDUP ((CUM).ints, GET_MODE_SIZE ((MODE))) \
+ 		   + ROUNDUP (GET_MODE_SIZE (MODE), 4)))	\
+   : 0)
+ 
+ /* Determine where to put an argument to a function.
+    Value is zero to push the argument on the stack,
+    or a hard register in which to store the argument.
+ 
+    MODE is the argument's machine mode.
+    TYPE is the data type of the argument (as a tree).
+     This is null for libcalls where that information may
+     not be available.
+    CUM is a variable of type CUMULATIVE_ARGS which gives info about
+     the preceding args and about the function being called.
+    NAMED is nonzero if this argument is a named parameter
+     (otherwise it is an extra parameter matching an ellipsis).  */
+ 
+ /* On the i860, the first 12 words of integer arguments go in r16-r27,
+    and the first 8 words of floating arguments go in f8-f15.
+    DImode values are treated as floats.  */
+ 
+ #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED)		\
+  ((TYPE) != 0 && (TREE_CODE ((TYPE)) == RECORD_TYPE	\
+ 		  || TREE_CODE ((TYPE)) == UNION_TYPE)	\
+   ? 0							\
+   : GET_MODE_CLASS ((MODE)) == MODE_FLOAT || (MODE) == DImode	\
+   ? (ROUNDUP ((CUM).floats, GET_MODE_SIZE ((MODE))) < 32	\
+      ? gen_rtx (REG, (MODE),				\
+ 		40+(ROUNDUP ((CUM).floats,		\
+ 			     GET_MODE_SIZE ((MODE)))	\
+ 		    / 4))				\
+      : 0)						\
+   : GET_MODE_CLASS ((MODE)) == MODE_INT			\
+   ? (ROUNDUP ((CUM).ints, GET_MODE_SIZE ((MODE))) < 48	\
+      ? gen_rtx (REG, (MODE),				\
+ 		16+(ROUNDUP ((CUM).ints,		\
+ 			     GET_MODE_SIZE ((MODE)))	\
+ 		    / 4))				\
+      : 0)						\
+   : 0)
+ 
+ /* For an arg passed partly in registers and partly in memory,
+    this is the number of registers used.
+    For args passed entirely in registers or entirely in memory, zero.  */
+ 
+ #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
+ 
+ /* This macro generates the assembly code for function entry.
+    FILE is a stdio stream to output the code to.
+    SIZE is an int: how many units of temporary storage to allocate.
+    Refer to the array `regs_ever_live' to determine which registers
+    to save; `regs_ever_live[I]' is nonzero if register number I
+    is ever used in the function.  This macro is responsible for
+    knowing which registers should not be saved even if used.  */
+ 
+ #define FUNCTION_PROLOGUE(FILE, SIZE)				\
+ {								\
+   extern char call_used_regs[];					\
+   int fsize = (SIZE);						\
+   int nregs, i;							\
+   for (i = 0, nregs = 0; i < FIRST_PSEUDO_REGISTER; i++)	\
+     {								\
+       if (regs_ever_live[i] && ! call_used_regs[i])		\
+         nregs++;						\
+     }								\
+   fsize += nregs * 4 + 8;					\
+   fsize = (fsize + 15) & -16;					\
+   if (fsize > 0x7fff)						\
+     {								\
+       fprintf (FILE, "\tadds -16,sp,sp\n");			\
+       fprintf (FILE, "\tst.l fp,8(sp)\n");			\
+       fprintf (FILE, "\tst.l r1,12(sp)\n");			\
+       fprintf (FILE, "\tadds 8,sp,fp\n");			\
+       fprintf (FILE, "\torh %d,r0,r31\n", (fsize - 16) >> 16);	\
+       fprintf (FILE, "\tor %d,r31,r31\n", (fsize - 16) & 0xffff); \
+       fprintf (FILE, "\tsubs sp,r31,sp\n");			\
+     }								\
+   else								\
+     {								\
+       fprintf (FILE, "\tadds -%d,sp,sp\n", fsize);		\
+       fprintf (FILE, "\tst.l fp,%d(sp)\n", fsize - 8);		\
+       fprintf (FILE, "\tst.l r1,%d(sp)\n", fsize - 4);		\
+       fprintf (FILE, "\tadds %d,sp,fp\n", fsize - 8);		\
+     }								\
+   for (i = 0, nregs = 0; i < 32; i++)				\
+     if (regs_ever_live[i] && ! call_used_regs[i])		\
+       fprintf (FILE, "\tst.l %s,%d(sp)\n",			\
+ 	       reg_names[i], 4 * nregs++);			\
+   for (i = 32; i < 64; i++)					\
+     if (regs_ever_live[i] && ! call_used_regs[i])		\
+       fprintf (FILE, "\tfst.l %s,%d(sp)\n",			\
+ 	       reg_names[i], 4 * nregs++);			\
+ }
+ /* ??? maybe save pairs or quads of fp registers.  */
+ 
+ /* Output assembler code to FILE to increment profiler label # LABELNO
+    for profiling a function entry.  */
+ 
+ #define FUNCTION_PROFILER(FILE, LABELNO)  \
+    abort ();
+ 
+ /* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
+    the stack pointer does not matter.  The value is tested only in
+    functions that have frame pointers.
+    No definition is equivalent to always zero.  */
+ 
+ /* #define EXIT_IGNORE_STACK 0 */
+ 
+ /* This macro generates the assembly code for function exit,
+    on machines that need it.  If FUNCTION_EPILOGUE is not defined
+    then individual return instructions are generated for each
+    return statement.  Args are same as for FUNCTION_PROLOGUE.
+ 
+    The function epilogue should not depend on the current stack pointer!
+    It should use the frame pointer only.  This is mandatory because
+    of alloca; we also take advantage of it to omit stack adjustments
+    before returning.  */
+ 
+ #define FUNCTION_EPILOGUE(FILE, SIZE)				\
+ {								\
+   extern char call_used_regs[];					\
+   int fsize = (SIZE);						\
+   int nregs, i;							\
+   for (i = 0, nregs = 0; i < FIRST_PSEUDO_REGISTER; i++)	\
+     {								\
+       if (regs_ever_live[i] && ! call_used_regs[i])		\
+         nregs++;						\
+     }								\
+   fsize += nregs * 4 + 8;					\
+   fsize = (fsize + 15) & -16;					\
+   if (fsize < 0x7fff)						\
+     {								\
+       for (i = 0, nregs = 0; i < 32; i++)			\
+ 	if (regs_ever_live[i] && ! call_used_regs[i])		\
+ 	  fprintf (FILE, "\tld.l %d(fp),%s\n",			\
+ 		   4 * nregs++ - (fsize - 8), reg_names[i]);	\
+       for (i = 32; i < 64; i++)					\
+ 	if (regs_ever_live[i] && ! call_used_regs[i])		\
+ 	  fprintf (FILE, "\tfld.l %d(fp),%s\n",			\
+ 		   4 * nregs++ - (fsize - 8), reg_names[i]);	\
+     }								\
+   else								\
+     {								\
+       fprintf (FILE, "\torh %d,r0,r31\n", (fsize - 8) >> 16);	\
+       fprintf (FILE, "\tor %d,r31,r31\n", (fsize - 8) & 0xffff); \
+       fprintf (FILE, "\tsubs fp,r31,sp\n");			\
+       for (i = 0, nregs = 0; i < 32; i++)			\
+ 	if (regs_ever_live[i] && ! call_used_regs[i])		\
+ 	  fprintf (FILE, "\tld.l %d(sp),%s\n",			\
+ 		   4 * nregs++, reg_names[i]);			\
+       for (i = 32; i < 64; i++)					\
+ 	if (regs_ever_live[i] && ! call_used_regs[i])		\
+ 	  fprintf (FILE, "\tfld.l %d(sp),%s\n",			\
+ 		   4 * nregs++, reg_names[i]);			\
+     }								\
+   if (fsize < 0x7fff)						\
+     {								\
+       fprintf (FILE, "\tld.l 4(fp),r1\n");			\
+       fprintf (FILE, "\tld.l 0(fp),fp\n");			\
+       fprintf (FILE, "\tbri r1\n\taddu %d,sp,sp\n", fsize);	\
+     }								\
+   else								\
+     {								\
+       fprintf (FILE, "\tld.l 4(fp),r1\n");			\
+       fprintf (FILE, "\tadds 8,fp,r31\n");			\
+       fprintf (FILE, "\tld.l 0(fp),fp\n");			\
+       fprintf (FILE, "\tbri r1\n\tmov r31,sp\n");		\
+     }								\
+ }
+ 
+ /* If the memory address ADDR is relative to the frame pointer,
+    correct it to be relative to the stack pointer instead.
+    This is for when we don't use a frame pointer.
+    ADDR should be a variable name.  */
+ 
+ #define FIX_FRAME_POINTER_ADDRESS(ADDR,DEPTH)  abort ();
+ \f


+ /* Addressing modes, and classification of registers for them.  */
+ 
+ /* #define HAVE_POST_INCREMENT */
+ /* #define HAVE_POST_DECREMENT */
+ 
+ /* #define HAVE_PRE_DECREMENT */
+ #define HAVE_PRE_INCREMENT
+ 
+ /* Macros to check register numbers against specific register classes.  */
+ 
+ /* These assume that REGNO is a hard or pseudo reg number.
+    They give nonzero only if REGNO is a hard reg of the suitable class
+    or a pseudo reg currently allocated to a suitable hard reg.
+    Since they use reg_renumber, they are safe only once reg_renumber
+    has been allocated, which happens in local-alloc.c.  */
+ 
+ #define REGNO_OK_FOR_INDEX_P(REGNO) \
+ ((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32)
+ #define REGNO_OK_FOR_BASE_P(REGNO) \
+ ((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32)
+ #define REGNO_OK_FOR_FP_P(REGNO) \
+ (((REGNO) ^ 0x20) < 32 || (unsigned) (reg_renumber[REGNO] ^ 0x20) < 32)
+ 
+ /* Now macros that check whether X is a register and also,
+    strictly, whether it is in a specified class.
+ 
+    These macros are specific to the i860, and may be used only
+    in code for printing assembler insns and in conditions for
+    define_optimization.  */
+ 
+ /* 1 if X is an fp register.  */
+ 
+ #define FP_REG_P(X) (REG_P (X) && REGNO_OK_FOR_FP_P (REGNO (X)))
+ \f


+ /* Maximum number of registers that can appear in a valid memory address.  */
+ 
+ #define MAX_REGS_PER_ADDRESS 2
+ 
+ /* Recognize any constant value that is a valid address.  */
+ 
+ #define CONSTANT_ADDRESS_P(X)  CONSTANT_P (X)
+ 
+ /* Nonzero if the constant value X is a legitimate general operand.
+    It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.
+ 
+    On the Sparc, this is anything but a CONST_DOUBLE.
+    Let's try permitting CONST_DOUBLEs and see what happens.  */
+ 
+ #define LEGITIMATE_CONSTANT_P(X) 1
+ 
+ /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
+    and check its validity for a certain class.
+    We have two alternate definitions for each of them.
+    The usual definition accepts all pseudo regs; the other rejects
+    them unless they have been allocated suitable hard regs.
+    The symbol REG_OK_STRICT causes the latter definition to be used.
+ 
+    Most source files want to accept pseudo regs in the hope that
+    they will get allocated to the class that the insn wants them to be in.
+    Source files for reload pass need to be strict.
+    After reload, it makes no difference, since pseudo regs have
+    been eliminated by then.  */
+ 
+ #ifndef REG_OK_STRICT
+ 
+ /* Nonzero if X is a hard reg that can be used as an index
+    or if it is a pseudo reg.  */
+ #define REG_OK_FOR_INDEX_P(X) (((unsigned) REGNO (X)) - 32 >= 14)
+ /* Nonzero if X is a hard reg that can be used as a base reg
+    or if it is a pseudo reg.  */
+ #define REG_OK_FOR_BASE_P(X) (((unsigned) REGNO (X)) - 32 >= 14)
+ 
+ #else
+ 
+ /* Nonzero if X is a hard reg that can be used as an index.  */
+ #define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
+ /* Nonzero if X is a hard reg that can be used as a base reg.  */
+ #define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
+ 
+ #endif
+ \f


+ /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
+    that is a valid memory address for an instruction.
+    The MODE argument is the machine mode for the MEM expression
+    that wants to use this address.
+ 
+    On SPARC, the actual legitimate addresses must be REG+REG or REG+SMALLINT.
+    But we can treat a SYMBOL_REF as legitimate if it is part of this
+    function's constant-pool, because such addresses can actually
+    be output as REG+SMALLINT.
+ 
+    Try making SYMBOL_REF (and other things which are CONSTANT_ADDRESS_P)
+    a legitimate address, regardless.  Because the only insns which can use
+    memory are load or store insns, the added hair in the machine description
+    is not that bad.  It should also speed up the compiler by halving the number
+    of insns it must manage for each (MEM (SYMBOL_REF ...)) involved.  */
+ 
+ #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)		\
+ { if (GET_CODE (X) == REG)				\
+     { if (REG_OK_FOR_BASE_P (X)) goto ADDR; }		\
+   else if (GET_CODE (X) == PLUS)			\
+     {							\
+       if (GET_CODE (XEXP (X, 0)) == REG			\
+ 	  && REG_OK_FOR_BASE_P (XEXP (X, 0)))		\
+ 	{						\
+ 	  if (GET_CODE (XEXP (X, 1)) == CONST_INT	\
+ 	      && INTVAL (XEXP (X, 1)) >= -0x8000	\
+ 	      && INTVAL (XEXP (X, 1)) < 0x8000)		\
+ 	    goto ADDR;					\
+ 	}						\
+       else if (GET_CODE (XEXP (X, 1)) == REG		\
+ 	  && REG_OK_FOR_BASE_P (XEXP (X, 1)))		\
+ 	{						\
+ 	  if (GET_CODE (XEXP (X, 0)) == CONST_INT	\
+ 	      && INTVAL (XEXP (X, 0)) >= -0x8000	\
+ 	      && INTVAL (XEXP (X, 0)) < 0x8000)		\
+ 	    goto ADDR;					\
+ 	}						\
+     }							\
+   else if (CONSTANT_ADDRESS_P (X))			\
+     goto ADDR;						\
+ }
+ \f


+ /* Try machine-dependent ways of modifying an illegitimate address
+    to be legitimate.  If we find one, return the new, valid address.
+    This macro is used in only one place: `memory_address' in explow.c.
+ 
+    OLDX is the address as it was before break_out_memory_refs was called.
+    In some cases it is useful to look at this to decide what needs to be done.
+ 
+    MODE and WIN are passed so that this macro can use
+    GO_IF_LEGITIMATE_ADDRESS.
+ 
+    It is always safe for this macro to do nothing.  It exists to recognize
+    opportunities to optimize the output.  */
+ 
+ /* On the i860, change COMPLICATED + CONSTANT to REG+CONSTANT.
+    Also change a symbolic constant to a REG,
+    though that may not be necessary.  */
+ 
+ #define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)	\
+ { if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == MULT)	\
+     (X) = gen_rtx (PLUS, SImode, XEXP (X, 1),			\
+ 		   force_operand (XEXP (X, 0), 0));		\
+   if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == MULT)	\
+     (X) = gen_rtx (PLUS, SImode, XEXP (X, 0),			\
+ 		   force_operand (XEXP (X, 1), 0));		\
+   if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == PLUS)	\
+     (X) = gen_rtx (PLUS, SImode, XEXP (X, 1),			\
+ 		   force_operand (XEXP (X, 0), 0));		\
+   if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == PLUS)	\
+     (X) = gen_rtx (PLUS, SImode, XEXP (X, 0),			\
+ 		   force_operand (XEXP (X, 1), 0));		\
+   if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) != REG	\
+       && GET_CODE (XEXP (X, 0)) != CONST_INT)			\
+     (X) = gen_rtx (PLUS, SImode, XEXP (X, 1),			\
+ 		   copy_to_mode_reg (SImode, XEXP (X, 0)));	\
+   if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) != REG	\
+       && GET_CODE (XEXP (X, 1)) != CONST_INT)			\
+     (X) = gen_rtx (PLUS, SImode, XEXP (X, 0),			\
+ 		   copy_to_mode_reg (SImode, XEXP (X, 1)));	\
+   if (GET_CODE (x) == SYMBOL_REF)				\
+     (X) = copy_to_reg (X);					\
+   if (GET_CODE (x) == CONST)					\
+     (X) = copy_to_reg (X);					\
+   if (memory_address_p (MODE, X))				\
+     goto WIN; }
+ 
+ /* Go to LABEL if ADDR (a legitimate address expression)
+    has an effect that depends on the machine mode it is used for.
+    On the SPUR this is never true.  */
+ 
+ #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL)
+ \f


+ /* Specify the machine mode that this machine uses
+    for the index in the tablejump instruction.  */
+ #define CASE_VECTOR_MODE SImode
+ 
+ /* Define this if the tablejump instruction expects the table
+    to contain offsets from the address of the table.
+    Do not define this if the table should contain absolute addresses.  */
+ /* #define CASE_VECTOR_PC_RELATIVE */
+ 
+ /* Specify the tree operation to be used to convert reals to integers.  */
+ #define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
+ 
+ /* This is the kind of divide that is easiest to do in the general case.  */
+ #define EASY_DIV_EXPR TRUNC_DIV_EXPR
+ 
+ #define DIVSI3_LIBCALL "*.div"
+ #define UDIVSI3_LIBCALL "*.udiv"
+ #define REMSI3_LIBCALL "*.rem"
+ #define UREMSI3_LIBCALL "*.urem"
+ 
+ /* Define this as 1 if `char' should by default be signed; else as 0.  */
+ #define DEFAULT_SIGNED_CHAR 1
+ 
+ /* Max number of bytes we can move from memory to memory
+    in one reasonably fast instruction.  */
+ #define MOVE_MAX 16
+ 
+ /* Nonzero if access to memory by bytes is slow and undesirable.  */
+ #define SLOW_BYTE_ACCESS 0
+ 
+ /* This is System V, so it wants sdb format.  */
+ #define DBX_DEBUGGING_INFO
+ 
+ /* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
+    is done just by pretending it is already truncated.  */
+ #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
+ 
+ /* Specify the machine mode that pointers have.
+    After generation of rtl, the compiler makes no further distinction
+    between pointers and any other objects of this machine mode.  */
+ #define Pmode SImode
+ 
+ /* A function address in a call instruction
+    is a byte address (for indexing purposes)
+    so give the MEM rtx a byte's mode.  */
+ #define FUNCTION_MODE SImode
+ 
+ /* Define this if addresses of constant functions
+    shouldn't be put through pseudo regs where they can be cse'd.
+    Desirable on machines where ordinary constants are expensive
+    but a CALL with constant address is cheap.  */
+ #define NO_FUNCTION_CSE
+ 
+ /* Compute the cost of computing a constant rtl expression RTX
+    whose rtx-code is CODE.  The body of this macro is a portion
+    of a switch statement.  If the code is computed here,
+    return it with a return statement.  Otherwise, break from the switch.  */
+ 
+ #define CONST_COSTS(RTX,CODE) \
+   case CONST_INT:						\
+     if (INTVAL (RTX) == 0)					\
+       return 0;							\
+     if (INTVAL (RTX) < 0x2000 && INTVAL (RTX) >= -0x2000) return 1; \
+   case CONST:							\
+   case LABEL_REF:						\
+   case SYMBOL_REF:						\
+     return 2;							\
+   case CONST_DOUBLE:						\
+     return 4;
+ \f


+ /* Tell final.c how to eliminate redundant test instructions.  */
+ 
+ /* Here we define machine-dependent flags and fields in cc_status
+    (see `conditions.h').  */
+ 
+ /* This holds the value sourcing h%r31.  We keep this info
+    around so that mem/mem ops, such as increment and decrement,
+    etc, can be performed reasonably.  */
+ #define CC_STATUS_MDEP rtx
+ 
+ #define CC_STATUS_MDEP_INIT (cc_status.mdep = 0)
+ 
+ /* On the i860, each comparison tests just one condition,
+    so only that condition can be remembered.
+    We don't need GT, GE, GTU and GEU because CC_REVERSED can handle them.  */
+ #define CC_ONLY_EQ 0100
+ #define CC_ONLY_LE 0200
+ #define CC_ONLY_LT 0400
+ #define CC_ONLY_LEU 02000
+ #define CC_ONLY_LTU 04000
+ #define CC_CONDITION_MASK 07700
+ 
+ /* Non-zero to invert the sense of the condition code.  */
+ #define CC_NEGATED 010000
+ 
+ /* Nonzero if we know the value of h%r31.  */
+ #define CC_KNOW_HI_R31 0100000
+ 
+ /* Nonzero if h%r31 is actually ha%something, rather than h%something.  */
+ #define CC_HI_R31_ADJ 0200000
+ 
+ /* Store in cc_status the expressions
+    that the condition codes will describe
+    after execution of an instruction whose pattern is EXP.
+    Do not alter them if the instruction would not alter the cc's.  */
+ 
+ /* On the i860, only compare insns set a useful condition code.  */
+ 
+ #define NOTICE_UPDATE_CC(EXP, INSN) \
+ { cc_status.flags &= (CC_KNOW_HI_R31 | CC_HI_R31_ADJ);	\
+   cc_status.value1 = 0; cc_status.value2 = 0; }
+ \f


+ /* Control the assembler format that we output.  */
+ 
+ /* Output at beginning of assembler file.  */
+ /* The .file command should always begin the output.  */
+ 
+ #define ASM_FILE_START(FILE)
+ #if 0
+ #define ASM_FILE_START(FILE)				\
+   do { sdbout_filename ((FILE), main_input_filename);	\
+        if (optimize) ASM_FILE_START_1 (FILE);		\
+      } while (0)
+ #endif
+ 
+ #define ASM_FILE_START_1(FILE)
+ 
+ /* Output to assembler file text saying following lines
+    may contain character constants, extra white space, comments, etc.  */
+ 
+ #define ASM_APP_ON ""
+ 
+ /* Output to assembler file text saying following lines
+    no longer contain unusual constructs.  */
+ 
+ #define ASM_APP_OFF ""
+ 
+ /* Output before read-only data.  */
+ 
+ #define TEXT_SECTION_ASM_OP ".text"
+ 
+ /* Output before writable data.  */
+ 
+ #define DATA_SECTION_ASM_OP ".data"
+ 
+ /* How to refer to registers in assembler output.
+    This sequence is indexed by compiler's hard-register-number (see above).  */
+ 
+ #define REGISTER_NAMES \
+ {"r0", "r1", "sp", "fp", "r4", "r5", "r6", "r7", "r8", "r9",		\
+  "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19",	\
+  "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29",	\
+  "r30", "r31",								\
+  "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9",		\
+  "f10", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19",	\
+  "f20", "f21", "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29",	\
+  "f30", "f31" }
+ 
+ /* How to renumber registers for dbx and gdb.  */
+ 
+ #define DBX_REGISTER_NUMBER(REGNO) (REGNO)
+ 
+ /* 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 (".globl ", FILE); assemble_name (FILE, NAME); fputs ("\n", FILE);} while (0)
+ 
+ /* This is how to output a reference to a user-level label named NAME.
+    `assemble_name' uses this.  */
+ 
+ #define ASM_OUTPUT_LABELREF(FILE,NAME)	\
+   fprintf (FILE, "_%s", NAME)
+ 
+ /* This is how to output an internal numbered label where
+    PREFIX is the class of label and NUM is the number within the class.  */
+ 
+ #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)	\
+   fprintf (FILE, ".%s%d:\n", PREFIX, NUM)
+ 
+ /* This is how to output an internal numbered label which
+    labels a jump table.  */
+ 
+ #define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,JUMPTABLE)	\
+   fprintf (FILE, "\t.data\n.%s%d:\n", PREFIX, NUM)
+ 
+ /* Output at the end of a jump table.  */
+ 
+ #define ASM_OUTPUT_CASE_END(FILE,NUM,INSN)	\
+   fprintf (FILE, "\t.text\n")
+ 
+ /* This is how to store into the string LABEL
+    the symbol_ref name of an internal numbered label where
+    PREFIX is the class of label and NUM is the number within the class.
+    This is suitable for output with `assemble_name'.  */
+ 
+ #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)	\
+   sprintf (LABEL, "*.%s%d", PREFIX, NUM)
+ 
+ #define ASCII_DATA_ASM_OP ".byte"
+ #define	ASM_OUTPUT_ASCII(f, p, size)	\
+ { register int i;			\
+   int inside;				\
+   inside = FALSE;			\
+   for (i = 0; i < size; i++) {		\
+     if (i % 64 == 0) {			\
+       if (i != 0) {			\
+ 	if (inside)			\
+ 	  putc('"', f);			\
+ 	putc('\n', f);			\
+ 	inside = FALSE;			\
+       }					\
+       fprintf(f, "%s ", ASCII_DATA_ASM_OP);	\
+     }					\
+     if (p[i] < 32 || p[i] == '\\' || p[i] == '"' || p[i] == 127) {	\
+       if (inside) {			\
+ 	putc('"', f);			\
+ 	inside = FALSE;			\
+       }					\
+       if (i % 64 != 0)			\
+ 	putc(',', f);			\
+       fprintf(f, "%d", p[i]);		\
+     } else {				\
+       if (!inside) {			\
+ 	if (i % 64 != 0)			\
+ 	  putc(',', f);			\
+ 	putc('"', f);			\
+ 	inside = TRUE;			\
+       }					\
+       putc(p[i], f);			\
+     }					\
+   }					\
+   if (inside)				\
+     putc('"', f);			\
+   putc('\n', f);			\
+ }
+ 
+ /* This is how to output an assembler line defining a `double' constant.  */
+ 
+ #define ASM_OUTPUT_DOUBLE(FILE,VALUE)  \
+   fprintf (FILE, "\t.double %.20e\n", (VALUE))
+ 
+ /* This is how to output an assembler line defining a `float' constant.  */
+ 
+ #define ASM_OUTPUT_FLOAT(FILE,VALUE)  \
+   fprintf (FILE, "\t.float %.12e\n", (VALUE))
+ 
+ /* This is how to output an assembler line defining an `int' constant.  */
+ 
+ #define ASM_OUTPUT_INT(FILE,VALUE)  \
+ ( fprintf (FILE, "\t.long "),			\
+   output_addr_const (FILE, (VALUE)),		\
+   fprintf (FILE, "\n"))
+ 
+ /* Likewise for `char' and `short' constants.  */
+ 
+ #define ASM_OUTPUT_SHORT(FILE,VALUE)  \
+ ( fprintf (FILE, "\t.short "),			\
+   output_addr_const (FILE, (VALUE)),		\
+   fprintf (FILE, "\n"))
+ 
+ #define ASM_OUTPUT_CHAR(FILE,VALUE)  \
+ ( fprintf (FILE, "\t.byte "),			\
+   output_addr_const (FILE, (VALUE)),		\
+   fprintf (FILE, "\n"))
+ 
+ /* This is how to output an assembler line for a numeric constant byte.  */
+ 
+ #define ASM_OUTPUT_BYTE(FILE,VALUE)  \
+   fprintf (FILE, "\t.byte 0x%x\n", (VALUE))
+ 
+ /* This is how to output code to push a register on the stack.
+    It need not be very fast code.  */
+ 
+ #define ASM_OUTPUT_REG_PUSH(FILE,REGNO)  \
+   fprintf (FILE, "\taddu -16,r3,r3\n\t%sst.l %s,0(r3)\n",	\
+ 	   ((REGNO) < 32 ? "" : "f"), reg_names[REGNO])
+ 
+ /* This is how to output an insn to pop a register from the stack.
+    It need not be very fast code.  */
+ 
+ #define ASM_OUTPUT_REG_POP(FILE,REGNO)  \
+   fprintf (FILE, "\t%sld.l 0(r3),%s\n\taddu 16,r3,r3\n",	\
+ 	   ((REGNO) < 32 ? "" : "f"), reg_names[REGNO])
+ 
+ /* This is how to output an element of a case-vector that is absolute.  */
+ 
+ #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)  \
+   fprintf (FILE, "\t.long .L%d\n", VALUE)
+ 
+ /* This is how to output an element of a case-vector that is relative.
+    (The i860 does not use such vectors,
+    but we must define this macro anyway.)  */
+ 
+ #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL)  \
+   fprintf (FILE, "\t.word .L%d-.L%d\n", VALUE, REL)
+ 
+ /* This is how to output an assembler line
+    that says to advance the location counter
+    to a multiple of 2**LOG bytes.  */
+ 
+ #define ASM_OUTPUT_ALIGN(FILE,LOG)	\
+   if ((LOG) != 0)			\
+     fprintf (FILE, "\t.align %d\n", 1 << (LOG))
+ 
+ #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
+   fprintf (FILE, "\t.blkb %d\n", (SIZE))
+ 
+ /* This says how to output an assembler line
+    to define a global common symbol.  */
+ 
+ #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)  \
+ ( fputs (".comm ", (FILE)),			\
+   assemble_name ((FILE), (NAME)),		\
+   fprintf ((FILE), ",%d\n", (ROUNDED)))
+ 
+ /* This says how to output an assembler line
+    to define a local common symbol.  */
+ 
+ #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)  \
+ ( fputs (".lcomm ", (FILE)),			\
+   assemble_name ((FILE), (NAME)),		\
+   fprintf ((FILE), ",%d\n", (ROUNDED)))
+ 
+ /* Store in OUTPUT a string (made with alloca) containing
+    an assembler-name for a local static variable named NAME.
+    LABELNO is an integer which is different for each call.  */
+ 
+ #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)	\
+ ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10),	\
+   sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
+ 
+ /* Define the parentheses used to group arithmetic operations
+    in assembler code.  */
+ 
+ #define ASM_OPEN_PAREN "("
+ #define ASM_CLOSE_PAREN ")"
+ 
+ /* Define results of standard character escape sequences.  */
+ #define TARGET_BELL 007
+ #define TARGET_BS 010
+ #define TARGET_TAB 011
+ #define TARGET_NEWLINE 012
+ #define TARGET_VT 013
+ #define TARGET_FF 014
+ #define TARGET_CR 015
+ 
+ /* Print operand X (an rtx) in assembler syntax to file FILE.
+    CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
+    For `%' followed by punctuation, CODE is the punctuation and X is null.
+ 
+    On the i860, the CODE can be `r', meaning this is a register-only operand
+    and an immediate zero should be represented as `r0'.
+    It can also be `m', meaning this is a memory ref,
+    but print its address as a constant.  */
+ 
+ #define PRINT_OPERAND(FILE, X, CODE)  \
+ { if (GET_CODE (X) == REG)						\
+     fprintf (FILE, "%s", reg_names[REGNO (X)]);				\
+   else if ((CODE) == 'm')					\
+     output_address (XEXP (X, 0));				\
+   else if (GET_CODE (X) == MEM)						\
+     output_address (XEXP (X, 0));					\
+   else if ((CODE) == 'r' && (X) == const0_rtx)				\
+     fprintf (FILE, "r0");						\
+   else if ((CODE) == 'r' && (X) == CONST0_RTX (GET_MODE (X)))		\
+     fprintf (FILE, "f0");						\
+   else if (GET_CODE (X) == CONST_DOUBLE)				\
+     abort ();								\
+   else									\
+     output_addr_const (FILE, X); }
+ \f


+ /* Print a memory address as an operand to reference that memory location.  */
+ 
+ #define PRINT_OPERAND_ADDRESS(FILE, ADDR)  \
+ { register rtx base, index = 0;					\
+   int offset = 0;						\
+   register rtx addr = ADDR;					\
+   if (GET_CODE (addr) == REG)					\
+     {								\
+       fprintf (FILE, "0(%s)", reg_names[REGNO (addr)]);		\
+     }								\
+   else if (GET_CODE (addr) == PLUS)				\
+     {								\
+       if (GET_CODE (XEXP (addr, 0)) == CONST_INT)		\
+ 	offset = INTVAL (XEXP (addr, 0)), base = XEXP (addr, 1);\
+       else if (GET_CODE (XEXP (addr, 1)) == CONST_INT)		\
+ 	offset = INTVAL (XEXP (addr, 1)), base = XEXP (addr, 0);\
+       else							\
+ 	base = XEXP (addr, 0), index = XEXP (addr, 1);		\
+       if (index != 0)						\
+ 	fprintf (FILE, "%s", reg_names[REGNO (index)]);		\
+       else							\
+ 	fprintf (FILE, "%d", offset);				\
+       fprintf (FILE, "(%s)", reg_names[REGNO (base)]);		\
+     }								\
+   else								\
+     {								\
+ /* ??? this may be wrong.  */  \
+       output_addr_const (FILE, addr);				\
+     }								\
+ }
diff -rc2N gcc-1.35/config/tm-iris.h gcc-1.36/config/tm-iris.h
*** gcc-1.35/config/tm-iris.h	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config/tm-iris.h	Tue Aug 29 17:28:58 1989
***************
*** 0 ****
--- 1,45 ----
+ #include "tm-mips.h"
+ \f


+ /* Names to predefine in the preprocessor for this target machine.  */
+ 
+ #undef CPP_PREDEFINES
+ #define CPP_PREDEFINES "-Dunix -Dmips"
+ #undef CPP_SPEC
+ #define CPP_SPEC "-Dsgi -DSVR3 -Dhost_mips -DMIPSEB -DSYSTYPE_SYSV -DLANGUAGE_C"
+ 
+ #define STARTFILE_SPEC  \
+   "%{pg:gcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}"
+ 
+ #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} crtn.o%s"
+ 
+ #define ASM_OUTPUT_SOURCE_FILENAME(FILE, FILENAME) \
+   fprintf (FILE, "\t.file\t1 \"%s\"\n", FILENAME)
+ 
+ #undef ASM_OUTPUT_SOURCE_LINE
+ #define ASM_OUTPUT_SOURCE_LINE(file, line)              \
+   { static int sym_lineno = 1;                          \
+     fprintf (file, "\t.loc\t1 %d\nLM%d:\n",     \
+              line, sym_lineno);         \
+     sym_lineno += 1; }
+ 
+ #undef STACK_ARGS_ADJUST
+ #define STACK_ARGS_ADJUST(SIZE)                                         \
+ {                                                                       \
+   SIZE.constant += 4;                                                   \
+   if (SIZE.var)                                                         \
+     {                                                                   \
+       rtx size1 = ARGS_SIZE_RTX (SIZE);                                 \
+       rtx rounded = gen_reg_rtx (SImode);                               \
+       rtx label = gen_label_rtx ();                                     \
+       emit_move_insn (rounded, size1);                                  \
+       /* Needed: insns to jump to LABEL if ROUNDED is < 16.  */         \
+       abort ();                                                         \
+       emit_move_insn (rounded, gen_rtx (CONST_INT, VOIDmode, 16));      \
+       emit_label (label);                                               \
+       SIZE.constant = 0;                                                \
+       SIZE.var = rounded;                                               \
+     }                                                                   \
+   else if (SIZE.constant < 32)                                          \
+     SIZE.constant = 32;                                                 \
+ }
+ 
diff -rc2N gcc-1.35/config/tm-isi68-nfp.h gcc-1.36/config/tm-isi68-nfp.h
*** gcc-1.35/config/tm-isi68-nfp.h	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config/tm-isi68-nfp.h	Wed Aug  9 14:18:51 1989
***************
*** 0 ****
--- 1,5 ----
+ /* Define target machine as an ISI 68000/68020 with no 68881.  */
+ 
+ #define TARGET_DEFAULT 5
+ 
+ #include "tm-isi68.h"
diff -rc2N gcc-1.35/config/tm-isi68.h gcc-1.36/config/tm-isi68.h
*** gcc-1.35/config/tm-isi68.h	Wed Feb 22 12:27:42 1989
--- gcc-1.36/config/tm-isi68.h	Wed Aug  9 14:18:19 1989
***************
*** 23,28 ****
--- 23,31 ----
  /* See tm-m68k.h.  7 means 68020 with 68881. */
  
+ #ifndef TARGET_DEFAULT
  #define TARGET_DEFAULT 7
+ #endif
  
+ #if TARGET_DEFAULT & 2
  /* Define __HAVE_68881__ in preprocessor, unless -msoft-float is specified.
     This will control the use of inline 68881 insns in certain macros.  */
***************
*** 34,37 ****
--- 37,51 ----
  #define LIB_SPEC "%{msoft-float:%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}%{!msoft-float:%{!p:%{!pg:-lmc}}%{p:-lmc_p}%{pg:-lmc_p}}"
  
+ #else
+ /* Define __HAVE_68881__ in preprocessor if -m68881 is specified.
+    This will control the use of inline 68881 insns in certain macros.  */
+ 
+ #define CPP_SPEC "%{m68881:-D__HAVE_68881__}"
+ 
+ /* If the 68881 is used, link must load libmc.a instead of libc.a */
+ 
+ #define LIB_SPEC "%{!m68881:%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}%{m68881:%{!p:%{!pg:-lmc}}%{p:-lmc_p}%{pg:-lmc_p}}"
+ #endif
+ 
  /* Names to predefine in the preprocessor for this target machine.  */
  
***************
*** 63,65 ****
  
  /* Also output something to cause the correct _doprnt to be loaded.  */
! #define ASM_FILE_START(FILE) fprintf (FILE, "#NO_APP\n.globl fltused\n")
--- 77,79 ----
  
  /* Also output something to cause the correct _doprnt to be loaded.  */
! #define ASM_FILE_START(FILE) fprintf (FILE, "#NO_APP\n%s\n", TARGET_68881 ? ".globl fltused" : "")
diff -rc2N gcc-1.35/config/tm-m68k.h gcc-1.36/config/tm-m68k.h
*** gcc-1.35/config/tm-m68k.h	Tue Apr 11 15:57:06 1989
--- gcc-1.36/config/tm-m68k.h	Sun Aug  6 17:34:21 1989
***************
*** 373,378 ****
     We do a trick here to modify the effective constraints on the
     machine description; we zorch the constraint letters that aren't
!    appropriate for a specific target.  This allows us to guarrantee
!    that a specific kind of register will not be used for a given taget
     without fiddling with the register classes above. */
  
--- 373,378 ----
     We do a trick here to modify the effective constraints on the
     machine description; we zorch the constraint letters that aren't
!    appropriate for a specific target.  This allows us to guarantee
!    that a specific kind of register will not be used for a given target
     without fiddling with the register classes above. */
  
***************
*** 668,671 ****
--- 668,672 ----
    int fsize = ((SIZE) + 3) & -4;				\
    int big = 0;							\
+   FUNCTION_EXTRA_EPILOGUE (FILE, SIZE);				\
    nregs = 0;  fmask = 0; fpoffset = 0;				\
    for (regno = 24 ; regno < 56 ; regno++)			\
***************
*** 737,740 ****
--- 738,744 ----
    else fprintf (FILE, "\trts\n"); }
  
+ /* This is a hook for other tm files to change.  */
+ #define FUNCTION_EXTRA_EPILOGUE(FILE, SIZE)
+ 
  /* If the memory address ADDR is relative to the frame pointer,
     correct it to be relative to the stack pointer instead.
***************
*** 1406,1409 ****
--- 1410,1417 ----
         CONST_DOUBLE's as SunFPA constant RAM registers if
         possible, so it should not be used except for the SunFPA. */
+ 
+ #define PRINT_OPERAND_PUNCT_VALID_P(CODE)				\
+   ((CODE) == '.' || (CODE) == '#' || (CODE) == '-'			\
+    || (CODE) == '+' || (CODE) == '@' || (CODE) == '!')
  
  #define PRINT_OPERAND(FILE, X, CODE)  \
diff -rc2N gcc-1.35/config/tm-mips-bsd.h gcc-1.36/config/tm-mips-bsd.h
*** gcc-1.35/config/tm-mips-bsd.h	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config/tm-mips-bsd.h	Sun Sep 24 01:06:13 1989
***************
*** 0 ****
--- 1,3 ----
+ #define MIPS_BSD43
+ 
+ #include "tm-mips.h"
diff -rc2N gcc-1.35/config/tm-mips-sysv.h gcc-1.36/config/tm-mips-sysv.h
*** gcc-1.35/config/tm-mips-sysv.h	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config/tm-mips-sysv.h	Sun Sep 24 00:05:29 1989
***************
*** 0 ****
--- 1,3 ----
+ #define MIPS_SYSV
+ 
+ #include "tm-mips.h"
diff -rc2N gcc-1.35/config/tm-mips.h gcc-1.36/config/tm-mips.h
*** gcc-1.35/config/tm-mips.h	Fri Apr  7 15:40:44 1989
--- gcc-1.36/config/tm-mips.h	Sun Sep 24 00:52:22 1989
***************
*** 22,47 ****
     rest of GCC. ???  */
  
- /* Currently we know of 2 MIPS machines: MIPS- M series, and DECStations.  */
- /* Therefore we discriminate by declaring DECStations with */
- /* #define DECSTATION */
- \f


  /* Names to predefine in the preprocessor for this target machine.  */
  
! #define CPP_PREDEFINES "-Dmips"
! #ifdef DECSTATION
! #define CPP_SPEC " -DR3000 -DLANGUAGE_C -DMIPSEL -DSYSTYPE_BSD "
! #else
! #define CPP_SPEC " -DR3000  -Dhost_mips -DMIPSEB -DSYSTYPE_BSD -DLANGUAGE_C "
  #endif
  
  /* Extra switches sometimes passed to the assembler.  */
  
! #define ASM_SPEC   "%{O:-O2}"
  
  /* Print subsidiary information on the compiler version in use.  */
  
! #define TARGET_VERSION printf (" (AL-MIPS 1.04) <Naive-MIPS>\n");
! 				/* Depends on MIPS ASM format */
! #define TARGET_VERSNUM "1 04"
  
  /* Do not Generate DBX debugging information.  */
--- 22,191 ----
     rest of GCC. ???  */
  
  /* Names to predefine in the preprocessor for this target machine.  */
  
! #define CPP_PREDEFINES "-Dmips -Dunix"
! \f


! /*----------------------------------------------------------------------
! 
! SWITCHES:
! 
!     -O    optimization. Implies -fstrength-reduce -fomit-frame-pointer
!     -O2   optimization. Implies -O
! 
!           Tries to make use of short displacements using the
!           Sdata and Sbss sections. This uses the -G switches of as and ld.
! 
!     -G <size>
!           Pass size to as and ld. Default -G 8.
! 
!     -mG0 -mG1 -mG2
!           Construct a size to be passed to GCC for Data / Sdata selection.
! 
!           Value is ( (i=G0 + 2 G1 + 4 G2) , (i < 6) ? ( 1<<i) :(1 <<(i+3)))
!           Same value should be passed to as + ld using -G.
! 
! 	  Default = -mG1 -mG0 (Value = 8).
! 
!     -G32  Implies -G 32 -mG2 -mnG1 -mG0.
! 
! 
!     -bestGnum
!           Pass -bestGnum flag to ld. This helps setting best value for
!           the -G parameter.
! 
!     -SSYSV  for RISC-OS: use the System V environment
!     -SBSD43 for RISC-OS: use the BSD 4.3  environment
! ----------------------------------------------------------------------*/
! 
! 
! 
! /***********************************************************************
! 
! WARNING:
! 
!     No attempt to select (configure) the -B and -I parameters has been
!     made inside this version of gcc. They should be made (eg. thru a
!     shell script).
! 
!     -I should be set in such a way that the include file "va-mips.h"
!     gets included (via "varargs.h") for varargs. Otherwise gcc will not
!     bootstrap -- and produce wrong code for varargs.
! 
! 
! ***********************************************************************/
! \f


! 
! /* Switch  Recognition by gcc.c   */
! 
! #ifdef SWITCH_TAKES_ARG
! #undef SWITCH_TAKES_ARG
  #endif
  
+ #define SWITCH_TAKES_ARG(CHAR)      \
+   ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \
+    || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \
+    || (CHAR) == 'I' || (CHAR) == 'Y' || (CHAR) == 'm' \
+    || (CHAR) == 'L' || (CHAR) == 'i' || (CHAR) == 'A' \
+    || (CHAR) == 'G')
+ 
+ 
  /* Extra switches sometimes passed to the assembler.  */
  
! #define ASM_SPEC   "%{O:-O2} %{O2: -O2} %{!G32: %{G*}}			\
! %{!G:%{!G32: -G 8}} %{G32: -G 32}"
! 
! 
! /* Extra switches sometimes passed to the loader.  */
! 
! 
! #if defined(MIPS_SYSV)		/* RISC-OS SYSTEM V */
! 
! #define STARTFILE_SPEC						\
!   "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt1.o%s crtn.o%s}}"
! 
! #define LINK_SPEC  "%{!G32:%{G*}					\
! %{!G:%{!G32:%{mG0:%eYou should include ld/as option -G}			\
! %{mG1:%eYou should include ld/as option -G}				\
! %{mG2:%eYou should include ld/as option -G}				\
!  -G 8}}}								\
! %{G32: -G 32}								\
! %{bestGnum: -bestGnum}							\
! %{!ZBSD43:-systype /sysv/}%{ZBSD43:-systype /bsd43/}			\
! "
! 
! #else
! #if defined(MIPS_BSD43)		/* RISC-OS BSD */
! 
! #define STARTFILE_SPEC							\
!   "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt1.o%s crtn.o%s}}"
  
+ #define LINK_SPEC  "%{!G32:%{G*}					\
+ %{!G:%{!G32:%{mG0:%eYou should include ld/as option -G}			\
+ %{mG1:%eYou should include ld/as option -G}				\
+ %{mG2:%eYou should include ld/as option -G}				\
+  -G 8}}}								\
+ %{G32: -G 32}								\
+ %{bestGnum: -bestGnum}							\
+ %{!ZSYSV:-systype /bsd43/}%{ZSYSV:-systype /sysv/}"
+ 
+ #else		/* Default for MIPS BSD and ULTRIX */
+ 
+ #define LINK_SPEC  "%{!G32:%{G*}					\
+ %{!G:%{!G32:%{mG0:%eYou should include ld/as option -G}		\
+ %{mG1:%eYou should include ld/as option -G}				\
+ %{mG2:%eYou should include ld/as option -G}				\
+  -G 8}}}								\
+ %{G32: -G 32}								\
+ %{bestGnum: -bestGnum} "
+ #endif
+ #endif
+ 
+ /* CC1 SPECS */
+ 
+ #define CC1_SPEC   "%{!O2:%{O:-O -fstrength-reduce -fomit-frame-pointer}}\
+                     %{O2:-O -fstrength-reduce -fomit-frame-pointer -mgpOPT}\
+                     %{g:%eThis port of GCC does not support -g flag}	\
+                     %{G32: -mG2 -mnG1 }					\
+                     %{G32:%{!O2:%eOption -G32 may require -O2}}"
+ 
+ /* CPP SPECS */
+ 
+ #ifdef DECSTATION
+ 				/* default DECSTATION environment */
+ #define CPP_SPEC "-DR3000 -DLANGUAGE_C -DMIPSEL -DSYSTYPE_BSD -Dultrix"
+ #else /* not DECSTATION */
+ #if defined(MIPS_SYSV) || defined(MIPS_BSD43)
+ 				/* MIPS RISC-OS environments */
+ 
+ #ifdef MIPS_SYSV
+ #define CPP_SPEC "-DR3000  -Dhost_mips -DMIPSEB				\
+                    %{!ZBSD43:-DSYSTYPE_SYSV}%{ZBSD43:-DSYSTYPE_BSD43}	\
+                    -DLANGUAGE_C						\
+                    %{!ZBSD43:-I/sysv/usr/include}			\
+                    %{ZBSD43:-I/bsd43/usr/include}"
+ #else /* not MIPS_SYSV */
+ #define CPP_SPEC "-DR3000  -Dhost_mips -DMIPSEB				\
+                    %{!ZSYSV:-DSYSTYPE_BSD43}%{ZSYSV:-DSYSTYPE_SYSV}	\
+                    -DLANGUAGE_C						\
+                    %{!ZYSV:-I/bsd43/usr/include}%{ZBSD43:-I/sysv/usr/include}"
+ #endif /* not MIPS_SYSV */
+ 
+ #else /* not MIPS_SYSV and not MIPS_BSD43 */
+ 				/* default MIPS Bsd environment */
+ #define CPP_SPEC "-DR3000  -Dhost_mips -DMIPSEB -DSYSTYPE_BSD -DLANGUAGE_C "
+ 
+ #endif /* not MIPS_SYSV and not MIPS_BSD43 */
+ #endif /* not DECSTATION */
+ \f


  /* Print subsidiary information on the compiler version in use.  */
  
! #ifdef DECSTATION
! #define TARGET_VERSION printf (" (AL-MIPS 1.11) <Decstation>\n");
! 				/* Depends on MIPS ASM. */
! #else
! #define TARGET_VERSION printf (" (AL-MIPS 1.11) <MIPS>\n");
! 				/* Depends on MIPS ASM. */
! #endif
! #define TARGET_VERSNUM "1 11"
  
  /* Do not Generate DBX debugging information.  */
***************
*** 57,62 ****
  /* Nonzero if compiling code that Unix assembler can assemble.  */
  #define TARGET_UNIX_ASM (target_flags & 1)
! 				/* Debug Mode
! 				 */
  #define TARGET_DEBUG_MODE (target_flags & 2)
  #define TARGET_DEBUGA_MODE (target_flags & 4)
--- 201,205 ----
  /* Nonzero if compiling code that Unix assembler can assemble.  */
  #define TARGET_UNIX_ASM (target_flags & 1)
! 				/* Debug Mode */
  #define TARGET_DEBUG_MODE (target_flags & 2)
  #define TARGET_DEBUGA_MODE (target_flags & 4)
***************
*** 64,71 ****
  #define TARGET_DEBUGC_MODE (target_flags & 32)
  #define TARGET_DEBUGD_MODE (target_flags & 64)
  #define TARGET_NAME_REGS (target_flags & 8)
  #define TARGET_NOFIXED_OVFL (target_flags & 128)
  
- #define AL_DEBUG
  
  /* Macro to define tables used to set the flags.
--- 207,219 ----
  #define TARGET_DEBUGC_MODE (target_flags & 32)
  #define TARGET_DEBUGD_MODE (target_flags & 64)
+ 				/* Register Naming in .s ($21 vs. $a0) */
  #define TARGET_NAME_REGS (target_flags & 8)
+ 				/* Use addu / subbu or get FIXED_OVFL TRAPS */
  #define TARGET_NOFIXED_OVFL (target_flags & 128)
+ 				/* Optimize for Sdata/Sbss */
+ #define TARGET_GP_OPT (target_flags & 4096)
+ #define TARGET_GVALUE ((target_flags >> 8 ) & 0xf)
+ 
  
  
  /* Macro to define tables used to set the flags.
***************
*** 75,95 ****
     An empty string NAME is used to identify the default VALUE.  */
  
! #define TARGET_SWITCHES  \
!   { {"unix", 1},  \
!     {"gnu", -1},  \
      {"debug", 2 }, 		/* RELOAD and CONSTRAINTS Related DEBUG */\
!     {"nodebug", -2 }, \
!     {"debuga",   4 }, 		/* CALLING SEQUENCE RELATED DEBUG */\
!     {"nodebuga", -4 }, \
!     {"debugb",   16 }, 		/* GLOBAL/LOCAL ALLOC  DEBUG */\
!     {"nodebugb", -16 }, \
      {"debugc",   32 }, 		/* SPILL/RELOAD REGISTER ALLOCATOR DEBUG */\
!     {"nodebugc", -32 }, \
!     {"debugd",   64 }, 		/* CSE DEBUG */\
!     {"nodebugd", -64 }, \
!     {"rnames",   8 }, 		/* Output register names like $a0 */\
!     {"nornames", -8 },  	/* Output register numbers like $21 */\
!     {"nofixed-ovfl",128},       /* use addu and subu                */\
!     {"fixed-ovfl", -128},       /* use addu and subu                */\
      { "", TARGET_DEFAULT}}
  
--- 223,253 ----
     An empty string NAME is used to identify the default VALUE.  */
  
! #define TARGET_SWITCHES							\
!   { {"unix", 1},							\
!     {"gnu", -1},							\
      {"debug", 2 }, 		/* RELOAD and CONSTRAINTS Related DEBUG */\
!     {"nodebug", -2 },							\
!     {"debuga",   4 }, 		/* CALLING SEQUENCE RELATED DEBUG */	\
!     {"nodebuga", -4 },							\
!     {"debugb",   16 }, 		/* GLOBAL/LOCAL ALLOC  DEBUG */		\
!     {"nodebugb", -16 },							\
      {"debugc",   32 }, 		/* SPILL/RELOAD REGISTER ALLOCATOR DEBUG */\
!     {"nodebugc", -32 },							\
!     {"debugd",   64 }, 		/* CSE DEBUG */				\
!     {"nodebugd", -64 },							\
!     {"rnames",   8 }, 		/* Output register names like $a0 */	\
!     {"nornames", -8 },  	/* Output register numbers like $21 */	\
!     {"nofixed-ovfl",128},       /* use addu and subu                */	\
!     {"fixed-ovfl", -128},       /* use add and sub                */	\
! 				/* Following used to support the data/sdata */\
! 				/* feature */				\
!     {"G0",256},								\
!     {"nG0",-256},							\
!     {"G1",512},								\
!     {"nG1",-512},							\
!     {"G2",1024},							\
!     {"nG2",-1024},							\
!     {"gpOPT", 4096},		/* DO the full GP optimization data/sdata.. */\
!     {"ngpOPT", -4096},\
      { "", TARGET_DEFAULT}}
  
***************
*** 96,100 ****
  /* Default target_flags if no switches specified.  */
  
! #define TARGET_DEFAULT 129
  \f


  /* Target machine storage layout */
--- 254,265 ----
  /* Default target_flags if no switches specified.  */
  
! #define TARGET_DEFAULT 897
! 
! /* Default GVALUE  (data item size threshold for selection of Sdata/data)
!    is computed : GVALUE ==  ( ((i=G0+2*G1+4*G2) < 6)
! 				        ? 1<<i
! 					: 1<< (i+6))
! */
! #define MIPS_GVALUE_DEFAULT 8
  \f


  /* Target machine storage layout */
***************
*** 176,180 ****
  		         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1,\
  		         1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,\
! 		         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\
  }
  
--- 341,345 ----
  		         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1,\
  		         1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,\
! 		         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0	\
  }
  
***************
*** 201,206 ****
     use Floating point register pairs.
  */
! #define HARD_REGNO_NREGS(REGNO, MODE)   \
!  (((MODE == SFmode) ||(MODE == DFmode)) ? 2 :\
    ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
  
--- 366,371 ----
     use Floating point register pairs.
  */
! #define HARD_REGNO_NREGS(REGNO, MODE)					\
!  (((MODE == SFmode) ||(MODE == DFmode)) ? 2 :				\
    ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
  
***************
*** 209,216 ****
     FLOATING POINT.  */
  
! #define HARD_REGNO_MODE_OK(REGNO, MODE) \
!    (((REGNO) <32) ? ((MODE) != SFmode) && ((MODE) != DFmode)\
!                 : (   ((MODE) == SFmode) || ((MODE) == DFmode)) \
!                     && (((REGNO) % 2 ) == 0))
  
  
--- 374,381 ----
     FLOATING POINT.  */
  
! #define HARD_REGNO_MODE_OK(REGNO, MODE)					\
!    ((REGNO) < 32 ? (int) (((MODE) != SFmode) && ((MODE) != DFmode))	\
!     : (int) (((MODE) == SFmode || (MODE) == DFmode)			\
! 	     && ((REGNO) & 1) == 0))
  
  
***************
*** 219,224 ****
     If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
     for any hard reg, then this must be 0 for correct output.  */
! #define MODES_TIEABLE_P(MODE1, MODE2)   \
!   (   ((MODE1) == SFmode || (MODE1) == DFmode) \
     == ((MODE2) == SFmode || (MODE2) == DFmode))
  
--- 384,389 ----
     If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
     for any hard reg, then this must be 0 for correct output.  */
! #define MODES_TIEABLE_P(MODE1, MODE2)					\
!   (   ((MODE1) == SFmode || (MODE1) == DFmode)				\
     == ((MODE2) == SFmode || (MODE2) == DFmode))
  
***************
*** 236,241 ****
     may be accessed via the stack pointer) in functions that seem suitable.
     This is computed in `reload', in reload1.c.  */
- #define FRAME_POINTER_REQUIRED 0
  
  /* Base register for access to arguments of the function.  */
  #define ARG_POINTER_REGNUM FRAME_POINTER_REGNUM
--- 401,410 ----
     may be accessed via the stack pointer) in functions that seem suitable.
     This is computed in `reload', in reload1.c.  */
  
+ /* This is now 1 because we don't know until too late
+    whether the function is a varargs function.
+    Such functions currently require extra stack slots on the mips.  */
+ #define FRAME_POINTER_REQUIRED 1
+ 
  /* Base register for access to arguments of the function.  */
  #define ARG_POINTER_REGNUM FRAME_POINTER_REGNUM
***************
*** 276,282 ****
  #define N_REG_CLASSES (int) LIM_REG_CLASSES
  
- /* Since GENERAL_REGS is the same class as ALL_REGS,
-    don't give it a different class number; just make it an alias.  */
- 
  #define GENERAL_REGS GR_REGS
  
--- 445,448 ----
***************
*** 283,287 ****
  /* Give names of register classes as strings for dump file.   */
  
! #define REG_CLASS_NAMES \
   {"NO_REGS", "GR_REGS", "FP_REGS", "ALL_REGS" }
  
--- 449,453 ----
  /* Give names of register classes as strings for dump file.   */
  
! #define REG_CLASS_NAMES							\
   {"NO_REGS", "GR_REGS", "FP_REGS", "ALL_REGS" }
  
***************
*** 290,296 ****
     of length N_REG_CLASSES.  */
  
! #define REG_CLASS_CONTENTS {{0x00000000, 0x00000000},\
!                             {0xffffffff, 0x00000000},\
!                             {0x00000000, 0xffffffff},\
  			    {0xffffffff, 0xffffffff}}
  
--- 456,462 ----
     of length N_REG_CLASSES.  */
  
! #define REG_CLASS_CONTENTS {{0x00000000, 0x00000000},			\
!                             {0xffffffff, 0x00000000},			\
!                             {0x00000000, 0xffffffff},			\
  			    {0xffffffff, 0xffffffff}}
  
***************
*** 301,305 ****
     or could index an array.  */
  
! #define REGNO_REG_CLASS(REGNO) \
     ( (REGNO >= 32) ? FP_REGS : GR_REGS)
  
--- 467,471 ----
     or could index an array.  */
  
! #define REGNO_REG_CLASS(REGNO)						\
     ( (REGNO >= 32) ? FP_REGS : GR_REGS)
  
***************
*** 312,326 ****
  
  /* We give just a dummy for the first element, which is for NO_REGS.  */
! /* #define REG_CLASS_SUPERCLASSES  {{LIM_REG_CLASSES},\
!   {GR_REGS,ALL_REGS,LIM_REG_CLASSES},\
!   {FP_REGS,ALL_REGS,LIM_REG_CLASSES},\
!   {ALL_REGS,LIM_REG_CLASSES}\
  }
  */
  /* We give just a dummy for the first element, which is for NO_REGS.  */
! #define REG_CLASS_SUPERCLASSES  {{LIM_REG_CLASSES},\
!   {ALL_REGS,LIM_REG_CLASSES},\
!   {ALL_REGS,LIM_REG_CLASSES},\
!   {LIM_REG_CLASSES}\
  }
  
--- 478,492 ----
  
  /* We give just a dummy for the first element, which is for NO_REGS.  */
! /* #define REG_CLASS_SUPERCLASSES  {{LIM_REG_CLASSES},			\
!   {GR_REGS,ALL_REGS,LIM_REG_CLASSES},					\
!   {FP_REGS,ALL_REGS,LIM_REG_CLASSES},					\
!   {ALL_REGS,LIM_REG_CLASSES}						\
  }
  */
  /* We give just a dummy for the first element, which is for NO_REGS.  */
! #define REG_CLASS_SUPERCLASSES  {{LIM_REG_CLASSES},			\
!   {ALL_REGS,LIM_REG_CLASSES},						\
!   {ALL_REGS,LIM_REG_CLASSES},						\
!   {LIM_REG_CLASSES}							\
  }
  
***************
*** 327,333 ****
  /* The inverse relationship:
     for each class, a list of all reg classes contained in it.  */
! #define REG_CLASS_SUBCLASSES  \
! {{LIM_REG_CLASSES},\
!   {GR_REGS,LIM_REG_CLASSES},\
    {FP_REGS,LIM_REG_CLASSES},\
    {GR_REGS, FP_REGS, ALL_REGS, LIM_REG_CLASSES}\
--- 493,499 ----
  /* The inverse relationship:
     for each class, a list of all reg classes contained in it.  */
! #define REG_CLASS_SUBCLASSES						\
! {{LIM_REG_CLASSES},							\
!   {GR_REGS,LIM_REG_CLASSES},						\
    {FP_REGS,LIM_REG_CLASSES},\
    {GR_REGS, FP_REGS, ALL_REGS, LIM_REG_CLASSES}\
***************
*** 347,353 ****
     is just element [C1, C2].  */
  
! #define REG_CLASS_SUBUNION  {{NO_REGS,  GR_REGS,   FP_REGS,  ALL_REGS}, \
!  {GR_REGS,  GR_REGS,   ALL_REGS, ALL_REGS},\
!  {FP_REGS,  ALL_REGS,  FP_REGS,  ALL_REGS},\
   {ALL_REGS, ALL_REGS,  ALL_REGS, ALL_REGS}}
  
--- 513,519 ----
     is just element [C1, C2].  */
  
! #define REG_CLASS_SUBUNION  {{NO_REGS,  GR_REGS,   FP_REGS,  ALL_REGS},	\
!  {GR_REGS,  GR_REGS,   ALL_REGS, ALL_REGS},				\
!  {FP_REGS,  ALL_REGS,  FP_REGS,  ALL_REGS},				\
   {ALL_REGS, ALL_REGS,  ALL_REGS, ALL_REGS}}
  
***************
*** 371,376 ****
  				 */
  
! #define REG_CLASS_FROM_LETTER(C) \
!    ((C) == 'f' ? FP_REGS:\
       (C) == 'y' ? GR_REGS:NO_REGS)
  
--- 537,542 ----
  				 */
  
! #define REG_CLASS_FROM_LETTER(C)					\
!    ((C) == 'f' ? FP_REGS:						\
       (C) == 'y' ? GR_REGS:NO_REGS)
  
***************
*** 381,392 ****
     Return 1 if VALUE is in the range specified by C.  */
  
- 				/* DEFINED INTEGER CONSTANT CLASSES:
- 				**
- 				** 'I'     : any 16 bit integer
- 				** 'J'     : 0   (use register $0)
- 				 */
  /*   For MIPS, `I' is used for the range of constants an insn
!                    can actually contain.
!                `J' is used for the range which is just zero (since that is R0).
  */
  
--- 547,554 ----
     Return 1 if VALUE is in the range specified by C.  */
  
  /*   For MIPS, `I' is used for the range of constants an insn
!                    can actually contain (16 bits signed integers).
!                `J' is used for the range which is just zero (since that is
! 	           available as $R0).
  */
  
***************
*** 393,399 ****
  #define SMALL_INT(X) ((unsigned) (INTVAL (X) + 0x10000) < 0x20000)
  
! #define CONST_OK_FOR_LETTER_P(VALUE, C)  \
!   ((C) == 'I' ? (unsigned) ((VALUE) + 0x10000) < 0x20000	\
!    : (C) == 'J' ? (VALUE) == 0				\
     : 0)
  
--- 555,561 ----
  #define SMALL_INT(X) ((unsigned) (INTVAL (X) + 0x10000) < 0x20000)
  
! #define CONST_OK_FOR_LETTER_P(VALUE, C)					\
!   ((C) == 'I' ? (unsigned) ((VALUE) + 0x10000) < 0x20000		\
!    : (C) == 'J' ? (VALUE) == 0						\
     : 0)
  
***************
*** 405,409 ****
  				** 'G'     : Floating point 0
  				 */
! #define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C)  \
    ((C) == 'G' && XINT (VALUE, 0) == 0 && XINT (VALUE, 1) == 0)
  
--- 567,571 ----
  				** 'G'     : Floating point 0
  				 */
! #define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C)				\
    ((C) == 'G' && XINT (VALUE, 0) == 0 && XINT (VALUE, 1) == 0)
  
***************
*** 413,418 ****
     in some cases it is preferable to use a more restrictive class.  */
  
! #define PREFERRED_RELOAD_CLASS(X,CLASS) \
!     (((GET_MODE(X) == SFmode) || (GET_MODE(X) == DFmode))? FP_REGS  :\
       ((GET_MODE(X) == VOIDmode) ? GR_REGS :(CLASS)))
  
--- 575,580 ----
     in some cases it is preferable to use a more restrictive class.  */
  
! #define PREFERRED_RELOAD_CLASS(X,CLASS)					\
!     (((GET_MODE(X) == SFmode) || (GET_MODE(X) == DFmode))? FP_REGS  :	\
       ((GET_MODE(X) == VOIDmode) ? GR_REGS :(CLASS)))
  
***************
*** 420,425 ****
  */
  
! #define PREFERRED_RELOAD_CLASS_FM(X,CLASS) \
!     ((((X) == SFmode) || ((X) == DFmode))? FP_REGS  :\
       (((X) == VOIDmode) ? GR_REGS :(CLASS)))
  
--- 582,587 ----
  */
  
! #define PREFERRED_RELOAD_CLASS_FM(X,CLASS)				\
!     ((((X) == SFmode) || ((X) == DFmode))? FP_REGS  :			\
       (((X) == VOIDmode) ? GR_REGS :(CLASS)))
  
***************
*** 427,433 ****
     needed to represent mode MODE in a register of class CLASS.  */
  
! #define CLASS_MAX_NREGS(CLASS, MODE)	\
!  ((((MODE) == DFmode) || ((MODE) == SFmode)) ? 2 \
!   : ((MODE) == VOIDmode)? ((CLASS) == FP_REGS ? 2 :1) \
    : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
  
--- 589,595 ----
     needed to represent mode MODE in a register of class CLASS.  */
  
! #define CLASS_MAX_NREGS(CLASS, MODE)					\
!  ((((MODE) == DFmode) || ((MODE) == SFmode)) ? 2			\
!   : ((MODE) == VOIDmode)? ((CLASS) == FP_REGS ? 2 :1)			\
    : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
  
***************
*** 449,453 ****
     first local allocated.  Otherwise, it is the offset to the BEGINNING
     of the first local allocated.  */
! #define STARTING_FRAME_OFFSET -4
  
  /* If we generate an insn to push BYTES bytes,
--- 611,615 ----
     first local allocated.  Otherwise, it is the offset to the BEGINNING
     of the first local allocated.  */
! #define STARTING_FRAME_OFFSET -8
  
  /* If we generate an insn to push BYTES bytes,
***************
*** 454,458 ****
     this says how many the stack pointer really advances by.
     On the vax, sp@- in a byte insn really pushes a word.  */
!  /* #define PUSH_ROUNDING(BYTES) (((BYTES) + 1) & ~1)*/
  
  
--- 616,621 ----
     this says how many the stack pointer really advances by.
     On the vax, sp@- in a byte insn really pushes a word.  */
! 
! /* #define PUSH_ROUNDING(BYTES) 0 */
  
  
***************
*** 482,486 ****
  \f


  /* For the MIPS, there seems to be a minimum to the amount of stack space
!    used... evidence comes from the dis-assembled version of printf:
  
   cc (cc)
--- 645,650 ----
  \f


  /* For the MIPS, there seems to be a minimum to the amount of stack space
!    used... for varargs using functions.
!    evidence comes from the dis-assembled version of printf:
  
   cc (cc)
***************
*** 496,502 ****
    [printf.c:  14] 0x400520:     afa70024        sw      a3,36(sp)
    [printf.c:  18] 0x400524:     27a5001c        addiu   a1,sp,28
  */
  
! #define STACK_ARG_ADJUST(SIZE)						\
  {									\
    SIZE.constant += 4;							\
--- 660,670 ----
    [printf.c:  14] 0x400520:     afa70024        sw      a3,36(sp)
    [printf.c:  18] 0x400524:     27a5001c        addiu   a1,sp,28
+ 
+   it is however OK for functions that do not take arguments to have 0 size
+   frames.
+ 
  */
  
! #define STACK_ARGS_ADJUST(SIZE)						\
  {									\
    SIZE.constant += 4;							\
***************
*** 512,516 ****
        emit_label (label);						\
        SIZE.constant = 0;						\
!       SIZE.var = rounded;						\
      }									\
    else if (SIZE.constant < 16)						\
--- 680,684 ----
        emit_label (label);						\
        SIZE.constant = 0;						\
!       SIZE.var = (tree) rounded;					\
      }									\
    else if (SIZE.constant < 16)						\
***************
*** 525,537 ****
  #define RETURN_POPS_ARGS(FUNTYPE) 0
  
- /* Some subroutine macros specific to this machine.  */
- #define BASE_RETURN_VALUE_REG(MODE) \
-  ((MODE) == SFmode || (MODE) == DFmode ? 44 : 4)
- #define BASE_OUTGOING_VALUE_REG(MODE) \
-  ((MODE) == SFmode || (MODE) == DFmode ? 44 : 4)
- #define BASE_PASSING_ARG_REG(MODE) (\
-  ((MODE) == SFmode || (MODE) == DFmode ? 44 : 4)
- #define BASE_INCOMING_ARG_REG(MODE) \
-  ((MODE) == SFmode || (MODE) == DFmode ? 44 : 4)
  
  /* Define how to find the value returned by a function.
--- 693,696 ----
***************
*** 540,545 ****
     otherwise, FUNC is 0.  */
  
! #define FUNCTION_VALUE(VALTYPE, FUNC)  \
!   gen_rtx (REG, TYPE_MODE (VALTYPE), \
    (TYPE_MODE (VALTYPE) == SFmode) ||(TYPE_MODE (VALTYPE) == DFmode)?32 : 2)
  
--- 699,704 ----
     otherwise, FUNC is 0.  */
  
! #define FUNCTION_VALUE(VALTYPE, FUNC)					\
!   gen_rtx (REG, TYPE_MODE (VALTYPE),					\
    (TYPE_MODE (VALTYPE) == SFmode) ||(TYPE_MODE (VALTYPE) == DFmode)?32 : 2)
  
***************
*** 548,552 ****
  
  
! #define LIBCALL_VALUE(MODE)  gen_rtx (REG, MODE,\
     ((MODE) == DFmode || ( MODE) == SFmode) ? 32 : 2)
  
--- 707,711 ----
  
  
! #define LIBCALL_VALUE(MODE)  gen_rtx (REG, MODE,			\
     ((MODE) == DFmode || ( MODE) == SFmode) ? 32 : 2)
  
***************
*** 561,565 ****
      */
  
! #define FUNCTION_ARG_REGNO_P(N) (((N) < 8 && (N) > 3) \
                                  ||((N) < 48 && (N) > 44 && (0 == (N) % 2)))
  \f


--- 720,724 ----
      */
  
! #define FUNCTION_ARG_REGNO_P(N) (((N) < 8 && (N) > 3)			\
                                  ||((N) < 48 && (N) > 44 && (0 == (N) % 2)))
  \f


***************
*** 591,610 ****
  		     ARG_STA_GGGG =12 /* $4 $5 $6 $7 */
  		     };
! #define ARG_STA_AUTOMA \
! {\
!   {ARG_STA_F,ARG_STA_G,44,4        },   /* ARG_STA_INIT */\
!   {ARG_STA_FF,ARG_STA_FG,46,6      },   /* ARG_STA_F    */\
!   {ARG_STA_FF,ARG_STA_FF,-1,-1     },   /* ARG_STA_FF   */\
!   {ARG_STA_FGF,ARG_STA_FGG,-1,7    },   /* ARG_STA_FG   */\
!   {ARG_STA_FGG,ARG_STA_FGG,-1,-1   },   /* ARG_STA_FGG  */\
!   {ARG_STA_FGF,ARG_STA_FGF,-1,-1   },   /* ARG_STA_FGF  */\
!   {ARG_STA_GF,ARG_STA_GG,-2,5      },   /* ARG_STA_G    */\
!   {ARG_STA_GF,ARG_STA_GF,-1,-1     },   /* ARG_STA_GF   */\
!   {ARG_STA_GGF,ARG_STA_GGG,-2,6    },   /* ARG_STA_GG   */\
!   {ARG_STA_GGF,ARG_STA_GGF,-1,-1   },   /* ARG_STA_GGF  */\
!   {ARG_STA_GGGF,ARG_STA_GGGG,-1,7  },   /* ARG_STA_GGG  */\
!   {ARG_STA_GGGF,ARG_STA_GGGF,-1,-1 },   /* ARG_STA_GGGF */\
!   {ARG_STA_GGGG,ARG_STA_GGGG,-1,-1 }    /* ARG_STA_GGGG */\
  }
  /* Initialize a variable CUM of type CUMULATIVE_ARGS
     for a call to a function whose data type is FNTYPE.
--- 750,770 ----
  		     ARG_STA_GGGG =12 /* $4 $5 $6 $7 */
  		     };
! #define ARG_STA_AUTOMA							\
! {									\
!   {ARG_STA_F,ARG_STA_G,44,4        },   /* ARG_STA_INIT */		\
!   {ARG_STA_FF,ARG_STA_FG,46,6      },   /* ARG_STA_F    */		\
!   {ARG_STA_FF,ARG_STA_FF,-1,-1     },   /* ARG_STA_FF   */		\
!   {ARG_STA_FGF,ARG_STA_FGG,-1,7    },   /* ARG_STA_FG   */		\
!   {ARG_STA_FGG,ARG_STA_FGG,-1,-1   },   /* ARG_STA_FGG  */		\
!   {ARG_STA_FGF,ARG_STA_FGF,-1,-1   },   /* ARG_STA_FGF  */		\
!   {ARG_STA_GF,ARG_STA_GG,-2,5      },   /* ARG_STA_G    */		\
!   {ARG_STA_GF,ARG_STA_GF,-1,-1     },   /* ARG_STA_GF   */		\
!   {ARG_STA_GGF,ARG_STA_GGG,-2,6    },   /* ARG_STA_GG   */		\
!   {ARG_STA_GGF,ARG_STA_GGF,-1,-1   },   /* ARG_STA_GGF  */		\
!   {ARG_STA_GGGF,ARG_STA_GGGG,-1,7  },   /* ARG_STA_GGG  */		\
!   {ARG_STA_GGGF,ARG_STA_GGGF,-1,-1 },   /* ARG_STA_GGGF */		\
!   {ARG_STA_GGGG,ARG_STA_GGGG,-1,-1 }    /* ARG_STA_GGGG */		\
  }
+ 
  /* Initialize a variable CUM of type CUMULATIVE_ARGS
     for a call to a function whose data type is FNTYPE.
***************
*** 620,624 ****
     (TYPE is null for libcalls where that information may not be available.)  */
  
! #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)	\
  			    ( function_arg_advance(&CUM,MODE,TYPE));
  
--- 780,784 ----
     (TYPE is null for libcalls where that information may not be available.)  */
  
! #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)			\
  			    ( function_arg_advance(&CUM,MODE,TYPE));
  
***************
*** 643,653 ****
       ( (rtx) function_arg(&CUM,MODE,TYPE,NAMED))
  
- /* Define where a function finds its arguments.
-    This is different from FUNCTION_ARG because of register windows.  */
- 
- #define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED)			\
-      ( (rtx) function_inarg(&CUM,MODE,TYPE,NAMED))
- 
- 
  /* For an arg passed partly in registers and partly in memory,
     this is the number of registers used.
--- 803,806 ----
***************
*** 655,660 ****
  */
  
! #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 		\
!   (   0)
  \f


  
--- 808,812 ----
  */
  
! #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) (0)
  \f


  
***************
*** 679,691 ****
     The current implementation:
        a/ tries to figure out if the current routines uses varargs.(It becomes
!          ``suspect''.
  
!       b/when a function is suspected of using varags, (is our varargs.h
! 	has been included, and ``we think'' the macro va_start has been
! 	used in this function, a larger reg save_area is allocated which
! 	will hold regs f12 and f14. The varargs macros then have to find
! 	where is the argument they are looking for. This is made easier
!         by a modification in stack frame layout for these functions:the
!         stack frame-size is accessible on stack at location 4($30).
  
          Total overhead in PROLOGUE: 2 inns to put stacksize on stack
--- 831,843 ----
     The current implementation:
        a/ tries to figure out if the current routines uses varargs.(It becomes
!          ``suspect''.) This is currently done by looking for a special
! 	 static character string constant.
  
!       b/when a function is suspected of using varags,  a larger reg
!         save_area is allocated which will hold regs f12 and f14. The varargs
! 	macros then have to find where is the argument they are looking for.
! 	This is made easier by a modification in stack frame layout for
!         these functions:the  stack frame-size is accessible on stack at
!         location 4($30).
  
          Total overhead in PROLOGUE: 2 inns to put stacksize on stack
***************
*** 695,699 ****
          The only problem with ``thinking'', is that when functions are
          thought using varargs and dont do it, they get the above entry
!         overhead.
  
  
--- 847,851 ----
          The only problem with ``thinking'', is that when functions are
          thought using varargs and dont do it, they get the above entry
!         overhead.However the current method is quite precise, and is *safe*.
  
  
***************
*** 704,715 ****
  extern int  this_varargs_suspect ;
  
- #if 0
- extern int  function_suspect;
- 
- #define FUNCTION_SUSPECT(COND) function_suspect |= (COND)
- #define FUNCTION_NOTSUSPECT    function_suspect = 0
- #define FUNCTION_SUSPECTED    (function_suspect == 0xf )
- #endif
- 
  #define VARARGS_SUSPECT(COND) varargs_suspect |= (COND)
  #define VARARGS_NOTSUSPECT    varargs_suspect = 0
--- 856,859 ----
***************
*** 721,802 ****
  \f


  
! #define FUNCTION_PROLOGUE(FILE, SIZE)     \
! { register int regno;						\
    register int mask = 0, fmask=0;					\
!   static char dont_save_regs[] = CALL_USED_REGISTERS;	\
!   register int push_loc = 0,tsize = SIZE  - (STARTING_FRAME_OFFSET)+4;\
!   char *fp_str;\
!   extern char *reg_numchar[];\
!   extern int  current_function_total_framesize;  \
!   this_varargs_suspect = VARARGS_SUSPECTED  ;\
!   fp_str = TARGET_NAME_REGS ? reg_names[STACK_POINTER_REGNUM]\
! 	       : reg_numchar[STACK_POINTER_REGNUM];\
!   for (regno = 0; regno < 32; regno++)	\
!     if (MUST_SAVE_REG_LOGUES || (regs_ever_live[regno] && !dont_save_regs[regno]))\
!       {tsize += 4; mask |= 1 << regno;}\
!   for (regno = 32; regno < FIRST_PSEUDO_REGISTER; regno += 2)	\
!     if (regs_ever_live[regno] && !dont_save_regs[regno])	\
!       {tsize += 8; fmask |= 1 << (regno-32);}\
!     if (THIS_VARARGS_SUSPECTED) tsize += 16;  \
!   fprintf(FILE," #PROLOGUE\n");\
!     regno = STACK_POINTER_REGNUM;  \
!     tsize = AL_ADJUST_ALIGN(tsize);  \
! \
!   if(!frame_pointer_needed)\
!     fprintf(FILE,"#define __0__gcc  %d\n",tsize);\
!   \
!   push_loc = 0; current_function_total_framesize = tsize;\
!   fprintf (FILE, " #\t.mask\t0x%x\n", mask);		\
!   for (regno = 31; regno >= 30; regno--)	\
!    {\
!     if (MUST_SAVE_REG_LOGUES ||(regs_ever_live[regno] && !dont_save_regs[regno])){	\
!       push_loc += 4;\
!        fprintf(FILE,"\tsw\t%s,%d(%s)\n", TARGET_NAME_REGS ? reg_names[regno]\
! 	       : reg_numchar[regno],push_loc-tsize,fp_str);}\
! \
!     \
!    }   \
!    if (THIS_VARARGS_SUSPECTED)\
!       { int fregno;\
!         fprintf(FILE,"\taddi\t%s,$0,%d\t#Varargs suspicion\n",\
!              TARGET_NAME_REGS ? reg_names[9]\
! 		: reg_numchar[9],tsize);\
! 	fprintf(FILE,"\tsw\t%s,-4(%s)\t#Varargs suspicion\n",\
!              TARGET_NAME_REGS ? reg_names[9]\
! 		: reg_numchar[9],\
!              TARGET_NAME_REGS ? reg_names[29]\
! 		: reg_numchar[29]);\
! 	for (fregno = 44; fregno< 48; fregno += 2)\
!          {push_loc += 8;	\
!        fprintf(FILE,"\ts.d\t%s,%d(%s)\t#Varargs Suspicion\n",\
!                      ((TARGET_NAME_REGS)\
!                        ?reg_names[fregno]: reg_numchar[fregno]),\
!                                          push_loc-tsize,fp_str);}\
! 	}\
!   for (regno = 29; regno >= 0; regno--)	\
!    {\
!     if (MUST_SAVE_REG_LOGUES ||(regs_ever_live[regno] && !dont_save_regs[regno])){	\
!       push_loc += 4;\
!        fprintf(FILE,"\tsw\t%s,%d(%s)\n", TARGET_NAME_REGS ? reg_names[regno]\
! 	       : reg_numchar[regno],push_loc-tsize,fp_str);}\
! \
!     \
!    }   \
!   fprintf (FILE, " #\t.fmask\t0x%x\n", fmask);		\
!   for (regno = 32; regno < FIRST_PSEUDO_REGISTER; regno += 2)	\
!     if (regs_ever_live[regno] && !dont_save_regs[regno]){push_loc += 8;	\
!        fprintf(FILE,"\ts.d\t%s,%d(%s)\n",((TARGET_NAME_REGS) ?reg_names[regno]\
! 	       : reg_numchar[regno]),push_loc-tsize,fp_str);}\
!   if(frame_pointer_needed)\
!     fprintf(FILE,"\tadd\t%s,$0,%s\n",\
!                (TARGET_NAME_REGS ? reg_names[FRAME_POINTER_REGNUM]  :\
!                reg_numchar[FRAME_POINTER_REGNUM]),\
!                (TARGET_NAME_REGS ? reg_names[29]  : reg_numchar[29]));\
!   fprintf(FILE,"\tsubu\t%s,%d\t#temp=%5d,saveregs=%5d, sfo=%5d\n",\
!                 TARGET_NAME_REGS ? reg_names[29]\
! 	   :reg_numchar[29],tsize,SIZE,tsize-SIZE+ (STARTING_FRAME_OFFSET),\
!            STARTING_FRAME_OFFSET);\
!   fprintf(FILE," #END PROLOGUE\n");\
!   }
  
  /* Output assembler code to FILE to increment profiler label # LABELNO
--- 865,968 ----
  \f


  
! #define FUNCTION_PROLOGUE(FILE, SIZE)					\
! { register int regno;							\
    register int mask = 0, fmask=0;					\
!   static char dont_save_regs[] = CALL_USED_REGISTERS;			\
!   register int push_loc = 0,tsize = SIZE+8;				\
!   char *fp_str;								\
!   extern char *reg_numchar[];						\
!   extern int  current_function_total_framesize;				\
!   this_varargs_suspect = VARARGS_SUSPECTED  ;				\
!   fp_str = TARGET_NAME_REGS ? reg_names[STACK_POINTER_REGNUM]		\
!     : reg_numchar[STACK_POINTER_REGNUM];				\
!   for (regno = 0; regno < 32; regno++)					\
!     if (  MUST_SAVE_REG_LOGUES						\
! 	|| (regs_ever_live[regno] && !dont_save_regs[regno]))		\
!       {tsize += 4; mask |= 1 << regno;}					\
!   for (regno = 32; regno < FIRST_PSEUDO_REGISTER; regno += 2)		\
!     if (regs_ever_live[regno] && !dont_save_regs[regno])		\
!       {tsize += 8; fmask |= 1 << (regno-32);}				\
!   if (THIS_VARARGS_SUSPECTED) tsize += 16;				\
!   fprintf (FILE," #PROLOGUE\n");					\
!   regno = STACK_POINTER_REGNUM;						\
!   tsize = AL_ADJUST_ALIGN (tsize);					\
! 									\
!   if (!frame_pointer_needed)						\
!     fprintf (FILE,"#define __0__gcc  %d\n",				\
! 	     (!( regs_ever_live[29] || regs_ever_live[30]		\
! 		|| fmask || mask					\
! 		|| (SIZE > 0)))						\
! 	     ? 0:tsize);						\
! 									\
!   push_loc = 0; current_function_total_framesize = tsize;		\
!   fprintf (FILE, " #\t.mask\t0x%x\n", mask);				\
!   if (frame_pointer_needed || regs_ever_live[29] || regs_ever_live[30]	\
!       || fmask || mask							\
!       || (SIZE > 0))							\
!     fprintf (FILE,"\tsubu\t%s,%d\t#temp=%5d,saveregs=%5d, sfo=%5d\n",	\
! 	     TARGET_NAME_REGS ? reg_names[29]				\
! 	     :reg_numchar[29],tsize,SIZE,tsize-SIZE,			\
! 	     STARTING_FRAME_OFFSET);					\
!   else fprintf (FILE," #NO STACK PUSH:\tSP %sused, FP %sused, FP %sneeded\n",\
! 		regs_ever_live[29]? "":"un",				\
! 		regs_ever_live[30]? "":"un",				\
! 	       frame_pointer_needed ?"" : "not ");			\
!   for  (regno = 31; regno >= 30; regno--)				\
!     {									\
!       if (MUST_SAVE_REG_LOGUES						\
! 	  || (regs_ever_live[regno] && !dont_save_regs[regno]))		\
! 	{								\
! 	  fprintf (FILE, "\tsw\t%s,%d(%s)\n",				\
! 		   TARGET_NAME_REGS ? reg_names[regno] : reg_numchar[regno], \
! 		   push_loc, fp_str);					\
! 	  push_loc += 4;						\
! 	}								\
!     }									\
!   if (THIS_VARARGS_SUSPECTED)						\
!     { int fregno;							\
!       fprintf (FILE, "\taddi\t%s,$0,%d\t#Varargs suspicion\n",		\
! 	       TARGET_NAME_REGS ? reg_names[9] : reg_numchar[9],	\
! 	       tsize);							\
!       fprintf (FILE, "\tsw\t%s,%d(%s)\t#Varargs suspicion\n",		\
! 	       TARGET_NAME_REGS ? reg_names[9] : reg_numchar[9],	\
! 	       tsize - 4,						\
! 	       TARGET_NAME_REGS ? reg_names[29] : reg_numchar[29]);	\
!       for (fregno = 44; fregno< 48; fregno += 2)			\
! 	{								\
! 	  fprintf (FILE, "\ts.d\t%s,%d(%s)\t#Varargs Suspicion\n",	\
! 		   ((TARGET_NAME_REGS)					\
! 		    ? reg_names[fregno] : reg_numchar[fregno]),		\
! 		   push_loc, fp_str);					\
! 	  push_loc += 8;						\
! 	}								\
!     }									\
!   for (regno = 29; regno >= 0; regno--)					\
!     {									\
!       if (MUST_SAVE_REG_LOGUES						\
! 	  || (regs_ever_live[regno] && !dont_save_regs[regno]))		\
! 	{								\
! 	  fprintf (FILE, "\tsw\t%s,%d(%s)\n",				\
! 		   TARGET_NAME_REGS ? reg_names[regno] : reg_numchar[regno], \
! 		   push_loc, fp_str);					\
! 	  push_loc += 4;						\
! 	}								\
!     }									\
!   fprintf (FILE, " #\t.fmask\t0x%x\n", fmask);				\
!   for  (regno = 32; regno < FIRST_PSEUDO_REGISTER; regno += 2)		\
!     if (regs_ever_live[regno] && !dont_save_regs[regno])		\
!       {									\
! 	fprintf (FILE, "\ts.d\t%s,%d(%s)\n",				\
! 		 (TARGET_NAME_REGS) ? reg_names[regno] : reg_numchar[regno], \
! 		 push_loc, fp_str);					\
! 	push_loc += 8;							\
!       }									\
!   if (frame_pointer_needed)						\
!     fprintf (FILE, "\taddiu\t%s,%s,%d\t#Establish FramePTR\n",		\
! 	     (TARGET_NAME_REGS ? reg_names[FRAME_POINTER_REGNUM]	\
! 	      : reg_numchar[FRAME_POINTER_REGNUM]),			\
! 	     (TARGET_NAME_REGS ? reg_names[29] : reg_numchar[29]),	\
! 	     tsize);							\
!   fprintf (FILE," #END PROLOGUE\n");					\
! }
  
  /* Output assembler code to FILE to increment profiler label # LABELNO
***************
*** 803,807 ****
     for profiling a function entry.  */
  
! #define FUNCTION_PROFILER(FILE, LABELNO)  \
     fprintf (FILE, "ERROR\t profiler LP%d,r0\n", (LABELNO));
  
--- 969,973 ----
     for profiling a function entry.  */
  
! #define FUNCTION_PROFILER(FILE, LABELNO)				\
     fprintf (FILE, "ERROR\t profiler LP%d,r0\n", (LABELNO));
  
***************
*** 829,837 ****
  */
  
! #define MUST_SAVE_REG_LOGUES (( frame_pointer_needed && (regno == 30))\
!                               ||( (regno == 31) && regs_ever_live[31])\
                                   )
  
! 
  /* This macro generates the assembly code for function exit,
     on machines that need it.  If FUNCTION_EPILOGUE is not defined
--- 995,1003 ----
  */
  
! #define MUST_SAVE_REG_LOGUES (( frame_pointer_needed && (regno == 30))	\
!                               ||( (regno == 31) && regs_ever_live[31])	\
                                   )
  
! \f


  /* This macro generates the assembly code for function exit,
     on machines that need it.  If FUNCTION_EPILOGUE is not defined
***************
*** 840,895 ****
  
  
! #define FUNCTION_EPILOGUE(FILE, SIZE) \
! { register int regno;						\
!   register int mask = 0;					\
!   char *fp_str;\
!   static char dont_save_regs[] = CALL_USED_REGISTERS;	\
!   register int push_loc ;\
!   extern char *reg_numchar[];  \
!   extern char *current_function_name; \
!  extern int  current_function_total_framesize; \
!   push_loc = -current_function_total_framesize;  \
!   regno = STACK_POINTER_REGNUM;  \
!   fp_str = TARGET_NAME_REGS ? reg_names[STACK_POINTER_REGNUM]\
! 	       : reg_numchar[STACK_POINTER_REGNUM];\
!   fprintf(FILE," #EPILOGUE\n");\
!   if(frame_pointer_needed)\
!   fprintf(FILE,"\taddu\t%s,$0,%s\t# sp not trusted  here \n",\
!            TARGET_NAME_REGS ? reg_names[STACK_POINTER_REGNUM]\
! 	           :reg_numchar[STACK_POINTER_REGNUM],\
!            TARGET_NAME_REGS ? reg_names[FRAME_POINTER_REGNUM]\
! 	           :reg_numchar[FRAME_POINTER_REGNUM]\
!            );\
!   else\
!   fprintf(FILE,"\taddu\t%s,%d\t\n",TARGET_NAME_REGS ? reg_names[29]\
! 	   :reg_numchar[29],current_function_total_framesize);\
!   if(!frame_pointer_needed)\
!     fprintf(FILE,"#undef __0__gcc\n");\
!   for (regno = 0; regno < 32; regno++)	\
!     if ( MUST_SAVE_REG_LOGUES ||(regs_ever_live[regno] && !dont_save_regs[regno]))\
!        mask |= 1 << regno;					\
!   fprintf (FILE, " #\t.mask\t0x%x\n", mask);		\
!   for (regno = 31; regno >= 0; regno--)	\
!   { if ( MUST_SAVE_REG_LOGUES ||(regs_ever_live[regno] && !dont_save_regs[regno])){	\
!        push_loc += 4;\
!        fprintf(FILE,"\tlw\t%s,%d(%s)\n", TARGET_NAME_REGS ? reg_names[regno]\
! 	       : reg_numchar[regno],push_loc,fp_str);}\
!     if( THIS_VARARGS_SUSPECTED && (regno == 30)) push_loc += 16;\
!    }\
!    mask =0;\
!   for (regno = 32; regno < FIRST_PSEUDO_REGISTER; regno += 2)	\
!     if (regs_ever_live[regno] && !dont_save_regs[regno])	\
!        mask |= 1 << (regno-32);					\
!   fprintf (FILE, " #\t.fmask\t0x%x\n", mask);		\
!   for (regno = 32; regno < FIRST_PSEUDO_REGISTER; regno += 2){	\
!     if (regs_ever_live[regno] && !dont_save_regs[regno]){	\
!         push_loc += 8;\
!         fprintf(FILE,"\tl.d\t%s,%d(%s)\n",(( TARGET_NAME_REGS) ? reg_names[regno]\
! 	       : reg_numchar[regno]),push_loc,fp_str);\
!         }}\
!    fprintf(FILE,"\tj\t$31\n");\
!    fprintf(FILE," #END EPILOGUE\n");\
!    fprintf(FILE," \t.end\t%s\n",current_function_name);\
!    THIS_VARARGS_NOTSUSPECT; VARARGS_NOTSUSPECT;}\
  
  /* If the memory Address ADDR is relative to the frame pointer,
--- 1006,1090 ----
  
  
! #define FUNCTION_EPILOGUE(FILE, SIZE)					\
! { register int regno;							\
!   register int mask = 0;						\
!   register int fmask = 0;						\
!   char *fp_str;								\
!   char *sp_str;								\
!   static char dont_save_regs[] = CALL_USED_REGISTERS;			\
!   register int push_loc ;						\
!   extern char *reg_numchar[];						\
!   extern char *current_function_name;					\
!   extern int  current_function_total_framesize;				\
!   push_loc = 0;								\
!   regno = STACK_POINTER_REGNUM;						\
!   sp_str = TARGET_NAME_REGS ? reg_names[STACK_POINTER_REGNUM]		\
!     : reg_numchar[STACK_POINTER_REGNUM];				\
!   fp_str = TARGET_NAME_REGS ? reg_names[8]				\
!     :reg_numchar[8];							\
!   fprintf (FILE," #EPILOGUE\n");					\
!   if (!frame_pointer_needed)						\
!     fprintf (FILE,"#undef __0__gcc\n");					\
!   else									\
!     fprintf (FILE,"\taddu\t%s,$0,%s\t# sp not trusted  here \n",	\
! 	     fp_str,							\
! 	     TARGET_NAME_REGS ? reg_names[FRAME_POINTER_REGNUM]		\
! 	     :reg_numchar[FRAME_POINTER_REGNUM]				\
! 	     );								\
!   for  (regno = 0; regno < 32; regno++)					\
!     if  ( MUST_SAVE_REG_LOGUES						\
! 	 || (regs_ever_live[regno] && !dont_save_regs[regno]))		\
!       mask |= 1 << regno;						\
!   fprintf  (FILE, " #\t.mask\t0x%x\n", mask);				\
!   for  (regno = 31; regno >= 0; regno--)				\
!     { if  ( MUST_SAVE_REG_LOGUES					\
! 	   || (regs_ever_live[regno] && !dont_save_regs[regno]))	\
! 	{								\
! 	  fprintf (FILE,"\tlw\t%s,%d(%s)\n",				\
! 		   TARGET_NAME_REGS ? reg_names[regno]			\
! 		   : reg_numchar[regno],				\
! 		   (frame_pointer_needed ?				\
! 		    push_loc - current_function_total_framesize:	\
! 		    push_loc),						\
! 		   (frame_pointer_needed ? fp_str :sp_str));		\
! 	  push_loc += 4;						\
! 	}								\
!       if ( THIS_VARARGS_SUSPECTED &&  (regno == 30)) push_loc += 16;	\
!     }									\
!   for  (regno = 32; regno < FIRST_PSEUDO_REGISTER; regno += 2)		\
!     if  (regs_ever_live[regno] && !dont_save_regs[regno])		\
!       fmask |= 1 <<  (regno-32);					\
!   fprintf  (FILE, " #\t.fmask\t0x%x\n", fmask);				\
!     for  (regno = 32; regno < FIRST_PSEUDO_REGISTER; regno += 2)	\
!     {									\
!       if  (regs_ever_live[regno] && !dont_save_regs[regno])		\
! 	{								\
! 	  fprintf (FILE,"\tl.d\t%s,%d(%s)\n",				\
! 		   ( ( TARGET_NAME_REGS) ? reg_names[regno]		\
! 		    : reg_numchar[regno]),				\
! 		   (frame_pointer_needed ?				\
! 		    push_loc - current_function_total_framesize		\
! 		    : push_loc),					\
! 		   (frame_pointer_needed ? fp_str :sp_str));		\
! 	  push_loc += 8;						\
! 	}								\
!     }									\
!   if (frame_pointer_needed)						\
!     fprintf (FILE,"\taddu\t%s,$0,%s\t# sp not trusted  here \n",	\
! 	     TARGET_NAME_REGS ? reg_names[STACK_POINTER_REGNUM]		\
! 	     :reg_numchar[STACK_POINTER_REGNUM],			\
! 	     TARGET_NAME_REGS ? reg_names[8]				\
! 	     :reg_numchar[8]						\
! 	     );								\
!   else									\
!     if (regs_ever_live[29]|| regs_ever_live[30]				\
! 	|| fmask || mask						\
! 	||  (SIZE > 0))			\
!       fprintf (FILE,"\taddu\t%s,%d\t\n",TARGET_NAME_REGS ? reg_names[29]\
! 	       :reg_numchar[29],current_function_total_framesize);	\
!   fprintf (FILE,"\tj\t$31\n");						\
!   fprintf (FILE," #END EPILOGUE\n");					\
!   fprintf (FILE," \t.end\t%s\n",current_function_name);			\
!   THIS_VARARGS_NOTSUSPECT; VARARGS_NOTSUSPECT;}
  
  /* If the memory Address ADDR is relative to the frame pointer,
***************
*** 898,925 ****
     ADDR should be a variable name.  */
  
! #define FIX_FRAME_POINTER_ADDRESS(ADDR,DEPTH) \
! { rtx newaddr;\
!     int frame_offset = -1;\
!     /* fprintf(stderr,"FIX_FRAME depth=%d\n",DEPTH); */\
!   if(ADDR == frame_pointer_rtx)\
!     frame_offset = 0;\
!   else\
!       if (GET_CODE(ADDR) == PLUS)\
!           if(XEXP(ADDR,0) == frame_pointer_rtx)\
!              if(GET_CODE(XEXP(ADDR,1)) == CONST_INT)\
! 	       frame_offset = INTVAL(XEXP(ADDR,1));\
!              else abort_with_insn(ADDR,"Unable to FIX");\
!           else if (XEXP(ADDR,1) == frame_pointer_rtx)\
!              if(GET_CODE(XEXP(ADDR,0)) == CONST_INT)\
! 	       frame_offset = INTVAL(XEXP(ADDR,0));\
!              else abort_with_insn(ADDR,"Unable to FIX");\
! 	  else;\
!    if (frame_offset >= 0)\
!     { newaddr=gen_rtx(PLUS,Pmode,stack_pointer_rtx,\
!                       gen_rtx(PLUS,Pmode,\
                            gen_rtx(CONST_INT,VOIDmode,frame_offset+(DEPTH)),\
! 			      gen_rtx(SYMBOL_REF,SImode,"__0__gcc")));\
!       ADDR = newaddr;\
!     }  \
    }
  
--- 1093,1120 ----
     ADDR should be a variable name.  */
  
! #define FIX_FRAME_POINTER_ADDRESS(ADDR,DEPTH)				\
! { rtx newaddr;								\
!     int frame_offset = -1;						\
!     /* fprintf(stderr,"FIX_FRAME depth=%d\n",DEPTH); */			\
!   if(ADDR == frame_pointer_rtx)						\
!     frame_offset = 0;							\
!   else									\
!       if (GET_CODE(ADDR) == PLUS)					\
!           if(XEXP(ADDR,0) == frame_pointer_rtx)				\
!              if(GET_CODE(XEXP(ADDR,1)) == CONST_INT)			\
! 	       frame_offset = INTVAL(XEXP(ADDR,1));			\
!              else abort_with_insn(ADDR,"Unable to FIX");		\
!           else if (XEXP(ADDR,1) == frame_pointer_rtx)			\
!              if(GET_CODE(XEXP(ADDR,0)) == CONST_INT)			\
! 	       frame_offset = INTVAL(XEXP(ADDR,0));			\
!              else abort_with_insn(ADDR,"Unable to FIX");		\
! 	  else;								\
!    if (frame_offset >= 0)						\
!     { newaddr=gen_rtx(PLUS,Pmode,stack_pointer_rtx,			\
!                       gen_rtx(PLUS,Pmode,				\
                            gen_rtx(CONST_INT,VOIDmode,frame_offset+(DEPTH)),\
! 			      gen_rtx(SYMBOL_REF,SImode,"__0__gcc")));	\
!       ADDR = newaddr;							\
!     }									\
    }
  
***************
*** 939,947 ****
     These definitions are NOT overridden anywhere.  */
  
! #define REGNO_OK_FOR_INDEX_P(regno)  \
  ((regno) < FIRST_PSEUDO_REGISTER || reg_renumber[regno] >= 0)
! #define REGNO_OK_FOR_BASE_P(regno) \
  ((regno) < FIRST_PSEUDO_REGISTER || reg_renumber[regno] >= 0)
! #define REGNO_OK_FOR_FP_P(REGNO) \
  (((REGNO) ^ 0x20) < 32 || (unsigned) (reg_renumber[REGNO] ^ 0x20) < 32)
  
--- 1134,1142 ----
     These definitions are NOT overridden anywhere.  */
  
! #define REGNO_OK_FOR_INDEX_P(regno)					\
  ((regno) < FIRST_PSEUDO_REGISTER || reg_renumber[regno] >= 0)
! #define REGNO_OK_FOR_BASE_P(regno)					\
  ((regno) < FIRST_PSEUDO_REGISTER || reg_renumber[regno] >= 0)
! #define REGNO_OK_FOR_FP_P(REGNO)					\
  (((REGNO) ^ 0x20) < 32 || (unsigned) (reg_renumber[REGNO] ^ 0x20) < 32)
  
***************
*** 979,983 ****
  #define REGNO_OK_FOR_CLASS_P(X, C)  0
  
! #define ADDRESS_REG_P(X)	\
    (GET_CODE (X) == REG )
  
--- 1174,1178 ----
  #define REGNO_OK_FOR_CLASS_P(X, C)  0
  
! #define ADDRESS_REG_P(X)						\
    (GET_CODE (X) == REG )
  
***************
*** 999,1003 ****
  
  /* 1 if X is an address that we could indirect through.  */
! #define INDIRECTABLE_ADDRESS_P(X)  \
    (CONSTANT_ADDRESS_P (X)						\
     || (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X))			\
--- 1194,1198 ----
  
  /* 1 if X is an address that we could indirect through.  */
! #define INDIRECTABLE_ADDRESS_P(X)					\
    (CONSTANT_ADDRESS_P (X)						\
     || (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X))			\
***************
*** 1010,1018 ****
  
  /* 1 if X is an address which is (+ (reg) (+ (const_int) (symbol_ref)  )) */
! #define FIXED_FRAME_PTR_REL_P(X)\
!   (    (GET_CODE(X) == PLUS)\
!    &&  (GET_CODE(XEXP((X),0)) == REG)\
!    &&  (GET_CODE(XEXP((X),1)) == PLUS)\
!    &&  (GET_CODE(XEXP(XEXP((X),1),0)) == CONST_INT)\
     &&   (GET_CODE(XEXP(XEXP((X),1),1)) == SYMBOL_REF))
  
--- 1205,1213 ----
  
  /* 1 if X is an address which is (+ (reg) (+ (const_int) (symbol_ref)  )) */
! #define FIXED_FRAME_PTR_REL_P(X)					\
!   (    (GET_CODE(X) == PLUS)						\
!    &&  (GET_CODE(XEXP((X),0)) == REG)					\
!    &&  (GET_CODE(XEXP((X),1)) == PLUS)					\
!    &&  (GET_CODE(XEXP(XEXP((X),1),0)) == CONST_INT)			\
     &&   (GET_CODE(XEXP(XEXP((X),1),1)) == SYMBOL_REF))
  
***************
*** 1019,1023 ****
  /* Go to ADDR if X is a valid address not using indexing.
     (This much is the easy part.)  */
! #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)  \
  { register rtx xfoob = (X);						\
    if (GET_CODE (xfoob) == REG) goto ADDR;				\
--- 1214,1218 ----
  /* Go to ADDR if X is a valid address not using indexing.
     (This much is the easy part.)  */
! #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)				\
  { register rtx xfoob = (X);						\
    if (GET_CODE (xfoob) == REG) goto ADDR;				\
***************
*** 1029,1033 ****
  
  
! #define CONSTANT_ADDRESS_P(X)   \
    (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF		\
     || GET_CODE (X) == CONST_INT						\
--- 1224,1228 ----
  
  
! #define CONSTANT_ADDRESS_P(X)						\
    (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF		\
     || GET_CODE (X) == CONST_INT						\
***************
*** 1034,1038 ****
     || GET_CODE (X) == CONST)
  
- 
  /* Nonzero if the constant value X is a legitimate general operand.
     It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.
--- 1229,1232 ----
***************
*** 1040,1049 ****
     Anything but a CONST_DOUBLE can be made to work.  */
  
! #define LEGITIMATE_CONSTANT_P(X)		\
   (GET_CODE (X) != CONST_DOUBLE)
  
- #define REG_P(X)	\
-   (GET_CODE (X) == REG)
- 
  /* Try machine-dependent ways of modifying an illegitimate address
     to be legitimate.  If we find one, return the new, valid address.
--- 1234,1240 ----
     Anything but a CONST_DOUBLE can be made to work.  */
  
! #define LEGITIMATE_CONSTANT_P(X)					\
   (GET_CODE (X) != CONST_DOUBLE)
  
  /* Try machine-dependent ways of modifying an illegitimate address
     to be legitimate.  If we find one, return the new, valid address.
***************
*** 1074,1078 ****
  				/* See if this is of any use here */
  
! #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL)	\
  { }
  
--- 1265,1269 ----
  				/* See if this is of any use here */
  
! #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL)			\
  { }
  
***************
*** 1094,1098 ****
  
  /* Define this as 1 if `char' should by default be signed; else as 0.  */
! #define DEFAULT_SIGNED_CHAR 0
  
  /* Max number of bytes we can move from memory to memory
--- 1285,1289 ----
  
  /* Define this as 1 if `char' should by default be signed; else as 0.  */
! #define DEFAULT_SIGNED_CHAR 1
  
  /* Max number of bytes we can move from memory to memory
***************
*** 1144,1157 ****
     return it with a return statement.  Otherwise, break from the switch.  */
  
! #define CONST_COSTS(RTX,CODE) \
!   case CONST_INT:						\
!     /* Constant zero is super cheap due to register 0.  */	\
!     if (RTX == const0_rtx) return 0;				\
      if ((INTVAL (RTX) < 0x7fff) && (- INTVAL(RTX) < 0x7fff)) return 1;	\
!   case CONST:							\
!   case LABEL_REF:						\
!   case SYMBOL_REF:						\
!     return 3;							\
!   case CONST_DOUBLE:						\
      return 5;
  \f


--- 1335,1348 ----
     return it with a return statement.  Otherwise, break from the switch.  */
  
! #define CONST_COSTS(RTX,CODE)						\
!   case CONST_INT:							\
!     /* Constant zero is super cheap due to register 0.  */		\
!     if (RTX == const0_rtx) return 0;					\
      if ((INTVAL (RTX) < 0x7fff) && (- INTVAL(RTX) < 0x7fff)) return 1;	\
!   case CONST:								\
!   case LABEL_REF:							\
!   case SYMBOL_REF:							\
!     return 3;								\
!   case CONST_DOUBLE:							\
      return 5;
  \f


***************
*** 1172,1176 ****
     Do not alter them if the instruction would not alter the cc's.  */
  
! #define NOTICE_UPDATE_CC(EXP, INSN) \
    CC_STATUS_INIT;
  
--- 1363,1367 ----
     Do not alter them if the instruction would not alter the cc's.  */
  
! #define NOTICE_UPDATE_CC(EXP, INSN)					\
    CC_STATUS_INIT;
  
***************
*** 1184,1193 ****
  /* Output at beginning of assembler file.  */
  
! #define ASM_FILE_START(FILE) \
!  if(TARGET_NAME_REGS) \
!   fprintf(FILE,"#include <regdef.h>\n\t.verstamp\t%s\n",TARGET_VERSNUM);\
!   else fprintf(FILE," #\t.verstamp\t%s\n",TARGET_VERSNUM);\
!   print_options(FILE);
! 
  
  /* Output to assembler file text saying following lines
--- 1375,1387 ----
  /* Output at beginning of assembler file.  */
  
! #define ASM_FILE_START(FILE)						\
! {									\
!   if (TARGET_NAME_REGS)							\
!     fprintf (FILE, "#include <regdef.h>\n\t.verstamp\t%s\n", TARGET_VERSNUM);\
!   else fprintf (FILE, " #\t.verstamp\t%s\n", TARGET_VERSNUM);		\
! /* print_options(FILE);  */						\
!   if (TARGET_GP_OPT)							\
!     fprintf (FILE, "#ifdef %sRESCAN_GCC\n", "__x_");			\
! }
  
  /* Output to assembler file text saying following lines
***************
*** 1209,1236 ****
  #define DATA_SECTION_ASM_OP ".data"
  
  /* How to refer to registers in assembler output.
     This sequence is indexed by compiler's hard-register-number (see above).  */
  
! #define REGISTER_NAMES \
! {"$0", "at", "v0", "v1", "a0", "a1", "a2", "a3", "t0", \
!  "t1", "t2", "t3", "t4", "t5", "t6", "t7","s0",\
!  "s1","s2","s3","s4","s5","s6","s7","t8","t9",\
!  "k0","k1","gp","sp","fp","ra",\
!  "$f0","$f1","$f2","$f3","$f4","$f5","$f6","$f7","$f8","$f9",\
! "$f10","$f11","$f12","$f13","$f14","$f15","$f16","$f17","$f18","$f19",\
! "$f20","$f21","$f22","$f23","$f24","$f25","$f26","$f27","$f28","$f29",\
! "$f30","$f31"\
! }
! #define REGISTER_NUMCHAR \
! {\
! "$0","$1","$2","$3","$4","$5","$6","$7","$8","$9",\
! "$10","$11","$12","$13","$14","$15","$16","$17","$18","$19",\
! "$20","$21","$22","$23","$24","$25","$26","$27","$28","$29",\
! "$30","$31",\
! "$f0","$f1","$f2","$f3","$f4","$f5","$f6","$f7","$f8","$f9",\
! "$f10","$f11","$f12","$f13","$f14","$f15","$f16","$f17","$f18","$f19",\
! "$f20","$f21","$f22","$f23","$f24","$f25","$f26","$f27","$f28","$f29",\
! "$f30","$f31"\
  }
  
  
--- 1403,1438 ----
  #define DATA_SECTION_ASM_OP ".data"
  
+ #define  ASM_OUTPUT_MIPS_SECTIONS
+ #define  OUTPUT_MIPS_SECTION_THRESHOLD  ((mips_section_threshold >= 0 )?\
+ 					mips_section_threshold : mips_section_get())
+ 
+ /* Output before writable  short data.  */
+ 
+ #define SDATA_SECTION_ASM_OP ".sdata"
+ 
  /* How to refer to registers in assembler output.
     This sequence is indexed by compiler's hard-register-number (see above).  */
  
! #define REGISTER_NAMES							\
! {"$0", "at", "v0", "v1", "a0", "a1", "a2", "a3", "t0",			\
!  "t1", "t2", "t3", "t4", "t5", "t6", "t7","s0",				\
!  "s1","s2","s3","s4","s5","s6","s7","t8","t9",				\
!  "k0","k1","gp","sp","fp","ra",						\
!  "$f0","$f1","$f2","$f3","$f4","$f5","$f6","$f7","$f8","$f9",		\
! "$f10","$f11","$f12","$f13","$f14","$f15","$f16","$f17","$f18","$f19",	\
! "$f20","$f21","$f22","$f23","$f24","$f25","$f26","$f27","$f28","$f29",	\
! "$f30","$f31"								\
  }
+ #define REGISTER_NUMCHAR						\
+ {									\
+ "$0","$1","$2","$3","$4","$5","$6","$7","$8","$9",			\
+ "$10","$11","$12","$13","$14","$15","$16","$17","$18","$19",		\
+ "$20","$21","$22","$23","$24","$25","$26","$27","$28","$29",		\
+ "$30","$31",								\
+ "$f0","$f1","$f2","$f3","$f4","$f5","$f6","$f7","$f8","$f9",		\
+ "$f10","$f11","$f12","$f13","$f14","$f15","$f16","$f17","$f18","$f19",	\
+ "$f20","$f21","$f22","$f23","$f24","$f25","$f26","$f27","$f28","$f29",	\
+ "$f30","$f31"								\
+ }
  
  
***************
*** 1253,1257 ****
  
  				/* 'x'  X is CONST_INT, prints 16 bits in
! 				**      Hexadecimal format = "0x%4x"
  				*/
  
--- 1455,1463 ----
  
  				/* 'x'  X is CONST_INT, prints 16 bits in
! 				**      Hexadecimal format = "0x%4x",
! 				** 'd'  output integer constant in decimal,
! 				** 'u'  Prints an 'u' if flag -mnofixed-ovfl
! 				**      has been set, thus selecting addu
! 				**      instruction instead of add.
  				*/
  
***************
*** 1260,1276 ****
     CODE is the code from the %-spec that requested printing this operand;
     if `%z3' was used to print operand 3, then CODE is 'z'.
!    Codes used on the MIPS include `u', `x' and `z'.
!    ??? SOMEONE PLEASE DOCUMENT THEM??? */
  
! #define PRINT_OPERAND(FILE, X, CODE)  \
! { if ((CODE) == 'u')\
!     if (TARGET_NOFIXED_OVFL)fprintf(FILE,"u");      \
    else if (GET_CODE (X) == REG)						\
!     { extern char *reg_numchar[];\
!       fprintf (FILE, "%s", TARGET_NAME_REGS ?reg_names[REGNO (X)]\
! 	       :reg_numchar[REGNO (X) ]);	\
!     }\
!   else
!     { \
        if (GET_CODE (X) == MEM)						\
  	output_address (XEXP (X, 0));					\
--- 1466,1495 ----
     CODE is the code from the %-spec that requested printing this operand;
     if `%z3' was used to print operand 3, then CODE is 'z'.
!    CODE is used as follows:
! 
! 				    LIST OF PRINT OPERAND CODES
! 
! 
! 				   'x'  X is CONST_INT, prints 16 bits in
! 				**      Hexadecimal format = "0x%4x",
! 				** 'd'  output integer constant in decimal,
! 				** ':'  Prints an 'u' if flag -mnofixed-ovfl
! 				**      has been set, thus selecting addu
! 				**      instruction instead of add.
! 				*/
  
! #define PRINT_OPERAND_PUNCT_VALID_P(CODE)				\
!   ((CODE) == ':')
! 
! #define PRINT_OPERAND(FILE, X, CODE)					\
! { if ((CODE) == ':')							\
!     {if (TARGET_NOFIXED_OVFL)fprintf(FILE,"u");}			\
    else if (GET_CODE (X) == REG)						\
!     { extern char *reg_numchar[];					\
!       fprintf (FILE, "%s", TARGET_NAME_REGS ?reg_names[REGNO (X)]	\
! 	       :reg_numchar[REGNO (X) ]);				\
!     }									\
!   else									\
!     {									\
        if (GET_CODE (X) == MEM)						\
  	output_address (XEXP (X, 0));					\
***************
*** 1283,1339 ****
  	  if (GET_MODE (X) == SFmode)					\
  	    u.d = u1.f;							\
! 	  fprintf (FILE, "%.20e", u.d); }        			\
!       else \
! 	{ if ((CODE == 'x') && (GET_CODE(X) == CONST_INT))\
! 	    fprintf(FILE,"0x%x",0xffff & (INTVAL(X)));\
! 	  else { if ((CODE == 'd') && (GET_CODE(X) == CONST_INT))\
! 		   fprintf(FILE,"%d",(INTVAL(X)));\
! 	         else\
! 		   {\
! 		      if ((CODE) == 'd') my_print_rtx(X);\
! 		      else output_addr_const (FILE, X);}\
  		}}}}
  
- 
- 
  /* Print a memory operand whose address is X, on file FILE.  */
  
! #define PRINT_OPERAND_ADDRESS(FILE, ADDR)  \
  { register rtx reg1, reg2, breg, ireg;					\
    register rtx addr = ADDR;						\
    rtx offset;								\
!   extern char *reg_numchar[];\
! /*	my_print_rtx(addr);*/\
   retry:									\
    switch (GET_CODE (addr))						\
      {									\
-     case MEM:								\
-       fprintf (FILE, "ERROR:*");					\
-       addr = XEXP (addr, 0);						\
-       goto retry;							\
      case REG:								\
!       fprintf (FILE, "0(%s)", TARGET_NAME_REGS ? reg_names[REGNO (addr)]\
! 	       : reg_numchar[REGNO(addr)]);			\
        break;								\
      case PRE_DEC:							\
-       fprintf (FILE, "(ERROR)-(%s)", reg_names[REGNO (XEXP (addr, 0))]);\
-       break;								\
      case POST_INC:							\
!       fprintf (FILE, "(ERROR)(%s)+", reg_names[REGNO (XEXP (addr, 0))]);\
! 	my_print_rtx(addr);                                             \
        break;								\
      case PLUS:								\
!       if(   (GET_CODE (XEXP(addr,0)) == REG)\
!          && (GET_CODE (XEXP(addr,1)) == PLUS)\
!          && (GET_CODE (XEXP(XEXP(addr,1),1)) == SYMBOL_REF)\
!          && (GET_CODE (XEXP(XEXP(addr,1),0)) == CONST_INT))\
! 	{output_address(XEXP(XEXP(addr,1),0));\
!          fprintf(FILE,"+");\
!          output_address(XEXP(XEXP(addr,1),1));\
!          breg = XEXP(addr,0);\
! 	 fprintf(FILE,"(%s)", TARGET_NAME_REGS ?\
! 		   reg_names[REGNO (breg)]: reg_numchar[REGNO(breg)]);\
! 	 break;\
!         }\
  									\
        reg1 = 0;	reg2 = 0;						\
--- 1502,1550 ----
  	  if (GET_MODE (X) == SFmode)					\
  	    u.d = u1.f;							\
! 	  fprintf (FILE, "%.20e", u.d); }				\
!       else								\
! 	{ if ((CODE == 'x') && (GET_CODE(X) == CONST_INT))		\
! 	    fprintf(FILE,"0x%x",0xffff & (INTVAL(X)));			\
! 	  else { if ((CODE == 'd') && (GET_CODE(X) == CONST_INT))	\
! 		   fprintf(FILE,"%d",(INTVAL(X)));			\
! 	         else							\
! 		   {							\
! 		      if ((CODE) == 'd') abort();			\
! 		      else output_addr_const (FILE, X);}		\
  		}}}}
  
  /* Print a memory operand whose address is X, on file FILE.  */
  
! #define PRINT_OPERAND_ADDRESS(FILE, ADDR)				\
  { register rtx reg1, reg2, breg, ireg;					\
    register rtx addr = ADDR;						\
    rtx offset;								\
!   extern char *reg_numchar[];						\
! /*	my_print_rtx(addr);*/						\
   retry:									\
    switch (GET_CODE (addr))						\
      {									\
      case REG:								\
!       fprintf (FILE, "0(%s)", TARGET_NAME_REGS ? reg_names [REGNO (addr)]\
! 	       : reg_numchar[REGNO(addr)]);				\
        break;								\
+     case MEM:								\
      case PRE_DEC:							\
      case POST_INC:							\
!       abort();								\
        break;								\
      case PLUS:								\
!       if(   (GET_CODE (XEXP(addr,0)) == REG)				\
!          && (GET_CODE (XEXP(addr,1)) == PLUS)				\
!          && (GET_CODE (XEXP(XEXP(addr,1),1)) == SYMBOL_REF)		\
!          && (GET_CODE (XEXP(XEXP(addr,1),0)) == CONST_INT))		\
! 	{output_address(XEXP(XEXP(addr,1),0));				\
!          fprintf(FILE,"+");						\
!          output_address(XEXP(XEXP(addr,1),1));				\
!          breg = XEXP(addr,0);						\
! 	 fprintf(FILE,"(%s)", TARGET_NAME_REGS ?			\
! 		   reg_names[REGNO (breg)]: reg_numchar[REGNO(breg)]);	\
! 	 break;								\
!         }								\
  									\
        reg1 = 0;	reg2 = 0;						\
***************
*** 1340,1344 ****
        ireg = 0;	breg = 0;						\
        offset = 0;							\
!         /*fprintf(stderr,"PRINT_OPERAND_ADDRESS"); */                   \
        if (CONSTANT_ADDRESS_P (XEXP (addr, 0))				\
  	  || GET_CODE (XEXP (addr, 0)) == MEM)				\
--- 1551,1555 ----
        ireg = 0;	breg = 0;						\
        offset = 0;							\
!         /*fprintf(stderr,"PRINT_OPERAND_ADDRESS"); */			\
        if (CONSTANT_ADDRESS_P (XEXP (addr, 0))				\
  	  || GET_CODE (XEXP (addr, 0)) == MEM)				\
***************
*** 1389,1399 ****
        if (breg != 0)							\
  	{ if (GET_CODE (breg) != REG) abort ();				\
! 	  fprintf (FILE, "(%s)", TARGET_NAME_REGS ?\
! 		   reg_names[REGNO (breg)]: reg_numchar[REGNO(breg)]); }	\
        if (ireg != 0)							\
  	{ if (GET_CODE (ireg) == MULT) ireg = XEXP (ireg, 0);		\
  	  if (GET_CODE (ireg) != REG) abort ();				\
! 	  fprintf (FILE, "[%s]",  TARGET_NAME_REGS ?\
! 		   reg_names[REGNO (ireg)]: reg_numchar[REGNO(ireg)]); }	\
        break;								\
      default:								\
--- 1600,1610 ----
        if (breg != 0)							\
  	{ if (GET_CODE (breg) != REG) abort ();				\
! 	  fprintf (FILE, "(%s)", TARGET_NAME_REGS ?			\
! 		   reg_names[REGNO (breg)]: reg_numchar[REGNO(breg)]); }\
        if (ireg != 0)							\
  	{ if (GET_CODE (ireg) == MULT) ireg = XEXP (ireg, 0);		\
  	  if (GET_CODE (ireg) != REG) abort ();				\
! 	  fprintf (FILE, "[%s]",  TARGET_NAME_REGS ?			\
! 		   reg_names[REGNO (ireg)]: reg_numchar[REGNO(ireg)]); }\
        break;								\
      default:								\
***************
*** 1407,1414 ****
     This is needed for SunOS 4.0, and should not hurt for 3.2
     versions either.  */
! #define ASM_OUTPUT_SOURCE_LINE(file, line)		\
!   { static int sym_lineno = 1;				\
!     fprintf (file, " #.stabn 68,0,%d,LM%d\nLM%d:\n",	\
! 	     line, sym_lineno, sym_lineno);		\
      sym_lineno += 1; }
  
--- 1618,1625 ----
     This is needed for SunOS 4.0, and should not hurt for 3.2
     versions either.  */
! #define ASM_OUTPUT_SOURCE_LINE(file, line)				\
!   { static int sym_lineno = 1;						\
!     fprintf (file, " #.stabn 68,0,%d,LM%d\nLM%d:\n",			\
! 	     line, sym_lineno, sym_lineno);				\
      sym_lineno += 1; }
  
***************
*** 1416,1420 ****
     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)
  
--- 1627,1631 ----
     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)
  
***************
*** 1422,1431 ****
     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)
  
! #define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL)\
!   fprintf(FILE,"\t.ent\t%s\n",NAME);\
!   current_function_name = NAME;\
    ASM_OUTPUT_LABEL(FILE,NAME);
  
--- 1633,1648 ----
     defined for reference from other files.  */
  
! #define ASM_GLOBALIZE_LABEL(FILE,NAME)					\
!   do { fputs ("\t.globl ", FILE); assemble_name (FILE, NAME);		\
!        fputs ("\n", FILE);						\
!        if(TARGET_GP_OPT) {fputs ("#define _gccx__",FILE);		\
!        assemble_name(FILE,NAME);					\
!        fputs ("\n", FILE);						\
!        }								\
!      } while (0)
  
! #define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL)			\
!   fprintf(FILE,"\t.ent\t%s\n",NAME);					\
!   current_function_name = NAME;						\
    ASM_OUTPUT_LABEL(FILE,NAME);
  
***************
*** 1433,1437 ****
     `assemble_name' uses this.  */
  
! #define ASM_OUTPUT_LABELREF(FILE,NAME)	\
    fprintf (FILE, "%s", NAME)
  
--- 1650,1654 ----
     `assemble_name' uses this.  */
  
! #define ASM_OUTPUT_LABELREF(FILE,NAME)					\
    fprintf (FILE, "%s", NAME)
  
***************
*** 1439,1443 ****
     PREFIX is the class of label and NUM is the number within the class.  */
  
! #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)	\
    fprintf (FILE, "%s%d:\n", PREFIX, NUM)
  
--- 1656,1660 ----
     PREFIX is the class of label and NUM is the number within the class.  */
  
! #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)			\
    fprintf (FILE, "%s%d:\n", PREFIX, NUM)
  
***************
*** 1447,1451 ****
     This is suitable for output with `assemble_name'.  */
  
! #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)	\
    sprintf (LABEL, "*%s%d", PREFIX, NUM)
  
--- 1664,1668 ----
     This is suitable for output with `assemble_name'.  */
  
! #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)			\
    sprintf (LABEL, "*%s%d", PREFIX, NUM)
  
***************
*** 1452,1456 ****
  /* This is how to output an assembler line defining a `double' constant.  */
  
! #define ASM_OUTPUT_DOUBLE(FILE,VALUE)  \
    fprintf (FILE, "\t.double %.20e\n", (VALUE))
  
--- 1669,1673 ----
  /* This is how to output an assembler line defining a `double' constant.  */
  
! #define ASM_OUTPUT_DOUBLE(FILE,VALUE)					\
    fprintf (FILE, "\t.double %.20e\n", (VALUE))
  
***************
*** 1457,1461 ****
  /* This is how to output an assembler line defining a `float' constant.  */
  
! #define ASM_OUTPUT_FLOAT(FILE,VALUE)  \
    fprintf (FILE, "\t.float %.12e\n", (VALUE))
  
--- 1674,1678 ----
  /* This is how to output an assembler line defining a `float' constant.  */
  
! #define ASM_OUTPUT_FLOAT(FILE,VALUE)					\
    fprintf (FILE, "\t.float %.12e\n", (VALUE))
  
***************
*** 1462,1468 ****
  /* This is how to output an assembler line defining an `int' constant.  */
  
! #define ASM_OUTPUT_INT(FILE,VALUE)  \
! ( fprintf (FILE, "\t.word "),			\
!   output_addr_const (FILE, (VALUE)),		\
    fprintf (FILE, "\n"))
  
--- 1679,1685 ----
  /* This is how to output an assembler line defining an `int' constant.  */
  
! #define ASM_OUTPUT_INT(FILE,VALUE)					\
! ( fprintf (FILE, "\t.word "),						\
!   output_addr_const (FILE, (VALUE)),					\
    fprintf (FILE, "\n"))
  
***************
*** 1469,1480 ****
  /* Likewise for `char' and `short' constants.  */
  
! #define ASM_OUTPUT_SHORT(FILE,VALUE)  \
! ( fprintf (FILE, "\t.half "),			\
!   output_addr_const (FILE, (VALUE)),		\
    fprintf (FILE, "\n"))
  
! #define ASM_OUTPUT_CHAR(FILE,VALUE)  \
! ( fprintf (FILE, "\t.byte "),			\
!   output_addr_const (FILE, (VALUE)),		\
    fprintf (FILE, "\n"))
  
--- 1686,1697 ----
  /* Likewise for `char' and `short' constants.  */
  
! #define ASM_OUTPUT_SHORT(FILE,VALUE)					\
! ( fprintf (FILE, "\t.half "),						\
!   output_addr_const (FILE, (VALUE)),					\
    fprintf (FILE, "\n"))
  
! #define ASM_OUTPUT_CHAR(FILE,VALUE)					\
! ( fprintf (FILE, "\t.byte "),						\
!   output_addr_const (FILE, (VALUE)),					\
    fprintf (FILE, "\n"))
  
***************
*** 1481,1485 ****
  /* This is how to output an assembler line for a numeric constant byte.  */
  
! #define ASM_OUTPUT_BYTE(FILE,VALUE)  \
    fprintf (FILE, "\t.byte 0x%x\n", (VALUE))
  
--- 1698,1702 ----
  /* This is how to output an assembler line for a numeric constant byte.  */
  
! #define ASM_OUTPUT_BYTE(FILE,VALUE)					\
    fprintf (FILE, "\t.byte 0x%x\n", (VALUE))
  
***************
*** 1486,1490 ****
  /* This is how to output an element of a case-vector that is absolute.  */
  
! #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)  \
    fprintf (FILE, "\t.word L%d\n", VALUE)
  
--- 1703,1707 ----
  /* This is how to output an element of a case-vector that is absolute.  */
  
! #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)				\
    fprintf (FILE, "\t.word L%d\n", VALUE)
  
***************
*** 1493,1497 ****
     but we must define this macro anyway.)  */
  
! #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL)  \
    fprintf (FILE, "\t.word L%d-L%d\n", VALUE, REL)
  
--- 1710,1714 ----
     but we must define this macro anyway.)  */
  
! #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL)			\
    fprintf (FILE, "\t.word L%d-L%d\n", VALUE, REL)
  
***************
*** 1500,1525 ****
     to a multiple of 2**LOG bytes.  */
  
! #define ASM_OUTPUT_ALIGN(FILE,LOG)	\
      fprintf (FILE, "\t.align %d\n", (LOG))
  
! #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
    fprintf (FILE, "\t.space %d\n", (SIZE))
  
  /* This says how to output an assembler line
     to define a global common symbol.  */
  
! #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)  \
! ( fputs ("\n.comm ", (FILE)),			\
!   assemble_name ((FILE), (NAME)),		\
!   fprintf ((FILE), ",%d\n", (ROUNDED)))
  
  /* This says how to output an assembler line
     to define a local common symbol.  */
  
! #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)  \
! ( fputs ("\t.lcomm\t", (FILE)),			\
!   assemble_name ((FILE), (NAME)),		\
    fprintf ((FILE), ",%d\n", (ROUNDED)))
  
  /* Store in OUTPUT a string (made with alloca) containing
     an assembler-name for a local static variable named NAME.
--- 1717,1824 ----
     to a multiple of 2**LOG bytes.  */
  
! #define ASM_OUTPUT_ALIGN(FILE,LOG)					\
      fprintf (FILE, "\t.align %d\n", (LOG))
  
! #define ASM_OUTPUT_SKIP(FILE,SIZE)					\
    fprintf (FILE, "\t.space %d\n", (SIZE))
+ \f


+ /* The support of .comm and .extern  below permits to take advantage
+    of the SDATA/SBSS sections supported by the MIPS ASSEMBLER and LOADER
+    However some problems have to be solved
+         a/  externs should be included ONCE
+ 	b/  the same external cannot appear both on an extern and .comm stmt
+ 	    in the same assembly
+ 	c/  for the whole scheme to bring some benefit, .comm should appear
+ 	    in front of the source asm -- whereas GCC put them at the end
+ */
+ 
+ 
+ 				/* ALL THESE PROBLEMS ARE PRESENTLY SOLVED   */
+ 				/* USING CONDITIONAL ASSEMBLY + FILE RESCAN  */
+ 
+ #define EXTRA_SECTIONS in_sdata
+ 
+ /* Define the additional functions to select our additional sections.  */
+ 
+        /* on the MIPS it is not a good idea to put constants  in the
+ 	  text section, since this defeats the sdata/data mechanism. This
+ 	  is especially true when -O2 is used. In this case an effort is
+ 	  made to address with faster (gp) register relative addressing,
+ 	  which can only get at sdata and sbss items (there is no stext !!)
+        */
+ #define EXTRA_SECTION_FUNCTIONS						\
+ void									\
+ sdata_section ()							\
+ {									\
+   if (in_section != in_sdata)						\
+     {									\
+       fprintf (asm_out_file, "%s\n", SDATA_SECTION_ASM_OP);		\
+       in_section = in_sdata;						\
+     }								\
+ }
+ 
+ /* Given a decl node or constant node, choose the section to output it in
+    and select that section.  */
  
+        /* following takes  care of constants  emitted from
+ 	  the hash table entries (see above comment)
+        */
+ #define SELECT_SECTION_MODE(MODE,RTX)					\
+ {									\
+   extern int mips_section_threshold;					\
+   if (( GET_MODE_SIZE(MODE)/ BITS_PER_UNIT)				\
+ 	      <= OUTPUT_MIPS_SECTION_THRESHOLD)				\
+ 	    sdata_section();						\
+ 	  else								\
+ 	    data_section ();						\
+ }									\
+ 
+ #define SELECT_SECTION(DECL)						\
+ {									\
+   extern int mips_section_threshold;					\
+ 	  if (int_size_in_bytes (TREE_TYPE (DECL))			\
+ 	      <= OUTPUT_MIPS_SECTION_THRESHOLD)				\
+ 	    sdata_section ();						\
+ 	  else								\
+ 	    data_section ();						\
+ }
+ 
  /* This says how to output an assembler line
     to define a global common symbol.  */
  
! #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)			\
! ( ((TARGET_GP_OPT)?							\
!    fprintf((FILE),"\n#else"),0 :0),					\
!  fputs ("\n\t.comm ", (FILE)),						\
!  assemble_name ((FILE), (NAME)),					\
!  fprintf ((FILE), ",%d\n", (ROUNDED)),					\
!  (TARGET_GP_OPT ? (fputs("\n#define _gccx__",(FILE)),			\
! 		   assemble_name((FILE),NAME),0):0),			\
!  ((TARGET_GP_OPT)?							\
!   fprintf((FILE),"\n#endif\n#ifdef %sRESCAN_GCC","__x_"),0 :0)		\
! )
! 
! 
! /* This says how to output an external                                      */
! /* It would be possible not to output anything and let undefined            */
! /* symbol become external. However the assembler uses length  information on*/
! /* externals to allocate in data/sdata bss/sbss, thereby saving exec time   */
! 
! #define ASM_OUTPUT_EXTERNAL(FILE,DECL,NAME)				\
!         mips_output_external(FILE,DECL,NAME)
  
+ 
  /* This says how to output an assembler line
     to define a local common symbol.  */
  
! #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)			\
! ( fputs ("\n\t.lcomm\t", (FILE)),					\
!   assemble_name ((FILE), (NAME)),					\
    fprintf ((FILE), ",%d\n", (ROUNDED)))
  
+ /* This says what to print at the end of the assembly file */
+ #define ASM_FILE_END(FILE)						\
+        mips_asm_file_end(FILE)
+ \f


  /* Store in OUTPUT a string (made with alloca) containing
     an assembler-name for a local static variable named NAME.
***************
*** 1526,1536 ****
     LABELNO is an integer which is different for each call.  */
  
! #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)	\
! ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10),	\
    sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
  
! #define ASM_OUTPUT_REG_POP(FILE,REGNO) \
    (fprintf (FILE,"ERROR: ASM_OUTPUT_REG_POP\n"))
! #define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \
    (fprintf (FILE,"ERROR: ASM_OUTPUT_REG_PUSH\n"))
  
--- 1825,1835 ----
     LABELNO is an integer which is different for each call.  */
  
! #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)			\
! ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10),			\
    sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
  
! #define ASM_OUTPUT_REG_POP(FILE,REGNO)					\
    (fprintf (FILE,"ERROR: ASM_OUTPUT_REG_POP\n"))
! #define ASM_OUTPUT_REG_PUSH(FILE,REGNO)					\
    (fprintf (FILE,"ERROR: ASM_OUTPUT_REG_PUSH\n"))
  
***************
*** 1538,1565 ****
  				/*  C-text of varasm.c. It has been modified */
  				/*  to handle the VARARG_SUSPECTED hack      */
! #define  ASM_OUTPUT_ASCII(FILE, P , SIZE)\
! {  int i;\
! 	  fprintf ((FILE), "\t.ascii \"");\
!           VARARGS_SUSPECT( 0 == strncmp((P),"__%%VARARGS",11));\
! 	  for (i = 0; i < (SIZE); i++)\
! 	    {\
! 	      register int c = (P)[i];\
! 	      if (c == '\"' || c == '\\')\
! 		putc ('\\', (FILE));\
! 	      if (c >= ' ' && c < 0177)\
! 		putc (c, (FILE));\
! 	      else\
! 		{\
! 		  fprintf ((FILE), "\\%o", c);\
! 		  /* After an octal-escape, if a digit follows,\
! 		     terminate one string constant and start another.\
! 		     The Vax assembler fails to stop reading the escape\
! 		     after three digits, so this is the only way we\
! 		     can get it to parse the data properly.  */\
  		  if (i < (SIZE) - 1 && (P)[i + 1] >= '0' && (P)[i + 1] <= '9')\
! 		    fprintf ((FILE), "\"\n\t.ascii \"");\
! 		}\
! 	    }\
! 	  fprintf ((FILE), "\"\n");\
   }
  
--- 1837,1866 ----
  				/*  C-text of varasm.c. It has been modified */
  				/*  to handle the VARARG_SUSPECTED hack      */
! #define  ASM_OUTPUT_ASCII(FILE, P , SIZE)				\
! {  int i;								\
! 	  fprintf ((FILE), "\t.ascii \"");				\
!           VARARGS_SUSPECT( 0 == strncmp((P),"__%%VARARGS",11));		\
! 	  for (i = 0; i < (SIZE); i++)					\
! 	    {								\
! 	      register int c = (P)[i];					\
! 	      if (i != 0 && (i / 200) * 200 == i)			\
! 		fprintf ((FILE), "\"\n\t.ascii \"");			\
! 	      if (c == '\"' || c == '\\')				\
! 		putc ('\\', (FILE));					\
! 	      if (c >= ' ' && c < 0177)					\
! 		putc (c, (FILE));					\
! 	      else							\
! 		{							\
! 		  fprintf ((FILE), "\\%o", c);				\
! 		  /* After an octal-escape, if a digit follows,		\
! 		     terminate one string constant and start another.	\
! 		     The Vax assembler fails to stop reading the escape	\
! 		     after three digits, so this is the only way we	\
! 		     can get it to parse the data properly.  */		\
  		  if (i < (SIZE) - 1 && (P)[i + 1] >= '0' && (P)[i + 1] <= '9')\
! 		    fprintf ((FILE), "\"\n\t.ascii \"");		\
! 		}							\
! 	    }								\
! 	  fprintf ((FILE), "\"\n");					\
   }
  
***************
*** 1580,1588 ****
  
  \f


! #define DEBUG_LOG_INSN(X)  {\
!             extern rtx al_log_insn_debug;\
              al_log_insn_debug=(X); }
- 
- 
- 
- 
--- 1881,1885 ----
  
  \f


! #define DEBUG_LOG_INSN(X)  {						\
!             extern rtx al_log_insn_debug;				\
              al_log_insn_debug=(X); }
diff -rc2N gcc-1.35/config/tm-news.h gcc-1.36/config/tm-news.h
*** gcc-1.35/config/tm-news.h	Thu Mar 30 00:38:35 1989
--- gcc-1.36/config/tm-news.h	Sat Aug 26 00:00:15 1989
***************
*** 18,25 ****
  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  
- /* Use the GNU Assembler, because the system's assembler
-    has no way to assemble the difference of two labels
-    for the displacement in a switch-dispatch instruction.  */
- 
  #ifndef USE_GAS
  /* This controls conditionals in tm-m68k.h.  */
--- 18,21 ----
***************
*** 40,64 ****
  
  /* Names to predefine in the preprocessor for this target machine.  */
  
  #ifdef news700
! #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68020 -Dnews700"
  #endif
  #ifdef news800
! #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68020 -Dnews800"
  #endif
  #ifdef news900
! #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68020 -Dnews900"
  #endif
  #ifdef news1500
! #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68020 -Dmc68030 -Dnews1500"
  #endif
  #ifdef news1700
! #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68020 -Dmc68030 -Dnews1700"
  #endif
  #ifdef news1800
! #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68020 -Dmc68030 -Dnews1800"
  #endif
  #ifdef news1900
! #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68020 -Dmc68030 -Dnews1900"
  #endif
  
--- 36,62 ----
  
  /* Names to predefine in the preprocessor for this target machine.  */
+ /* These are the ones defined by Sony, plus mc68000 for uniformity with
+    GCC on other 68000 systems.  */
  
  #ifdef news700
! #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dnews700"
  #endif
  #ifdef news800
! #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dnews800"
  #endif
  #ifdef news900
! #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dnews900"
  #endif
  #ifdef news1500
! #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dmc68030 -Dnews1500"
  #endif
  #ifdef news1700
! #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dmc68030 -Dnews1700"
  #endif
  #ifdef news1800
! #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dmc68030 -Dnews1800"
  #endif
  #ifdef news1900
! #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dmc68030 -Dnews1900"
  #endif
  
***************
*** 350,358 ****
  	    fprintf (FILE, "(L%d.b,pc,%s.w",				\
  		     CODE_LABEL_NUMBER (XEXP (addr, 0)),		\
! 		     reg_name[REGNO (XEXP (ireg, 0))]); 		\
  	  else								\
  	    fprintf (FILE, "(L%d.b,pc,%s.l",				\
  		     CODE_LABEL_NUMBER (XEXP (addr, 0)),		\
! 		     reg_name[REGNO (ireg)]);				\
  	  if (scale != 1) fprintf (FILE, "*%d", scale);			\
  	  putc (')', FILE);						\
--- 348,356 ----
  	    fprintf (FILE, "(L%d.b,pc,%s.w",				\
  		     CODE_LABEL_NUMBER (XEXP (addr, 0)),		\
! 		     reg_names[REGNO (XEXP (ireg, 0))]); 		\
  	  else								\
  	    fprintf (FILE, "(L%d.b,pc,%s.l",				\
  		     CODE_LABEL_NUMBER (XEXP (addr, 0)),		\
! 		     reg_names[REGNO (ireg)]);				\
  	  if (scale != 1) fprintf (FILE, "*%d", scale);			\
  	  putc (')', FILE);						\
***************
*** 361,365 ****
          { fprintf (FILE, "(L%d.b,pc,%s.l",				\
  		   CODE_LABEL_NUMBER (XEXP (addr, 0)),			\
! 		   reg_name[REGNO (breg)]);				\
  	  putc (')', FILE);						\
  	  break; }							\
--- 359,363 ----
          { fprintf (FILE, "(L%d.b,pc,%s.l",				\
  		   CODE_LABEL_NUMBER (XEXP (addr, 0)),			\
! 		   reg_names[REGNO (breg)]);				\
  	  putc (')', FILE);						\
  	  break; }							\
***************
*** 389,394 ****
        else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF)		\
  	{ fprintf (FILE, "(L%d.b,pc,%s:l)",				\
- 	{ fprintf (FILE, "(L%d-LI%d.b,pc,%s:l)",			\
- 		   CODE_LABEL_NUMBER (XEXP (addr, 0)),			\
  		   CODE_LABEL_NUMBER (XEXP (addr, 0)),			\
  		   reg_names[REGNO (reg1)]);				\
--- 387,390 ----
diff -rc2N gcc-1.35/config/tm-newsgas.h gcc-1.36/config/tm-newsgas.h
*** gcc-1.35/config/tm-newsgas.h	Thu Mar 30 00:39:08 1989
--- gcc-1.36/config/tm-newsgas.h	Fri Jun  2 15:53:52 1989
***************
*** 1,2 ****
--- 1,6 ----
+ /* In Sony versions before 3.0, use the GNU Assembler, because the
+    system's assembler has no way to assemble the difference of two
+    labels for the displacement in a switch-dispatch instruction.  */  
+ 
  #define USE_GAS
  
diff -rc2N gcc-1.35/config/tm-next.h gcc-1.36/config/tm-next.h
*** gcc-1.35/config/tm-next.h	Tue Apr 18 18:57:43 1989
--- gcc-1.36/config/tm-next.h	Thu Sep 14 04:33:40 1989
***************
*** 1,13 ****
! /* Definitions for Next as target machine for GNU C compiler.  */
  
! #include "tm-sun3.h"
  
! #undef CPP_PREDEFINES
  #define CPP_PREDEFINES "-Dmc68000 -DNeXT -Dunix -D__MACH__"
  
! /* Assumes no need to run special floating-point initialization code.  */
! #undef STARTFILE_SPEC
! #define STARTFILE_SPEC "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}"
  
  #define CPLUSPLUS
  #define DOLLARS_IN_IDENTIFIERS 1
--- 1,93 ----
! /* tm-next.h:  Definitions for Next as target machine for GNU C compiler.  */
  
! #include "tm-m68k.h"
  
! /* See tm-m68k.h.  7 means 68020/030 with 68881/882.  */
! 
! #define TARGET_DEFAULT 7
! 
! /* These compiler options take an argument.  */
! 
! #define WORD_SWITCH_TAKES_ARG(STR)	\
!   (!strcmp (STR, "Ttext") || !strcmp (STR, "Tdata"))
! 
! /* Names to predefine in the preprocessor for this target machine.  */
! 
  #define CPP_PREDEFINES "-Dmc68000 -DNeXT -Dunix -D__MACH__"
  
! /* Machine dependent ccp options.  */
! 
! #define CPP_SPEC "%{bsd:-D__STRICT_BSD__}"
! 
! /* Machine dependent ld options.  */
! 
! #define LINK_SPEC "${Z} %{M} %{Mach} %{segcreate*} %{seglinkedit}"
  
+ /* Machine dependent libraries.  */
+ 
+ #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lsys_p}%{pg:-lsys_p}"
+  
+ /* We specify crt0.o as -lcrt0.o so that ld will search the library path. */
+ #define STARTFILE_SPEC  \
+   "%{pg:-lgcrt0.o}%{!pg:%{p:-lmcrt0.o}%{!p:-lcrt0.o}}"
+ 
+ /* Every structure or union's size must be a multiple of 2 bytes.  */
+ 
+ #define STRUCTURE_SIZE_BOUNDARY 16
+ 
+ /* We want C++ style comments to be supported for Objective-C */
+ 
  #define CPLUSPLUS
+ 
+ /* Why not? */
+ 
  #define DOLLARS_IN_IDENTIFIERS 1
+ 
+ #if 0 /* These pertain to code changes that are not present in 1.36.  */
+ 
+ /* Allow Mach -MD and -MMD make depend switches. */
+ 
+ #define MACH_MAKE_DEPEND
+ 
+ /* These options take an argument.  Note that we don't support -Ttext or -Tdata.  */
+ 
+ #define WORD_SWITCH_TAKES_ARG(STR) (!strcmp (STR, "MD") || !strcmp (STR,  
+ "MMD"))
+ 
+ #endif /* 0 */
+ 
+ /* Allow #sscs (but don't do anything). */
+ 
+ #define SCCS_DIRECTIVE
+ 
+ /* We use Dbx symbol format.  */
+ 
+ #define DBX_DEBUGGING_INFO
+ 
+ /* This is how to output an assembler line defining a `double' constant.  */
+ 
+ #undef ASM_OUTPUT_DOUBLE
+ #define ASM_OUTPUT_DOUBLE(FILE,VALUE)					\
+   (isinf ((VALUE))							\
+    ? fprintf (FILE, "\t.double 0r%s99e999\n", ((VALUE) > 0 ? "" : "-")) \
+    : fprintf (FILE, "\t.double 0r%.20e\n", (VALUE)))
+ 
+ /* This is how to output an assembler line defining a `float' constant.  */
+ 
+ #undef ASM_OUTPUT_FLOAT
+ #define ASM_OUTPUT_FLOAT(FILE,VALUE)					\
+   (isinf ((VALUE))							\
+    ? fprintf (FILE, "\t.single 0r%s99e999\n", ((VALUE) > 0 ? "" : "-")) \
+    : fprintf (FILE, "\t.single 0r%.20e\n", (VALUE)))
+ 
+ #undef ASM_OUTPUT_FLOAT_OPERAND
+ #define ASM_OUTPUT_FLOAT_OPERAND(FILE,VALUE)				\
+   (isinf ((VALUE))							\
+    ? fprintf (FILE, "#0r%s99e999", ((VALUE) > 0 ? "" : "-")) \
+    : fprintf (FILE, "#0r%.9g", (VALUE)))
+ 
+ #undef ASM_OUTPUT_DOUBLE_OPERAND
+ #define ASM_OUTPUT_DOUBLE_OPERAND(FILE,VALUE)				\
+   (isinf ((VALUE))							\
+    ? fprintf (FILE, "#0r%s99e999", ((VALUE) > 0 ? "" : "-")) \
+    : fprintf (FILE, "#0r%.20g", (VALUE)))
diff -rc2N gcc-1.35/config/tm-ns32k.h gcc-1.36/config/tm-ns32k.h
*** gcc-1.35/config/tm-ns32k.h	Wed Mar 29 17:48:37 1989
--- gcc-1.36/config/tm-ns32k.h	Sat Jun  3 19:28:14 1989
***************
*** 766,769 ****
--- 766,770 ----
     && (((xfoo0 = XEXP (X, 0), MEM_REG (xfoo0))				\
         || (GET_CODE (xfoo0) == PLUS					\
+ 	   && GET_CODE (XEXP (xfoo0, 0)) == REG				\
  	   && MEM_REG (XEXP (xfoo0, 0))					\
  	   && CONSTANT_ADDRESS_NO_LABEL_P (XEXP (xfoo0, 1))))		\
***************
*** 1189,1192 ****
--- 1190,1196 ----
  
  /* %$ means print the prefix for an immediate operand.  */
+ 
+ #define PRINT_OPERAND_PUNCT_VALID_P(CODE)				\
+   ((CODE) == '$' || (CODE) == '?')
  
  #define PRINT_OPERAND(FILE, X, CODE)  \
diff -rc2N gcc-1.35/config/tm-pyr.h gcc-1.36/config/tm-pyr.h
*** gcc-1.35/config/tm-pyr.h	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config/tm-pyr.h	Sun Sep 17 04:12:17 1989
***************
*** 0 ****
--- 1,1431 ----
+ /* Definitions of target machine for GNU compiler for Pyramid 90 Series.
+    Copyright (C) 1989 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+ \f


+ /*
+  * If you're going to change this, and you haven't already,
+  * you should get and read
+  * 	``OSx Operating System Porting Guide'',
+  *	  publication number 4100-0066-A
+  *	  Revision A
+  *	  Pyramid Technology Corporation.
+  *
+  * or whatever the most recent version is.  In any case, page and
+  * section number references given herein refer to this document.
+  *
+  *  The instruction table for gdb lists the available insns and
+  *  the valid addressing modes.
+  *
+  *  Any other information on the Pyramid architecture is proprietary
+  *  and hard to get. (Pyramid cc -S and adb are also useful.)
+  *
+  */
+ 
+ /*** Run-time compilation parameters selecting different hardware subsets. ***/
+ 
+ /* Names to predefine in the preprocessor for this target machine.  */
+ 
+ #define CPP_PREDEFINES "-Dpyr -Dunix"
+ 
+ /* Print subsidiary information on the compiler version in use.  */
+ 
+ #define TARGET_VERSION fprintf (stderr, " (pyr)");
+ 
+ extern int target_flags;
+ 
+ /* Nonzero if compiling code that Unix assembler can assemble.  */
+ #define TARGET_UNIX_ASM (target_flags & 1)
+ 
+ /* Use the indexed addressing modes (were once not known to work).
+    Leaving this in means we can disable them and so find out what
+    they win us.  */
+ #define TARGET_INDEX (target_flags & 2)
+ 
+ /* Implement stdard in the same fashion used on all other machines.  */
+ #define TARGET_GNU_STDARG   (target_flags & 4)
+ 
+ /* Compile using RETD to pop off the args.
+    This will not work unless you use prototypes at least
+    for all functions that can take varying numbers of args.
+    This contravenes the Pyramid calling convention, so we don't
+    do it yet.  */
+ 
+ #define TARGET_RTD (0)
+ 
+ /* Macros used in the machine description to test the flags.  */
+ 
+ /* Macro to define tables used to set the flags.
+    This is a list in braces of pairs in braces,
+    each pair being { "NAME", VALUE }
+    where VALUE is the bits to set or minus the bits to clear.
+    An empty string NAME is used to identify the default VALUE.
+ 
+    -mgnu will be useful if we ever have GAS on a pyramid.
+    -mindex was used to enable indexing when I didn't understand
+     how pyramid's indexing modes worked.  */
+ 
+ #define TARGET_SWITCHES  \
+   { {"unix", 1},  		\
+     {"gnu", -1},  		\
+     {"index", 2},		\
+     {"noindex", -2},		\
+     {"gnu-stdarg", 4},		\
+     {"nognu-stdarg", -4},	\
+     { "", TARGET_DEFAULT}}
+ 
+ /* Default target_flags if no switches specified.
+ 
+    (equivalent to "-munix -mindex -mgnu-stdarg")  */
+ 
+ #ifndef TARGET_DEFAULT
+ #define TARGET_DEFAULT (1 + 2 + 4)
+ #endif
+ \f


+ /*** Target machine storage layout ***/
+ 
+ /* Define this if most significant bit is lowest numbered
+    in instructions that operate on numbered bit-fields.
+    This is not true on the pyramid.  */
+ /* #define BITS_BIG_ENDIAN */
+ 
+ /* Define this if most significant byte of a word is the lowest numbered.  */
+ #define BYTES_BIG_ENDIAN
+ 
+ /* Define this if most significant word of a multiword number is numbered.  */
+ #define WORDS_BIG_ENDIAN
+ 
+ /* Number of bits in an addressible 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 32
+ 
+ /* Width of a word, in units (bytes).  */
+ #define UNITS_PER_WORD 4
+ 
+ /* Width in bits of a pointer.
+    See also the macro `Pmode' defined below.  */
+ #define POINTER_SIZE 32
+ 
+ /* Allocation boundary (in *bits*) for storing pointers in memory.  */
+ #define POINTER_BOUNDARY 32
+ 
+ /* Allocation boundary (in *bits*) for storing arguments in argument list.  */
+ #define PARM_BOUNDARY 32
+ 
+ /* Boundary (in *bits*) on which stack pointer should be aligned.  */
+ #define STACK_BOUNDARY 32
+ 
+ /* Allocation boundary (in *bits*) for the code of a function.  */
+ #define FUNCTION_BOUNDARY 32
+ 
+ /* Alignment of field after `int : 0' in a structure.  */
+ #define EMPTY_FIELD_BOUNDARY 32
+ 
+ /* Every structure's size must be a multiple of this.  */
+ /*  --> FIXME: I don't know if this is what pyr cc does.  */
+ #define STRUCTURE_SIZE_BOUNDARY 32
+ 
+ /* No data type wants to be aligned rounder than this.  */
+ #define BIGGEST_ALIGNMENT 32
+ 
+ /* Make strings word-aligned so dhrystone will run faster.
+    Pyramid documentation says the best alignment is to align
+    on the size of a cache line, which is 16 bytes.
+    Newer pyrs have single insns that do strcmp() and strcpy(), so this
+    may not actually win anything.   */
+ #define CONSTANT_ALIGNMENT(CODE, TYPEALIGN) \
+   ((CODE) == STRING_CST ? TYPEALIGN * 4 : TYPEALIGN)
+ 
+ /* Define this if move instructions will actually fail to work
+    when given unaligned data.  */
+ #define STRICT_ALIGNMENT
+ \f


+ /*** Standard register usage.  ***/
+ 
+ /* Number of actual hardware registers.
+    The hardware registers are assigned numbers for the compiler
+    from 0 to just below FIRST_PSEUDO_REGISTER.
+    All registers that the compiler knows about must be given numbers,
+    even those that are not normally considered general registers.  */
+ 
+ /* Nota Bene:
+    Pyramids have 64 addressable 32-bit registers, arranged as four
+    groups: global, parameter, local, and temporary.
+      The sixteen global registers are fairly conventional; the last
+    four are overloaded with a PSW, frame pointer, and stack pointer.
+    The non-dedicated global registers used to be reserved for Pyramid
+    operating systems, and still have cryptic and undocumented uses for
+    certain library calls.  We avoid them.
+ 
+    (FIXME: say something about control stack, calls, frames, _window_
+     onto call stack)
+ 
+    The parameter, local, and temporary registers provide _register_
+    _windowing_. Each procedure call has its own set of these 48
+    registers, which constitute its call frame. (These frames are
+    allocated on a stack separate from the conventional data stack,
+    called the _control_ _stack_.
+    facility hereby the temporary registers of frame n
+    become the parameter registers of frame n+1, viz.:
+ 
+                                  0         15 0         15 0         15
+                                 +------------+------------+------------+
+                                 |            |            |            |
+                                 +------------+------------+------------+
+                                    Parameter     Local       Temporary
+ 
+                                       ^
+                                       |
+                                       v
+ 
+         0         15 0         15 0         15
+       +------------+------------+------------+
+       |            |            |            |
+       +------------+------------+------------+
+          Parameter     Local       Temporary
+ 
+ 
+    Temporary registers are used for parameter passing, and are not
+    preserved across calls.  TR14 and TR15 are reserved and should
+    never be used; since they are used to save the next frame's PC
+    and stack pointer, their contents may be destroyed at any time by
+    an interrupt.
+  */
+ 
+ #define PYR_GREG(n) (n)
+ #define PYR_PREG(n) (16+(n))
+ #define PYR_LREG(n) (32+(n))
+ #define PYR_TREG(n) (48+(n))
+ 
+ #define FIRST_PSEUDO_REGISTER 64
+ 
+ /* 1 for registers that have pervasive standard uses
+    and are not available for the register allocator.
+ 
+    --> On the pyramid, these are LOGPSW, CFP, SP, PC.
+ 
+    --> ***** Damn!!!!  Because we use Pyramid's varargs, we *have* to
+    --> leave the parameter registers strictly alone.
+    --> A better way is to know about va_..., like the MipsCo compiler. */
+ #define FIXED_REGISTERS \
+   {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	\
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,	\
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	\
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1}
+ 
+ /* 1 for registers not available across function calls.
+    These must include the FIXED_REGISTERS and also any
+    registers that can be used without being saved.
+    The latter must include the registers where values are returned
+    and the register where structure-value addresses are passed.
+    Aside from that, you can include as many other registers as you like.  */
+ #define CALL_USED_REGISTERS \
+   {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	\
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,	\
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 	\
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
+ 
+ /* #define DEFAULT_CALLER_SAVES */
+ 
+ /* Return number of consecutive hard regs needed starting at reg REGNO
+    to hold something of mode MODE.
+    This is ordinarily the length in words of a value of mode MODE
+    but can be less for certain modes in special long registers.
+    On the pyramid, all registers are one word long.  */
+ #define HARD_REGNO_NREGS(REGNO, MODE)   \
+  ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+ 
+ /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
+    On the pyramid, all registers can hold all modes.  */
+ 
+ /* -->FIXME: this is not the case for 64-bit quantities in tr11/12 through
+    --> TR14/15.  This should be fixed,  but to do it correctly, we also
+    --> need to fix MODES_TIEABLE_P. Yuk.  We ignore this, since GCC should
+    --> do the "right" thing due to FIXED_REGISTERS. */
+ #define HARD_REGNO_MODE_OK(REGNO, MODE) 1
+ 
+ /* Value is 1 if it is a good idea to tie two pseudo registers
+    when one has mode MODE1 and one has mode MODE2.
+    If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
+    for any hard reg, then this must be 0 for correct output.  */
+ #define MODES_TIEABLE_P(MODE1, MODE2) 1
+ 
+ /* Specify the registers used for certain standard purposes.
+    The values of these macros are register numbers.  */
+ 
+ /* Pyramid pc is overloaded on global register 15.  */
+ #define PC_REGNUM PYR_GREG(15)
+ 
+ /* Register to use for pushing function arguments.
+    --> on Pyramids, the data stack pointer. */
+ #define STACK_POINTER_REGNUM PYR_GREG(14)
+ 
+ /* Base register for access to local variables of the function.
+    Pyramid uses CFP (GR13) as both frame pointer and argument pointer. */
+ #define FRAME_POINTER_REGNUM 13 /* PYR_GREG(13) */
+ 
+ /* Value should be nonzero if functions must have frame pointers.
+    Zero means the frame pointer need not be set up (and parms
+    may be accessed via the stack pointer) in functions that seem suitable.
+    This is computed in `reload', in reload1.c.
+ 
+    Setting this to 1 can't break anything.  Since the Pyramid has
+    register windows, I don't know if defining this to be zero can
+    win anything.  It could changed later, if it wins. */
+ #define FRAME_POINTER_REQUIRED 1
+ 
+ /* Base register for access to arguments of the function.  */
+ #define ARG_POINTER_REGNUM 13 /* PYR_GREG(13) */
+ 
+ /* Register in which static-chain is passed to a function.  */
+ /* If needed, Pyramid says to use temporary register 12. */
+ #define STATIC_CHAIN_REGNUM PYR_TREG(12)
+ 
+ /* Register in which address to store a structure value
+    is passed to a function.
+    On a Pyramid, this is temporary register 0 (TR0).   */
+ 
+ #define STRUCT_VALUE_REGNUM PYR_TREG(0)
+ #define STRUCT_VALUE_INCOMING_REGNUM PYR_PREG(0)
+ \f


+ /* Define the classes of registers for register constraints in the
+    machine description.  Also define ranges of constants.
+ 
+    One of the classes must always be named ALL_REGS and include all hard regs.
+    If there is more than one class, another class must be named NO_REGS
+    and contain no registers.
+ 
+    The name GENERAL_REGS must be the name of a class (or an alias for
+    another name such as ALL_REGS).  This is the class of registers
+    that is allowed by "g" or "r" in a register constraint.
+    Also, registers outside this class are allocated only when
+    instructions express preferences for them.
+ 
+    The classes must be numbered in nondecreasing order; that is,
+    a larger-numbered class must never be contained completely
+    in a smaller-numbered class.
+ 
+    For any two classes, it is very desirable that there be another
+    class that represents their union.  */
+ 
+ /* The pyramid has only one kind of registers, so NO_REGS and ALL_REGS
+    are the only classes.  */
+ 
+ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
+ 
+ #define N_REG_CLASSES (int) LIM_REG_CLASSES
+ 
+ /* Since GENERAL_REGS is the same class as ALL_REGS,
+    don't give it a different class number; just make it an alias.  */
+ 
+ #define GENERAL_REGS ALL_REGS
+ 
+ /* Give names of register classes as strings for dump file.   */
+ 
+ #define REG_CLASS_NAMES \
+  {"NO_REGS", "ALL_REGS" }
+ 
+ /* Define which registers fit in which classes.
+    This is an initializer for a vector of HARD_REG_SET
+    of length N_REG_CLASSES.  */
+ 
+ #define REG_CLASS_CONTENTS {{0,0}, {0xffffffff,0xffffffff}}
+ 
+ /* The same information, inverted:
+    Return the class number of the smallest class containing
+    reg number REGNO.  This could be a conditional expression
+    or could index an array.  */
+ 
+ #define REGNO_REG_CLASS(REGNO) ALL_REGS
+ 
+ /* The class value for index registers, and the one for base regs.  */
+ 
+ #define BASE_REG_CLASS ALL_REGS
+ #define INDEX_REG_CLASS ALL_REGS
+ 
+ /* Get reg_class from a letter such as appears in the machine description.  */
+ 
+ #define REG_CLASS_FROM_LETTER(C) NO_REGS
+ 
+ /* Given an rtx X being reloaded into a reg required to be
+    in class CLASS, return the class of reg to actually use.
+    In general this is just CLASS; but on some machines
+    in some cases it is preferable to use a more restrictive class.  */
+ 
+ #define PREFERRED_RELOAD_CLASS(X,CLASS)  (CLASS)
+ 
+ /* Return the maximum number of consecutive registers
+    needed to represent mode MODE in a register of class CLASS.  */
+ /* On the pyramid, this is always the size of MODE in words,
+    since all registers are the same size.  */
+ #define CLASS_MAX_NREGS(CLASS, MODE)	\
+  ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+ 
+ /* The letters I, J, K, L and M in a register constraint string
+    can be used to stand for particular ranges of immediate operands.
+    This macro defines what the ranges are.
+    C is the letter, and VALUE is a constant value.
+    Return 1 if VALUE is in the range specified by C.
+ 
+    --> For the Pyramid, 'I' can be used for the 6-bit signed integers
+    --> (-32 to 31) allowed as immediate short operands in many
+    --> instructions. 'J' cane be used for any value that doesn't fit
+    --> in 6 bits.  */
+ 
+ #define CONST_OK_FOR_LETTER_P(VALUE, C)  \
+   ((C) == 'I' ? (VALUE) >= -32 && (VALUE) < 32 : \
+    (C) == 'J' ? (VALUE) < -32 || (VALUE) >= 32 : \
+    (C) == 'K' ? (VALUE) == 0xff || (VALUE) == 0xffff : 0)
+ 
+ /* Similar, but for floating constants, and defining letters G and H.
+    Here VALUE is the CONST_DOUBLE rtx itself.
+    --> FIXME: I don't know what the Pyramid accepts as floating-point
+    --> immediate constants.  Help! */
+ 
+ #define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) 1
+ 
+ \f


+ /*** Stack layout; function entry, exit and calling.  ***/
+ 
+ /* Define this if pushing a word on the stack
+    makes the stack pointer a smaller address.  */
+ #define STACK_GROWS_DOWNWARD
+ 
+ /* Define this if the nominal address of the stack frame
+    is at the high-address end of the local variables;
+    that is, each additional local variable allocated
+    goes at a more negative offset in the frame.  */
+ #define FRAME_GROWS_DOWNWARD
+ 
+ /* Offset within stack frame to start allocating local variables at.
+    If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
+    first local allocated.  Otherwise, it is the offset to the BEGINNING
+    of the first local allocated.  */
+ /* FIXME: this used to work when defined as 0.  But that makes gnu
+    stdargs clobber the first arg.  What gives?? */
+ #define STARTING_FRAME_OFFSET 0
+ 
+ /* Offset of first parameter from the argument pointer register value.  */
+ #define FIRST_PARM_OFFSET(FNDECL) 0
+ 
+ /* Value is 1 if returning from a function call automatically
+    pops the arguments described by the number-of-args field in the call.
+    FUNTYPE is the data type of the function (as a tree),
+    or for a library call it is an identifier node for the subroutine name.
+ 
+    The Pyramid OSx Porting Guide says we are never to do this;
+    using RETD in this way violates the Pyramid calling convention.
+    We may nevertheless provide this as an option.   */
+ 
+ #define RETURN_POPS_ARGS(FUNTYPE)   \
+   (TARGET_RTD && TREE_CODE (FUNTYPE) != IDENTIFIER_NODE		\
+    && (TYPE_ARG_TYPES (FUNTYPE) == 0				\
+        || TREE_VALUE (tree_last (TYPE_ARG_TYPES (FUNTYPE))) == void_type_node))
+ 
+ /* Define how to find the value returned by a function.
+    VALTYPE is the data type of the value (as a tree).
+    If the precise function being called is known, FUNC is its FUNCTION_DECL;
+    otherwise, FUNC is 0.  */
+ 
+ /* --> Pyramid has register windows.
+    --> The caller sees the return value is in TR0(/TR1) regardless of
+    --> its type.   */
+ 
+ #define FUNCTION_VALUE(VALTYPE, FUNC)  \
+   gen_rtx (REG, TYPE_MODE (VALTYPE), PYR_TREG(0))
+ 
+ /* --> but the callee has to leave it in PR0(/PR1) */
+ 
+ #define FUNCTION_OUTGOING_VALUE(VALTYPE, FUNC)	\
+   gen_rtx (REG, TYPE_MODE (VALTYPE), PYR_PREG(0))
+ 
+ /* Define how to find the value returned by a library function
+    assuming the value has mode MODE.  */
+ 
+ /* --> On Pyramid the return value is in TR0/TR1 regardless.  */
+ 
+ #define LIBCALL_VALUE(MODE)  gen_rtx (REG, MODE, PYR_TREG(0))
+ 
+ /* Define this if PCC uses the nonreentrant convention for returning
+    structure and union values.  */
+ 
+ #define PCC_STATIC_STRUCT_RETURN
+ 
+ /* 1 if N is a possible register number for a function value
+    as seen by the caller.
+ 
+   On the Pyramid, TR0 is the only register thus used.   */
+ 
+ #define FUNCTION_VALUE_REGNO_P(N) ((N) == PYR_TREG(0))
+ 
+ /* 1 if N is a possible register number for function argument passing.
+    On the Pyramid, the first twelve temporary registers are available.  */
+ 
+ /* FIXME FIXME FIXME
+    it's not clear whether this macro should be defined from the point
+    of view of the caller or the callee.  Since it's never actually used
+    in GNU CC, the point is somewhat moot :-).
+ 
+    This definition is consistent with register usage in the md's for
+    other register-window architectures (sparc and spur).
+  */
+ #define FUNCTION_ARG_REGNO_P(N) ((PYR_TREG(0) <= (N)) && ((N) <= PYR_TREG(11)))
+ \f


+ /*** Parameter passing: FUNCTION_ARG and FUNCTION_INCOMING_ARG ***/
+ 
+ /* Define a data type for recording info about an argument list
+    during the scan of that argument list.  This data type should
+    hold all necessary information about the function itself
+    and about the args processed so far, enough to enable macros
+    such as FUNCTION_ARG to determine where the next arg should go.
+ 
+    On Pyramids, each parameter is passed either completely on the stack
+    or completely in registers.  No parameter larger than a double may
+    be passed in a register.  Also, no struct or union may be passed in
+    a register, even if it would fit.
+ 
+     So parameters are not necessarily passed "consecutively".
+     Thus we need a vector data type: one element to record how many
+     parameters have been passed in registers and on the stack,
+     respectively.
+ 
+     ((These constraints seem like a gross waste of registers. But if we
+     ignore the constraint about structs & unions, we won`t be able to
+     freely mix gcc-compiled code and pyr cc-compiled code.  It looks
+     like better argument passing conventions, and a machine-dependent
+     flag to enable them, might be a win.))   */
+ 
+ 
+ #define CUMULATIVE_ARGS int
+ 
+ /* Define the number of registers that can hold paramters.
+    This macro is used only in other macro definitions below.   */
+ #define NPARM_REGS 12
+ 
+ /* Decide whether or not a parameter can be put in a register.
+    (We may still have problems with libcalls. GCC doesn't seem
+    to know about anything more than the machine mode.  I trust
+    structures are never passed to a libcall...
+ 
+    If compiling with -mgnu-stdarg, this definition should make
+    functions using the gcc-supplied stdarg, and calls to such
+    functions (declared with an arglist ending in"..."),  work.
+    But such fns won't be able to call pyr cc-compiled
+    varargs fns (eg, printf(), _doprnt.)
+ 
+    If compiling with -mnognu-stdarg, this definition should make
+    calls to pyr cc-compiled functions work.  Functions using
+    the gcc-supplied stdarg will be utterly broken.
+    There will be no better solution until RMS can be persuaded that
+    one is needed.
+ 
+    This macro is used only in other macro definitions below.
+    (well, it may be used in out-pyr.c, because the damn pyramid cc
+    can't handle the macro definition of PARAM_SAFE_FOR_REG_P !   */
+ 
+ 
+ #define INNER_PARAM_SAFE_HELPER(TYPE) \
+  ((TARGET_GNU_STDARG ? (! TREE_ADDRESSABLE ((tree)TYPE)): 1)	\
+    && (TREE_CODE ((tree)TYPE) != RECORD_TYPE)			\
+    && (TREE_CODE ((tree)TYPE) != UNION_TYPE))
+ 
+ #ifdef __GNUC__
+ #define PARAM_SAFE_HELPER(TYPE) \
+   INNER_PARAM_SAFE_HELPER((TYPE))
+ #else
+ extern int inner_param_safe_helper();
+ #define PARAM_SAFE_HELPER(TYPE) \
+   inner_param_safe_helper((tree)(TYPE))
+ #endif
+ 
+ /* Be careful with the expression (long) (TYPE) == 0.
+    Writing it in more obvious/correct forms makes the Pyr cc
+    dump core!   */
+ #define PARAM_SAFE_FOR_REG_P(MODE, TYPE, NAMED) \
+   (((MODE) != BLKmode)				\
+    && ((TARGET_GNU_STDARG) ? (NAMED) : 1)	\
+    && ((((long)(TYPE))==0) || PARAM_SAFE_HELPER((TYPE))))
+ 
+ /* 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.   */
+ 
+ #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE) \
+ do { 						\
+     tree type = (tree) 0;			\
+     (CUM) = 0;					\
+     if (FNTYPE) {				\
+ 	type = TREE_TYPE(FNTYPE);		\
+ 	(CUM) = (TYPE_MODE (type) == BLKmode); 	\
+      }						\
+ } while (0)
+ 
+ 
+ /* Detemine where to put an argument to a function.
+    Value is zero to push the argument on the stack,
+    or a hard register in which to store the argument.
+ 
+    MODE is the argument's machine mode.
+    TYPE is the data type of the argument (as a tree).
+     This is null for libcalls where that information may
+     not be available.
+    CUM is a variable of type CUMULATIVE_ARGS which gives info about
+     the preceding args and about the function being called.
+    NAMED is nonzero if this argument is a named parameter
+     (otherwise it is an extra parameter matching an ellipsis). */
+ 
+ #define FUNCTION_ARG_HELPER(CUM, MODE, TYPE, NAMED) \
+ (PARAM_SAFE_FOR_REG_P(MODE,TYPE,NAMED)				\
+  ? (NPARM_REGS >= ((CUM)					\
+ 		   + ((MODE) == BLKmode				\
+ 		      ? (int_size_in_bytes (TYPE) + 3) / 4	\
+ 		      : (GET_MODE_SIZE (MODE) + 3) / 4))	\
+     ? gen_rtx (REG, (MODE), PYR_TREG(CUM))			\
+     : 0)							\
+  : 0)
+ #ifdef __GNUC__
+ #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
+ 	FUNCTION_ARG_HELPER(CUM, MODE, TYPE, NAMED)
+ #else
+ /*****************  Avoid bug in Pyramid OSx compiler... ******************/
+ #define FUNCTION_ARG  (rtx) pyr_function_arg
+ extern void* pyr_function_arg ();
+ #endif
+ 
+ /* Define where a function finds its arguments.
+    This is different from FUNCTION_ARG because of register windows.  */
+ 
+ #define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
+ (PARAM_SAFE_FOR_REG_P(MODE,TYPE,NAMED)			\
+  ? (NPARM_REGS >= ((CUM)				\
+ 	   + ((MODE) == BLKmode				\
+ 	      ? (int_size_in_bytes (TYPE) + 3) / 4	\
+ 	      : (GET_MODE_SIZE (MODE) + 3) / 4))	\
+     ? gen_rtx (REG, (MODE), PYR_PREG(CUM))		\
+     : 0)						\
+  : 0)
+ 
+ /* Update the data in CUM to advance over an argument
+    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)	+=  (PARAM_SAFE_FOR_REG_P(MODE,TYPE,NAMED)	\
+ 	     ? ((MODE) != BLKmode			\
+ 		? (GET_MODE_SIZE (MODE) + 3) / 4	\
+ 		: (int_size_in_bytes (TYPE) + 3) / 4)	\
+ 	     : 0))
+ 
+ /* This macro generates the assembly code for function entry.
+    FILE is a stdio stream to output the code to.
+    SIZE is an int: how many units of temporary storage to allocate.
+    Refer to the array `regs_ever_live' to determine which registers
+    to save; `regs_ever_live[I]' is nonzero if register number I
+    is ever used in the function.  This macro is responsible for
+    knowing which registers should not be saved even if used.  */
+ 
+ #if FRAME_POINTER_REQUIRED
+ 
+ /* We always have frame pointers */
+ #define FUNCTION_PROLOGUE(FILE, SIZE) \
+ {									\
+  fprintf ((FILE), "\tadsf $%d\n", 					\
+ 	  ((SIZE) + current_function_pretend_args_size + 31) & ~31);	\
+  if (current_function_pretend_args_size > 0)				\
+    fprintf ((FILE), "\tsubw $%d, cfp\n",				\
+ 	  current_function_pretend_args_size);				\
+ }
+ 
+ #else /* !FRAME_POINTER_REQUIRED */
+ 
+ #define FUNCTION_PROLOGUE(FILE, SIZE) \
+ { int _size = (SIZE) + current_function_pretend_args_size;		\
+ 	  if (_size > 0) {						\
+ 	      if (! frame_pointer_needed) abort();			\
+ 	      _size = (_size + 31) & ~31;				\
+ 	      fprintf (FILE, "\tadsf $%d\n", _size);			\
+ 	      if (current_function_pretend_args_size > 0)		\
+ 		fprintf ((FILE), "\tsubw $%d, cfp\n",			\
+ 		      current_function_pretend_args_size);		\
+ 	  }								\
+ }
+ #endif /* !FRAME_POINTER_REQUIRED */
+ 
+ /* Output assembler code to FILE to increment profiler label # LABELNO
+    for profiling a function entry.  */
+ #define FUNCTION_PROFILER(FILE, LABELNO)  \
+    fprintf (FILE, "\tmova LP%d,tr0\n\tcall mcount\n", (LABELNO));
+ 
+ /* Output assembler code to FILE to initialize this source file's
+    basic block profiling info, if that has not already been done.
+    Don't know if this works on Pyrs. */
+ 
+ #if 0 /* don't do basic_block profiling yet */
+ #define FUNCTION_BLOCK_PROFILER(FILE, LABELNO)  \
+   fprintf (FILE, \
+            "\tmtstw LPBX0,tr0\n\tbne LPI%d\n\tmova LP%d,TR0\n\tcall __bb_init_func\nLPI%d:\n", \
+            LABELNO, LABELNO);
+ 
+ /* Output assembler code to increment the count associated with
+    the basic block number BLOCKNO.  Not sure how to do this on pyrs. */
+ #define BLOCK_PROFILER(FILE, BLOCKNO)  \
+     fprintf (FILE, "\taddw", 4 * BLOCKNO)
+ #endif /* don't do basic_block profiling yet */
+ 
+ /* When returning from a function, the stack pointer does not matter
+    (as long as there is a frame pointer).
+    We currently always have a frame pointer... */
+ #define EXIT_IGNORE_STACK 1
+ 
+ /* This macro generates the assembly code for function exit,
+    on machines that need it.  If FUNCTION_EPILOGUE is not defined
+    then individual return instructions are generated for each
+    return statement.  Args are same as for FUNCTION_PROLOGUE.  */
+ 
+ #if FRAME_POINTER_REQUIRED
+ #define FUNCTION_EPILOGUE(FILE, SIZE)  \
+     fprintf(FILE, "\tretd $0x0\n");
+ #else
+ 	/* This may cause bugs accessing arguments?? */
+ #define FUNCTION_EPILOGUE(FILE, SIZE)  \
+   if ((SIZE)!=0)					\
+     fprintf(FILE, "\tretd $0x0\n");			\
+   else fprintf(FILE, "\tret\n" );
+ #endif
+ 
+ /* If the memory address ADDR is relative to the frame pointer,
+    correct it to be relative to the stack pointer instead.
+    This is for when we don't use a frame pointer.
+    ADDR should be a variable name.  */
+ 
+ /* ---> Since we always have a frame pointer, it is safe for this
+    to not work.   */
+ 
+ #define FIX_FRAME_POINTER_ADDRESS(ADDR,DEPTH) \
+ 	fatal ("compiler error, Pyramid call without frame ptr!\n")
+ \f


+ /*** Addressing modes, and classification of registers for them.  ***/
+ 
+ /* #define HAVE_POST_INCREMENT */	/* pyramid has none of these */
+ /* #define HAVE_POST_DECREMENT */
+ 
+ /* #define HAVE_PRE_DECREMENT */
+ /* #define HAVE_PRE_INCREMENT */
+ 
+ /* Macros to check register numbers against specific register classes.  */
+ 
+ /* These assume that REGNO is a hard or pseudo reg number.
+    They give nonzero only if REGNO is a hard reg of the suitable class
+    or a pseudo reg currently allocated to a suitable hard reg.
+    Since they use reg_renumber, they are safe only once reg_renumber
+    has been allocated, which happens in local-alloc.c.  */
+ 
+ /* All registers except gr0 OK as index or base registers.  */
+ 
+ #define REGNO_OK_FOR_BASE_P(regno) \
+ ((0 < (regno) && (regno) < FIRST_PSEUDO_REGISTER) || reg_renumber[regno] > 0)
+ 
+ #define REGNO_OK_FOR_INDEX_P(regno)  \
+ ((0 < (regno) && (regno) < FIRST_PSEUDO_REGISTER) || reg_renumber[regno] > 0)
+ 
+ /* Maximum number of registers that can appear in a valid memory address.  */
+ 
+ #define MAX_REGS_PER_ADDRESS 2     /* check MAX_REGS_PER_ADDRESS */
+ 
+ /* 1 if X is an rtx for a constant that is a valid address.  */
+ 
+ #define CONSTANT_ADDRESS_P(X) CONSTANT_P (X)
+ 
+ /* Nonzero if the constant value X is a legitimate general operand.
+    It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.  */
+ 
+ #define LEGITIMATE_CONSTANT_P(X) 1
+ 
+ /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
+    and check its validity for a certain class.
+    We have two alternate definitions for each of them.
+    The usual definition accepts all pseudo regs; the other rejects
+    them unless they have been allocated suitable hard regs.
+    The symbol REG_OK_STRICT causes the latter definition to be used.
+ 
+    Most source files want to accept pseudo regs in the hope that
+    they will get allocated to the class that the insn wants them to be in.
+    Source files for reload pass need to be strict.
+    After reload, it makes no difference, since pseudo regs have
+    been eliminated by then.  */
+ 
+ #ifndef REG_OK_STRICT
+ 
+ /* Nonzero if X is a hard reg that can be used as an index
+    or if it is a pseudo reg.  */
+ #define REG_OK_FOR_INDEX_P(X) 1
+ /* Nonzero if X is a hard reg that can be used as a base reg
+    or if it is a pseudo reg.  */
+ #define REG_OK_FOR_BASE_P(X) 1
+ 
+ #else
+ 
+ /* Nonzero if X is a hard reg that can be used as an index.  */
+ #define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
+ /* Nonzero if X is a hard reg that can be used as a base reg.  */
+ #define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
+ 
+ #endif
+ \f


+ /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
+    that is a valid memory address for an instruction.
+    The MODE argument is the machine mode for the MEM expression
+    that wants to use this address.
+ 
+    The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS,
+    except for CONSTANT_ADDRESS_P which is actually machine-independent.  */
+ 
+ 
+ /* Go to ADDR if X is indexable -- ie, neither indexed nor offset.
+    Note that X is indexable iff x is offset.  */
+ #define GO_IF_INDEXABLE_ADDRESS(X, ADDR)  \
+ { register rtx xfoob = (X);						\
+   if ((CONSTANT_ADDRESS_P (xfoob))					\
+       || (GET_CODE (xfoob) == REG && (REG_OK_FOR_BASE_P (xfoob))))	\
+ 	  goto ADDR;							\
+  }
+ 
+ 
+ /* Go to label ADDR if X is a valid address that doesn't use indexing.
+    This is so if X is either a simple address, or the contents of a register
+    plus an offset.
+    This macro also gets used in output-pyramid.h in the function that
+    recognizes non-indexed operands.  */
+ 
+ #define GO_IF_NONINDEXED_ADDRESS(X, ADDR)  \
+ {									\
+   if (GET_CODE (X) == REG)						\
+       goto ADDR;							\
+   GO_IF_INDEXABLE_ADDRESS (X, ADDR);					\
+   if (GET_CODE (X) == PLUS)						\
+     { /* Handle offset(reg) represented with offset on left */		\
+       if (CONSTANT_ADDRESS_P (XEXP (X, 0)))				\
+ 	{ if (GET_CODE (XEXP (X, 1)) == REG				\
+ 	      && REG_OK_FOR_BASE_P (XEXP (X, 1)))			\
+ 	    goto ADDR;							\
+ 	 }								\
+       /* Handle offset(reg) represented with offset on right */		\
+       if (CONSTANT_ADDRESS_P (XEXP (X, 1)))				\
+ 	{ if (GET_CODE (XEXP (X, 0)) == REG				\
+ 	      && REG_OK_FOR_BASE_P (XEXP (X, 0)))			\
+ 	    goto ADDR;							\
+ 	 }								\
+      }									\
+ }
+ 
+ /* 1 if PROD is either a reg or a reg times a valid offset multiplier
+    (ie, 2, 4, or 8).
+    This macro's expansion uses the temporary variables xfoo0 and xfoo1
+    that must be declared in the surrounding context.  */
+ #define INDEX_TERM_P(PROD, MODE)   \
+ ((GET_CODE (PROD) == REG && REG_OK_FOR_BASE_P (PROD))			\
+   || (GET_CODE (PROD) == MULT						\
+       &&								\
+       (xfoo0 = XEXP (PROD, 0), xfoo1 = XEXP (PROD, 1),			\
+        ((GET_CODE (xfoo0) == CONST_INT					\
+          && (INTVAL (xfoo0) == 1					\
+ 	     || INTVAL (xfoo0) == 2					\
+ 	     || INTVAL (xfoo0) == 4					\
+ 	     || INTVAL (xfoo0) == 8)					\
+          && GET_CODE (xfoo1) == REG					\
+          && REG_OK_FOR_INDEX_P (xfoo1))					\
+         ||								\
+         (GET_CODE (xfoo1) == CONST_INT					\
+ 	 && (INTVAL (xfoo1) == 1					\
+ 	     || INTVAL (xfoo1) == 2					\
+ 	     || INTVAL (xfoo1) == 4					\
+ 	     || INTVAL (xfoo1) == 8)					\
+         && GET_CODE (xfoo0) == REG					\
+         && REG_OK_FOR_INDEX_P (xfoo0))))))
+ 
+ 
+ #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)  \
+ { register rtx xone, xtwo, xfoo0, xfoo1;				\
+   GO_IF_NONINDEXED_ADDRESS (X, ADDR);					\
+   if (TARGET_INDEX && GET_CODE (X) == PLUS)				\
+     {									\
+       /* Handle <address>[index] represented with index-sum outermost */\
+       xone = XEXP (X, 0);						\
+       xtwo = XEXP (X, 1);						\
+       if (INDEX_TERM_P (xone, MODE))					\
+ 	{ GO_IF_INDEXABLE_ADDRESS (xtwo, ADDR); }			\
+       /* Handle <address>[index] represented with index-sum innermost */\
+       if (INDEX_TERM_P (xtwo, MODE))					\
+ 	{ GO_IF_INDEXABLE_ADDRESS (xone, ADDR); }			\
+     }									\
+ }
+ 
+ /* Try machine-dependent ways of modifying an illegitimate address
+    to be legitimate.  If we find one, return the new, valid address.
+    This macro is used in only one place: `memory_address' in explow.c.
+ 
+    OLDX is the address as it was before break_out_memory_refs was called.
+    In some cases it is useful to look at this to decide what needs to be done.
+ 
+    MODE and WIN are passed so that this macro can use
+    GO_IF_LEGITIMATE_ADDRESS.
+ 
+    It is always safe for this macro to do nothing.  It exists to recognize
+    opportunities to optimize the output.
+ 
+    --> FIXME: We haven't yet figured out what optimizations are useful
+    --> on Pyramids.   */
+ 
+ #define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)  {}
+ 
+ /* Go to LABEL if ADDR (a legitimate address expression)
+    has an effect that depends on the machine mode it is used for.
+    There don't seem to be any such modes on pyramids. */
+ #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL)
+ \f


+ /*** Miscellaneous Parameters ***/
+ 
+ /* Specify the machine mode that this machine uses
+    for the index in the tablejump instruction.  */
+ #define CASE_VECTOR_MODE SImode
+ 
+ /* Define this if the tablejump instruction expects the table
+    to contain offsets from the address of the table.
+    Do not define this if the table should contain absolute addresses.  */
+ /*#define CASE_VECTOR_PC_RELATIVE*/
+ 
+ /* Specify the tree operation to be used to convert reals to integers.  */
+ #define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
+ 
+ /* This is the kind of divide that is easiest to do in the general case.
+    It's just a guess. I have no idea of insn cost on pyrs. */
+ #define EASY_DIV_EXPR TRUNC_DIV_EXPR
+ 
+ /* Define this as 1 if `char' should by default be signed; else as 0.  */
+ #define DEFAULT_SIGNED_CHAR 1
+ 
+ /* This flag, if defined, says the same insns that convert to a signed fixnum
+    also convert validly to an unsigned one.
+    I don't know whether this is so for pyrs, but it seems to work.
+    I don't remember if I had any evidence for defining this or not.  */
+ #define FIXUNS_TRUNC_LIKE_FIX_TRUNC
+ 
+ /* Define this macro if the preprocessor should silently ignore
+   '#sccs' directives. */
+ /* #define SCCS_DIRECTIVE */
+ 
+ /* Define this macro if the preprocessor should silently ignore
+   '#ident' directives. */
+ /* #define IDENT_DIRECTIVE */
+ 
+ /* Max number of bytes we can move from memory to memory
+    in one reasonably fast instruction.  */
+ #define MOVE_MAX 8
+ 
+ /* Define this if zero-extension is slow (more than one real instruction).  */
+ /* #define SLOW_ZERO_EXTEND */
+ 
+ /* number of bits in an 'int' on target machine */
+ #define INT_TYPE_SIZE 32
+ 
+ /* 1 if byte access requires more than one instruction */
+ #define SLOW_BYTE_ACCESS 0
+ 
+ /* Define if shifts truncate the shift count
+    which implies one can omit a sign-extension or zero-extension
+    of a shift count.  */
+ #define SHIFT_COUNT_TRUNCATED
+ 
+ /* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
+    is done just by pretending it is already truncated.  */
+ #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
+ 
+ /* Define this macro if it is as good or better to call a constant
+    function address than to call an address kept in a register.
+ /* #define NO_FUNCTION_CSE */
+ 
+ /* When a prototype says `char' or `short', really pass an `int'.  */
+ #define PROMOTE_PROTOTYPES
+ 
+ /* I don't know har to store the flags on a pyr. */
+ /* #define STORE_FLAG_VALUE */
+ 
+ /* Specify the machine mode that pointers have.
+    After generation of rtl, the compiler makes no further distinction
+    between pointers and any other objects of this machine mode.  */
+ #define Pmode SImode
+ 
+ /* A function address in a call instruction
+    is a byte address (for indexing purposes)
+    so give the MEM rtx a byte's mode.  */
+ #define FUNCTION_MODE QImode
+ 
+ /* Compute the cost of computing a constant rtl expression RTX
+    whose rtx-code is CODE.  The body of this macro is a portion
+    of a switch statement.  If the code is computed here,
+    return it with a return statement.  Otherwise, break from the switch.  */
+ 
+ #define CONST_COSTS(RTX,CODE) \
+   case CONST_INT:						\
+     if (CONST_OK_FOR_LETTER_P (INTVAL (RTX),'I')) return 0;	\
+   case CONST:							\
+   case LABEL_REF:						\
+   case SYMBOL_REF:						\
+     return 2;							\
+   case CONST_DOUBLE:						\
+     return 4;
+ \f


+ /*** Condition Code Information ***/
+ 
+ /* Tell final.c how to eliminate redundant test instructions.  */
+ 
+ /* Here we define machine-dependent flags and fields in cc_status
+    (see `conditions.h').  No extra ones are needed for the pyr.  */
+ 
+ /* Store in cc_status the expressions
+    that the condition codes will describe
+    after execution of an instruction whose pattern is EXP.
+    Do not alter them if the instruction would not alter the cc's.  */
+ 
+ /* This is a very simple definition of NOTICE_UPDATE_CC.
+    Many cases can be optimized, to improve condition code usage.
+    Maybe we should handle this entirely in the md, since it complicated
+    to describe the way pyr sets cc.  */
+ 
+ #define NOTICE_UPDATE_CC(EXP, INSN) \
+ { CC_STATUS_INIT; }
+ #if 0
+ { \
+   if (GET_CODE (EXP) == SET) \
+     { \
+       if (SET_DEST (EXP) == cc0_rtx) \
+ 	{ CC_STATUS_INIT; } \
+       else if (GET_CODE (SET_SRC (EXP)) == CALL) \
+ 	{ CC_STATUS_INIT; } \
+       else if (GET_CODE (SET_DEST (EXP)) == REG) \
+ 	{ \
+ 	  cc_status.flags = 0; \
+ 	  cc_status.value1 = SET_DEST (EXP); \
+ 	  cc_status.value2 = SET_SRC (EXP); \
+ 	} \
+       else if (GET_CODE (SET_DEST (EXP)) == MEM) \
+ 	{ \
+ 	  cc_status.flags = 0; \
+ 	  cc_status.value1 = SET_DEST (EXP); \
+ 	  cc_status.value2 = SET_SRC (EXP); \
+ 	} \
+       else \
+ 	{ CC_STATUS_INIT; } \
+     } \
+   else \
+     { CC_STATUS_INIT; } \
+ }
+ #endif /* 0 */
+ \f


+ /*** Output of Assembler Code ***/
+ 
+ /* Output at beginning of assembler file.  */
+ 
+ #define ASM_FILE_START(FILE) \
+   fprintf (FILE, ((TARGET_UNIX_ASM)? "" : "#NO_APP\n"));
+ 
+ /* Output to assembler file text saying following lines
+    may contain character constants, extra white space, comments, etc.  */
+ 
+ #define ASM_APP_ON ((TARGET_UNIX_ASM) ? "" : "#APP\n")
+ 
+ /* Output to assembler file text saying following lines
+    no longer contain unusual constructs.  */
+ 
+ #define ASM_APP_OFF ((TARGET_UNIX_ASM) ? "" : "#NO_APP\n")
+ 
+ /* Output before read-only data.  */
+ 
+ #define TEXT_SECTION_ASM_OP ".text"
+ 
+ /* Output before writable data.  */
+ 
+ #define DATA_SECTION_ASM_OP ".data"
+ 
+ /* How to refer to registers in assembler output.
+    This sequence is indexed by compiler's hard-register-number (see above).  */
+ 
+ #define REGISTER_NAMES \
+ {"gr0", "gr1", "gr2", "gr3", "gr4", "gr5", "gr6", "gr7", "gr8", \
+  "gr9", "gr10", "gr11", "logpsw", "cfp", "sp", "pc", \
+  "pr0", "pr1", "pr2", "pr3", "pr4", "pr5", "pr6", "pr7", \
+  "pr8", "pr9", "pr10", "pr11", "pr12", "pr13", "pr14", "pr15", \
+  "lr0", "lr1", "lr2", "lr3", "lr4", "lr5", "lr6", "lr7", \
+  "lr8", "lr9", "lr10", "lr11", "lr12", "lr13", "lr14", "lr15", \
+  "tr0", "tr1", "tr2", "tr3", "tr4", "tr5", "tr6", "tr7", \
+  "tr8", "tr9", "tr10", "tr11", "tr12", "tr13", "tr14", "tr15"}
+ 
+ /* How to renumber registers for dbx and gdb.  */
+ 
+ #define DBX_REGISTER_NUMBER(REGNO) (REGNO)
+ 
+ /* Our preference is for dbx rather than sdb.
+    Yours may be different. */
+ #define DBX_DEBUGGING_INFO
+ /* #define SDB_DEBUGGING_INFO */
+ 
+ /* Don't use the `xsfoo;' construct in DBX output; this system
+    doesn't support it.  */
+ 
+ #define DBX_NO_XREFS 1
+ 
+ /* Do not break .stabs pseudos into continuations.  */
+ 
+ #define DBX_CONTIN_LENGTH 0
+ 
+ /* This is the char to use for continuation (in case we need to turn
+    continuation back on).  */
+ 
+ #define DBX_CONTIN_CHAR '?'
+ 
+ /* 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 (".globl ", FILE); assemble_name (FILE, NAME); fputs ("\n", FILE);} while (0)
+ 
+ /* This is how to output a reference to a user-level label named NAME.  */
+ 
+ #define ASM_OUTPUT_LABELREF(FILE,NAME)	\
+    fprintf (FILE, "_%s", NAME);
+ 
+ /* This is how to output an internal numbered label where
+    PREFIX is the class of label and NUM is the number within the class.  */
+ 
+ #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)	\
+   fprintf (FILE, "%s%d:\n", PREFIX, NUM)
+ 
+ /* This is how to store into the string LABEL
+    the symbol_ref name of an internal numbered label where
+    PREFIX is the class of label and NUM is the number within the class.
+    This is suitable for output with `assemble_name'.  */
+ 
+ #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)	\
+   sprintf (LABEL, "*%s%d", PREFIX, NUM)
+ 
+ /* This is how to output an assembler line defining a `double' constant.  */
+ 
+ #define ASM_OUTPUT_DOUBLE(FILE,VALUE)  \
+   fprintf (FILE, "\t.double 0d%.20e\n", (VALUE))
+ 
+ /* This is how to output an assembler line defining a `float' constant.  */
+ 
+ #define ASM_OUTPUT_FLOAT(FILE,VALUE)  \
+   fprintf (FILE, "\t.float 0f%.20e\n", (VALUE))
+ 
+ /* This is how to output an assembler line defining an `int' constant.  */
+ 
+ #define ASM_OUTPUT_INT(FILE,VALUE)  \
+ ( fprintf (FILE, "\t.word "),			\
+   output_addr_const (FILE, (VALUE)),		\
+   fprintf (FILE, "\n"))
+ 
+ /* Likewise for `char' and `short' constants.  */
+ 
+ #define ASM_OUTPUT_SHORT(FILE,VALUE)  \
+ ( fprintf (FILE, "\t.half "),			\
+   output_addr_const (FILE, (VALUE)),		\
+   fprintf (FILE, "\n"))
+ 
+ #define ASM_OUTPUT_CHAR(FILE,VALUE)  \
+ ( fprintf (FILE, "\t.byte "),			\
+   output_addr_const (FILE, (VALUE)),		\
+   fprintf (FILE, "\n"))
+ 
+ /* This is how to output an assembler line for a numeric constant byte.  */
+ 
+ #define ASM_OUTPUT_BYTE(FILE,VALUE)  \
+   fprintf (FILE, "\t.byte 0x%x\n", (VALUE))
+ 
+ /* This is how to output an insn to push a register on the stack.
+    It need not be very fast code.  */
+ 
+ #define ASM_OUTPUT_REG_PUSH(FILE,REGNO)  \
+   fprintf (FILE, "\tpushw %s,sp\n", reg_names[REGNO])
+ 
+ /* This is how to output an insn to pop a register from the stack.
+    It need not be very fast code.  */
+ 
+ #define ASM_OUTPUT_REG_POP(FILE,REGNO)  \
+   fprintf (FILE, "\tpopw %s\n", reg_names[REGNO])
+ 
+ /* Store in OUTPUT a string (made with alloca) containing
+    an assembler-name for a local static variable named NAME.
+    LABELNO is an integer which is different for each call.  */
+ 
+ #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)	\
+ ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10),	\
+   sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
+ 
+ /* This is how to output an element of a case-vector that is absolute.
+ 
+    --> FIXME: We aren't sure whether the switch code we output uses
+    --> absolute or pc-relative jumps.
+  */
+ 
+ /* check case vectors ?????? */
+ #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)  \
+   fprintf (FILE, "\t.word L%d\n", VALUE)
+ 
+ /* This is how to output an element of a case-vector that is relative.  */
+ 
+ 
+ #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL)  \
+   fprintf (FILE, "\t.word L%d-L%d\n", VALUE, REL)
+ 
+ /* This is how to output an assembler line
+    that says to advance the location counter
+    to a multiple of 2**LOG bytes.
+ 
+    On Pyramids, the text segment must always be word aligned.
+   */
+ 
+ #define ASM_OUTPUT_ALIGN(FILE,LOG)  \
+   fprintf (FILE, "\t.align %d\n", ((LOG) < 2) ? 2 : (LOG) )
+ 
+ #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
+   fprintf (FILE, "\t.space %d\n", (SIZE))
+ 
+ /* This says how to output an assembler line
+    to define a global common symbol.  */
+ 
+ #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)  \
+ ( fputs (".comm ", (FILE)),			\
+   assemble_name ((FILE), (NAME)),		\
+   fprintf ((FILE), ",%d\n", (ROUNDED)))
+ 
+ /* This says how to output an assembler line
+    to define a local common symbol.  */
+ 
+ #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)  \
+ ( fputs (".lcomm ", (FILE)),			\
+   assemble_name ((FILE), (NAME)),		\
+   fprintf ((FILE), ",%d\n", (ROUNDED)))
+ 
+ /* Define the parentheses used to group arithmetic operations
+    in assembler code.  */
+ 
+ #define ASM_OPEN_PAREN "("
+ #define ASM_CLOSE_PAREN ")"
+ 
+ /* Define results of standard character escape sequences.  */
+ #define TARGET_BELL 007
+ #define TARGET_BS 010
+ #define TARGET_TAB 011
+ #define TARGET_NEWLINE 012
+ #define TARGET_VT 013
+ #define TARGET_FF 014
+ #define TARGET_CR 015
+ 
+ /* Print operand X (an rtx) in assembler syntax to file FILE.
+    CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
+    For `%' followed by punctuation, CODE is the punctuation and X is null.
+    On the Pyr, we support the conventional CODE characters:
+ 
+    'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)
+ 
+   which are never used. */
+ /* FIXME : should be more robust with CONST_DOUBLE. */
+ 
+ #define PRINT_OPERAND(FILE, X, CODE)  \
+ { if (GET_CODE (X) == REG)						\
+     fprintf (FILE, "%s", reg_names [REGNO (X)]);			\
+ 									\
+   else if (GET_CODE (X) == MEM)						\
+     output_address (XEXP (X, 0));					\
+ 									\
+   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode)	\
+     { union { double d; int i[2]; } u;					\
+       union { float f; int i; } u1;					\
+       u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X);	\
+       u1.f = u.d;							\
+       if (CODE == 'f')							\
+         fprintf (FILE, "$0f%.0e", u1.f);				\
+       else								\
+         fprintf (FILE, "$0x%x", u1.i); }				\
+ 									\
+   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != DImode)	\
+     { union { double d; int i[2]; } u;					\
+       u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X);	\
+       fprintf (FILE, "$0d%.20e", u.d); }				\
+ 									\
+   else if (CODE == 'N')							\
+     switch (GET_CODE (X))						\
+       {									\
+       case EQ:	fputs ("eq", FILE);	break;				\
+       case NE:	fputs ("ne", FILE);	break;				\
+       case GT:								\
+       case GTU:	fputs ("gt", FILE);	break;				\
+       case LT:								\
+       case LTU:	fputs ("lt", FILE);	break;				\
+       case GE:								\
+       case GEU:	fputs ("ge", FILE);	break;				\
+       case LE:								\
+       case LEU:	fputs ("le", FILE);	break;				\
+       }									\
+ 									\
+   else if (CODE == 'C')							\
+     switch (GET_CODE (X))						\
+       {									\
+       case EQ:	fputs ("ne", FILE);	break;				\
+       case NE:	fputs ("eq", FILE);	break;				\
+       case GT:								\
+       case GTU:	fputs ("le", FILE);	break;				\
+       case LT:								\
+       case LTU:	fputs ("ge", FILE);	break;				\
+       case GE:								\
+       case GEU:	fputs ("lt", FILE);	break;				\
+       case LE:								\
+       case LEU:	fputs ("gt", FILE);	break;				\
+       }									\
+ 									\
+   else { putc ('$', FILE); output_addr_const (FILE, X); }		\
+ }
+ 
+ /* Print a memory operand whose address is X, on file FILE.  */
+ #define PRINT_OPERAND_ADDRESS(FILE, ADDR)  \
+ {									\
+   register rtx reg1, reg2, breg, ireg;					\
+   register rtx addr = ADDR;						\
+   rtx offset, scale;							\
+  retry:									\
+   switch (GET_CODE (addr))						\
+     {									\
+     case MEM:								\
+       fprintf (stderr, "bad Mem "); debug_rtx (addr);			\
+       addr = XEXP (addr, 0);						\
+       abort ();								\
+     case REG:								\
+       fprintf (FILE, "(%s)", reg_names [REGNO (addr)]);			\
+       break;								\
+     case PLUS:								\
+       reg1 = 0;	reg2 = 0;						\
+       ireg = 0;	breg = 0;						\
+       offset = 0;							\
+       if (CONSTANT_ADDRESS_P (XEXP (addr, 0))				\
+ 	  || GET_CODE (XEXP (addr, 0)) == MEM)				\
+ 	{								\
+ 	  offset = XEXP (addr, 0);					\
+ 	  addr = XEXP (addr, 1);					\
+ 	}								\
+       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))			\
+ 	       || GET_CODE (XEXP (addr, 1)) == MEM)			\
+ 	{								\
+ 	  offset = XEXP (addr, 1);					\
+ 	  addr = XEXP (addr, 0);					\
+ 	}								\
+       if (GET_CODE (addr) != PLUS) ;					\
+       else if (GET_CODE (XEXP (addr, 0)) == MULT)			\
+ 	{								\
+ 	  reg1 = XEXP (addr, 0);					\
+ 	  addr = XEXP (addr, 1);					\
+ 	}								\
+       else if (GET_CODE (XEXP (addr, 1)) == MULT)			\
+ 	{								\
+ 	  reg1 = XEXP (addr, 1);					\
+ 	  addr = XEXP (addr, 0);					\
+ 	}								\
+       else if (GET_CODE (XEXP (addr, 0)) == REG)			\
+ 	{								\
+ 	  reg1 = XEXP (addr, 0);					\
+ 	  addr = XEXP (addr, 1);					\
+ 	}								\
+       else if (GET_CODE (XEXP (addr, 1)) == REG)			\
+ 	{								\
+ 	  reg1 = XEXP (addr, 1);					\
+ 	  addr = XEXP (addr, 0);					\
+ 	}								\
+       if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)		\
+ 	{								\
+ 	  if (reg1 == 0)						\
+ 	    reg1 = addr;						\
+           else								\
+ 	    reg2 = addr;						\
+ 	  addr = 0;							\
+ 	}								\
+       if (offset != 0) 							\
+ 	{								\
+ 	  if (addr != 0) {						\
+ 	    fprintf (stderr, "\nBad addr "); debug_rtx (addr);		\
+ 	    abort ();}							\
+ 	  addr = offset;						\
+ 	}								\
+       if (reg1 != 0 && GET_CODE (reg1) == MULT)				\
+ 	{ breg = reg2; ireg = reg1; }					\
+       else if (reg2 != 0 && GET_CODE (reg2) == MULT)			\
+ 	{ breg = reg1; ireg = reg2; }					\
+       else if (reg2 != 0 || GET_CODE (addr) == MEM)			\
+ 	{ breg = reg2; ireg = reg1; }					\
+       else								\
+ 	{ breg = reg1; ireg = reg2; }					\
+       if (addr != 0)							\
+ 	output_address (offset);					\
+       if (breg != 0)							\
+ 	{ if (GET_CODE (breg) != REG)					\
+ 	    {								\
+ 	      fprintf (stderr, "bad Breg"); debug_rtx (addr);		\
+ 	      abort ();							\
+ 	    }								\
+ 	  fprintf (FILE, "(%s)", reg_names[REGNO (breg)]); }		\
+       if (ireg != 0)							\
+ 	{								\
+ 	  if (GET_CODE (ireg) == MULT)					\
+ 	    {								\
+ 	      scale = XEXP (ireg, 1);					\
+ 	      ireg = XEXP (ireg, 0);					\
+ 	      if (GET_CODE (ireg) != REG)				\
+ 	        { register rtx tem;					\
+ 		  tem = ireg; ireg = scale; scale = tem;		\
+ 	        }							\
+  	      if (GET_CODE (ireg) != REG) {				\
+ 		      fprintf (stderr, "bad idx "); debug_rtx (addr);	\
+ 		abort (); }						\
+ 	      if ((GET_CODE (scale) == CONST_INT) && (INTVAL(scale) >= 1))\
+ 		fprintf (FILE, "[%s*0x%x]", reg_names[REGNO (ireg)],	\
+ 			 INTVAL(scale));				\
+ 	      else							\
+ 		fprintf (FILE, "[%s*1]", reg_names[REGNO (ireg)]);	\
+  	    } 								\
+ 	  else if (GET_CODE (ireg) == REG)				\
+ 	      fprintf (FILE, "[%s*1]", reg_names[REGNO (ireg)]);	\
+ 	  else								\
+ 	    {								\
+ 	      fprintf (stderr, "Not indexed at all!"); debug_rtx (addr);\
+ 	      abort ();							\
+ 	    }								\
+ 	 }								\
+        break;								\
+     default:								\
+       output_addr_const (FILE, addr);					\
+    }									\
+ }
diff -rc2N gcc-1.35/config/tm-sparc.h gcc-1.36/config/tm-sparc.h
*** gcc-1.35/config/tm-sparc.h	Wed Mar 29 17:48:30 1989
--- gcc-1.36/config/tm-sparc.h	Mon Sep 18 14:59:15 1989
***************
*** 24,30 ****
  /* Specify library to handle `-a' basic block profiling.  */
  
! #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} \
! %{a:/usr/lib/bb_link.o} "
  
  /* Special flags to the Sun-4 assembler when using pipe for input.  */
  
--- 24,36 ----
  /* Specify library to handle `-a' basic block profiling.  */
  
! #define LIB_SPEC "%{a:/usr/lib/bb_link.o} \
! %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} "
  
+ /* Provide required defaults for linker -e and -d switches.
+    Also, it is hard to debug with shared libraries,
+    so don't use them if going to debug.  */
+ 
+ #define LINK_SPEC "%{!e*:-e start} -dc -dp %{g:-Bstatic} %{static:-Bstatic} %{-Bstatic}"
+ 
  /* Special flags to the Sun-4 assembler when using pipe for input.  */
  
***************
*** 31,34 ****
--- 37,44 ----
  #define ASM_SPEC " %{pipe:-} "
  
+ /* Prevent error on `-sun4' option.  */
+ 
+ #define CC1_SPEC "%{sun4:}"
+ 
  /* Names to predefine in the preprocessor for this target machine.  */
  
***************
*** 132,135 ****
--- 142,148 ----
  #define STRUCTURE_SIZE_BOUNDARY 8
  
+ /* A bitfield declared as `int' forces `int' alignment for the struct.  */
+ #define PCC_BITFIELD_TYPE_MATTERS
+ 
  /* No data type wants to be aligned rounder than this.  */
  #define BIGGEST_ALIGNMENT 64
***************
*** 138,141 ****
--- 151,187 ----
     when given unaligned data.  */
  #define STRICT_ALIGNMENT
+ 
+ /* Things that must be doubleword aligned cannot go in the text section,
+    because the linker fails to align the text section enough!
+    Put them in the data section.  */
+ #define MAX_TEXT_ALIGN 32
+ 
+ #define SELECT_SECTION(T)						\
+ {									\
+   if (TREE_CODE (T) == VAR_DECL)					\
+     {									\
+       if (TREE_READONLY (T) && ! TREE_VOLATILE (T)			\
+ 	  && DECL_ALIGN (T) <= MAX_TEXT_ALIGN)				\
+ 	text_section ();						\
+       else								\
+ 	data_section ();						\
+     }									\
+   if (*tree_code_type[(int) TREE_CODE (T)] == 'c')			\
+     {									\
+       if ((TREE_CODE (T) == STRING_CST && flag_writable_strings)	\
+ 	  || TYPE_ALIGN (TREE_TYPE (T)) > MAX_TEXT_ALIGN)		\
+ 	data_section ();						\
+       else								\
+ 	text_section ();						\
+     }									\
+ }
+ 
+ #define SELECT_RTX_SECTION(MODE, X)		\
+ {						\
+   if (GET_MODE_BITSIZE (MODE) > MAX_TEXT_ALIGN)	\
+     text_section ();				\
+   else						\
+     data_section ();				\
+ }
  \f


  /* Standard register usage.  */
***************
*** 548,552 ****
    extern int current_function_pretend_args_size;		\
    extern int frame_pointer_needed;				\
!   int fsize = ((SIZE) + 7) & -8;				\
    int actual_fsize;						\
    int n_fregs = 0, i;						\
--- 594,598 ----
    extern int current_function_pretend_args_size;		\
    extern int frame_pointer_needed;				\
!   int fsize = (((SIZE) + 7 - STARTING_FRAME_OFFSET) & -8);	\
    int actual_fsize;						\
    int n_fregs = 0, i;						\
***************
*** 649,653 ****
    extern int max_pending_stack_adjust;				\
    extern int frame_pointer_needed;				\
!   int fsize = ((SIZE) + 7) & -8;				\
    int actual_fsize;						\
    int n_fregs = 0, i;						\
--- 695,699 ----
    extern int max_pending_stack_adjust;				\
    extern int frame_pointer_needed;				\
!   int fsize = (((SIZE) + 7 - STARTING_FRAME_OFFSET) & -8);	\
    int actual_fsize;						\
    int n_fregs = 0, i;						\
diff -rc2N gcc-1.35/config/tm-sun3-fpa.h gcc-1.36/config/tm-sun3-fpa.h
*** gcc-1.35/config/tm-sun3-fpa.h	Sat Dec 31 14:13:10 1988
--- gcc-1.36/config/tm-sun3-fpa.h	Wed Dec 31 19:00:00 1969
***************
*** 1,5 ****
- /* Define target machine as a Sun 3 with an FPA.  */
- 
- #define TARGET_DEFAULT 0107
- 
- #include "tm-sun3.h"
--- 0 ----
diff -rc2N gcc-1.35/config/tm-sun3.h gcc-1.36/config/tm-sun3.h
*** gcc-1.35/config/tm-sun3.h	Wed Feb 22 12:27:23 1989
--- gcc-1.36/config/tm-sun3.h	Sun Jul 30 23:35:39 1989
***************
*** 58,62 ****
--- 58,65 ----
  #endif
  
+ /* Prevent error on `-sun3' option.  */
  
+ #define CC1_SPEC "%{sun3:}"
+ 
  /* -m68000 requires special flags to the assembler.  */
  
***************
*** 98,102 ****
     %{mfpa:Wcrt1.o%s}					\
     %{!m68881:%{!mfpa:Fcrt1.o%s}}"
! #endif
  #endif
  
--- 101,105 ----
     %{mfpa:Wcrt1.o%s}					\
     %{!m68881:%{!mfpa:Fcrt1.o%s}}"
! #endif
  #endif
  
***************
*** 105,108 ****
--- 108,117 ----
  #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} \
  %{a:/usr/lib/bb_link.o} "
+ 
+ /* Provide required defaults for linker -e and -d switches.
+    Also, it is hard to debug with shared libraries,
+    so don't use them if going to debug.  */
+ 
+ #define LINK_SPEC "%{!e*:-e start} -dc -dp %{g:-Bstatic} %{static:-Bstatic} %{-Bstatic}"
  
  /* Every structure or union's size must be a multiple of 2 bytes.  */
diff -rc2N gcc-1.35/config/tm-sun386.h gcc-1.36/config/tm-sun386.h
*** gcc-1.35/config/tm-sun386.h	Wed Feb 22 12:27:21 1989
--- gcc-1.36/config/tm-sun386.h	Tue Jul  4 14:01:53 1989
***************
*** 114,117 ****
--- 114,118 ----
        int len = strlen (dump_base_name);		\
        char *na = dump_base_name + len;			\
+       char shorter[15];					\
        /* NA gets DUMP_BASE_NAME sans directory names.  */\
        while (na > dump_base_name)			\
***************
*** 121,125 ****
  	  na--;						\
  	}						\
!       fprintf (FILE, "\t.file\t\"%s\"\n", na);		\
      }							\
      fprintf (FILE, "\t.version\t\"%s %s\"\n",		\
--- 122,128 ----
  	  na--;						\
  	}						\
!       strncpy (shorter, na, 14);			\
!       shorter[14] = 0;					\
!       fprintf (FILE, "\t.file\t\"%s\"\n", shorter);	\
      }							\
      fprintf (FILE, "\t.version\t\"%s %s\"\n",		\
diff -rc2N gcc-1.35/config/tm-sun386i.h gcc-1.36/config/tm-sun386i.h
*** gcc-1.35/config/tm-sun386i.h	Wed Mar 29 17:31:02 1989
--- gcc-1.36/config/tm-sun386i.h	Wed May 24 15:27:55 1989
***************
*** 34,38 ****
    "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}"
  
! #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}"
  
  /* Extra switches to give the assembler.  */
--- 34,40 ----
    "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}"
  
! #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}\
! %{sun386:}"
! /* That last item is just to prevent a spurious error.  */
  
  /* Extra switches to give the assembler.  */
***************
*** 81,85 ****
  #undef DBX_REGISTER_NUMBER
  #define DBX_REGISTER_NUMBER(n) \
! ((n) == 1 ? 2 : (n) == 2 ? 1 : (n) < 8 ? (n) : 12)
  
  /* Every debugger symbol must be in the text section.
--- 83,88 ----
  #undef DBX_REGISTER_NUMBER
  #define DBX_REGISTER_NUMBER(n) \
!   ((n) == 0 ? 11 : (n)  == 1 ? 9 : (n) == 2 ? 10 : (n) == 3 ? 8	\
!    : (n) == 4 ? 5 : (n) == 5 ? 4 : (n) == 6 ? 6 : (n))
  
  /* Every debugger symbol must be in the text section.
diff -rc2N gcc-1.35/config/tm-sun3os3.h gcc-1.36/config/tm-sun3os3.h
*** gcc-1.35/config/tm-sun3os3.h	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config/tm-sun3os3.h	Sun Jul 30 23:34:54 1989
***************
*** 0 ****
--- 1,5 ----
+ #include "tm-sun3.h"
+ 
+ /* LINK_SPEC is needed only for Sunos 4.  */
+ 
+ #undef LINK_SPEC
diff -rc2N gcc-1.35/config/tm-sun3os3nf.h gcc-1.36/config/tm-sun3os3nf.h
*** gcc-1.35/config/tm-sun3os3nf.h	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config/tm-sun3os3nf.h	Sun Jul 30 23:39:16 1989
***************
*** 0 ****
--- 1,5 ----
+ #include "tm-sun3-nfp.h"
+ 
+ /* LINK_SPEC is needed only for Sunos 4.  */
+ 
+ #undef LINK_SPEC
diff -rc2N gcc-1.35/config/tm-sun4os3.h gcc-1.36/config/tm-sun4os3.h
*** gcc-1.35/config/tm-sun4os3.h	Thu Feb 23 05:56:01 1989
--- gcc-1.36/config/tm-sun4os3.h	Sun Jul 30 23:24:51 1989
***************
*** 9,10 ****
--- 9,15 ----
    fprintf (FILE, "\tsethi %%hi(LP%d),%%o0\n\tcall .mcount\n\tor %%lo(LP%d),%%o0,%%o0\n", \
  	   (LABELNO), (LABELNO))
+ 
+ /* LINK_SPEC is needed only for Sunos 4.  */
+ 
+ #undef LINK_SPEC
+ 
diff -rc2N gcc-1.35/config/tm-tahoe.h gcc-1.36/config/tm-tahoe.h
*** gcc-1.35/config/tm-tahoe.h	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config/tm-tahoe.h	Sun Sep 24 00:21:18 1989
***************
*** 0 ****
--- 1,850 ----
+ /* Definitions of target machine for GNU compiler.  Tahoe version.
+    Copyright (C) 1989 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+ 
+ /*
+  * File: tm-tahoe.h
+  *
+  * This port made at the University of Buffalo by Devon Bowen,
+  * Dale Wiles and Kevin Zachmann.
+  *
+  * Mail bugs reports or fixes to:	gcc@cs.buffalo.edu
+  */
+ 
+ 
+ /*
+  * Run-time Target Specification
+  */
+ 
+ /* we want "tahoe" and "unix" auto-defined for all future compilations */
+ 
+ #define CPP_PREDEFINES "-Dtahoe -Dunix"
+ 
+ /* have cc1 print that this is the tahoe version */
+ 
+ #define TARGET_VERSION printf (" (tahoe)");
+ 
+ /* this is required in all tm files to hold flags */
+ 
+ extern int target_flags;
+ 
+ /* Zero if it is safe to output .dfloat and .float pseudos.  */
+ #define TARGET_HEX_FLOAT (target_flags & 1)
+ 
+ #define TARGET_DEFAULT 1
+ 
+ #define TARGET_SWITCHES		\
+   { {"hex-float", 1},		\
+     {"no-hex-float", -1},	\
+     { "", TARGET_DEFAULT} }
+ \f


+ 
+ /*
+  * Storage Layout
+  */
+ 
+ /* tahoe uses a big endian byte order */
+ 
+ #define BYTES_BIG_ENDIAN
+ 
+ /* tahoe uses a big endian word order */
+ 
+ #define WORDS_BIG_ENDIAN
+ 
+ /* standard byte size is usable on tahoe */
+ 
+ #define BITS_PER_UNIT 8
+ 
+ /* longs on the tahoe are 4 byte groups */
+ 
+ #define BITS_PER_WORD 32
+ 
+ /* from the last two params we get 4 bytes per word */
+ 
+ #define UNITS_PER_WORD 4
+ 
+ /* addresses are 32 bits (one word) */
+ 
+ #define POINTER_SIZE 32
+ 
+ /* pointers should align every 32 bits */
+ 
+ #define POINTER_BOUNDARY 32
+ 
+ /* all parameters line up on 32 boundaries */
+ 
+ #define PARM_BOUNDARY 32
+ 
+ /* stack should line up on 32 boundaries */
+ 
+ #define STACK_BOUNDARY 32
+ 
+ /* line functions up on 32 bits */
+ 
+ #define FUNCTION_BOUNDARY 32
+ 
+ /* the biggest alignment the tahoe needs in 32 bits */
+ 
+ #define BIGGEST_ALIGNMENT 32
+ 
+ /* we have to align after an 'int : 0' in a structure */
+ 
+ #define EMPTY_FIELD_BOUNDARY 32
+ 
+ /* structures must be made of full bytes */
+ 
+ #define STRUCTURE_SIZE_BOUNDARY 8
+ 
+ /* tahoe is picky about data alignment */
+ 
+ #define STRICT_ALIGNMENT
+ 
+ /* keep things standard with pcc */
+ 
+ #define PCC_BITFIELD_TYPE_MATTERS
+ 
+ /* this section is borrowed from the vax version since the */
+ /* formats are the same in both of the architectures	   */
+ 
+ #define CHECK_FLOAT_VALUE(mode, d) \
+   if ((mode) == SFmode) \
+     { \
+       if ((d) > 1.7014117331926443e+38) \
+ 	{ error ("magnitude of constant too large for `float'"); \
+ 	  (d) = 1.7014117331926443e+38; } \
+       else if ((d) < -1.7014117331926443e+38) \
+ 	{ error ("magnitude of constant too large for `float'"); \
+ 	  (d) = -1.7014117331926443e+38; } \
+       else if (((d) > 0) && ((d) < 2.9387358770557188e-39)) \
+ 	{ warning ("`float' constant truncated to zero"); \
+ 	  (d) = 0.0; } \
+       else if (((d) < 0) && ((d) > -2.9387358770557188e-39)) \
+ 	{ warning ("`float' constant truncated to zero"); \
+ 	  (d) = 0.0; } \
+     }
+ 
+ 
+ /*
+  * Register Usage
+  */
+ 
+ /* define 15 general regs plus one for the floating point reg (FPP) */
+ 
+ #define FIRST_PSEUDO_REGISTER 17
+ 
+ /* let the compiler know what the fp, sp and pc are */
+ 
+ #define FIXED_REGISTERS {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0}
+ 
+ /* lots of regs aren't guarenteed to return from a call. The FPP reg */
+ /* must be included in these since it can't be saved by the reg mask */
+ 
+ #define CALL_USED_REGISTERS {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1}
+ 
+ /* The FPP can handle any type, but the others may require as many as */
+ /* two regs depending on the mode needed 			      */
+ 
+ #define HARD_REGNO_NREGS(REGNO, MODE) \
+  (REGNO != 16 ? ((GET_MODE_SIZE(MODE)+UNITS_PER_WORD-1) / UNITS_PER_WORD) : 1)
+ 
+ /* any mode greater than 4 bytes (doubles) can only go in an even regs */
+ /* and the FPP can only hold SFmode and DFmode 			       */
+ 
+ #define HARD_REGNO_MODE_OK(REGNO, MODE) \
+  (REGNO != 16 ? (GET_MODE_SIZE (MODE) <= 4 ? 1 : (REGNO % 2 - 1)) : \
+ 	(MODE == SFmode || MODE == DFmode))
+ 
+ /* if mode1 or mode2, but not both, are doubles then modes cannot be tied */
+ 
+ #define MODES_TIEABLE_P(MODE1, MODE2) \
+  ((MODE1 == DFmode) == (MODE2 == DFmode))
+ 
+ /* the program counter is reg 15 */
+ 
+ #define PC_REGNUM 15
+ 
+ /* the stack pointer is reg 14 */
+ 
+ #define STACK_POINTER_REGNUM 14
+ 
+ /* the frame pointer is reg 13 */
+ 
+ #define FRAME_POINTER_REGNUM 13
+ 
+ /* tahoe does require an fp */
+ 
+ #define FRAME_POINTER_REQUIRED 1
+ 
+ /* since tahoe doesn't have a argument pointer, make it the fp */
+ 
+ #define ARG_POINTER_REGNUM 13
+ 
+ /* this isn't currently used since C doesn't support this feature */
+ 
+ #define STATIC_CHAIN_REGNUM 0
+ 
+ /* we'll use reg 1 for structure passing cause the destination */
+ /* of the eventual movblk requires it to be there anyway.      */
+ 
+ #define STRUCT_VALUE_REGNUM 1
+ 
+ 
+ /*
+  * Register Classes
+  */
+ 
+ /* tahoe has two types of regs. GENERALY_REGS are all the regs up */
+ /* to number 15. FPP_REG is the special floating point processor  */
+ /* register class (only one reg).				  */
+ 
+ enum reg_class {NO_REGS,GENERAL_REGS,FPP_REG,ALL_REGS,LIM_REG_CLASSES};
+ 
+ /* defines the number of reg classes.				    */
+ 
+ #define N_REG_CLASSES (int) LIM_REG_CLASSES
+ 
+ /* this defines what the classes are officially named for debugging */
+ 
+ #define REG_CLASS_NAMES \
+  {"NO_REGS","GENERAL_REGS","FPP_REG","ALL_REGS"}
+ 
+ /* set general regs to be the first 16 regs and the fpp reg to be 17th */
+ 
+ #define REG_CLASS_CONTENTS {0,0xffff,0x10000,0x1ffff}
+ 
+ /* register class for the fpp reg is FPP_REG, all others are GENERAL_REGS */
+ 
+ #define REGNO_REG_CLASS(REGNO) (REGNO == 16 ? FPP_REG : GENERAL_REGS)
+ 
+ /* only gereral registers can be used as a base reg */
+ 
+ #define BASE_REG_CLASS GENERAL_REGS
+ 
+ /* only gereral registers can be used to index */
+ 
+ #define INDEX_REG_CLASS GENERAL_REGS
+ 
+ /* 'a' as a contraint in the md file means the FFP_REG class */
+ 
+ #define REG_CLASS_FROM_LETTER(C) (C == 'a' ? FPP_REG : NO_REGS)
+ 
+ /* any general reg but the fpp can be a base reg */
+ 
+ #define REGNO_OK_FOR_BASE_P(regno) \
+ ((regno) < FIRST_PSEUDO_REGISTER - 1 || reg_renumber[regno] >= 0)
+ 
+ /* any general reg except the pc and fpp can be an index reg */
+ 
+ #define REGNO_OK_FOR_INDEX_P(regno)  \
+ ((regno) < FIRST_PSEUDO_REGISTER - 2 || reg_renumber[regno] >= 0)
+ 
+ /* if your loading a floating point constant, it can't be done */
+ /* through a register. Force it to be a memory constant.       */
+ 
+ #define PREFERRED_RELOAD_CLASS(X,CLASS) \
+ 	((GET_CODE (X) == CONST_DOUBLE) ? NO_REGS : CLASS)
+ 
+ /* for the fpp reg, all modes fit; for any others, you need two for doubles */
+ 
+ #define CLASS_MAX_NREGS(CLASS, MODE)	\
+  (CLASS != FPP_REG ? ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) : 1)
+ 
+ /* we don't define any special constant sizes so all should fail */
+ 
+ #define CONST_OK_FOR_LETTER_P(VALUE, C)  0
+ 
+ /* we don't define any special double sizes so all should fail */
+ 
+ #define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) 0
+ 
+ 
+ /*
+  * Describing Stack Layout
+  */
+ 
+ /* tahoe stack grows from high to low memory */
+ 
+ #define STACK_GROWS_DOWNWARD
+ 
+ /* Define this if longjmp restores from saved registers
+    rather than from what setjmp saved.  */
+ #define LONGJMP_RESTORE_FROM_STACK
+ 
+ /* tahoe call frames grow from high to low memory on the stack */
+ 
+ #define FRAME_GROWS_DOWNWARD
+ 
+ /* the tahoe fp points to the *top* of the frame instead of the   */
+ /* bottom, so we have to make this offset a constant large enough */
+ /* to jump over the biggest frame possible.			  */
+ 
+ #define STARTING_FRAME_OFFSET -52
+ 
+ /* tahoe always pushes 4 bytes unless it's a double in which case */
+ /* it pushes a full 8 bytes.					  */
+ 
+ #define PUSH_ROUNDING(BYTES) (BYTES <= 4 ? 4 : 8)
+ 
+ /* the first parameter in a function is at the fp + 4 */
+ 
+ #define FIRST_PARM_OFFSET(FNDECL) 4
+ 
+ /* the tahoe return function takes care of everything on the stack */
+ 
+ #define RETURN_POPS_ARGS(FUNTYPE) 1
+ 
+ /* function values for all types are returned in register 0 */
+ 
+ #define FUNCTION_VALUE(VALTYPE, FUNC)  \
+   gen_rtx (REG, TYPE_MODE (VALTYPE), 0)
+ 
+ /* libarary routines also return things in reg 0 */
+ 
+ #define LIBCALL_VALUE(MODE)  gen_rtx (REG, MODE, 0)
+ 
+ /* Tahoe doesn't return structures in a reentrant way */
+ 
+ #define PCC_STATIC_STRUCT_RETURN
+ 
+ /* we only return values from a function in reg 0 */
+ 
+ #define FUNCTION_VALUE_REGNO_P(N) ((N) == 0)
+ 
+ /* we never pass args through a register */
+ 
+ #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) 0
+ 
+ /* int is fine to hold the argument summary in FUNCTION_ARG */
+ 
+ #define CUMULATIVE_ARGS int
+ 
+ /* we just set CUM to 0 before the FUNCTION_ARG call. No matter what */
+ /* we make it, FUNCTION_ARG will return 0 anyway		     */
+ 
+ #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE)	\
+  ((CUM) = 0)
+ 
+ /* all modes push their size rounded to the nearest word boundary */
+ /* except block which is the size of the block rounded up	  */
+ 
+ #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)	\
+  ((CUM) += ((MODE) != BLKmode			\
+ 	    ? (GET_MODE_SIZE (MODE) + 3) & ~3	\
+ 	    : (int_size_in_bytes (TYPE) + 3) & ~3))
+ 
+ /* this is always false since we never pass params in regs */
+ 
+ #define FUNCTION_ARG_REGNO_P(N) 0
+ 
+ /* this code calculates the register entry mask and sets up    */
+ /* the stack pointer for the function. The stack is set down   */
+ /* far enough from the fp to jump over any push regs and local */
+ /* vars. This is a problem since the tahoe has the fp pointing */
+ /* to the top of the frame and the compiler must know the off- */
+ /* set off the fp to the local vars.			       */
+ 
+ #define FUNCTION_PROLOGUE(FILE, SIZE)     \
+ { register int regno;						\
+   register int mask = 0;					\
+   extern char call_used_regs[];					\
+   for (regno = 0; regno < FIRST_PSEUDO_REGISTER-1; regno++)	\
+     if (regs_ever_live[regno] && !call_used_regs[regno])	\
+        mask |= 1 << regno;					\
+   fprintf (FILE, "\t.word 0x%x\n", mask);			\
+   if (SIZE != 0) fprintf (FILE, "\tsubl3 $%d,fp,sp\n", (SIZE) - STARTING_FRAME_OFFSET); }
+ 
+ /* to call the profiler, push the variable value onto the stack */
+ /* and call mcount like a regular function.			*/
+ 
+ #define FUNCTION_PROFILER(FILE, LABELNO)  \
+    fprintf (FILE, "\tpushl $LP%d\n\tcallf $8,mcount\n", (LABELNO));
+ 
+ /* all stack handling at the end of a function is handled by the */
+ /* return command.						 */
+ 
+ #define EXIT_IGNORE_STACK 1
+ 
+ /* this never gets executed since the system knows it always gets  */
+ /* an fp to work with. It just prints a friendly message since the */
+ /* person must be playing with the tm file defs 		   */
+ 
+ #define FIX_FRAME_POINTER_ADDRESS(ADDR,DEPTH) \
+  { abort(); }
+ 
+ 
+ /*
+  * Library Subroutine Names
+  */
+ 
+ /* udiv is a valid C library routine in libc.a, so we call that */
+ 
+ #define UDIVSI3_LIBCALL "*udiv"
+ 
+ /* urem is a valid C library routine in libc.a, so we call that */
+ 
+ #define UMODSI3_LIBCALL "*urem"
+ 
+ 
+ /*
+  * Addressing Modes
+  */
+ 
+ /* constant addresses can be treated exactly the same as normal constants */
+ 
+ #define CONSTANT_ADDRESS_P(X) CONSTANT_P (X)
+ 
+ /* we can have as many as two regs in any given address */
+ 
+ #define MAX_REGS_PER_ADDRESS 2
+ 
+ /* The following is all the code for GO_IF_LEGITIMATE_ADDRESS */
+ /* most of this taken directly from the vax tm file since the */
+ /* tahoe and vax addressing modes are nearly identicle.	      */
+ 
+ /* Is x an indirectable address? */
+ 
+ #define INDIRECTABLE_ADDRESS_P(X)  \
+   (CONSTANT_ADDRESS_P (X)						\
+    || (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X))			\
+    || (GET_CODE (X) == PLUS						\
+        && GET_CODE (XEXP (X, 0)) == REG					\
+        && REG_OK_FOR_BASE_P (XEXP (X, 0))				\
+        && CONSTANT_ADDRESS_P (XEXP (X, 1))))
+ 
+ /* If x is a non-indexed-address, go to ADDR. */
+ 
+ #define GO_IF_NONINDEXED_ADDRESS(X, ADDR)  \
+ { register rtx xfoob = (X);						\
+   if (GET_CODE (xfoob) == REG) goto ADDR;				\
+   if (INDIRECTABLE_ADDRESS_P (xfoob)) goto ADDR;			\
+   xfoob = XEXP (X, 0);							\
+   if (GET_CODE (X) == MEM && INDIRECTABLE_ADDRESS_P (xfoob))		\
+     goto ADDR;								\
+   if ((GET_CODE (X) == PRE_DEC || GET_CODE (X) == POST_INC)		\
+       && GET_CODE (xfoob) == REG && REGNO (xfoob) == 14)		\
+     goto ADDR; }
+ 
+ /* Is PROD an index term in mode MODE. */
+ 
+ #define INDEX_TERM_P(PROD, MODE)   \
+ (GET_MODE_SIZE (MODE) == 1						\
+  ? (GET_CODE (PROD) == REG && REG_OK_FOR_BASE_P (PROD))			\
+  : (GET_CODE (PROD) == MULT						\
+     &&									\
+     (xfoo0 = XEXP (PROD, 0), xfoo1 = XEXP (PROD, 1),			\
+      ((GET_CODE (xfoo0) == CONST_INT					\
+        && INTVAL (xfoo0) == GET_MODE_SIZE (MODE)			\
+        && GET_CODE (xfoo1) == REG					\
+        && REG_OK_FOR_INDEX_P (xfoo1))					\
+       ||								\
+       (GET_CODE (xfoo1) == CONST_INT					\
+        && INTVAL (xfoo1) == GET_MODE_SIZE (MODE)			\
+        && GET_CODE (xfoo0) == REG					\
+        && REG_OK_FOR_INDEX_P (xfoo0))))))
+ 
+ /* Is the addition to the index a reg? */
+ 
+ #define GO_IF_REG_PLUS_INDEX(X, MODE, ADDR)	\
+ { register rtx xfooa;							\
+   if (GET_CODE (X) == PLUS)						\
+     { if (GET_CODE (XEXP (X, 0)) == REG					\
+ 	  && REG_OK_FOR_BASE_P (XEXP (X, 0))				\
+ 	  && (xfooa = XEXP (X, 1),					\
+ 	      INDEX_TERM_P (xfooa, MODE)))				\
+ 	goto ADDR;							\
+       if (GET_CODE (XEXP (X, 1)) == REG					\
+ 	  && REG_OK_FOR_BASE_P (XEXP (X, 1))				\
+ 	  && (xfooa = XEXP (X, 0),					\
+ 	      INDEX_TERM_P (xfooa, MODE)))				\
+ 	goto ADDR; } }
+ 
+ /* Is the rtx X a valid memoy address for operand of mode MODE? */
+ /* If it is, go to ADDR */
+ 
+ #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)  \
+ { register rtx xfoo, xfoo0, xfoo1;					\
+   GO_IF_NONINDEXED_ADDRESS (X, ADDR);					\
+   if (GET_CODE (X) == PLUS)						\
+     { xfoo = XEXP (X, 0);						\
+       if (INDEX_TERM_P (xfoo, MODE))					\
+ 	{ GO_IF_NONINDEXED_ADDRESS (XEXP (X, 1), ADDR); }		\
+       xfoo = XEXP (X, 1);						\
+       if (INDEX_TERM_P (xfoo, MODE))					\
+ 	{ GO_IF_NONINDEXED_ADDRESS (XEXP (X, 0), ADDR); }		\
+       if (CONSTANT_ADDRESS_P (XEXP (X, 0)))				\
+ 	{ if (GET_CODE (XEXP (X, 1)) == REG				\
+ 	      && REG_OK_FOR_BASE_P (XEXP (X, 1)))			\
+ 	    goto ADDR;							\
+ 	  GO_IF_REG_PLUS_INDEX (XEXP (X, 1), MODE, ADDR); }		\
+       if (CONSTANT_ADDRESS_P (XEXP (X, 1)))				\
+ 	{ if (GET_CODE (XEXP (X, 0)) == REG				\
+ 	      && REG_OK_FOR_BASE_P (XEXP (X, 0)))			\
+ 	    goto ADDR;							\
+ 	  GO_IF_REG_PLUS_INDEX (XEXP (X, 0), MODE, ADDR); } } }
+ 
+ /* Register 16 can never be used for index or base */
+ 
+ #ifndef REG_OK_STRICT
+ #define REG_OK_FOR_INDEX_P(X) (REGNO(X) != 16)
+ #define REG_OK_FOR_BASE_P(X) (REGNO(X) != 16)
+ #else
+ #define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
+ #define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
+ #endif
+ 
+ /* Addressing is too simple to allow optimizing here */
+ 
+ #define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)  {}
+ 
+ /* Post_inc and pre_dec always adds 4 */
+ 
+ #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL)	\
+  { if (GET_CODE(ADDR) == POST_INC || GET_CODE(ADDR) == PRE_DEC)		\
+        goto LABEL;							\
+    if (GET_CODE (ADDR) == PLUS)						\
+      { if (CONSTANT_ADDRESS_P (XEXP (ADDR, 0))				\
+ 	   && GET_CODE (XEXP (ADDR, 1)) == REG);			\
+        else if (CONSTANT_ADDRESS_P (XEXP (ADDR, 1))			\
+ 		&& GET_CODE (XEXP (ADDR, 0)) == REG);			\
+        else goto LABEL; }}
+ 
+ /* Double's are not legitimate as immediate operands */
+ 
+ #define LEGITIMATE_CONSTANT_P(X) \
+   (GET_CODE (X) != CONST_DOUBLE)
+ 
+ 
+ /*
+  * Miscellaneous Parameters
+  */
+ 
+ /* the elements in the case jump table are all words */
+ 
+ #define CASE_VECTOR_MODE HImode
+ 
+ /* each of the table elements in a case are relative to the jump addess */
+ 
+ #define CASE_VECTOR_PC_RELATIVE
+ 
+ /* tahoe case instructions just fall through to the next instruction */
+ /* if not satisfied. It doesn't support a default action	     */
+ 
+ #define CASE_DROPS_THROUGH
+ 
+ /* the standard answer is given here and work ok */
+ 
+ #define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
+ 
+ /* in a general div case, it's easiest to use TRUNC_DIV_EXPR */
+ 
+ #define EASY_DIV_EXPR TRUNC_DIV_EXPR
+ 
+ /* the standard seems to be leaving char's as signed so we left it */
+ /* this way even though we think they should be unsigned!	   */
+ 
+ #define DEFAULT_SIGNED_CHAR 1
+ 
+ /* the most we can move without cutting down speed is 4 bytes */
+ 
+ #define MOVE_MAX 4
+ 
+ /* our int is 32 bits */
+ 
+ #define INT_TYPE_SIZE 32
+ 
+ /* byte access isn't really slower than anything else */
+ 
+ #define SLOW_BYTE_ACCESS 0
+ 
+ /* zero extension is more than one instruction so try to avoid it */
+ 
+ #define SLOW_ZERO_EXTEND
+ 
+ /* any bits higher than the low 4 are ignored in the shift count */
+ /* so don't bother zero extending or sign extending them         */
+ 
+ #define SHIFT_COUNT_TRUNCATED
+ 
+ /* we don't need to officially convert from one fixed type to another */
+ /* in order to use it as that type. We can just assume it's the same  */
+ 
+ #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
+ 
+ /* pass chars as ints */
+ 
+ #define PROMOTE_PROTOTYPES
+ 
+ /* pointers can be represented by an si mode expression */
+ 
+ #define Pmode SImode
+ 
+ /* function addresses are made by specifying a byte address */
+ 
+ #define FUNCTION_MODE QImode
+ 
+ /* all the costs here were borrowed from the vax version of the */
+ /* tm file. They're pretty much the same in the tahoe           */
+ 
+ #define CONST_COSTS(RTX,CODE) \
+   case CONST_INT:						\
+     if (RTX == const0_rtx) return 0;				\
+     if ((unsigned) INTVAL (RTX) < 077) return 1;		\
+   case CONST:							\
+   case LABEL_REF:						\
+   case SYMBOL_REF:						\
+     return 3;							\
+   case CONST_DOUBLE:						\
+     return 5;
+ 
+ 
+ /*
+  * Condition Code Information
+  */
+ 
+ /* Condition codes still break in one case that we haven't tracked */
+ /* down yet, so we have to leave them like this for now.	   */
+ 
+ #define NOTICE_UPDATE_CC(EXP, INSN) \
+ { if (GET_CODE(EXP) == SET && GET_CODE(SET_DEST(EXP)) == CC0) {		\
+ 	cc_status.flags = 0;					\
+ 	cc_status.value1 = SET_DEST(EXP);			\
+ 	cc_status.value2 = SET_SRC(EXP);			\
+   } else							\
+ 	CC_STATUS_INIT; }
+ 
+ 
+ /*
+  * Output of Assembler Code
+  */
+ 
+ /* start the assembly by turning off APP */
+ 
+ #define ASM_FILE_START(FILE) fprintf (FILE, "#NO_APP\n\n");
+ 
+ /* the instruction that turns on the APP for the gnu assembler */
+ 
+ #define ASM_APP_ON "#APP\n"
+ 
+ /* the instruction that turns off the APP for the gnu assembler */
+ 
+ #define ASM_APP_OFF "#NO_APP\n"
+ 
+ /* what to output before read-only data.  */
+ 
+ #define TEXT_SECTION_ASM_OP ".text"
+ 
+ /* what to output before writable data.  */
+ 
+ #define DATA_SECTION_ASM_OP ".data"
+ 
+ /* this is what we call each of the regs. notice that the FPP reg is   */
+ /* called "ac". This should never get used due to the way we've set    */
+ /* up FPP instructions in the md file. But we call it "ac" here to     */
+ /* fill the list.						       */
+ 
+ #define REGISTER_NAMES \
+ {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", \
+  "r9", "r10", "r11", "r12", "fp", "sp", "pc", "ac"}
+ 
+ /* registers are called the same thing in dbx anything else */
+ 
+ #define DBX_REGISTER_NUMBER(REGNO) (REGNO)
+ 
+ /* allow generation of dbx info in the assembly */
+ 
+ #define DBX_DEBUGGING_INFO
+ 
+ /* our dbx doesn't support this */
+ 
+ #define DBX_NO_XREFS
+ 
+ /* we don't want symbols broken up */
+ 
+ #define DBX_CONTIN_LENGTH 0
+ 
+ /* this'll really never be used, but we'll leave it at this */
+ 
+ #define DBX_CONTIN_CHAR '?'
+ 
+ /* labels are the label followed by a colon and a newline */
+ /* must be a statement, so surround it in a null loop     */
+ 
+ #define ASM_OUTPUT_LABEL(FILE,NAME)	\
+   do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0)
+ 
+ /* use the .globl directive to make labels global for the linker */
+ 
+ #define ASM_GLOBALIZE_LABEL(FILE,NAME)	\
+   do { fputs (".globl ", FILE); assemble_name (FILE, NAME); fputs ("\n", FILE);} while (0)
+ 
+ /* output a label by appending an underscore to it */
+ 
+ #define ASM_OUTPUT_LABELREF(FILE,NAME)	\
+   fprintf (FILE, "_%s", NAME)
+ 
+ /* use the standard format for printing internal labels */
+ 
+ #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)	\
+   fprintf (FILE, "%s%d:\n", PREFIX, NUM)
+ 
+ /* a * is used for label indirection in unix assembly */
+ 
+ #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)	\
+   sprintf (LABEL, "*%s%d", PREFIX, NUM)
+ 
+ /* outputing a double is easy cause we only have one kind */
+ 
+ #define ASM_OUTPUT_DOUBLE(FILE,VALUE)  \
+ {							\
+   union { int i[2]; double d;} temp;			\
+   temp.d = (VALUE);					\
+   if (TARGET_HEX_FLOAT)					\
+     fprintf ((FILE), "\t.long 0x%x,0x%x  # %.20e\n",	\
+ 	     temp.i[0], temp.i[1], temp.d);		\
+   else							\
+     fprintf (FILE, "\t.dfloat 0d%.20e\n", temp.d);	\
+ }
+ 
+ /* This is how to output an assembler line defining a `float' constant.  */
+ 
+ #define ASM_OUTPUT_FLOAT(FILE,VALUE)  \
+ {							\
+   union { int i; float f;} temp;			\
+   temp.f = (float) (VALUE);				\
+   if (TARGET_HEX_FLOAT)					\
+     fprintf ((FILE), "\t.long 0x%x  # %.20e\n",		\
+ 	     temp.i, temp.f);				\
+   else							\
+     fprintf (FILE, "\t.float 0f%.20e\n", temp.f);	\
+ }
+ 
+ /* This is how to output an assembler line defining an `int' constant.  */
+ 
+ #define ASM_OUTPUT_INT(FILE,VALUE)  \
+ ( fprintf (FILE, "\t.long "),			\
+   output_addr_const (FILE, (VALUE)),		\
+   fprintf (FILE, "\n"))
+ 
+ /* Likewise for `char' and `short' constants.  */
+ 
+ #define ASM_OUTPUT_SHORT(FILE,VALUE)  \
+ ( fprintf (FILE, "\t.word "),			\
+   output_addr_const (FILE, (VALUE)),		\
+   fprintf (FILE, "\n"))
+ 
+ #define ASM_OUTPUT_CHAR(FILE,VALUE)  \
+ ( fprintf (FILE, "\t.byte "),			\
+   output_addr_const (FILE, (VALUE)),		\
+   fprintf (FILE, "\n"))
+ 
+ /* This is how to output an assembler line for a numeric constant byte.  */
+ 
+ #define ASM_OUTPUT_BYTE(FILE,VALUE)  \
+   fprintf (FILE, "\t.byte 0x%x\n", (VALUE))
+ 
+ /* this is the insn to push a register onto the stack */
+ 
+ #define ASM_OUTPUT_REG_PUSH(FILE,REGNO)	\
+   fprintf (FILE, "\tpushl %s\n", reg_names[REGNO])
+ 
+ /* this is the insn to pop a register from the stack */
+ 
+ #define ASM_OUTPUT_REG_POP(FILE,REGNO)	\
+   fprintf (FILE, "\tmovl (sp)+,%s\n", reg_names[REGNO])
+ 
+ /* this is required even thought tahoe doesn't support it */
+ /* cause the C code expects it to be defined		  */
+ 
+ #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)  \
+   fprintf (FILE, "\t.long L%d\n", VALUE)
+ 
+ /* This is how to output an element of a case-vector that is relative.  */
+ 
+ #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL)  \
+   fprintf (FILE, "\t.word L%d-L%d\n", VALUE, REL)
+ 
+ /* This aligns the assembler output */
+ 
+ #define ASM_OUTPUT_ALIGN(FILE,LOG)  \
+   LOG ? fprintf (FILE, "\t.align %d\n", (LOG)) : 0
+ 
+ /* This is how to skip over some space */
+ 
+ #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
+   fprintf (FILE, "\t.space %d\n", (SIZE))
+ 
+ /* This defines common variables across files */
+ 
+ #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)  \
+ ( fputs (".comm ", (FILE)),			\
+   assemble_name ((FILE), (NAME)),		\
+   fprintf ((FILE), ",%d\n", (ROUNDED)))
+ 
+ /* This defines a common varible in the local file */
+ 
+ #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)  \
+ ( fputs (".lcomm ", (FILE)),			\
+   assemble_name ((FILE), (NAME)),		\
+   fprintf ((FILE), ",%d\n", (ROUNDED)))
+ 
+ /* code to generate a label */
+ 
+ #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)	\
+ ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10),	\
+   sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
+ 
+ /* parenthesis for expressions in the assembly */
+ 
+ #define ASM_OPEN_PAREN "("
+ #define ASM_CLOSE_PAREN ")"
+ 
+ /* Define results of standard character escape sequences.  */
+ 
+ #define TARGET_BELL 007
+ #define TARGET_BS 010
+ #define TARGET_TAB 011
+ #define TARGET_NEWLINE 012
+ #define TARGET_VT 013
+ #define TARGET_FF 014
+ #define TARGET_CR 015
+ 
+ /* Print an operand.  Some difference from the vax code,
+    since the tahoe can't support immediate floats and doubles.
+ 
+    %@ means print the proper alignment operand for aligning after a casesi.
+    This depends on the assembler syntax.
+    This is 1 for our assembler, since .align is logarithmic.  */
+ 
+ #define PRINT_OPERAND_PUNCT_VALID_P(CODE)				\
+   ((CODE) == '@')
+ 
+ #define PRINT_OPERAND(FILE, X, CODE)  \
+ { if (CODE == '@')							\
+     putc ('1', FILE);							\
+   else if (GET_CODE (X) == REG)						\
+     fprintf (FILE, "%s", reg_names[REGNO (X)]);				\
+   else if (GET_CODE (X) == MEM)						\
+     output_address (XEXP (X, 0));					\
+   else { putc ('$', FILE); output_addr_const (FILE, X); }}
+ 
+ /* When the operand is an address, call print_operand_address to */
+ /* do the work from output-tahoe.c.				 */
+ 
+ #define PRINT_OPERAND_ADDRESS(FILE, ADDR)  \
+  print_operand_address (FILE, ADDR)
+ 
diff -rc2N gcc-1.35/config/tm-vax.h gcc-1.36/config/tm-vax.h
*** gcc-1.35/config/tm-vax.h	Wed Mar 29 17:48:18 1989
--- gcc-1.36/config/tm-vax.h	Thu Sep 21 15:03:05 1989
***************
*** 280,283 ****
--- 280,287 ----
  #define STACK_GROWS_DOWNWARD
  
+ /* Define this if longjmp restores from saved registers
+    rather than from what setjmp saved.  */
+ #define LONGJMP_RESTORE_FROM_STACK
+ 
  /* Define this if the nominal address of the stack frame
     is at the high-address end of the local variables;
***************
*** 841,844 ****
--- 845,851 ----
  #define DBX_NO_XREFS
  
+ /* Output the .stabs for a C `static' variable in the data section.  */
+ #define DBX_STATIC_STAB_DATA_SECTION
+ 
  /* Vax specific: which type character is used for type double?  */
  
***************
*** 994,997 ****
--- 1001,1007 ----
     `d' or `g' should be printed, depending on whether we're using dfloat
     or gfloat.  */
+ 
+ #define PRINT_OPERAND_PUNCT_VALID_P(CODE)				\
+   ((CODE) == '#')
  
  #define PRINT_OPERAND(FILE, X, CODE)  \
diff -rc2N gcc-1.35/config/tm.h gcc-1.36/config/tm.h
*** gcc-1.35/config/tm.h	Thu Apr  6 16:59:48 1989
--- gcc-1.36/config/tm.h	Wed Dec 31 19:00:00 1969
***************
*** 1,5 ****
- /* This is needed when one xm- file includes another;
-    then the xm- file that includes tm.h is found explicitly in `config'
-    and therefore will only look in `config'.  */
- 
- #include "../tm.h"
--- 0 ----
diff -rc2N gcc-1.35/config/vax.md gcc-1.36/config/vax.md
*** gcc-1.35/config/vax.md	Wed Feb 22 12:31:02 1989
--- gcc-1.36/config/vax.md	Wed Sep  6 03:44:59 1989
***************
*** 62,65 ****
--- 62,67 ----
    "tstf %0")
  
+ ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
+ 
  (define_insn "cmpsi"
    [(set (cc0)
***************
*** 1153,1157 ****
    else
      operands[0]
!       = adj_offsetable_operand (operands[0], INTVAL (operands[2]) / 8);
  
    if (INTVAL (operands[1]) == 8)
--- 1155,1159 ----
    else
      operands[0]
!       = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8);
  
    if (INTVAL (operands[1]) == 8)
***************
*** 1180,1184 ****
    else
      operands[1]
!       = adj_offsetable_operand (operands[1], INTVAL (operands[3]) / 8);
  
    if (INTVAL (operands[2]) == 8)
--- 1182,1186 ----
    else
      operands[1]
!       = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
  
    if (INTVAL (operands[2]) == 8)
***************
*** 1207,1211 ****
    else
      operands[1]
!       = adj_offsetable_operand (operands[1], INTVAL (operands[3]) / 8);
  
    if (INTVAL (operands[2]) == 8)
--- 1209,1213 ----
    else
      operands[1]
!       = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);
  
    if (INTVAL (operands[2]) == 8)
***************
*** 1218,1222 ****
  (define_insn ""
    [(set (cc0)
! 	(minus
  	 (sign_extract:SI (match_operand:SI 0 "general_operand" "r")
  			  (match_operand:SI 1 "general_operand" "g")
--- 1220,1224 ----
  (define_insn ""
    [(set (cc0)
! 	(compare
  	 (sign_extract:SI (match_operand:SI 0 "general_operand" "r")
  			  (match_operand:SI 1 "general_operand" "g")
***************
*** 1228,1232 ****
  (define_insn ""
    [(set (cc0)
! 	(minus
  	 (zero_extract:SI (match_operand:SI 0 "general_operand" "r")
  			  (match_operand:SI 1 "general_operand" "g")
--- 1230,1234 ----
  (define_insn ""
    [(set (cc0)
! 	(compare
  	 (zero_extract:SI (match_operand:SI 0 "general_operand" "r")
  			  (match_operand:SI 1 "general_operand" "g")
***************
*** 1258,1262 ****
  (define_insn ""
    [(set (cc0)
! 	(minus
  	 (sign_extract:SI (match_operand:QI 0 "nonimmediate_operand" "rm")
  			  (match_operand:SI 1 "general_operand" "g")
--- 1260,1264 ----
  (define_insn ""
    [(set (cc0)
! 	(compare
  	 (sign_extract:SI (match_operand:QI 0 "nonimmediate_operand" "rm")
  			  (match_operand:SI 1 "general_operand" "g")
***************
*** 1268,1272 ****
  (define_insn ""
    [(set (cc0)
! 	(minus
  	 (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "rm")
  			  (match_operand:SI 1 "general_operand" "g")
--- 1270,1274 ----
  (define_insn ""
    [(set (cc0)
! 	(compare
  	 (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "rm")
  			  (match_operand:SI 1 "general_operand" "g")
***************
*** 1932,1936 ****
  
  (define_insn "call_value"
!   [(set (match_operand 0 "" "g")
  	(call (match_operand:QI 1 "general_operand" "g")
  	      (match_operand:QI 2 "general_operand" "g")))]
--- 1934,1938 ----
  
  (define_insn "call_value"
!   [(set (match_operand 0 "" "=g")
  	(call (match_operand:QI 1 "general_operand" "g")
  	      (match_operand:QI 2 "general_operand" "g")))]
***************
*** 1949,1952 ****
--- 1951,1959 ----
    "ret")
  
+ (define_insn "nop"
+   [(const_int 0)]
+   ""
+   "nop")
+ 
  (define_insn "casesi"
    [(set (pc)
***************
*** 1990,1993 ****
--- 1997,2010 ----
    ""
    "casel %0,$0,%1")
+ 
+ ;; This arises from casesi if operand 0 is a constant, in range.
+ (define_insn ""
+   [(set (pc)
+ 	(plus:SI (sign_extend:SI
+ 		  (mem:HI (plus:SI (pc)
+ 				   (match_operand:SI 0 "general_operand" "g"))))
+ 		 (label_ref:SI (match_operand 3 "" ""))))]
+   ""
+   "casel %0,$0,%0")
  \f


  ;;- load or push effective address 
diff -rc2N gcc-1.35/config/xm-aix386.h gcc-1.36/config/xm-aix386.h
*** gcc-1.35/config/xm-aix386.h	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config/xm-aix386.h	Fri Aug  4 17:30:51 1989
***************
*** 0 ****
--- 1,47 ----
+ /* Configuration for GNU C-compiler for IBM PS/2 running AIX/386.
+    Copyright (C) 1988 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+ 
+ 
+ /* #defines that need visibility everywhere.  */
+ #define FALSE 0
+ #define TRUE 1
+ 
+ /* This describes the machine the compiler is hosted on.  */
+ #define HOST_BITS_PER_CHAR 8
+ #define HOST_BITS_PER_SHORT 16
+ #define HOST_BITS_PER_INT 32
+ #define HOST_BITS_PER_LONG 32
+ 
+ /* Arguments to use with `exit'.  */
+ #define SUCCESS_EXIT_CODE 0
+ #define FATAL_EXIT_CODE 33
+ 
+ #define USG
+ 
+ /* target machine dependencies.
+    tm.h is a symbolic link to the actual target specific file.   */
+ #include "tm.h"
+ 
+ #define bcopy(a,b,c) memcpy (b,a,c)
+ #define bzero(a,b) memset (a,0,b)
+ #define bcmp(a,b,c) memcmp (a,b,c)
+ 
+ #ifdef __GNUC__
+ #define alloca(n) __builtin_alloca(n)
+ #endif
diff -rc2N gcc-1.35/config/xm-alliant.h gcc-1.36/config/xm-alliant.h
*** gcc-1.35/config/xm-alliant.h	Wed Feb 22 12:27:06 1989
--- gcc-1.36/config/xm-alliant.h	Tue May 23 15:59:14 1989
***************
*** 1,3 ****
! /* Configuration for GNU C-compiler for Alliant computer.
     Copyright (C) 1989 Free Software Foundation, Inc.
  
--- 1,3 ----
! /* Configuration for GNU C-compiler for Alliant FX computers.
     Copyright (C) 1989 Free Software Foundation, Inc.
  
***************
*** 41,42 ****
--- 41,48 ----
  #define alloca __builtin_alloca
  #endif
+ 
+ /* Make the linker remove temporary labels, since the Alliant assembler
+    doesn't.  */
+ 
+ #define LINK_SPEC "-X"
+ 
diff -rc2N gcc-1.35/config/xm-iris.h gcc-1.36/config/xm-iris.h
*** gcc-1.35/config/xm-iris.h	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config/xm-iris.h	Mon Jul 24 17:58:12 1989
***************
*** 0 ****
--- 1,11 ----
+ #include "xm-mips.h"
+ 
+ #define USG
+ 
+ #define bcopy(a,b,c) memcpy (b,a,c)
+ #define bzero(a,b) memset (a,0,b)
+ #define bcmp(a,b,c) memcmp (a,b,c)
+ 
+ #ifdef __GNUC__
+ #define alloca(n) __builtin_alloca(n)
+ #endif
diff -rc2N gcc-1.35/config/xm-pyr.h gcc-1.36/config/xm-pyr.h
*** gcc-1.35/config/xm-pyr.h	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config/xm-pyr.h	Sun Sep 17 04:13:20 1989
***************
*** 0 ****
--- 1,43 ----
+ /* Configuration for GNU compiler for Pyramid 90 Series.
+    Copyright (C) 1989 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+ 
+ /* xm-pyr.h -- based on xm-vax.h */
+ 
+ /* #defines that need visibility everywhere.  */
+ #define FALSE 0
+ #define TRUE 1
+ 
+ /* target machine dependencies.
+    tm.h is a symbolic link to the actual target specific file.   */
+ #include "tm.h"
+ 
+ /* This describes the machine the compiler is hosted on.  */
+ #define HOST_BITS_PER_CHAR 8
+ #define HOST_BITS_PER_SHORT 16
+ #define HOST_BITS_PER_INT 32
+ #define HOST_BITS_PER_LONG 32
+ 
+ /* Arguments to use with `exit'.  */
+ #define SUCCESS_EXIT_CODE 0
+ #define FATAL_EXIT_CODE 33
+ 
+ /* If compiled with GNU C, use the built-in alloca */
+ #ifdef __GNUC__
+ #define alloca __builtin_alloca
+ #endif
diff -rc2N gcc-1.35/config/xm-sunos4.h gcc-1.36/config/xm-sunos4.h
*** gcc-1.35/config/xm-sunos4.h	Wed Nov 23 02:15:40 1988
--- gcc-1.36/config/xm-sunos4.h	Wed Dec 31 19:00:00 1969
***************
*** 1,14 ****
- /* Config file for running GCC on Sunos version 4.
-    This file is good for either a Sun 3 or a Sun 4 machine.  */
- 
- #ifdef sparc 
- #include "xm-sparc.h" 
- #else 
- #include "xm-m68k.h"
- #endif
- 
- /* Provide required defaults for linker -e and -d switches.
-    Also, it is hard to debug with shared libraries,
-    so don't use them if going to debug.  */
- 
- #define LINK_SPEC "%{!e*:-e start} -dc -dp %{g:-Bstatic} %{static:-Bstatic}"
--- 0 ----
diff -rc2N gcc-1.35/config/xm-tahoe.h gcc-1.36/config/xm-tahoe.h
*** gcc-1.35/config/xm-tahoe.h	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config/xm-tahoe.h	Tue May 16 16:24:35 1989
***************
*** 0 ****
--- 1,57 ----
+ /* Configuration for GNU C-compiler for Tahoe.
+    Copyright (C) 1987 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+ 
+ /*
+  * File: xm-tahoe.h
+  *
+  * This port made at the University of Buffalo by Devon Bowen,
+  * Dale Wiles and Kevin Zachmann.
+  *
+  * Mail bugs reports or fixes to:	gcc@cs.buffalo.edu
+  */
+ 
+ 
+ /* This file has the same stuff the vax version does */
+ 
+ /* defines that need visibility everywhere */
+ 
+ #define FALSE 0
+ #define TRUE 1
+ 
+ /* target machine dependencies */
+ 
+ #include "tm.h"
+ 
+ /* This describes the machine the compiler is hosted on.  */
+ 
+ #define HOST_BITS_PER_CHAR 8
+ #define HOST_BITS_PER_SHORT 16
+ #define HOST_BITS_PER_INT 32
+ #define HOST_BITS_PER_LONG 32
+ 
+ /* Arguments to use with `exit'.  */
+ 
+ #define SUCCESS_EXIT_CODE 0
+ #define FATAL_EXIT_CODE 33
+ 
+ /* use built in alloca if gcc compiled */
+ 
+ #ifdef __GNUC__
+ #define alloca __builtin_alloca
+ #endif
diff -rc2N gcc-1.35/config/xm-vms.h gcc-1.36/config/xm-vms.h
*** gcc-1.35/config/xm-vms.h	Wed Feb 22 12:26:49 1989
--- gcc-1.36/config/xm-vms.h	Thu Aug 31 15:26:37 1989
***************
*** 33,37 ****
  
  #define SUCCESS_EXIT_CODE 1
! #define FATAL_EXIT_CODE 0
  
  /* A couple of conditionals for execution machine are controlled here.  */
--- 33,38 ----
  
  #define SUCCESS_EXIT_CODE 1
! #define FATAL_EXIT_CODE (44 | 0x10000000)  /* Failure, and no DCL message.  */
! 
  
  /* A couple of conditionals for execution machine are controlled here.  */
diff -rc2N gcc-1.35/config-gcc.com gcc-1.36/config-gcc.com
*** gcc-1.35/config-gcc.com	Wed Dec 31 19:00:00 1969
--- gcc-1.36/config-gcc.com	Tue Jul 11 19:16:17 1989
***************
*** 0 ****
--- 1,26 ----
+ $ !
+ $ !	Set up to compile GCC on VMS
+ $ !
+ $ echo = "write sys$output"
+ $ !
+ $ if f$search("config.h") .nes. "" then delete config.h.*
+ $ copy [.config]xm-vms.h []config.h
+ $ echo "Linked `config.h' to `[.config]xm-vms.h'.
+ $ !
+ $ if f$search("tm.h") .nes. "" then delete tm.h.*
+ $ copy [.config]tm-vms.h []tm.h
+ $ echo "Linked `tm.h' to `[.config]tm-vms.h'.
+ $ !
+ $ if f$search("md.") .nes. "" then delete md..*
+ $ copy [.config]vax.md []md.
+ $ echo "Linked `md' to `[.config]vax.md'.
+ $ !
+ $ if f$search("aux-output.c") .nes. "" then delete aux-output.c.*
+ $ copy [.config]out-vax.c []aux-output.c
+ $ echo "Linked `aux-output.c' to `[.config]out-vax.c'.
+ $ !
+ $ if f$search("config.status") .nes. "" then delete config.status.*
+ $ open/write file config.status
+ $ write file "Links are now set up for use with a vax running VMS."
+ $ close file
+ $ type config.status
diff -rc2N gcc-1.35/config.gcc gcc-1.36/config.gcc
*** gcc-1.35/config.gcc	Fri Apr  7 11:56:55 1989
--- gcc-1.36/config.gcc	Sun Sep 24 00:13:11 1989
***************
*** 41,60 ****
  #symbolic_link="echo ln -s"
  
! case $# in
! 2)
  	vint=on
- 	shift
  	;;
! *)
  	;;
! esac
  
! case $# in
! 1)
! 	machine=$1
  
  	case $machine in
  	vax)					# for vaxen running bsd
  		;;
  	vms)					# for vaxen running VMS
  		cpu_type=vax
--- 41,91 ----
  #symbolic_link="echo ln -s"
  
! for arg in $*;
! do
!   case $arg in
!    -srcdir=*)
! 	srcdir=`echo $arg | sed s/-srcdir=//`
! 	;;
!    -vint)
  	vint=on
  	;;
!    *)
! 	machine=$arg
  	;;
!   esac
! done
! 
! # Find the source files, if location was not specified.
! if [ x$srcdir = x ]
! then
! 	srcdirdefaulted=1
! 	srcdir=.
! 	if [ ! -r tree.c ]
! 	then
! 		srcdir=..
! 	fi
! fi
  
! if [ ! -r ${srcdir}/tree.c ]
! then
! 	if [ x$srcdirdefaulted = x ]
! 	then
! 	  echo "$progname: Can't find compiler sources in \`${srcdir}'." 1>&2
! 	else
! 	  echo "$progname: Can't find compiler sources in \`.' or \`..'." 1>&2
! 	fi
! 	exit 1
! fi
  
+ if [ x$machine != x ];
+ then
  	case $machine in
  	vax)					# for vaxen running bsd
  		;;
+         tahoe)                                  # for tahoe's running bsd
+                 ;;
+         harris)                                 # for harris tahoe, using COFF.
+ 		cpu_type=tahoe
+                 ;;
  	vms)					# for vaxen running VMS
  		cpu_type=vax
***************
*** 76,80 ****
  		cpu_type=i386
  		configuration_file=xm-${machine}.h
- 		target_machine=tm-${machine}.h
  		;;
  	i386-sysv-gas | i386g)
--- 107,110 ----
***************
*** 83,114 ****
  		target_machine=tm-i386gas.h
  		;;		
  	next )
  		cpu_type=m68k
- 		configuration_file=xm-m68k.h      
  		target_machine=tm-next.h
! 	;;
! 	sun4 | sun-4)
  		cpu_type=sparc
- 		configuration_file=xm-sparc.h
  		target_machine=tm-sun4os3.h
  		;;
! 	sun3 | sun-3)
! 		cpu_type=m68k
! 		configuration_file=xm-m68k.h
! 		target_machine=tm-sun3.h
! 		;;
! 	sun3-nfp | sun-3-nfp)
  		cpu_type=m68k
! 		configuration_file=xm-m68k.h
! 		target_machine=tm-sun3-nfp.h
  		;;
! 	sun3-fpa | sun-3-fpa)
  		cpu_type=m68k
! 		configuration_file=xm-m68k.h
! 		target_machine=tm-sun3-fpa.h
  		;;
! 	sun2 | sun-2)
  		cpu_type=m68k
- 		configuration_file=xm-m68k.h
  		target_machine=tm-sun2.h
  		;;
--- 113,141 ----
  		target_machine=tm-i386gas.h
  		;;		
+ 	i386-aix | ps2-aix | aix386 | ps2aix )		# for IBM PS/2 running AIX
+ 		machine=aix386
+ 		cpu_type=i386
+ 		configuration_file=xm-${machine}.h
+ 		;;
+ 	i860)
+ 		;;
  	next )
  		cpu_type=m68k
  		target_machine=tm-next.h
! 		;;
! 	sun4 | sun-4 | sun4-os3 | sun-4-os3)
  		cpu_type=sparc
  		target_machine=tm-sun4os3.h
  		;;
! 	sun3 | sun-3 | sun3-os3 | sun-3-os3)
  		cpu_type=m68k
! 		target_machine=tm-sun3os3.h
  		;;
! 	sun3-nfp | sun-3-nfp | sun3-nfp-os3 | sun-3-nfp-os3)
  		cpu_type=m68k
! 		target_machine=tm-sun3os3nf.h
  		;;
! 	sun2 | sun-2 | sun2-os3 | sun-2-os3)
  		cpu_type=m68k
  		target_machine=tm-sun2.h
  		;;
***************
*** 120,124 ****
  	sun4-os4 | sun-4-os4)
  		cpu_type=sparc
- 		configuration_file=xm-sunos4.h
  		target_machine=tm-sparc.h
  		;;
--- 147,150 ----
***************
*** 125,129 ****
  	sun3-os4 | sun-3-os4)
  		cpu_type=m68k
- 		configuration_file=xm-sunos4.h
  		target_machine=tm-sun3.h
  		;;
--- 151,154 ----
***************
*** 130,144 ****
  	sun3-nfp-os4 | sun-3-nfp-os4)
  		cpu_type=m68k
- 		configuration_file=xm-sunos4.h
  		target_machine=tm-sun3-nfp.h
  		;;
- 	sun3-fpa-os4 | sun-3-fpa-os4)
- 		cpu_type=m68k
- 		configuration_file=xm-sunos4.h
- 		target_machine=tm-sun3-fpa.h
- 		;;
  	sun2-os4 |sun-2-os4)
  		cpu_type=m68k
- 		configuration_file=xm-sunos4.h
  		target_machine=tm-sun2.h
  		;;
--- 155,162 ----
***************
*** 147,159 ****
  		configuration_file=xm-hp9k320.h
  		;;
  	hp9k320-gas | hp9k320g)		#    with gnu as, ld and gdb
  		cpu_type=m68k
  		configuration_file=xm-hp9k320.h
  		;;
  	isi68)
  		cpu_type=m68k
  		;;
  	news | news800)
! 	        configuration_file=xm-news.h
  	        target_machine=tm-news.h
  		cpu_type=m68k
--- 165,190 ----
  		configuration_file=xm-hp9k320.h
  		;;
+ 	hp9k320-old)			# HP 9000 series 300 with gcc alone
+ 		cpu_type=m68k
+ 		target_machine=tm-hp9k32old.h
+ 		configuration_file=xm-hp9k320.h
+ 		;;
  	hp9k320-gas | hp9k320g)		#    with gnu as, ld and gdb
  		cpu_type=m68k
  		configuration_file=xm-hp9k320.h
+ 		target_machine=tm-hp9k320g.h
  		;;
+ 	hp9k320-bsd)			# HP 9000/3xx running Berkeley Unix
+ 		cpu_type=m68k
+ 		target_machine=tm-hp9k3bsd.h
+ 		;;
  	isi68)
  		cpu_type=m68k
  		;;
+ 	isi68-nfp)
+ 		cpu_type=m68k
+ 		;;
  	news | news800)
! 	        configuration_file=xm-m68k.h
  	        target_machine=tm-news.h
  		cpu_type=m68k
***************
*** 160,164 ****
  		;;
  	news-gas | news-g)
! 	        configuration_file=xm-news.h
  	        target_machine=tm-newsgas.h
  		cpu_type=m68k
--- 191,195 ----
  		;;
  	news-gas | news-g)
! 	        configuration_file=xm-m68k.h
  	        target_machine=tm-newsgas.h
  		cpu_type=m68k
***************
*** 174,183 ****
  		;;
  	sequent-ns32k | sequent)
  		cpu_type=ns32k
- 		aux_output=out-ns32k.c
  		;;
  	encore)
  		cpu_type=ns32k
- 		aux_output=out-ns32k.c
  		;;
  	genix)
--- 205,213 ----
  		;;
  	sequent-ns32k | sequent)
+ 		machine=sequent
  		cpu_type=ns32k
  		;;
  	encore)
  		cpu_type=ns32k
  		;;
  	genix)
***************
*** 184,188 ****
  		machine=ns32k
  		cpu_type=ns32k
! 		configuration_file=xm-gnx.h
  		;;
  	88000)
--- 214,218 ----
  		machine=ns32k
  		cpu_type=ns32k
! 		configuration_file=xm-genix.h
  		;;
  	88000)
***************
*** 200,205 ****
  		cpu_type=convex
  		;;
! 	mips)
! 		machine=mips
  		;;
  #	370)
--- 230,256 ----
  		cpu_type=convex
  		;;
! 	iris)					# Mostly like a MIPS.
! 		cpu_type=mips
! 		target_machine=tm-iris.h
! 		configuration_file=xm-iris.h
! 		;;
! 	mips)				# Default MIPS environment
! 		;;
! 	mips-sysv)			# SYSV variant of MIPS system.
! 		cpu_type=mips
! 		target_machine=tm-mips-sysv.h
! 	        ;;
! 	mips-bsd43)			# BSD 4.3 variant of MIPS system.
! 		cpu_type=mips
! 		target_machine=tm-mips-bsd.h
! 	        ;;
! 	dec-3100 | decstation)		# Decstation or pmax.
! 		cpu_type=mips
! 		target_machine=tm-decstatn.h
! 	        ;;
! 	apollo68)
! 		cpu_type=m68k
! 		;;
! 	pyr | pyramid)
  		;;
  #	370)
***************
*** 233,240 ****
  		set $links; link=$1; shift; links=$*
  
! 		if [ ! -r config/$file ]
  		then
! 			echo "$progname: cannot create a link \`$link',"
! 			echo "since the file \`config/$file' does not exist."
  			exit 1
  		fi
--- 284,291 ----
  		set $links; link=$1; shift; links=$*
  
! 		if [ ! -r ${srcdir}/config/$file ]
  		then
! 			echo "$progname: cannot create a link \`$link'," 1>&2
! 			echo "since the file \`config/$file' does not exist." 1>&2
  			exit 1
  		fi
***************
*** 243,254 ****
  		rm -f config.status
  		# Make a symlink if possible, otherwise try a hard link
! 		$symbolic_link config/$file $link 2>/dev/null || $hard_link config/$file $link
  
  		if [ ! -r $link ]
  		then
! 			echo "$progname: unable to link \`$link' to \`config/$file'."
  			exit 1
  		fi
! 		echo "Linked \`$link' to \`config/$file'."
  	done
  
--- 294,305 ----
  		rm -f config.status
  		# Make a symlink if possible, otherwise try a hard link
! 		$symbolic_link ${srcdir}/config/$file $link 2>/dev/null || $hard_link ${srcdir}/config/$file $link
  
  		if [ ! -r $link ]
  		then
! 			echo "$progname: unable to link \`$link' to \`${srcdir}/config/$file'." 1>&2
  			exit 1
  		fi
! 		echo "Linked \`$link' to \`${srcdir}/config/$file'."
  	done
  
***************
*** 261,268 ****
  			| tee config.status
  	fi
- 	exit 0
  
! 	;;
! *)
  	echo "Usage: $progname machine"
  	echo -n "Where \`machine' is something like "
--- 312,335 ----
  			| tee config.status
  	fi
  
! 	# Install a makefile, and make it set VPATH
! 	# if necessary so that the sources are found.
! 	# Also change its value of srcdir.
! 	# Also create a .gdbinit file which runs the one in srcdir
! 	# and tells GDB to look there for source files.
! 	case $srcdir in
! 	.)
! 		;;
! 	*)
! 		echo "VPATH = ${srcdir}" > x
! 		cat x ${srcdir}/Makefile | sed "s@^srcdir = \.@srcdir = ${srcdir}@" > Makefile
! 		rm x
! 		echo "dir ${srcdir}" > .gdbinit
! 		echo "source ${srcdir}/.gdbinit" >> .gdbinit
! 		;;
! 	esac
! 
! 	exit 0
! else
  	echo "Usage: $progname machine"
  	echo -n "Where \`machine' is something like "
***************
*** 273,276 ****
  	fi
  	exit 1
! 	;;
! esac
--- 340,342 ----
  	fi
  	exit 1
! fi
diff -rc2N gcc-1.35/cpp.texinfo gcc-1.36/cpp.texinfo
*** gcc-1.35/cpp.texinfo	Sat Apr 22 00:02:48 1989
--- gcc-1.36/cpp.texinfo	Thu Sep 21 23:29:56 1989
***************
*** 302,311 ****
  @item #include "@var{file}"
  This variant is used for header files of your own program.  It
! searches for a file named @var{file} first in the current
! directory, then in the same directories used for system header
! files.  The current directory is tried first because it is
! presumed to be the location of the files of the program being
! compiled.  (If the @samp{-I-} option is used, the special treatment
! of the current directory is inhibited.)
  
  The argument @var{file} may not contain @samp{"} characters.  If
--- 302,311 ----
  @item #include "@var{file}"
  This variant is used for header files of your own program.  It
! searches for a file named @var{file} first in the current directory,
! then in the same directories used for system header files.  The
! current directory is the directory of the current input file.  It is
! tried first because it is presumed to be the location of the files
! that the current input file refers to.  (If the @samp{-I-} option is
! used, the special treatment of the current directory is inhibited.)
  
  The argument @var{file} may not contain @samp{"} characters.  If
***************
*** 2026,2036 ****
  
  @example
! # @var{linenum} @var{filename}
  @end example
  
  @noindent
! which are inserted as needed into the middle of the input (but never within
! a string or character constant).  Such a line means that the following line
! originated in file @var{filename} at line @var{linenum}.
  
  @node Invocation,, Output, Top
--- 2026,2041 ----
  
  @example
! # @var{linenum} @var{filename} @var{flag}
  @end example
  
  @noindent
! which are inserted as needed into the middle of the input (but never
! within a string or character constant).  Such a line means that the
! following line originated in file @var{filename} at line @var{linenum}.
! 
! The third field, @var{flag}, may be a number, or may be absent.  It is
! @samp{1} for the beginning of a new source file, and @samp{2} for return
! to an old source file at the end of an included file.  It is absent
! otherwise.
  
  @node Invocation,, Output, Top
diff -rc2N gcc-1.35/cse.c gcc-1.36/cse.c
*** gcc-1.35/cse.c	Wed Apr 12 23:08:43 1989
--- gcc-1.36/cse.c	Sat Sep 16 01:15:22 1989
***************
*** 207,210 ****
--- 207,216 ----
  static int prev_insn_cc0;
  
+ /* For machines where CC0 is one bit, we may see CC0 assigned a
+    constant value (after fold_rtx).
+    Record here the value stored in the previous insn (0 if none).  */
+ 
+ static rtx prev_insn_explicit_cc0;
+ 
  /* Previous actual insn.  0 if at first insn of basic block.  */
  
***************
*** 263,274 ****
  static int cse_skip_to_next_block;
  
! /* UID of insn that starts the basic block currently being cse-processed.  */
  
  static int cse_basic_block_start;
  
! /* UID of insn that ends the basic block currently being cse-processed.  */
  
  static int cse_basic_block_end;
  
  /* Nonzero if cse has altered conditional jump insns
     in such a way that jump optimization should be redone.  */
--- 269,290 ----
  static int cse_skip_to_next_block;
  
! /* CUID of insn that starts the basic block currently being cse-processed.  */
  
  static int cse_basic_block_start;
  
! /* CUID of insn that ends the basic block currently being cse-processed.  */
  
  static int cse_basic_block_end;
  
+ /* Vector mapping INSN_UIDs to cuids.
+    The cuids are like uids but increase monononically always.
+    We use them to see whether a reg is used outside a given basic block.  */
+ 
+ static short *uid_cuid;
+ 
+ /* Get the cuid of an insn.  */
+ 
+ #define INSN_CUID(INSN) (uid_cuid[INSN_UID (INSN)])
+ 
  /* Nonzero if cse has altered conditional jump insns
     in such a way that jump optimization should be redone.  */
***************
*** 490,493 ****
--- 506,510 ----
  
    prev_insn_cc0 = 0;
+   prev_insn_explicit_cc0 = 0;
    prev_insn = 0;
  }
***************
*** 530,536 ****
    if (new >= FIRST_PSEUDO_REGISTER
        && (firstr < FIRST_PSEUDO_REGISTER
! 	  || ((regno_last_uid[new] > cse_basic_block_end
! 	       || regno_first_uid[new] < cse_basic_block_start)
! 	      && regno_last_uid[new] > regno_last_uid[firstr])))
      {
        reg_prev_eqv[firstr] = new;
--- 547,554 ----
    if (new >= FIRST_PSEUDO_REGISTER
        && (firstr < FIRST_PSEUDO_REGISTER
! 	  || ((uid_cuid[regno_last_uid[new]] > cse_basic_block_end
! 	       || uid_cuid[regno_first_uid[new]] < cse_basic_block_start)
! 	      && (uid_cuid[regno_last_uid[new]]
! 		  > uid_cuid[regno_last_uid[firstr]]))))
      {
        reg_prev_eqv[firstr] = new;
***************
*** 898,905 ****
      ((X)->cost == (Y)->cost						\
       && GET_CODE ((X)->exp) == REG && GET_CODE ((Y)->exp) == REG	\
!      && (regno_last_uid[REGNO ((X)->exp)] > cse_basic_block_end		\
! 	 || regno_first_uid[REGNO ((X)->exp)] < cse_basic_block_start)	\
!      && (regno_last_uid[REGNO ((X)->exp)]				\
! 	 > regno_last_uid[REGNO ((Y)->exp)])))
  
  static struct table_elt *
--- 916,923 ----
      ((X)->cost == (Y)->cost						\
       && GET_CODE ((X)->exp) == REG && GET_CODE ((Y)->exp) == REG	\
!      && (uid_cuid[regno_last_uid[REGNO ((X)->exp)]] > cse_basic_block_end		\
! 	 || uid_cuid[regno_first_uid[REGNO ((X)->exp)]] < cse_basic_block_start)	\
!      && (uid_cuid[regno_last_uid[REGNO ((X)->exp)]]			\
! 	 > uid_cuid[regno_last_uid[REGNO ((Y)->exp)]])))
  
  static struct table_elt *
***************
*** 1402,1410 ****
  	{
  	  register char *p = XSTR (x, i);
! 	  while (*p)
! 	    {
! 	      register int tem = *p++;
! 	      hash += ((1 << HASHBITS) - 1) & (tem + (tem >> HASHBITS));
! 	    }
  	}
        else
--- 1420,1429 ----
  	{
  	  register char *p = XSTR (x, i);
! 	  if (p)
! 	    while (*p)
! 	      {
! 		register int tem = *p++;
! 		hash += ((1 << HASHBITS) - 1) & (tem + (tem >> HASHBITS));
! 	      }
  	}
        else
***************
*** 1498,1501 ****
--- 1517,1522 ----
  	{
  	  int j;
+ 	  if (XVECLEN (x, i) != XVECLEN (y, i))
+ 	    return 0;
  	  for (j = 0; j < XVECLEN (x, i); j++)
  	    if (! exp_equiv_p (XVECEXP (x, i, j), XVECEXP (y, i, j), validate))
***************
*** 1762,1765 ****
--- 1783,1787 ----
  
    width = GET_MODE_BITSIZE (GET_MODE (x));
+ 
    code = GET_CODE (x);
    switch (code)
***************
*** 1950,1954 ****
  #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
        else if (GET_CODE (const_arg0) == CONST_DOUBLE
! 	       && GET_CODE (x) == NEG)
  	{
  	  union real_extract u;
--- 1972,1977 ----
  #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
        else if (GET_CODE (const_arg0) == CONST_DOUBLE
! 	       && GET_CODE (x) == NEG
! 	       && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
  	{
  	  union real_extract u;
***************
*** 1967,1970 ****
--- 1990,1994 ----
      {
        register int arg0, arg1, arg0s, arg1s;
+       int arithwidth = width;
  
        /* If 1st arg is the condition codes, 2nd must be zero
***************
*** 1978,1982 ****
  	    arg0 = prev_insn_cc0;
  	  else
! 	    arg0 = fold_cc0 (XEXP (x, 0));
  
  	  if (arg0 == 0
--- 2002,2006 ----
  	    arg0 = prev_insn_cc0;
  	  else
! 	    arg0 = fold_cc0 (VOIDmode, XEXP (x, 0));
  
  	  if (arg0 == 0
***************
*** 2023,2026 ****
--- 2047,2053 ----
  	  /* Even if we can't compute a constant result,
  	     there are some cases worth simplifying.  */
+ 	  /* Note that we cannot rely on constant args to come last,
+ 	     even for commutative operators,
+ 	     because that happens only when the constant is explicit.  */
  	  switch (code)
  	    {
***************
*** 2112,2115 ****
--- 2139,2146 ----
  		  && GET_MODE (XEXP (x, 0)) == GET_MODE (x))
  		return gen_rtx (NEG, GET_MODE (x), XEXP (x, 0));
+ 	      if (const_arg0 && GET_CODE (const_arg0) == CONST_INT
+ 		  && INTVAL (const_arg0) == -1
+ 		  && GET_MODE (XEXP (x, 1)) == GET_MODE (x))
+ 		return gen_rtx (NEG, GET_MODE (x), XEXP (x, 1));
  	      if (const_arg1 == const0_rtx || const_arg0 == const0_rtx)
  		new = const0_rtx;
***************
*** 2133,2136 ****
--- 2164,2171 ----
  		      == GET_MODE_MASK (GET_MODE (x)))
  		new = const_arg1;
+ 	      if (const_arg0 && GET_CODE (const_arg0) == CONST_INT
+ 		  && (INTVAL (const_arg0) & GET_MODE_MASK (GET_MODE (x)))
+ 		      == GET_MODE_MASK (GET_MODE (x)))
+ 		new = const_arg0;
  	      break;
  
***************
*** 2144,2147 ****
--- 2179,2186 ----
  		      == GET_MODE_MASK (GET_MODE (x)))
  		return gen_rtx (NOT, GET_MODE (x), XEXP (x, 0));
+ 	      if (const_arg0 && GET_CODE (const_arg0) == CONST_INT
+ 		  && (INTVAL (const_arg0) & GET_MODE_MASK (GET_MODE (x)))
+ 		      == GET_MODE_MASK (GET_MODE (x)))
+ 		return gen_rtx (NOT, GET_MODE (x), XEXP (x, 1));
  	      break;
  
***************
*** 2153,2156 ****
--- 2192,2199 ----
  		      == GET_MODE_MASK (GET_MODE (x)))
  		return XEXP (x, 0);
+ 	      if (const_arg0 && GET_CODE (const_arg0) == CONST_INT
+ 		  && (INTVAL (const_arg0) & GET_MODE_MASK (GET_MODE (x)))
+ 		      == GET_MODE_MASK (GET_MODE (x)))
+ 		return XEXP (x, 1);
  	      break;
  
***************
*** 2187,2190 ****
--- 2230,2241 ----
  	}
  
+       if (arithwidth == 0)
+ 	{
+ 	  if (GET_MODE (XEXP (x, 0)) != VOIDmode)
+ 	    arithwidth = GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)));
+ 	  if (GET_MODE (XEXP (x, 1)) != VOIDmode)
+ 	    arithwidth = GET_MODE_BITSIZE (GET_MODE (XEXP (x, 1)));
+ 	}
+ 
        /* Get the integer argument values in two forms:
  	 zero-extended in ARG0, ARG1 and sign-extended in ARG0S, ARG1S.  */
***************
*** 2193,2208 ****
        arg1 = INTVAL (const_arg1);
  
!       if (width < HOST_BITS_PER_INT)
  	{
! 	  arg0 &= (1 << width) - 1;
! 	  arg1 &= (1 << width) - 1;
  
  	  arg0s = arg0;
! 	  if (arg0s & (1 << (width - 1)))
! 	    arg0s |= ((-1) << width);
  
  	  arg1s = arg1;
! 	  if (arg1s & (1 << (width - 1)))
! 	    arg1s |= ((-1) << width);
  	}
        else
--- 2244,2259 ----
        arg1 = INTVAL (const_arg1);
  
!       if (arithwidth < HOST_BITS_PER_INT && arithwidth > 0)
  	{
! 	  arg0 &= (1 << arithwidth) - 1;
! 	  arg1 &= (1 << arithwidth) - 1;
  
  	  arg0s = arg0;
! 	  if (arg0s & (1 << (arithwidth - 1)))
! 	    arg0s |= ((-1) << arithwidth);
  
  	  arg1s = arg1;
! 	  if (arg1s & (1 << (arithwidth - 1)))
! 	    arg1s |= ((-1) << arithwidth);
  	}
        else
***************
*** 2353,2356 ****
--- 2404,2410 ----
  	   && GET_CODE (const_arg0) == CONST_INT)
      return XEXP (x, ((INTVAL (const_arg0) != 0) ? 1 : 2));
+   else if (code == IF_THEN_ELSE && XEXP (x, 0) == cc0_rtx
+ 	   && prev_insn_explicit_cc0 != 0)
+     return XEXP (x, ((INTVAL (prev_insn_explicit_cc0) != 0) ? 1 : 2));
    else if (code == SIGN_EXTRACT || code == ZERO_EXTRACT)
      {
***************
*** 2388,2392 ****
       So we get either a reasonable negative value or a reasonable
       unsigned value for this mode.  */
!   if (width < HOST_BITS_PER_INT)
      {
        if ((val & ((-1) << (width - 1)))
--- 2442,2446 ----
       So we get either a reasonable negative value or a reasonable
       unsigned value for this mode.  */
!   if (width < HOST_BITS_PER_INT && width > 0)
      {
        if ((val & ((-1) << (width - 1)))
***************
*** 2444,2451 ****
     how the condition codes would be set by that expression.
     Return 0 if the value is not constant
!    or if there is any doubt what condition codes result from it.  */
  
  static int
! fold_cc0 (x)
       rtx x;
  {
--- 2498,2508 ----
     how the condition codes would be set by that expression.
     Return 0 if the value is not constant
!    or if there is any doubt what condition codes result from it.
! 
!    MODE is the machine mode to use to interpret X if it is a CONST_INT.  */
  
  static int
! fold_cc0 (mode, x)
!      enum machine_mode mode;
       rtx x;
  {
***************
*** 2527,2530 ****
--- 2584,2589 ----
  
      m = GET_MODE (y0);
+     if (m == VOIDmode)
+       m = mode;
  
      if (GET_CODE (y0) == REG)
***************
*** 2535,2538 ****
--- 2594,2601 ----
        return 0;
  
+     /* If we don't know the mode, we can't test the sign.  */
+     if (m == VOIDmode)
+       return 0;
+ 
      /* Value is frame-pointer plus a constant?  Or non-explicit constant?
         That isn't zero, but we don't know its sign.  */
***************
*** 2547,2560 ****
  
      s0 = u0 = INTVAL (y0);
!     if (m != VOIDmode)
!       {
! 	int width = GET_MODE_BITSIZE (m);
! 	if (width < HOST_BITS_PER_INT)
! 	  {
! 	    s0 = u0 &= ~ ((-1) << GET_MODE_BITSIZE (m));
! 	    if (u0 & (1 << (GET_MODE_BITSIZE (m) - 1)))
! 	      s0 |= ((-1) << GET_MODE_BITSIZE (m));
! 	  }
!       }
      return 0100 + ((s0 < 0 ? 7 : s0 > 0) << 3) + (u0 != 0);
    }
--- 2610,2622 ----
  
      s0 = u0 = INTVAL (y0);
!     {
!       int width = GET_MODE_BITSIZE (m);
!       if (width < HOST_BITS_PER_INT)
! 	{
! 	  s0 = u0 &= ~ ((-1) << GET_MODE_BITSIZE (m));
! 	  if (u0 & (1 << (GET_MODE_BITSIZE (m) - 1)))
! 	    s0 |= ((-1) << GET_MODE_BITSIZE (m));
! 	}
!     }
      return 0100 + ((s0 < 0 ? 7 : s0 > 0) << 3) + (u0 != 0);
    }
***************
*** 2595,2598 ****
--- 2657,2661 ----
       propagating constants, to see if result is determined.  */
    prev_insn_cc0 = 0;
+   prev_insn_explicit_cc0 = 0;
    /* Avoid infinite loop if we find a cycle of jumps.  */
    while (count < 10)
***************
*** 2617,2621 ****
  	       && SET_DEST (PATTERN (p)) == cc0_rtx)
  	{
! 	  prev_insn_cc0 = fold_cc0 (copy_rtx (SET_SRC (PATTERN (p))));
  	}
        else if (GET_CODE (p) == JUMP_INSN
--- 2680,2687 ----
  	       && SET_DEST (PATTERN (p)) == cc0_rtx)
  	{
! 	  prev_insn_cc0 = fold_cc0 (GET_MODE (SET_SRC (PATTERN (p))),
! 				    copy_rtx (SET_SRC (PATTERN (p))));
! 	  if (GET_CODE (SET_SRC (PATTERN (p))) == CONST_INT)
! 	    prev_insn_explicit_cc0 = SET_SRC (PATTERN (p));
  	}
        else if (GET_CODE (p) == JUMP_INSN
***************
*** 2688,2691 ****
--- 2754,2759 ----
    /* The SET_DEST, with SUBREG, etc., stripped.  */
    rtx inner_dest;
+   /* Place where the pointer to the INNER_DEST was found.  */
+   rtx *inner_dest_loc;
    /* Nonzero if the SET_SRC is in memory.  */ 
    char src_in_memory;
***************
*** 2695,2698 ****
--- 2763,2768 ----
       whose value cannot be predicted and understood.  */
    char src_volatile;
+   /* Original machine mode, in case it becomes a CONST_INT.  */
+   enum machine_mode mode;
  };
  
***************
*** 2708,2711 ****
--- 2778,2783 ----
       using same encoding used for prev_insn_cc0.  */
    int this_insn_cc0 = 0;
+   /* Likewise, what to store in prev_insn_explicit_cc0.  */
+   rtx this_insn_explicit_cc0 = 0;
    struct write_data writes_memory;
    static struct write_data init = {0, 0, 0};
***************
*** 2774,2777 ****
--- 2846,2863 ----
        sets = (struct set *) alloca (lim * sizeof (struct set));
  
+       /* Find all regs explicitly clobbered in this insn,
+ 	 and ensure they are not replaced with any other regs
+ 	 elsewhere in this insn.
+ 	 When a reg that is clobbered is also used for input,
+ 	 we should presume that that is for a reason,
+ 	 and we should not substitute some other register
+ 	 which is not supposed to be clobbered.  */
+       for (i = 0; i < lim; i++)
+ 	{
+ 	  register rtx y = XVECEXP (x, 0, i);
+ 	  if (GET_CODE (y) == CLOBBER && GET_CODE (XEXP (y, 0)) == REG)
+ 	    invalidate (XEXP (y, 0));
+ 	}
+ 	    
        for (i = 0; i < lim; i++)
  	{
***************
*** 2780,2784 ****
  	    sets[n_sets++].rtl = y;
  	  else if (GET_CODE (y) == CLOBBER)
! 	    note_mem_written (XEXP (y, 0), &writes_memory);
  	  else if (GET_CODE (y) == CALL)
  	    canon_reg (y);
--- 2866,2881 ----
  	    sets[n_sets++].rtl = y;
  	  else if (GET_CODE (y) == CLOBBER)
! 	    {
! 	      /* If we clobber memory, take note of that,
! 		 and canon the address.
! 		 This does nothing when a register is clobbered
! 		 because we have already invalidated the reg.  */
! 	      canon_reg (y);
! 	      note_mem_written (XEXP (y, 0), &writes_memory);
! 	    }
! 	  else if (GET_CODE (y) == USE
! 		   && ! (GET_CODE (XEXP (y, 0)) == REG
! 			 && REGNO (XEXP (y, 0)) < FIRST_PSEUDO_REGISTER))
! 	    canon_reg (y);
  	  else if (GET_CODE (y) == CALL)
  	    canon_reg (y);
***************
*** 2818,2821 ****
--- 2915,2919 ----
  
        mode = GET_MODE (src) == VOIDmode ? GET_MODE (dest) : GET_MODE (src);
+       sets[i].mode = mode;
  
        /* Replace each registers in SRC with oldest equivalent register,
***************
*** 3037,3040 ****
--- 3135,3139 ----
  
        do_not_record = 0;
+       sets[i].inner_dest_loc = &SET_DEST (sets[0].rtl);
  
        /* Look within any SIGN_EXTRACT or ZERO_EXTRACT
***************
*** 3047,3050 ****
--- 3146,3150 ----
  	      XEXP (dest, 1) = canon_reg (XEXP (dest, 1));
  	      XEXP (dest, 2) = canon_reg (XEXP (dest, 2));
+ 	      sets[i].inner_dest_loc = &XEXP (dest, 0);
  	      dest = XEXP (dest, 0);
  	    }
***************
*** 3051,3055 ****
  	  else if (GET_CODE (dest) == SUBREG
  		   || GET_CODE (dest) == STRICT_LOW_PART)
! 	    dest = XEXP (dest, 0);
  	  else
  	    break;
--- 3151,3158 ----
  	  else if (GET_CODE (dest) == SUBREG
  		   || GET_CODE (dest) == STRICT_LOW_PART)
! 	    {
! 	      sets[i].inner_dest_loc = &XEXP (dest, 0);
! 	      dest = XEXP (dest, 0);
! 	    }
  	  else
  	    break;
***************
*** 3125,3129 ****
  		      MEM_IN_STRUCT_P (dest)
  			= MEM_IN_STRUCT_P (sets[i].inner_dest);
! 		      SET_DEST (sets[i].rtl) = dest;
  		      sets[i].inner_dest = dest;
  		    }
--- 3228,3232 ----
  		      MEM_IN_STRUCT_P (dest)
  			= MEM_IN_STRUCT_P (sets[i].inner_dest);
! 		      *sets[i].inner_dest_loc = dest;
  		      sets[i].inner_dest = dest;
  		    }
***************
*** 3171,3175 ****
  	      || CONSTANT_P (src)
  	      || GET_CODE (src) == REG))
! 	this_insn_cc0 = fold_cc0 (src);
      }
  
--- 3274,3281 ----
  	      || CONSTANT_P (src)
  	      || GET_CODE (src) == REG))
! 	this_insn_cc0 = fold_cc0 (sets[i].mode, src);
! 
!       if (dest == cc0_rtx && GET_CODE (src) == CONST_INT)
! 	this_insn_explicit_cc0 = src;
      }
  
***************
*** 3364,3368 ****
  	  cse_jumps_altered = 1;
  	  /* If previous insn just set CC0 for us, delete it too.  */
! 	  if (prev_insn_cc0 != 0)
  	    {
  	      PUT_CODE (prev_insn, NOTE);
--- 3470,3474 ----
  	  cse_jumps_altered = 1;
  	  /* If previous insn just set CC0 for us, delete it too.  */
! 	  if (prev_insn_cc0 != 0 || prev_insn_explicit_cc0 != 0)
  	    {
  	      PUT_CODE (prev_insn, NOTE);
***************
*** 3370,3380 ****
  	      NOTE_SOURCE_FILE (prev_insn) = 0;
  	    }
  	}
        else if (GET_CODE (SET_SRC (x)) == LABEL_REF)
  	{
  	  emit_barrier_after (insn);
  	  cse_jumps_altered = 1;
  	  /* If previous insn just set CC0 for us, delete it too.  */
! 	  if (prev_insn_cc0 != 0)
  	    {
  	      PUT_CODE (prev_insn, NOTE);
--- 3476,3490 ----
  	      NOTE_SOURCE_FILE (prev_insn) = 0;
  	    }
+ 	  /* One less use of the label this insn used to jump to.  */
+ 	  --LABEL_NUSES (JUMP_LABEL (insn));
  	}
        else if (GET_CODE (SET_SRC (x)) == LABEL_REF)
  	{
+ 	  rtx label;
+ 
  	  emit_barrier_after (insn);
  	  cse_jumps_altered = 1;
  	  /* If previous insn just set CC0 for us, delete it too.  */
! 	  if (prev_insn_cc0 != 0 || prev_insn_explicit_cc0 != 0)
  	    {
  	      PUT_CODE (prev_insn, NOTE);
***************
*** 3384,3389 ****
  	  /* If jump target is the following label, and this is only use of it,
  	     skip direct to that label and continue optimizing there.  */
! 	  if (no_labels_between_p (insn, XEXP (SET_SRC (x), 0))
! 	      && LABEL_NUSES (XEXP (SET_SRC (x), 0)) == 1)
  	    cse_skip_to_next_block = 1;
  	}
--- 3494,3502 ----
  	  /* If jump target is the following label, and this is only use of it,
  	     skip direct to that label and continue optimizing there.  */
! 	  label = insn;
! 	  while (label != 0 && GET_CODE (label) != CODE_LABEL)
! 	    label = NEXT_INSN (label);
! 	  if (label == XEXP (SET_SRC (x), 0)
! 	      && LABEL_NUSES (label) == 1)
  	    cse_skip_to_next_block = 1;
  	}
***************
*** 3402,3405 ****
--- 3515,3519 ----
      }
  
+   prev_insn_explicit_cc0 = this_insn_explicit_cc0;
    prev_insn_cc0 = this_insn_cc0;
    prev_insn = insn;
***************
*** 3490,3497 ****
  }
  \f


! /* Find the end of INSN's basic block, and return the uid of its last insn
     and the total number of SETs in all the insns of the block.  */
  
! struct cse_basic_block_data { int uid, nsets; rtx last; };
  
  static struct cse_basic_block_data
--- 3604,3611 ----
  }
  \f


! /* Find the end of INSN's basic block, and return the cuid of its last insn
     and the total number of SETs in all the insns of the block.  */
  
! struct cse_basic_block_data { int cuid, nsets; rtx last; };
  
  static struct cse_basic_block_data
***************
*** 3539,3543 ****
        p = NEXT_INSN (p);
      }
!   val.uid = last_uid;
    val.nsets = nsets;
    val.last = p;
--- 3653,3657 ----
        p = NEXT_INSN (p);
      }
!   val.cuid = uid_cuid[last_uid];
    val.nsets = nsets;
    val.last = p;
***************
*** 3592,3598 ****
--- 3706,3738 ----
    n_elements_made = 0;
  
+   /* Find the largest uid.  */
+ 
+   for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
+     if (INSN_UID (insn) > i)
+       i = INSN_UID (insn);
+ 
+   uid_cuid = (short *) alloca ((i + 1) * sizeof (short));
+   bzero (uid_cuid, (i + 1) * sizeof (short));
+ 
+   /* Compute the mapping from uids to cuids.
+      CUIDs are numbers assigned to insns, like uids,
+      except that cuids increase monotonically through the code.
+      Don't assign cuids to line-number NOTEs, so that the distance in cuids
+      between two insns is not affected by -g.  */
+ 
+   for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
+     {
+       if (GET_CODE (insn) != NOTE
+ 	  || NOTE_LINE_NUMBER (insn) < 0)
+ 	INSN_CUID (insn) = ++i;
+       else
+ 	/* Give a line number note the same cuid as preceding insn.  */
+ 	INSN_CUID (insn) = i;
+     }
+ 
    /* Loop over basic blocks.
       Compute the maximum number of qty's needed for each basic block
       (which is 2 for each SET).  */
+   insn = f;
    while (insn)
      {
***************
*** 3601,3606 ****
        val = cse_end_of_basic_block (insn);
  
!       cse_basic_block_end = val.uid;
!       cse_basic_block_start = INSN_UID (insn);
        max_qty = val.nsets * 2;
  
--- 3741,3746 ----
        val = cse_end_of_basic_block (insn);
  
!       cse_basic_block_end = val.cuid;
!       cse_basic_block_start = INSN_CUID (insn);
        max_qty = val.nsets * 2;
  
***************
*** 3682,3686 ****
  	}
  
!       if (cse_skip_to_next_block)
  	{
  	  struct cse_basic_block_data val;
--- 3822,3829 ----
  	}
  
!       /* See if it is ok to keep on going past the label
! 	 which used to end our basic block.  */
!       if (cse_skip_to_next_block
! 	  || (to != 0 && NEXT_INSN (insn) == to && LABEL_NUSES (to) == 0))
  	{
  	  struct cse_basic_block_data val;
***************
*** 3702,3706 ****
  	    break;
  
! 	  cse_basic_block_end = val.uid;
  	  to = val.last;
  	}
--- 3845,3849 ----
  	    break;
  
! 	  cse_basic_block_end = val.cuid;
  	  to = val.last;
  	}
diff -rc2N gcc-1.35/dbranch.c gcc-1.36/dbranch.c
*** gcc-1.35/dbranch.c	Wed Dec 31 19:00:00 1969
--- gcc-1.36/dbranch.c	Tue May 30 19:02:36 1989
***************
*** 0 ****
--- 1,449 ----
+ /* Delayed branch scheduling pass.
+    Copyright (C) 1987, 1988, 1989 Free Software Foundation, Inc.
+ 
+ This file is part of GNU CC.
+ 
+ GNU CC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY.  No author or distributor
+ accepts responsibility to anyone for the consequences of using it
+ or for whether it serves any particular purpose or works at all,
+ unless he says so in writing.  Refer to the GNU CC General Public
+ License for full details.
+ 
+ Everyone is granted permission to copy, modify and redistribute
+ GNU CC, but only under the conditions described in the
+ GNU CC General Public License.   A copy of this license is
+ supposed to have been given to you along with GNU CC so you
+ can know your rights and responsibilities.  It should be in a
+ file named COPYING.  Among other things, the copyright notice
+ and this notice must be preserved on all copies.  */
+ 
+ /*  Delayed Branch Scheduling Optimization
+ 
+ If the HAVE_DELAYED_BRANCH macro is defined in the machine 
+ description, this code is called by toplev.c during optimizing 
+ compilation immediately after the final jump optimization pass
+ and just before assembler output generation, if delayed branch
+ scheduling is requested with the -fdelayed-branch switch.
+ 
+ Machines with delayed branch allow one or more instructions
+ placed *after* a branch instruction to be executed while the
+ hardware is off fetching the next instruction.  These instructions
+ are executed after the branch is issued, but before the branch 
+ actually takes effect.  The decision as to whether or not
+ the branch is to be taken, and the address of the branch target
+ are fixed at the time the branch is issued, so only instructions
+ that do not appear in the dependency graphs for computing the 
+ branch decision and/or target address may be relocated "after" 
+ the branch.  Some machines might have additional restrictions,
+ such as not allowing memory instructions or condition code
+ modification in the delay sequence.
+ 
+ Note that this scheduling pass occurs after register allocation, and
+ (of course) final jump optimization.  This mechanism is *not* intended
+ to be hacked to deal with similar memory-latency pipeline scheduling
+ (i.e. slots after loads/stores), as tempting as that might be.  The
+ right place to do load-store latency scheduling is prior to register
+ allocation, since allocation may introduce artificial dependencies
+ that could have been avoided; note that these artificial dependencies
+ are *not* reflected in the flow information, which is one reason for
+ the somewhat ad hoc analysis done in this pass. 
+ 
+ The strategy and methods used are as follows.  The function DBR_SCHEDULE
+ is called from toplev.c if the scheduling pass is to be run.  That function
+ sets up the dump file, then scans the current function from top to bottom
+ for "d-blocks", which are like basic blocks (single-entry, single-exit),
+ with the additional condition that the last instruction in the block has
+ delay slots.  Note that if calls have slots, d-blocks can be smaller than
+ basic blocks.  If a basic block does not end with a delay-instruction,
+ it is skipped.
+ 
+ To re-order instructions in a d-block (see DBR_DBLOCK_SCHED), the scheduler
+ scans backward from the "d-instruction", trying to fill the slots.  The
+ scheduler is somewhat conservative.  Volatile memory references are
+ serialized (their order is never changed to avoid possible aliasing
+ problems).  Definitions of registers are serialized (so there is no
+ possibility of deadlock).  Since hard register dependencies are
+ not noted by flow analysis, the scheduler does its own simplified
+ tracking of the registers, memory, and condition code uses/defines
+ by the d-instruction and the instructions it depends on).  Information
+ available from flow analysis is used to shortcut the analysis where
+ possible.  
+ 
+ Since only data dependencies are considered by the scheduler, any
+ machine-specific restrictions, e.g. to keep memory instructions from
+ being scheduled into slots, must be explicit in the definition of
+ DBR_INSN_ELIGIBLE_P.
+ 
+ The scheduler scans backwards over the block, looking for eligible
+ insns to fill the slot(s).  If none are found, nothing is done, and no
+ changes are made to the code.  As eligible insns are found, they are
+ removed from the chain, and recorded in an INSN_LIST rtx.  When all
+ slots are full (or the top of the d-block is reached), the *pattern*
+ of the d-insn is replaced with a SEQUENCE rtx, which consists of
+ a copy of the original d-insn followed by the slot fillers.  Slot
+ filling instructions remain in the original relative order in the
+ sequence.
+ 
+ When the SEQUENCE pattern is encountered by final, the instructions
+ are output "normally", though the output code for the instructions
+ may test for this and alter their behavior appropriately.
+ 
+ */
+ 
+ #include <stdio.h>
+ #include "config.h"
+ #include "rtl.h"
+ #include "hard-reg-set.h"
+ #include "flags.h"
+ 
+ FILE *dbr_dump_file;
+ 
+ /* The number of unfilled delay slots in the current sequence. */
+ static int slots_avail;
+ 
+ /* A flag, nonzero indicating that some insn that could not 
+    go in a slot writes to memory.  */
+ 
+ static int memw;
+ 
+ /* A flag, nonzero indicating that the condition code is written 
+    by some insn that couldn't go in a delay slot.  */
+ 
+ static int ccw;
+ 
+ /* Each bit is nonzero if the corresponding hard register
+    is written by an insn that couldn't go in a delay slot.  */
+ 
+ static HARD_REG_SET regw;
+ 
+ /* A flag, set nonzero if ENOTE determines that
+    the current insn can't go in a delay slot because of a
+    data dependency detected by note_stores.  */
+ 
+ static int eflag;
+ 
+ /* The insn having delay slots.  Global because of the calls through
+    note_stores that need it.  */
+ 
+ static rtx dinsn;
+ 
+ /* The insn being currently considered for a delay slot.  */
+ 
+ static rtx insn;
+ 
+ /* An INSN_LIST (just like the insn field) that we use to hold
+    LOG_LINKS of ineligible insns.  We use what flow analysis 
+    stuff we can - this prevents exhaustive searches for write-read
+    dependencies in most cases.  This tactic only loses on reloads
+    and code generated with hard regs (instead of pseudos).  */
+ 
+ static rtx dep_insn_list;
+ \f


+ /* Called by note_stores on "ineligible" insns to keep track of
+    pre-branch dependencies.  */
+ static void
+ pnote (x, in)
+      rtx x;
+      rtx in;
+ {
+   switch (GET_CODE (x))
+     {
+     case REG:
+       if (GET_CODE (in) != SET
+ 	  || GET_CODE (SET_SRC (in)) != CALL)
+ 	SET_HARD_REG_BIT (regw, REGNO (x));
+       return;
+     case MEM:
+       memw = TRUE; /* this might be relaxed somewhat later */
+       return;
+     case CC0:
+       ccw = TRUE;
+       return;
+     case PC:
+       return;
+     default:
+       abort (); /* should never happen */
+     }
+ }
+ \f


+ /*  The d-block end insn is in DINSN.  Initialize the flags to
+     start building the delay sequence.  Calls PNOTE from note_stores
+     to track the written registers and memory.      */
+ 
+ static void
+ init_flags ()
+ {
+   CLEAR_HARD_REG_SET (regw);
+   memw = ccw = 0;
+   note_stores (PATTERN (dinsn), pnote);
+   if (LOG_LINKS (dinsn))
+     dep_insn_list = copy_rtx (LOG_LINKS (dinsn));
+   else
+     dep_insn_list = 0;
+   slots_avail = DBR_SLOTS_AFTER (dinsn);
+ }
+ 
+ \f


+ /* Called through note_stores on possibly eligible insn patterns.
+    Checks to see if a register written by the pattern is needed by an already
+    ineligible insn.  Sets the global EFLAG nonzero if a dependency
+    is found.  */
+ 
+ static void 
+ enote (x, p)
+      rtx x;
+      rtx p;
+ {
+   if (eflag == 0)
+     {
+       if (GET_CODE (x) == REG)
+ 	{
+ 	  if (reg_used_between_p (x, insn, dinsn))
+ 	    goto lose;
+ 	  if ((!FUNCTION_VALUE_REGNO_P (REGNO (x)) || 
+ 	       GET_CODE (dinsn) != CALL_INSN) &&
+ 	      reg_mentioned_p (x, (PATTERN (dinsn))))
+ 	    goto lose;
+ 	}
+       else if (x == cc0_rtx && 
+ 	       reg_used_between_p (x, insn, NEXT_INSN (dinsn)))
+ 	goto lose;
+       return;
+     lose:
+       eflag = 1;
+     }
+ }
+ 
+ /*  Search the current dependency list DEP_INSN_LIST for INSN,
+     return nonzero if found. */
+ 
+ static int
+ in_dep_list_p (insn)
+      rtx insn;
+ {
+   rtx l;
+   for (l = dep_insn_list; l ; l = XEXP (l, 1))
+     if (insn == XEXP (l, 0)) return 1;
+   return 0;
+ }
+ \f


+ /* Returns zero if INSN is ineligible to be put in a delay slot
+    of DINSN.  INSN is ineligible if it:
+      - is in the dependency list of an ineligible insn.
+      - writes a hard register needed by an ineligible insn.
+      - reads a register written by an ineligible insn.
+      - refers to memory.
+      - sets the condition code.    
+      - violates a machine-dependent constraint.  */
+ 
+ static int
+ insn_eligible_p ()
+ {
+   rtx dest;
+   rtx pat = PATTERN (insn);
+   int i,s;
+ 
+   /* See if there are any explicit dependencies on this insn. */
+   if (in_dep_list_p (insn))
+     return 0;
+   
+   /* Check for implicit dependencies by calling enote on each
+      store rtx.  ENOTE makes sure that no ineligible instruction
+      refers to a register in a way that flow analysis 
+      has missed or ignored.         */
+   eflag = 0;
+   note_stores (PATTERN (insn), enote);
+   if (eflag)
+     return 0;
+ 
+   /* Check for volatile memory refs if any already ineligible. */
+ 
+   if (memw && volatile_refs_p (pat))
+     {
+       memw = TRUE;
+       return 0;
+     }
+ 
+   /* See if it refers to any regs that are clobbered by ineligibles. */
+ 
+   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+     if (TEST_HARD_REG_BIT (regw, i) 
+ 	&& refers_to_regno_p (i, i + 1, pat, 0))
+       return 0;
+ 
+ #ifdef DBR_INSN_ELIGIBLE_P
+   /*  Check for arbitrary machine constraints if any. */
+   if (! DBR_INSN_ELIGIBLE_P (insn, dinsn))
+     return 0;
+ #endif
+ 
+   return 1;
+ }
+ \f


+ /* Add the links in LIST to the dependency list.  We put them
+    at the front since this should make searches faster in long
+    d-blocks.
+ */
+ static void 
+ prepend_to_dep_list (list)
+      rtx list;
+ {
+   rtx l = copy_rtx (list);
+   while (XEXP (l, 1) != 0)
+     l = XEXP (l, 1);
+   XEXP (l, 1) = dep_insn_list;
+   dep_insn_list = l;
+ }
+   
+ 
+ \f


+ /* Update the flags for ineligible INSN - it can't be put in a delay
+ slot.  This involves setting bits to indicate the stores of INSN, and
+ adding any flow-analysis dependencies of INSN's insn-list to
+ the ineligible list.  (Should ultimately catch reloads too.) */
+ 
+ static void 
+ update_flags (insn)
+      rtx insn;
+ {
+   rtx l;
+   note_stores (PATTERN (insn), pnote);
+   if (l = LOG_LINKS (insn))
+     prepend_to_dep_list (l);
+ }
+ \f


+ /* Put INSN and LIST together in a SEQUENCE rtx of LENGTH, and replace
+    the pattern of INSN with the SEQUENCE.  Include the available
+    slots AVAIL in the SEQUENCE insn.  */
+ static void
+ emit_delay_sequence (insn, list, length, avail)
+      rtx insn;
+      rtx list;
+      int length;
+      int avail;
+ {
+   register int i = 1;
+   register rtx li, tem;
+   /* Allocate the the rtvec to hold the insns and the SEQUENCE. */
+   rtvec seqv = rtvec_alloc (length + 1);
+   rtx seq = gen_rtx (SEQUENCE, VOIDmode, seqv);
+ 
+   /* Make a copy of the insn having delay slots. */
+   tem = copy_rtx (insn);
+   NEXT_INSN (tem) = 0;
+   PREV_INSN (tem) = 0;
+   /* Replace the original pattern with a sequence whose
+      first insn is the copy. */
+   PATTERN (insn) = seq;
+   INSN_CODE (insn) = -1;
+   XVECEXP (seq, 0, 0) = tem;
+   /* Copy in the delay-slot filling insns. */
+   for (li = list; li; li = XEXP (li, 1))
+     {
+       XVECEXP (seq, 0, i) = XEXP (li, 0);
+       i++;
+     }
+ }
+ \f


+ /*  Try to reorganize code in a d-block */
+ 
+ static void
+ dbr_dblock_sched (first, last)
+      rtx first, last;
+ { 
+   rtx delay_insn_list = 0;
+   int seq_len = 0;
+   dinsn = last;
+   if (first == last) return;
+   init_flags ();
+   insn = PREV_INSN (dinsn);
+   while (1)
+     {
+       rtx prev = PREV_INSN (insn);
+       rtx next = NEXT_INSN (insn);
+       if (GET_CODE (insn) == INSN
+ 	  && GET_CODE (PATTERN (insn)) != USE
+ 	  && GET_CODE (PATTERN (insn)) != CLOBBER
+ 	  && GET_CODE (PATTERN (insn)) != ADDR_VEC
+ 	  && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC)
+ 	{
+ 	  if (slots_avail >= DBR_INSN_SLOTS (insn) && insn_eligible_p ())
+ 	    {
+ 	      /* Add this insn to the delay sequence and
+ 		 update the number of slots available. */
+ 	      register rtx t = delay_insn_list;
+ 	      delay_insn_list = gen_rtx (INSN_LIST, VOIDmode, insn, t);
+ 	      seq_len++;
+ 	      slots_avail -= DBR_INSN_SLOTS (insn);
+ 
+ 	      /* Now remove it from the chain. */
+ 	      NEXT_INSN (prev) = next;
+ 	      PREV_INSN (next) = prev;
+ 	      NEXT_INSN (insn) = PREV_INSN (insn) = 0;
+ 	    }
+ 	  else
+ 	    update_flags (insn);
+ 	}
+       else
+ 	if (GET_CODE (insn) != NOTE)
+ 	  abort ();
+       if (slots_avail == 0 || insn == first)
+ 	break;
+       else
+ 	insn = prev;
+     }
+   /* Done.  If the delay list is non-empty, emit a sequence
+      in place of the dinsn.  */
+   if (delay_insn_list != 0)
+     emit_delay_sequence (dinsn, delay_insn_list, seq_len, slots_avail);
+ }
+ 
+ \f


+ /*
+ Identify d-blocks of a function, which are sort of like basic
+ blocks, except that any instruction with delay slots defines the end
+ of a dblock, and dblocks that do not end in delay-instructions are
+ uninteresting degenerate cases.
+ 
+ This function finds d-blocks in the code for a function, and calls
+ dbr_dblock_sched on non-degenerate blocks.  Called from toplev.c
+ if HAVE_DELAYED_BRANCH is defined and we are doing optimizing
+ compilation.   F is the first insn of the function, DUMP_FILE
+ is the file to output debugging info on if requested.  */
+ 
+ void
+ dbr_schedule (f, dump_file)
+      rtx f;
+      FILE *dump_file;
+ {
+   rtx first = f;
+   rtx insn;
+   /* Dump output if requested */
+   if (dbr_dump_file = dump_file)
+     fprintf (dbr_dump_file, "Delayed-branch reordering dump.\n");
+ 
+   /* Search for d-blocks by scanning the insns from top to bottom. */
+   for (insn = first; insn; insn = NEXT_INSN (insn))
+     {
+       if (DBR_SLOTS_AFTER (insn) > 0)
+ 	{
+ 	  /* An insn with delay slots always terminates a d-block.
+ 	     Call the scheduler to fill in the slots if possible. */
+ 	  dbr_dblock_sched (first, insn);
+ 	  
+ 	  /* Resume scanning after the end of the sequence. */
+ 	  first = NEXT_INSN (dinsn);
+ 	}
+       else
+ 	/* Not an end of a real d-block, but need to check
+ 	   if it is the end of a degenerate one.  Note that
+ 	   calls or jumps will only reach here if they aren't
+ 	   delayed instructions.              */
+ 
+ 	if (GET_CODE (insn) == CODE_LABEL ||
+ 	    GET_CODE (insn) == JUMP_INSN ||
+ 	    GET_CODE (insn) == CALL_INSN)
+ 	  first = NEXT_INSN (insn);	    
+     }
+ }
diff -rc2N gcc-1.35/dbxout.c gcc-1.36/dbxout.c
*** gcc-1.35/dbxout.c	Fri Apr 21 13:16:27 1989
--- gcc-1.36/dbxout.c	Thu Sep 21 15:01:52 1989
***************
*** 408,419 ****
  	    fprintf (asmfile, "%s:", IDENTIFIER_POINTER (DECL_NAME (tem)));
  	    CHARS (2 + IDENTIFIER_LENGTH (DECL_NAME (tem)));
! 	    if (use_gdb_dbx_extensions)
  	      {
  		putc ('/', asmfile);
- #ifdef TREE_PRIVATE
  		putc ((TREE_PRIVATE (tem) ? '0'
  		       : TREE_PROTECTED (tem) ? '1' : '2'),
  		      asmfile);
- #endif
  		CHARS (2);
  		if (TREE_CODE (tem) == FUNCTION_DECL)
--- 408,420 ----
  	    fprintf (asmfile, "%s:", IDENTIFIER_POINTER (DECL_NAME (tem)));
  	    CHARS (2 + IDENTIFIER_LENGTH (DECL_NAME (tem)));
! #ifdef TREE_PRIVATE
! 	    if (use_gdb_dbx_extensions
! 		&& (TREE_PRIVATE (tem) || TREE_PROTECTED (tem)
! 		    || TREE_CODE (tem) != FIELD_DECL))
  	      {
  		putc ('/', asmfile);
  		putc ((TREE_PRIVATE (tem) ? '0'
  		       : TREE_PROTECTED (tem) ? '1' : '2'),
  		      asmfile);
  		CHARS (2);
  		if (TREE_CODE (tem) == FUNCTION_DECL)
***************
*** 434,437 ****
--- 435,439 ----
  	      }
  	    else
+ #endif
  	      dbxout_type (TREE_TYPE (tem), 0);
  
***************
*** 689,693 ****
  	 V for static storage and local scope,
  	    for those two, use N_LCSYM if data is in bss segment,
! 	    N_STSYM otherwise.  (N_FUN confuses GDB.)
  	 no letter at all, and N_LSYM, for auto variable,
  	 r and N_RSYM for register variable.  */
--- 691,698 ----
  	 V for static storage and local scope,
  	    for those two, use N_LCSYM if data is in bss segment,
! 	    N_STSYM if in data segment, N_FUN otherwise.
! 	    (We used N_FUN originally, then changed to N_STSYM
! 	    to please GDB.  However, it seems that confused ld.
! 	    Now GDB has been fixed to like N_FUN, says Kingdon.)
  	 no letter at all, and N_LSYM, for auto variable,
  	 r and N_RSYM for register variable.  */
***************
*** 709,716 ****
  	      if (!DECL_INITIAL (decl))
  		current_sym_code = N_LCSYM;
- #if 0  /* Note: N_FUN confuses GDB, since GDB expects it to start a new
- 	  nest of N_LBRAC/N_RBRAC, etc.  But N_STSYM probably does not
- 	  work either, since it relocates as data segment.
- 	  Probably no standard N_ code works, so we must invent one.  */
  	      else if (TREE_READONLY (decl) && ! TREE_VOLATILE (decl))
  		/* This is not quite right, but it's the closest
--- 714,717 ----
***************
*** 717,723 ****
  		   of all the codes that Unix defines.  */
  		current_sym_code = N_FUN;
- #endif
  	      else
! 		current_sym_code = N_STSYM;
  	    }
  	}
--- 718,729 ----
  		   of all the codes that Unix defines.  */
  		current_sym_code = N_FUN;
  	      else
! 		{
! /* Ultrix `as' seems to need this.  */
! #ifdef DBX_STATIC_STAB_DATA_SECTION
! 		  data_section ();
! #endif
! 		  current_sym_code = N_STSYM;
! 		}
  	    }
  	}
***************
*** 754,758 ****
  	    }
  
! 	  type = build_pointer_type (TREE_TYPE (decl));
  	}
        else if (GET_CODE (DECL_RTL (decl)) == MEM
--- 760,768 ----
  	    }
  
! 	  /* Effectively do build_pointer_type, but don't cache this type,
! 	     since it might be temporary whereas the type it points to
! 	     might have been saved for inlining.  */
! 	  type = make_node (POINTER_TYPE);
! 	  TREE_TYPE (type) = TREE_TYPE (decl);
  	}
        else if (GET_CODE (DECL_RTL (decl)) == MEM
***************
*** 905,908 ****
--- 915,922 ----
  		   IDENTIFIER_POINTER (DECL_NAME (parms)));
  
+ #if 0 /* This is actually the case in which a parameter
+ 	 is passed in registers but lives on the stack in a local slot.
+ 	 The address we are using is already correct, so don't change it.  */
+ 
  	  /* This is the case where the parm is passed as an int or double
  	     and it is converted to a char, short or float and stored back
***************
*** 916,919 ****
--- 930,934 ----
  				  - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
  #endif
+ #endif /* 0 */
  
  	  dbxout_type (TREE_TYPE (parms), 0);
***************
*** 1083,1086 ****
--- 1098,1104 ----
  
  	case LET_STMT:
+ 	  /* Ignore LET_STMTs for blocks never really used to make RTL.  */
+ 	  if (! TREE_USED (stmt))
+ 	    break;
  	  /* In dbx format, the syms of a block come before the N_LBRAC.  */
  	  dbxout_tags (STMT_TYPE_TAGS (stmt));
***************
*** 1103,1108 ****
  	    }
  
! 	  /* Output the interior of the block.  */
! 	  dbxout_block (STMT_BODY (stmt), depth + 1, 0);
  
  	  /* Refer to the marker for the end of the block.  */
--- 1121,1126 ----
  	    }
  
! 	  /* Output the subblocks.  */
! 	  dbxout_block (STMT_SUBBLOCKS (stmt), depth + 1, 0);
  
  	  /* Refer to the marker for the end of the block.  */
diff -rc2N gcc-1.35/emit-rtl.c gcc-1.36/emit-rtl.c
*** gcc-1.35/emit-rtl.c	Mon Apr 10 23:40:21 1989
--- gcc-1.36/emit-rtl.c	Thu Sep 21 00:33:11 1989
***************
*** 36,40 ****
  #include "config.h"
  #include <stdio.h>
! #include "varargs.h"
  #include "rtl.h"
  #include "regs.h"
--- 36,40 ----
  #include "config.h"
  #include <stdio.h>
! #include "gvarargs.h"
  #include "rtl.h"
  #include "regs.h"
***************
*** 365,369 ****
       complain if an invalid MODE is used even in other cases.  */
    if (GET_MODE_SIZE (mode) > UNITS_PER_WORD
!       && GET_MODE_SIZE (mode) != GET_MODE_SIZE (GET_MODE (x)))
      abort ();
    if (GET_MODE (x) == mode)
--- 365,369 ----
       complain if an invalid MODE is used even in other cases.  */
    if (GET_MODE_SIZE (mode) > UNITS_PER_WORD
!       && GET_MODE_SIZE (mode) != GET_MODE_UNIT_SIZE (GET_MODE (x)))
      abort ();
    if (GET_MODE (x) == mode)
***************
*** 372,375 ****
--- 372,378 ----
      return gen_rtx (CONST_INT, VOIDmode, INTVAL (x) & GET_MODE_MASK (mode));
    if (GET_CODE (x) == CONST_DOUBLE)
+ /* In version 1.37, try this: */
+ /*  if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) abort (); */
+     /* Assume it's an int, so ..._LOW means the low-order word.  */
      return gen_rtx (CONST_INT, VOIDmode,
  		    CONST_DOUBLE_LOW (x) & GET_MODE_MASK (mode));
***************
*** 517,523 ****
  gen_inline_header_rtx (insn, last_insn,
  		       first_labelno, last_labelno,
! 		       max_parm_regnum, max_regnum, args_size)
       rtx insn, last_insn;
       int first_labelno, last_labelno, max_parm_regnum, max_regnum, args_size;
  {
    rtx header = gen_rtx (INLINE_HEADER, VOIDmode,
--- 520,528 ----
  gen_inline_header_rtx (insn, last_insn,
  		       first_labelno, last_labelno,
! 		       max_parm_regnum, max_regnum, args_size,
! 		       stack_slots)
       rtx insn, last_insn;
       int first_labelno, last_labelno, max_parm_regnum, max_regnum, args_size;
+      rtx stack_slots;
  {
    rtx header = gen_rtx (INLINE_HEADER, VOIDmode,
***************
*** 525,529 ****
  			insn, last_insn,
  			first_labelno, last_labelno,
! 			max_parm_regnum, max_regnum, args_size);
    return header;
  }
--- 530,534 ----
  			insn, last_insn,
  			first_labelno, last_labelno,
! 			max_parm_regnum, max_regnum, args_size, stack_slots);
    return header;
  }
***************
*** 737,740 ****
--- 742,756 ----
  }
  
+ /* Specify a new insn as the last in the chain.  */
+ 
+ void
+ set_last_insn (insn)
+      rtx insn;
+ {
+   if (NEXT_INSN (insn) != 0)
+     abort ();
+   last_insn = insn;
+ }
+ 
  /* Return a number larger than any instruction's uid in this function.  */
  
***************
*** 835,840 ****
    if (NEXT_INSN (insn))
      PREV_INSN (NEXT_INSN (insn)) = insn;
!   else
      last_insn = insn;
    NEXT_INSN (after) = insn;
  }
--- 851,865 ----
    if (NEXT_INSN (insn))
      PREV_INSN (NEXT_INSN (insn)) = insn;
!   else if (last_insn == after)
      last_insn = insn;
+   else
+     {
+       rtx stack = sequence_stack;
+       /* Scan all pending sequences too.  */
+       for (; stack; stack = XEXP (XEXP (stack, 1), 1))
+ 	if (after == XEXP (XEXP (stack, 1), 0))
+ 	  XEXP (XEXP (stack, 1), 0) = insn;
+     }
+ 
    NEXT_INSN (after) = insn;
  }
***************
*** 1158,1163 ****
--- 1183,1190 ----
    emit_lineno = line;
  
+ #if 0
    if (no_line_numbers)
      return 0;
+ #endif
  
    return emit_note (file, line);
***************
*** 1176,1182 ****
    register rtx note;
  
-   if (no_line_numbers && line > 0)
-     return 0;
- 
    if (line > 0)
      {
--- 1203,1206 ----
***************
*** 1188,1191 ****
--- 1212,1221 ----
      }
  
+   if (no_line_numbers && line > 0)
+     {
+       cur_insn_uid++;
+       return 0;
+     }
+ 
    note = rtx_alloc (NOTE);
    INSN_UID (note) = cur_insn_uid++;
***************
*** 1206,1209 ****
--- 1236,1248 ----
    return emit_line_note (file, line);
  }
+ 
+ /* Cause next statement to emit a line note even if the line number
+    has not changed.  This is used at the beginning of a function.  */
+ 
+ void
+ force_next_line_note ()
+ {
+   last_linenum = -1;
+ }
  \f


  /* Return an indication of which type of insn should have X as a body.
***************
*** 1434,1452 ****
  	      reg_rtx_no = REGNO (x);
  
! 	      if (reg_rtx_no == regno_pointer_flag_length)
  		{
  		  rtx *new1;
! 		  char *new =
! 		    (char *) oballoc (regno_pointer_flag_length * 2);
! 		  bzero (new, regno_pointer_flag_length * 2);
  		  bcopy (regno_pointer_flag, new, regno_pointer_flag_length);
- 		  regno_pointer_flag = new;
  
! 		  new1 = (rtx *) oballoc (regno_pointer_flag_length * 2 * sizeof (rtx));
! 		  bzero (new1, regno_pointer_flag_length * 2 * sizeof (rtx));
  		  bcopy (regno_reg_rtx, new1, regno_pointer_flag_length * sizeof (rtx));
- 		  regno_reg_rtx = new1;
  
! 		  regno_pointer_flag_length *= 2;
  		}
  	      reg_rtx_no ++;
--- 1473,1492 ----
  	      reg_rtx_no = REGNO (x);
  
! 	      if (reg_rtx_no >= regno_pointer_flag_length)
  		{
+ 		  int newlen = max (regno_pointer_flag_length * 2,
+ 				    reg_rtx_no + 30);
  		  rtx *new1;
! 		  char *new = (char *) oballoc (newlen);
! 		  bzero (new, newlen);
  		  bcopy (regno_pointer_flag, new, regno_pointer_flag_length);
  
! 		  new1 = (rtx *) oballoc (newlen * sizeof (rtx));
! 		  bzero (new1, newlen * sizeof (rtx));
  		  bcopy (regno_reg_rtx, new1, regno_pointer_flag_length * sizeof (rtx));
  
! 		  regno_pointer_flag = new;
! 		  regno_reg_rtx = new1;
! 		  regno_pointer_flag_length = newlen;
  		}
  	      reg_rtx_no ++;
diff -rc2N gcc-1.35/explow.c gcc-1.36/explow.c
*** gcc-1.35/explow.c	Wed Feb 22 11:49:44 1989
--- gcc-1.36/explow.c	Sun Aug 20 14:23:34 1989
***************
*** 163,167 ****
  
  rtx
! lookup_static_chain ()
  {
    abort ();
--- 163,168 ----
  
  rtx
! lookup_static_chain (context)
!      rtx context;
  {
    abort ();
***************
*** 308,311 ****
--- 309,317 ----
      return force_operand (x, 0);
  
+   /* If we have a register that's an invalid address,
+      it must be a hard reg of the wrong class.  Copy it to a pseudo.  */
+   if (GET_CODE (x) == REG)
+     return copy_to_reg (x);
+ 
    /* Last resort: copy the value to a register, since
       the register is a valid address.  */
***************
*** 321,325 ****
  	    && (XEXP (x, 0) == frame_pointer_rtx
  		|| XEXP (x, 0) == arg_pointer_rtx)))
!     return force_reg (Pmode, x);
    return x;
  }
--- 327,336 ----
  	    && (XEXP (x, 0) == frame_pointer_rtx
  		|| XEXP (x, 0) == arg_pointer_rtx)))
!     {
!       if (general_operand (x, Pmode))
! 	return force_reg (Pmode, x);
!       else
! 	return force_operand (x, 0);
!     }
    return x;
  }
***************
*** 377,381 ****
  {
    register rtx temp = gen_reg_rtx (GET_MODE (x));
!   emit_move_insn (temp, x);
    return temp;
  }
--- 388,400 ----
  {
    register rtx temp = gen_reg_rtx (GET_MODE (x));
!  
!   /* If not an operand, must be an address with PLUS and MULT so
!      do the computation.  */ 
!   if (! general_operand (x, VOIDmode))
!     x = force_operand (x, temp);
!   
!   if (x != temp)
!     emit_move_insn (temp, x);
! 
    return temp;
  }
***************
*** 388,394 ****
       rtx x;
  {
!   register rtx temp = gen_reg_rtx (Pmode);
!   emit_move_insn (temp, x);
!   return temp;
  }
  
--- 407,411 ----
       rtx x;
  {
!   return copy_to_mode_reg (Pmode, x);
  }
  
***************
*** 402,408 ****
  {
    register rtx temp = gen_reg_rtx (mode);
    if (GET_MODE (x) != mode && GET_MODE (x) != VOIDmode)
      abort ();
!   emit_move_insn (temp, x);
    return temp;
  }
--- 419,432 ----
  {
    register rtx temp = gen_reg_rtx (mode);
+   
+   /* If not an operand, must be an address with PLUS and MULT so
+      do the computation.  */ 
+   if (! general_operand (x, VOIDmode))
+     x = force_operand (x, temp);
+ 
    if (GET_MODE (x) != mode && GET_MODE (x) != VOIDmode)
      abort ();
!   if (x != temp)
!     emit_move_insn (temp, x);
    return temp;
  }
diff -rc2N gcc-1.35/expmed.c gcc-1.36/expmed.c
*** gcc-1.35/expmed.c	Wed Feb 22 11:49:42 1989
--- gcc-1.36/expmed.c	Tue Sep 12 15:46:21 1989
***************
*** 67,74 ****
     ALIGN is the alignment that STR_RTX is known to have, measured in bytes.  */
  
- /* ??? This should really have the ability to copy a word into a register
-    in order to store the bit-field into it, on machines whose insv insns
-    work that way.  */
- 
  rtx
  store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align)
--- 67,70 ----
***************
*** 175,178 ****
--- 171,217 ----
        rtx pat;
  
+       /* If this machine's insv can only insert into a register,
+ 	 copy OP0 into a register and save it back later.  */
+       if (GET_CODE (op0) == MEM
+ 	  && ! (*insn_operand_predicate[(int) CODE_FOR_insv][0]) (op0, VOIDmode))
+ 	{
+ 	  rtx tempreg;
+ 	  enum machine_mode trymode, bestmode = VOIDmode, insn_mode;
+ 	  int maxsize = GET_MODE_SIZE (insn_operand_mode[(int) CODE_FOR_extzv][0]);
+ 
+ 	  /* Find biggest machine mode we can safely use
+ 	     to fetch from this structure.
+ 	     But don't use a bigger mode than the insn wants.  */
+ 	  for (trymode = QImode;
+ 	       trymode && GET_MODE_SIZE (trymode) <= maxsize;
+ 	       trymode = GET_MODE_WIDER_MODE (trymode))
+ 	    if (GET_MODE_SIZE (trymode) <= align)
+ 	      bestmode = trymode;
+ 	  if (! bestmode)
+ 	    abort ();
+ 	  /* Adjust address to point to the containing unit of that mode.  */
+ 	  unit = GET_MODE_BITSIZE (bestmode);
+ 	  /* Compute offset as multiple of this unit, counting in bytes.  */
+ 	  offset = (bitnum / unit) * GET_MODE_SIZE (bestmode);
+ 	  bitpos = bitnum % unit;
+ 	  op0 = change_address (op0, bestmode, 
+ 				plus_constant (XEXP (op0, 0), offset));
+ 
+ 	  /* Fetch that unit, store the bitfield in it, then store the unit.  */
+ 	  tempreg = copy_to_reg (op0);
+ 	  /* To actually store in TEMPREG,
+ 	     look at it in the mode this insn calls for.
+ 	     (Probably SImode.)  */
+ 	  insn_mode = insn_operand_mode[(int) CODE_FOR_insv][0];
+ #ifdef BITS_BIG_ENDIAN
+ 	  if (GET_MODE_BITSIZE (insn_mode) > unit)
+ 	    bitpos += GET_MODE_BITSIZE (insn_mode) - unit;
+ #endif
+ 	  store_bit_field (gen_rtx (SUBREG, insn_mode, tempreg, 0),
+ 			   bitsize, bitpos, fieldmode, value, align);
+ 	  emit_move_insn (op0, tempreg);
+ 	  return value;
+ 	}
+ 
        /* Add OFFSET into OP0's address.  */
        if (GET_CODE (xop0) == MEM)
***************
*** 402,406 ****
      subtarget = expand_bit_and (mode, op0,
  				gen_rtx (CONST_INT, VOIDmode, 
! 					 (~ (((1 << bitsize) - 1) << bitpos))
  					 & ((GET_MODE_BITSIZE (mode)
  					     == HOST_BITS_PER_INT)
--- 441,447 ----
      subtarget = expand_bit_and (mode, op0,
  				gen_rtx (CONST_INT, VOIDmode, 
! 					 (~ (((unsigned) ~0
! 					      >> (HOST_BITS_PER_INT - bitsize))
! 					     << bitpos))
  					 & ((GET_MODE_BITSIZE (mode)
  					     == HOST_BITS_PER_INT)
***************
*** 438,441 ****
--- 479,485 ----
    rtx part1, part2;
  
+   /* Alignment of VALUE, after conversion.  */
+   int valalign = GET_MODE_SIZE (SImode);
+ 
    if (GET_MODE (value) != VOIDmode)
      value = convert_to_mode (SImode, value, 1);
***************
*** 457,463 ****
      {
        part1 = extract_fixed_bit_field (SImode, value, 0, bitsize_1,
! 				       BITS_PER_WORD - bitsize, 0, 1);
        part2 = extract_fixed_bit_field (SImode, value, 0, bitsize_2,
! 				       BITS_PER_WORD - bitsize_2, 0, 1);
      }
  #else
--- 501,507 ----
      {
        part1 = extract_fixed_bit_field (SImode, value, 0, bitsize_1,
! 				       BITS_PER_WORD - bitsize, 0, 1, valalign);
        part2 = extract_fixed_bit_field (SImode, value, 0, bitsize_2,
! 				       BITS_PER_WORD - bitsize_2, 0, 1, valalign);
      }
  #else
***************
*** 472,478 ****
    else
      {
!       part1 = extract_fixed_bit_field (SImode, value, 0, bitsize_1, 0, 0, 1);
        part2 = extract_fixed_bit_field (SImode, value, 0, bitsize_2,
! 				       bitsize_1, 0, 1);
      }
  #endif
--- 516,523 ----
    else
      {
!       part1 = extract_fixed_bit_field (SImode, value, 0, bitsize_1, 0,
! 				       0, 1, valalign);
        part2 = extract_fixed_bit_field (SImode, value, 0, bitsize_2,
! 				       bitsize_1, 0, 1, valalign);
      }
  #endif
***************
*** 623,638 ****
  		     (xop0, GET_MODE (xop0))))
  		{
! 		  /* If memory isn't acceptable for this operand,
! 		     copy it to a register.  */
! 		  unit = BITS_PER_WORD;
! 		  xoffset = bitnum / unit;
  		  xbitpos = bitnum % unit;
! 		  xop0 = change_address (xop0, SImode,
  					 plus_constant (XEXP (xop0, 0),
! 							xoffset * UNITS_PER_WORD));
! 		  xop0 = force_reg (GET_MODE (xop0), xop0);
  #ifdef BITS_BIG_ENDIAN
! 		  if (unit > GET_MODE_BITSIZE (GET_MODE (xop0)))
! 		    xbitpos += unit - GET_MODE_BITSIZE (GET_MODE (xop0));
  #endif
  		}
--- 668,702 ----
  		     (xop0, GET_MODE (xop0))))
  		{
! 		  enum machine_mode bestmode = VOIDmode, trymode;
! 		  int maxsize = GET_MODE_SIZE (insn_operand_mode[(int) CODE_FOR_extzv][1]);
! 
! 		  /* Find biggest machine mode we can safely use
! 		     to fetch from this structure.
! 		     But don't use a bigger mode than the insn wants.  */
! 		  for (trymode = QImode;
! 		       trymode && GET_MODE_SIZE (trymode) <= maxsize;
! 		       trymode = GET_MODE_WIDER_MODE (trymode))
! 		    if (GET_MODE_SIZE (trymode) <= align)
! 		      bestmode = trymode;
! 		  if (! bestmode)
! 		    abort ();
! 		  unit = GET_MODE_BITSIZE (bestmode);
! 
! 		  /* Compute offset as multiple of this unit,
! 		     counting in bytes.  */
! 		  xoffset = (bitnum / unit) * GET_MODE_SIZE (bestmode);
  		  xbitpos = bitnum % unit;
! 		  xop0 = change_address (xop0, bestmode,
  					 plus_constant (XEXP (xop0, 0),
! 							xoffset));
! 		  /* Fetch it to a register in that size.  */
! 		  xop0 = force_reg (bestmode, xop0);
! 
! 		  /* Now ref the register in the mode extzv wants.  */
! 		  xop0 = gen_rtx (SUBREG, insn_operand_mode[(int) CODE_FOR_extzv][1],
! 				  xop0, 0);
  #ifdef BITS_BIG_ENDIAN
! 		  if (GET_MODE_BITSIZE (GET_MODE (xop0)) > unit)
! 		    xbitpos += GET_MODE_BITSIZE (GET_MODE (xop0)) - unit;
  #endif
  		}
***************
*** 714,729 ****
  		     (xop0, GET_MODE (xop0))))
  		{
! 		  /* If memory isn't acceptable for this operand,
! 		     copy it to a register.  */
! 		  unit = BITS_PER_WORD;
! 		  xoffset = bitnum / unit;
  		  xbitpos = bitnum % unit;
! 		  xop0 = change_address (xop0, SImode,
  					 plus_constant (XEXP (xop0, 0),
! 							xoffset * UNITS_PER_WORD));
! 		  xop0 = force_reg (GET_MODE (xop0), xop0);
  #ifdef BITS_BIG_ENDIAN
! 		  if (unit > GET_MODE_BITSIZE (GET_MODE (xop0)))
! 		    xbitpos += unit - GET_MODE_BITSIZE (GET_MODE (xop0));
  #endif
  		}
--- 778,812 ----
  		     (xop0, GET_MODE (xop0))))
  		{
! 		  enum machine_mode bestmode = VOIDmode, trymode;
! 		  int maxsize = GET_MODE_SIZE (insn_operand_mode[(int) CODE_FOR_extzv][1]);
! 
! 		  /* Find biggest machine mode we can safely use
! 		     to fetch from this structure.
! 		     But don't use a bigger mode than the insn wants.  */
! 		  for (trymode = QImode;
! 		       trymode && GET_MODE_SIZE (trymode) <= maxsize;
! 		       trymode = GET_MODE_WIDER_MODE (trymode))
! 		    if (GET_MODE_SIZE (trymode) <= align)
! 		      bestmode = trymode;
! 		  if (! bestmode)
! 		    abort ();
! 		  unit = GET_MODE_BITSIZE (bestmode);
! 
! 		  /* Compute offset as multiple of this unit,
! 		     counting in bytes.  */
! 		  xoffset = (bitnum / unit) * GET_MODE_SIZE (bestmode);
  		  xbitpos = bitnum % unit;
! 		  xop0 = change_address (xop0, bestmode,
  					 plus_constant (XEXP (xop0, 0),
! 							xoffset));
! 		  /* Fetch it to a register in that size.  */
! 		  xop0 = force_reg (bestmode, xop0);
! 
! 		  /* Now ref the register in the mode extv wants.  */
! 		  xop0 = gen_rtx (SUBREG, insn_operand_mode[(int) CODE_FOR_extv][1],
! 				  xop0, 0);
  #ifdef BITS_BIG_ENDIAN
! 		  if (GET_MODE_BITSIZE (GET_MODE (xop0)) > unit)
! 		    xbitpos += GET_MODE_BITSIZE (GET_MODE (xop0)) - unit;
  #endif
  		}
***************
*** 1112,1115 ****
--- 1195,1205 ----
        if (! rotate && (! unsignedp || (! left && methods == OPTAB_WIDEN)))
  	{
+ 	  enum optab_methods methods1 = methods;
+ 
+ 	  /* If trying to widen a log shift to an arithmetic shift,
+ 	     don't accept an arithmetic shift of the same size.  */
+ 	  if (unsignedp)
+ 	    methods1 = OPTAB_MUST_WIDEN;
+ 
  	  /* Arithmetic shift */
  
***************
*** 1116,1120 ****
  	  temp = expand_binop (mode,
  			       left ? ashl_optab : ashr_optab,
! 			       shifted, op1, target, unsignedp, methods);
  	  if (temp != 0)
  	    return temp;
--- 1206,1210 ----
  	  temp = expand_binop (mode,
  			       left ? ashl_optab : ashr_optab,
! 			       shifted, op1, target, unsignedp, methods1);
  	  if (temp != 0)
  	    return temp;
***************
*** 1501,1503 ****
--- 1591,1638 ----
      abort ();
    return temp;
+ }
+ \f


+ /* Return a tree node with data type TYPE, describing the value of X.
+    Usually this is an RTL_EXPR, if there is no obvious better choice.  */
+ 
+ static tree
+ make_tree (type, x)
+      tree type;
+      rtx x;
+ {
+   tree t;
+   switch (GET_CODE (x))
+     {
+     case CONST_INT:
+       t = build_int_2 (INTVAL (x), 0);
+       TREE_TYPE (t) = type;
+       return fold (t);
+ 
+     default:
+       t = make_node (RTL_EXPR);
+       TREE_TYPE (t) = type;
+       RTL_EXPR_RTL (t) = x;
+       /* There are no insns to be output
+ 	 when this rtl_expr is used.  */
+       RTL_EXPR_SEQUENCE (t) = 0;
+       return t;
+     }
+ }
+ 
+ /* Return an rtx representing the value of X * MULT + ADD.
+    MODE is the machine mode for the computation.
+    UNSIGNEDP is non-zero to do unsigned multiplication.
+    This may emit insns.  */
+ 
+ rtx
+ expand_mult_add (x, mult, add, mode, unsignedp)
+      rtx x, mult, add;
+      enum machine_mode mode;
+      int unsignedp;
+ {
+   tree type = type_for_size (GET_MODE_BITSIZE (mode), unsignedp);
+   tree prod = fold (build (MULT_EXPR, type, make_tree (type, x),
+ 			   make_tree (type, mult)));
+   tree sum = fold (build (PLUS_EXPR, type, prod, make_tree (type, add)));
+   return expand_expr (sum, 0, VOIDmode, 0);
  }
diff -rc2N gcc-1.35/expr.c gcc-1.36/expr.c
*** gcc-1.35/expr.c	Tue Apr 25 15:47:06 1989
--- gcc-1.36/expr.c	Mon Sep 18 01:52:16 1989
***************
*** 28,32 ****
  #include "insn-config.h"
  #include "recog.h"
! #include "varargs.h"
  
  /* Decide whether a function's arguments should be processed
--- 28,33 ----
  #include "insn-config.h"
  #include "recog.h"
! #include "gvarargs.h"
! #include "typeclass.h"
  
  /* Decide whether a function's arguments should be processed
***************
*** 36,41 ****
  #ifdef PUSH_ROUNDING
  #define PUSH_ARGS_REVERSED	/* If it's last to first */
- #endif
  #endif
  
  /* Like STACK_BOUNDARY but in units of bytes, not bits.  */
--- 37,42 ----
  #ifdef PUSH_ROUNDING
  #define PUSH_ARGS_REVERSED	/* If it's last to first */
  #endif
+ #endif
  
  /* Like STACK_BOUNDARY but in units of bytes, not bits.  */
***************
*** 59,73 ****
  int pending_stack_adjust;
  
! /* Total size of arguments already pushed for function calls that
!    have not happened yet.  When this is nonzero,
!    args passed to function calls must be popped right away
!    to ensure contiguity of argument lists for future calls.
! 
!    This can also be temporarily incremented for various other reasons
!    to inhibit deferring of pops.  */
! static int current_args_size;
! 
! #define NO_DEFER_POP current_args_size += 1
! #define OK_DEFER_POP current_args_size -= 1
  
  /* A list of all cleanups which belong to the arguments of
--- 60,68 ----
  int pending_stack_adjust;
  
! /* Nonzero means stack pops must not be deferred, and deferred stack
!    pops must not be output.  It is nonzero inside a function call,
!    inside a conditional expression, inside a statement expression,
!    and in other cases as well.  */
! int inhibit_defer_pop;
  
  /* A list of all cleanups which belong to the arguments of
***************
*** 75,79 ****
  static tree cleanups_of_this_call;
  
! /* Nonzero means current function may call alloca.  */
  int may_call_alloca;
  
--- 70,75 ----
  static tree cleanups_of_this_call;
  
! /* Nonzero means current function may call alloca
!    as a subroutine.  (__builtin_alloca does not count.)  */
  int may_call_alloca;
  
***************
*** 91,99 ****
  static void preexpand_calls ();
  static rtx expand_increment ();
- static void move_by_pieces_1 ();
- static int move_by_pieces_ninsns ();
  static void init_queue ();
- static void store_one_arg ();
- static rtx target_for_arg ();
  
  void do_pending_stack_adjust ();
--- 87,91 ----
***************
*** 328,332 ****
        emit_library_call (gen_rtx (SYMBOL_REF, Pmode, (extending
  						      ? "__extendsfdf2"
! 						      : "__truncdfsf2")),
  			 GET_MODE (to), 1,
  			 from,  (extending ? SFmode : DFmode));
--- 320,324 ----
        emit_library_call (gen_rtx (SYMBOL_REF, Pmode, (extending
  						      ? "__extendsfdf2"
! 						      : "__truncdfsf2")), 0,
  			 GET_MODE (to), 1,
  			 from,  (extending ? SFmode : DFmode));
***************
*** 663,666 ****
--- 655,661 ----
  };
  
+ static void move_by_pieces_1 ();
+ static int move_by_pieces_ninsns ();
+ 
  static void
  move_by_pieces (to, from, len, align)
***************
*** 928,932 ****
  
  #ifdef TARGET_MEM_FUNCTIONS
!       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "memcpy"),
  			 VOIDmode, 3, XEXP (x, 0), Pmode,
  			 XEXP (y, 0), Pmode,
--- 923,927 ----
  
  #ifdef TARGET_MEM_FUNCTIONS
!       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "memcpy"), 0,
  			 VOIDmode, 3, XEXP (x, 0), Pmode,
  			 XEXP (y, 0), Pmode,
***************
*** 933,937 ****
  			 size, Pmode);
  #else
!       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "bcopy"),
  			 VOIDmode, 3, XEXP (y, 0), Pmode,
  			 XEXP (x, 0), Pmode,
--- 928,932 ----
  			 size, Pmode);
  #else
!       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "bcopy"), 0,
  			 VOIDmode, 3, XEXP (y, 0), Pmode,
  			 XEXP (x, 0), Pmode,
***************
*** 1017,1021 ****
      {
  #ifdef TARGET_MEM_FUNCTIONS
!       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "memset"),
  			 VOIDmode, 3,
  			 XEXP (object, 0), Pmode, const0_rtx, Pmode,
--- 1012,1016 ----
      {
  #ifdef TARGET_MEM_FUNCTIONS
!       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "memset"), 0,
  			 VOIDmode, 3,
  			 XEXP (object, 0), Pmode, const0_rtx, Pmode,
***************
*** 1022,1026 ****
  			 gen_rtx (CONST_INT, VOIDmode, size), Pmode);
  #else
!       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "bzero"),
  			 VOIDmode, 2,
  			 XEXP (object, 0), Pmode,
--- 1017,1021 ----
  			 gen_rtx (CONST_INT, VOIDmode, size), Pmode);
  #else
!       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "bzero"), 0,
  			 VOIDmode, 2,
  			 XEXP (object, 0), Pmode,
***************
*** 1199,1207 ****
    xinner = x = protect_from_queue (x, 0);
  
-   /* If part should go in registers, copy that part
-      into the appropriate registers.  */
-   if (partial > 0)
-     move_block_to_reg (REGNO (reg), x, partial);
- 
    if (extra)
      {
--- 1194,1197 ----
***************
*** 1223,1234 ****
    if (mode == BLKmode)
      {
        register rtx temp;
        int used = partial * UNITS_PER_WORD;
        int offset = used % (PARM_BOUNDARY / BITS_PER_UNIT);
  
        used -= offset;
  
!       if (size == 0)
! 	abort ();
  
        if (partial != 0)
--- 1213,1230 ----
    if (mode == BLKmode)
      {
+       /* Copy a block into the stack, entirely or partially.  */
+ 
        register rtx temp;
        int used = partial * UNITS_PER_WORD;
        int offset = used % (PARM_BOUNDARY / BITS_PER_UNIT);
+       int skip;
+       
+       if (size == 0)
+ 	abort ();
  
        used -= offset;
  
!       /* USED is now the # of bytes we need not copy to the stack
! 	 because registers will take care of them.  */
  
        if (partial != 0)
***************
*** 1236,1239 ****
--- 1232,1245 ----
  				 plus_constant (XEXP (xinner, 0), used));
  
+ /* If the partial register-part of the arg counts in its stack size,
+    skip the part of stack space corresponding to the registers.
+    Otherwise, start copying to the beginning of the stack space,
+    by setting SKIP to 0.  */
+ #ifndef FIRST_PARM_CALLER_OFFSET
+       skip = 0;
+ #else
+       skip = used;
+ #endif
+ 
  #ifdef PUSH_ROUNDING
        /* Do it with several push insns if that doesn't take lots of insns
***************
*** 1243,1246 ****
--- 1249,1253 ----
  	  && GET_CODE (size) == CONST_INT
  	  && args_addr == 0
+ 	  && skip == 0
  	  && (move_by_pieces_ninsns ((unsigned) INTVAL (size) - used, align)
  	      < MOVE_RATIO)
***************
*** 1254,1258 ****
  	     to the address of that space.  */
  
! 	  /* First deduct part put into registers from the size we need.  */
  	  if (partial != 0)
  	    {
--- 1261,1265 ----
  	     to the address of that space.  */
  
! 	  /* Deduct words put into registers from the size we must copy.  */
  	  if (partial != 0)
  	    {
***************
*** 1271,1275 ****
  	    temp = memory_address (BLKmode,
  				   plus_constant (args_addr,
! 						  used + INTVAL (args_so_far)));
  	  else
  	    temp = memory_address (BLKmode,
--- 1278,1282 ----
  	    temp = memory_address (BLKmode,
  				   plus_constant (args_addr,
! 						  skip + INTVAL (args_so_far)));
  	  else
  	    temp = memory_address (BLKmode,
***************
*** 1276,1281 ****
  				   plus_constant (gen_rtx (PLUS, Pmode,
  							   args_addr, args_so_far),
! 						  used));
! 
  
  	  /* TEMP is the address of the block.  Copy the data there.  */
--- 1283,1287 ----
  				   plus_constant (gen_rtx (PLUS, Pmode,
  							   args_addr, args_so_far),
! 						  skip));
  
  	  /* TEMP is the address of the block.  Copy the data there.  */
***************
*** 1353,1365 ****
  	    }
  
! 	  /* Make current_args_size nonzero around the library call
  	     to force it to pop the bcopy-arguments right away.  */
  	  NO_DEFER_POP;
  #ifdef TARGET_MEM_FUNCTIONS
! 	  emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "memcpy"),
  			     VOIDmode, 3, temp, Pmode, XEXP (xinner, 0), Pmode,
  			     size, Pmode);
  #else
! 	  emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "bcopy"),
  			     VOIDmode, 3, XEXP (xinner, 0), Pmode, temp, Pmode,
  			     size, Pmode);
--- 1359,1371 ----
  	    }
  
! 	  /* Make inhibit_defer_pop nonzero around the library call
  	     to force it to pop the bcopy-arguments right away.  */
  	  NO_DEFER_POP;
  #ifdef TARGET_MEM_FUNCTIONS
! 	  emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "memcpy"), 0,
  			     VOIDmode, 3, temp, Pmode, XEXP (xinner, 0), Pmode,
  			     size, Pmode);
  #else
! 	  emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "bcopy"), 0,
  			     VOIDmode, 3, XEXP (xinner, 0), Pmode, temp, Pmode,
  			     size, Pmode);
***************
*** 1377,1392 ****
        /* # words of start of argument
  	 that we must make space for but need not store.  */
!       int skip = partial % (PARM_BOUNDARY / BITS_PER_WORD);
        int args_offset = INTVAL (args_so_far);
  
        /* If we make space by pushing it, we might as well push
! 	 the real data.  Otherwise, we can leave SKIP nonzero
  	 and leave the space uninitialized.  */
        if (args_addr == 0)
! 	skip = 0;
  
!       /* Now NOT_STACK gets the number of units that we don't need to
  	 allocate on the stack.  */
!       not_stack = partial - skip;
  
        if (GET_CODE (x) == CONST_DOUBLE && x != dconst0_rtx)
--- 1383,1409 ----
        /* # words of start of argument
  	 that we must make space for but need not store.  */
!       int offset = partial % (PARM_BOUNDARY / BITS_PER_WORD);
        int args_offset = INTVAL (args_so_far);
+       int skip;
  
        /* If we make space by pushing it, we might as well push
! 	 the real data.  Otherwise, we can leave OFFSET nonzero
  	 and leave the space uninitialized.  */
        if (args_addr == 0)
! 	offset = 0;
  
!       /* Now NOT_STACK gets the number of words that we don't need to
  	 allocate on the stack.  */
!       not_stack = partial - offset;
! 
! /* If the partial register-part of the arg counts in its stack size,
!    skip the part of stack space corresponding to the registers.
!    Otherwise, start copying to the beginning of the stack space,
!    by setting SKIP to 0.  */
! #ifndef FIRST_PARM_CALLER_OFFSET
!       skip = 0;
! #else
!       skip = not_stack;
! #endif
  
        if (GET_CODE (x) == CONST_DOUBLE && x != dconst0_rtx)
***************
*** 1401,1405 ****
        for (i = size - 1; i >= not_stack; i--)
  #endif
! 	if (i >= not_stack + skip)
  	  {
  	    rtx wd;
--- 1418,1422 ----
        for (i = size - 1; i >= not_stack; i--)
  #endif
! 	if (i >= not_stack + offset)
  	  {
  	    rtx wd;
***************
*** 1425,1431 ****
  			    SImode, 0, align, 0, 0, 0, args_addr,
  			    gen_rtx (CONST_INT, VOIDmode,
! 				     args_offset + i * UNITS_PER_WORD));
! 
! 
  	  }
      }
--- 1442,1446 ----
  			    SImode, 0, align, 0, 0, 0, args_addr,
  			    gen_rtx (CONST_INT, VOIDmode,
! 				     args_offset + (i - not_stack + skip) * UNITS_PER_WORD));
  	  }
      }
***************
*** 1450,1453 ****
--- 1465,1474 ----
  
   ret:
+   /* If part should go in registers, copy that part
+      into the appropriate registers.  Do this now, at the end,
+      since mem-to-mem copies above may do function calls.  */
+   if (partial > 0)
+     move_block_to_reg (REGNO (reg), x, partial);
+ 
    if (extra && args_addr == 0 && where_pad == stack_direction)
      anti_adjust_stack (gen_rtx (CONST_INT, VOIDmode, extra));
***************
*** 1455,1459 ****
  \f


  /* Output a library call to function FUN (a SYMBOL_REF rtx)
!    for a value of mode OUTMODE
     with NARGS different arguments, passed as alternating rtx values
     and machine_modes to convert them to.
--- 1476,1481 ----
  \f


  /* Output a library call to function FUN (a SYMBOL_REF rtx)
!    (emitting the queue unless NO_QUEUE is nonzero),
!    for a value of mode OUTMODE,
     with NARGS different arguments, passed as alternating rtx values
     and machine_modes to convert them to.
***************
*** 1478,1486 ****
    struct arg { rtx value; enum machine_mode mode; };
    struct arg *argvec;
!   int old_args_size = current_args_size;
    int stack_padding = 0;
  
    va_start (p);
    orgfun = fun = va_arg (p, rtx);
    outmode = va_arg (p, enum machine_mode);
    nargs = va_arg (p, int);
--- 1500,1510 ----
    struct arg { rtx value; enum machine_mode mode; };
    struct arg *argvec;
!   int old_inhibit_defer_pop = inhibit_defer_pop;
    int stack_padding = 0;
+   int no_queue = 0;
  
    va_start (p);
    orgfun = fun = va_arg (p, rtx);
+   no_queue = va_arg (p, int);
    outmode = va_arg (p, enum machine_mode);
    nargs = va_arg (p, int);
***************
*** 1529,1535 ****
        register int partial;
  
!       reg = FUNCTION_ARG (args_so_far, mode, 0, 1);
  #ifdef FUNCTION_ARG_PARTIAL_NREGS
!       partial = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, mode, 0, 1);
  #else
        partial = 0;
--- 1553,1559 ----
        register int partial;
  
!       reg = FUNCTION_ARG (args_so_far, mode, (tree)0, 1);
  #ifdef FUNCTION_ARG_PARTIAL_NREGS
!       partial = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, mode, (tree)0, 1);
  #else
        partial = 0;
***************
*** 1539,1543 ****
        if (partial != 0)
  	args_size -= partial * GET_MODE_SIZE (SImode);
!       FUNCTION_ARG_ADVANCE (args_so_far, mode, 0, 1);
      }
  
--- 1563,1567 ----
        if (partial != 0)
  	args_size -= partial * GET_MODE_SIZE (SImode);
!       FUNCTION_ARG_ADVANCE (args_so_far, mode, (tree)0, 1);
      }
  
***************
*** 1575,1582 ****
        int arg_size;
  
!       reg = FUNCTION_ARG (args_so_far, mode, 0, 1);
        regvec[argnum] = reg;
  #ifdef FUNCTION_ARG_PARTIAL_NREGS
!       partial = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, mode, 0, 1);
  #else
        partial = 0;
--- 1599,1606 ----
        int arg_size;
  
!       reg = FUNCTION_ARG (args_so_far, mode, (tree)0, 1);
        regvec[argnum] = reg;
  #ifdef FUNCTION_ARG_PARTIAL_NREGS
!       partial = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, mode, (tree)0, 1);
  #else
        partial = 0;
***************
*** 1602,1609 ****
        args_size += arg_size;
        NO_DEFER_POP;
!       FUNCTION_ARG_ADVANCE (args_so_far, mode, 0, 1);
      }
  
!   emit_queue ();
  
    fun = prepare_call_address (fun, 0);
--- 1626,1635 ----
        args_size += arg_size;
        NO_DEFER_POP;
!       FUNCTION_ARG_ADVANCE (args_so_far, mode, (tree)0, 1);
      }
  
!   /* For version 1.37, try deleting this entirely.  */
!   if (! no_queue)
!     emit_queue ();
  
    fun = prepare_call_address (fun, 0);
***************
*** 1629,1633 ****
  	       FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
  	       outmode != VOIDmode ? hard_libcall_value (outmode) : 0,
! 	       old_args_size + 1);
    OK_DEFER_POP;
  }
--- 1655,1659 ----
  	       FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
  	       outmode != VOIDmode ? hard_libcall_value (outmode) : 0,
! 	       old_inhibit_defer_pop + 1);
    OK_DEFER_POP;
  }
***************
*** 1712,1715 ****
--- 1738,1742 ----
  	  tem = TREE_OPERAND (tem, 0);
  	}
+       /* TEM is now the containing data object.  */
  
        /* If we are going to use store_bit_field and extract_bit_field,
***************
*** 1726,1730 ****
  			   : VOIDmode),
  			  unsignedp,
! 			  TYPE_ALIGN (TREE_TYPE (to)));
      }
  
--- 1753,1758 ----
  			   : VOIDmode),
  			  unsignedp,
! 			  /* Required alignment of containing datum.  */
! 			  TYPE_ALIGN (TREE_TYPE (tem)) / BITS_PER_UNIT);
      }
  
***************
*** 1888,1892 ****
  		       /* The alignment of TARGET is
  			  at least what its type requires.  */
! 		       VOIDmode, 0, TYPE_ALIGN (TREE_TYPE (exp)));
  	}
      }
--- 1916,1921 ----
  		       /* The alignment of TARGET is
  			  at least what its type requires.  */
! 		       VOIDmode, 0,
! 		       TYPE_ALIGN (TREE_TYPE (exp)) / BITS_PER_UNIT);
  	}
      }
***************
*** 1931,1935 ****
  		       /* The alignment of TARGET is
  			  at least what its type requires.  */
! 		       VOIDmode, 0, TYPE_ALIGN (TREE_TYPE (exp)));
  	}
      }
--- 1960,1965 ----
  		       /* The alignment of TARGET is
  			  at least what its type requires.  */
! 		       VOIDmode, 0,
! 		       TYPE_ALIGN (TREE_TYPE (exp)) / BITS_PER_UNIT);
  	}
      }
***************
*** 2142,2145 ****
--- 2172,2179 ----
    if (subtarget && REGNO (subtarget) < FIRST_PSEUDO_REGISTER)
      subtarget = 0;
+   /* Avoid subtargets inside loops,
+      since they hide some invariant expressions.  */
+   if (optimize && inside_loop ())
+     subtarget = 0;
  
    if (ignore) target = 0, original_target = 0;
***************
*** 2240,2243 ****
--- 2274,2282 ----
        return SAVE_EXPR_RTL (exp);
  
+     case LET_STMT:
+       TREE_USED (exp) = 1;
+       temp = expand_expr (STMT_BODY (exp), target, tmode, modifier);
+       return temp;
+ 
      case RTL_EXPR:
        if (RTL_EXPR_SEQUENCE (exp) == const0_rtx)
***************
*** 2350,2353 ****
--- 2389,2419 ----
  	}
  
+       /* Fold an expression like: "foo"[2].
+ 	 This is not done in fold so it won't happen inside &.  */
+       {
+ 	int i;
+ 	tree arg0 = TREE_OPERAND (exp, 0);
+ 	tree arg1 = TREE_OPERAND (exp, 1);
+ 
+ 	if (TREE_CODE (arg0) == STRING_CST
+ 	    && TREE_CODE (arg1) == INTEGER_CST
+ 	    && !TREE_INT_CST_HIGH (arg1)
+ 	    && (i = TREE_INT_CST_LOW (arg1)) < TREE_STRING_LENGTH (arg0))
+ 	  {
+ 	    if (TREE_TYPE (TREE_TYPE (arg0)) == integer_type_node)
+ 	      {
+ 		exp = build_int_2 (((int *)TREE_STRING_POINTER (arg0))[i], 0);
+ 		TREE_TYPE (exp) = integer_type_node;
+ 		return expand_expr (exp, target, tmode, modifier);
+ 	      }
+ 	    if (TREE_TYPE (TREE_TYPE (arg0)) == char_type_node)
+ 	      {
+ 		exp = build_int_2 (TREE_STRING_POINTER (arg0)[i], 0);
+ 		TREE_TYPE (exp) = integer_type_node;
+ 		return expand_expr (convert (TREE_TYPE (TREE_TYPE (arg0)), exp), target, tmode, modifier);
+ 	      }
+ 	  }
+       }
+ 
        /* If this is a constant index into a constant array,
  	 just get the value from the array.  */
***************
*** 2427,2435 ****
  	if (mode1 == BImode || GET_CODE (op0) == REG
  	    || GET_CODE (op0) == SUBREG)
! 	  {
! 	    return extract_bit_field (op0, bitsize, bitpos, unsignedp,
! 				      target, mode, tmode,
! 				      TYPE_ALIGN (TREE_TYPE (tem)));
! 	  }
  	/* Get a reference to just this component.  */
  	if (modifier == EXPAND_CONST_ADDRESS)
--- 2493,2499 ----
  	if (mode1 == BImode || GET_CODE (op0) == REG
  	    || GET_CODE (op0) == SUBREG)
! 	  return extract_bit_field (op0, bitsize, bitpos, unsignedp,
! 				    target, mode, tmode,
! 				    TYPE_ALIGN (TREE_TYPE (tem)) / BITS_PER_UNIT);
  	/* Get a reference to just this component.  */
  	if (modifier == EXPAND_CONST_ADDRESS)
***************
*** 2477,2481 ****
  	  && (DECL_FUNCTION_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
  	      != NOT_BUILT_IN))
! 	return expand_builtin (exp, target, subtarget, tmode);
        /* If this call was expanded already by preexpand_calls,
  	 just return the result we got.  */
--- 2541,2545 ----
  	  && (DECL_FUNCTION_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
  	      != NOT_BUILT_IN))
! 	return expand_builtin (exp, target, subtarget, tmode, ignore);
        /* If this call was expanded already by preexpand_calls,
  	 just return the result we got.  */
***************
*** 2661,2665 ****
  	  this_optab = (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
  			? umul_widen_optab : smul_widen_optab);
! 	  if ((int) innermode + 1 == (int) mode
  	      && this_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
  	    {
--- 2725,2729 ----
  	  this_optab = (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
  			? umul_widen_optab : smul_widen_optab);
! 	  if (mode == GET_MODE_WIDER_MODE (innermode)
  	      && this_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
  	    {
***************
*** 2682,2685 ****
--- 2746,2750 ----
      case CEIL_DIV_EXPR:
      case ROUND_DIV_EXPR:
+     case EXACT_DIV_EXPR:
        preexpand_calls (exp);
        subtarget = validate_subtarget (subtarget, TREE_OPERAND (exp, 1));
***************
*** 3136,3139 ****
--- 3201,3205 ----
  	    emit_move_insn (target, temp);
  
+ 	  emit_queue ();
  	  do_pending_stack_adjust ();
  	  emit_label (op0);
***************
*** 3155,3162 ****
     with result going to TARGET if that's convenient
     (and in mode MODE if that's convenient).
!    SUBTARGET may be used as the target for computing one of EXP's operands.  */
  
  static rtx
! expand_builtin (exp, target, subtarget, mode)
       tree exp;
       rtx target;
--- 3221,3229 ----
     with result going to TARGET if that's convenient
     (and in mode MODE if that's convenient).
!    SUBTARGET may be used as the target for computing one of EXP's operands.
!    IGNORE is nonzero if the value is to be ignored.  */
  
  static rtx
! expand_builtin (exp, target, subtarget, mode, ignore)
       tree exp;
       rtx target;
***************
*** 3163,3166 ****
--- 3230,3234 ----
       rtx subtarget;
       enum machine_mode mode;
+      int ignore;
  {
    tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
***************
*** 3184,3191 ****
  	/* Now really call the function.  `expand_call' does not call
  	   expand_builtin, so there is no danger of infinite recursion here.  */
! 	expand_call (exp, target, 1);
! 	reorder_insns (last, get_last_insn (), get_insns ());
        }
!       
      case BUILT_IN_ALLOCA:
        if (arglist == 0
--- 3252,3306 ----
  	/* Now really call the function.  `expand_call' does not call
  	   expand_builtin, so there is no danger of infinite recursion here.  */
! 	rtx temp = expand_call (exp, target, ignore);
! 	reorder_insns (NEXT_INSN (last), get_last_insn (), get_insns ());
! 	return temp;
        }
! 
!     case BUILT_IN_CLASSIFY_TYPE:
!       if (arglist != 0)
! 	{
! 	  tree type = TREE_TYPE (TREE_VALUE (arglist));
! 	  enum tree_code code = TREE_CODE (type);
! 	  if (code == VOID_TYPE)
! 	    return gen_rtx (CONST_INT, VOIDmode, void_type_class);
! 	  if (code == INTEGER_TYPE)
! 	    return gen_rtx (CONST_INT, VOIDmode, integer_type_class);
! 	  if (code == CHAR_TYPE)
! 	    return gen_rtx (CONST_INT, VOIDmode, char_type_class);
! 	  if (code == ENUMERAL_TYPE)
! 	    return gen_rtx (CONST_INT, VOIDmode, enumeral_type_class);
! 	  if (code == BOOLEAN_TYPE)
! 	    return gen_rtx (CONST_INT, VOIDmode, boolean_type_class);
! 	  if (code == POINTER_TYPE)
! 	    return gen_rtx (CONST_INT, VOIDmode, pointer_type_class);
! 	  if (code == REFERENCE_TYPE)
! 	    return gen_rtx (CONST_INT, VOIDmode, reference_type_class);
! 	  if (code == OFFSET_TYPE)
! 	    return gen_rtx (CONST_INT, VOIDmode, offset_type_class);
! 	  if (code == REAL_TYPE)
! 	    return gen_rtx (CONST_INT, VOIDmode, real_type_class);
! 	  if (code == COMPLEX_TYPE)
! 	    return gen_rtx (CONST_INT, VOIDmode, complex_type_class);
! 	  if (code == FUNCTION_TYPE)
! 	    return gen_rtx (CONST_INT, VOIDmode, function_type_class);
! 	  if (code == METHOD_TYPE)
! 	    return gen_rtx (CONST_INT, VOIDmode, method_type_class);
! 	  if (code == RECORD_TYPE)
! 	    return gen_rtx (CONST_INT, VOIDmode, record_type_class);
! 	  if (code == UNION_TYPE)
! 	    return gen_rtx (CONST_INT, VOIDmode, union_type_class);
! 	  if (code == ARRAY_TYPE)
! 	    return gen_rtx (CONST_INT, VOIDmode, array_type_class);
! 	  if (code == STRING_TYPE)
! 	    return gen_rtx (CONST_INT, VOIDmode, string_type_class);
! 	  if (code == SET_TYPE)
! 	    return gen_rtx (CONST_INT, VOIDmode, set_type_class);
! 	  if (code == FILE_TYPE)
! 	    return gen_rtx (CONST_INT, VOIDmode, file_type_class);
! 	  if (code == LANG_TYPE)
! 	    return gen_rtx (CONST_INT, VOIDmode, lang_type_class);
! 	}
!       return gen_rtx (CONST_INT, VOIDmode, no_type_class);
! 
      case BUILT_IN_ALLOCA:
        if (arglist == 0
***************
*** 3194,3197 ****
--- 3309,3313 ----
  	return const0_rtx;
        frame_pointer_needed = 1;
+       current_function_calls_alloca = 1;
        /* Compute the argument.  */
        op0 = expand_expr (TREE_VALUE (arglist), 0, VOIDmode, 0);
***************
*** 3245,3248 ****
--- 3361,3370 ----
        anti_adjust_stack (round_push (op0));
  #endif
+       /* Some systems require a particular insn to refer to the stack
+ 	 to make the pages exist.  */
+ #ifdef HAVE_probe
+       if (HAVE_probe)
+ 	emit_insn (gen_probe ());
+ #endif
        return target;
  
***************
*** 3288,3292 ****
    if (TREE_CODE (incremented) == COMPONENT_REF
        && (TREE_CODE (TREE_OPERAND (incremented, 0)) != INDIRECT_REF
! 	  || DECL_MODE (TREE_OPERAND (exp, 1)) == BImode))
      incremented = stabilize_reference (incremented);
  
--- 3410,3414 ----
    if (TREE_CODE (incremented) == COMPONENT_REF
        && (TREE_CODE (TREE_OPERAND (incremented, 0)) != INDIRECT_REF
! 	  || DECL_MODE (TREE_OPERAND (incremented, 1)) == BImode))
      incremented = stabilize_reference (incremented);
  
***************
*** 3367,3371 ****
    /* Increment however we can.  */
    op1 = expand_binop (mode, this_optab, op0, op1, op0,
! 		      0, OPTAB_LIB_WIDEN);
    /* Make sure the value is stored into OP0.  */
    if (op1 != op0)
--- 3489,3493 ----
    /* Increment however we can.  */
    op1 = expand_binop (mode, this_optab, op0, op1, op0,
! 		      TREE_UNSIGNED (TREE_TYPE (exp)), OPTAB_LIB_WIDEN);
    /* Make sure the value is stored into OP0.  */
    if (op1 != op0)
***************
*** 3514,3523 ****
     or 0 if the call does not return a value.
  
!    OLD_ARGS_SIZE is the value that `current_args_size' had before
     the args to this call were processed.
!    We restore `current_args_size' to that value.  */
  
  static void
! emit_call_1 (funexp, funtype, stack_size, next_arg_reg, valreg, old_args_size)
       rtx funexp;
       tree funtype;
--- 3636,3645 ----
     or 0 if the call does not return a value.
  
!    OLD_INHIBIT_DEFER_POP is the value that `inhibit_defer_pop' had before
     the args to this call were processed.
!    We restore `inhibit_defer_pop' to that value.  */
  
  static void
! emit_call_1 (funexp, funtype, stack_size, next_arg_reg, valreg, old_inhibit_defer_pop)
       rtx funexp;
       tree funtype;
***************
*** 3525,3529 ****
       rtx next_arg_reg;
       rtx valreg;
!      int old_args_size;
  {
    rtx stack_size_rtx = gen_rtx (CONST_INT, VOIDmode, stack_size);
--- 3647,3651 ----
       rtx next_arg_reg;
       rtx valreg;
!      int old_inhibit_defer_pop;
  {
    rtx stack_size_rtx = gen_rtx (CONST_INT, VOIDmode, stack_size);
***************
*** 3537,3541 ****
  			      stack_size_rtx, next_arg_reg));
  
!   current_args_size = old_args_size;
  
    /* If returning from the subroutine does not automatically pop the args,
--- 3659,3663 ----
  			      stack_size_rtx, next_arg_reg));
  
!   inhibit_defer_pop = old_inhibit_defer_pop;
  
    /* If returning from the subroutine does not automatically pop the args,
***************
*** 3546,3550 ****
        && stack_size != 0)
      {
!       if (flag_defer_pop && current_args_size == 0)
  	pending_stack_adjust += stack_size;
        else
--- 3668,3672 ----
        && stack_size != 0)
      {
!       if (flag_defer_pop && inhibit_defer_pop == 0)
  	pending_stack_adjust += stack_size;
        else
***************
*** 3576,3586 ****
  }
  
- /* At start of function, initialize.  */
- void
- clear_current_args_size ()
- {
-   current_args_size = 0;
- }
- 
  /* Pop any previously-pushed arguments that have not been popped yet.  */
  
--- 3698,3701 ----
***************
*** 3588,3592 ****
  do_pending_stack_adjust ()
  {
!   if (current_args_size == 0)
      {
        if (pending_stack_adjust != 0)
--- 3703,3707 ----
  do_pending_stack_adjust ()
  {
!   if (inhibit_defer_pop == 0)
      {
        if (pending_stack_adjust != 0)
***************
*** 3596,3604 ****
  }
  \f


! /* Generate all the code for a function call
!    and return an rtx for its value.
!    Store the value in TARGET (specified as an rtx) if convenient.
!    If the value is stored in TARGET then TARGET is returned.
!    If IGNORE is nonzero, then we ignore the value of the function call.  */
  
  struct arg_data
--- 3711,3715 ----
  }
  \f


! /* Data structure and subroutines used within expand_call.  */
  
  struct arg_data
***************
*** 3628,3631 ****
--- 3739,3751 ----
  };
  
+ static void store_one_arg ();
+ static rtx target_for_arg ();
+ \f


+ /* Generate all the code for a function call
+    and return an rtx for its value.
+    Store the value in TARGET (specified as an rtx) if convenient.
+    If the value is stored in TARGET then TARGET is returned.
+    If IGNORE is nonzero, then we ignore the value of the function call.  */
+ 
  static rtx
  expand_call (exp, target, ignore)
***************
*** 3717,3721 ****
    rtx old_stack_level = 0;
    int old_pending_adj;
!   int old_current_args_size = current_args_size;
    tree old_cleanups = cleanups_of_this_call;
  
--- 3837,3841 ----
    rtx old_stack_level = 0;
    int old_pending_adj;
!   int old_inhibit_defer_pop = inhibit_defer_pop;
    tree old_cleanups = cleanups_of_this_call;
  
***************
*** 3743,3748 ****
  	      /* In case this function later becomes inlineable,
  		 record that there was already a non-inline call to it.  */
! 	      TREE_ADDRESSABLE (fndecl) = 1;
! 	      TREE_ADDRESSABLE (DECL_NAME (fndecl)) = 1;
  	    }
  
--- 3863,3867 ----
  	      /* In case this function later becomes inlineable,
  		 record that there was already a non-inline call to it.  */
! 	      mark_addressable (fndecl);
  	    }
  
***************
*** 3752,3762 ****
      }
  
    /* Set up a place to return a structure.  */
  
!   if (TYPE_MODE (TREE_TYPE (exp)) == BLKmode
!       || RETURN_IN_MEMORY (TREE_TYPE (exp))
!       || (flag_pcc_struct_return
! 	  && (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
! 	      || TREE_CODE (TREE_TYPE (exp)) == UNION_TYPE)))
      {
        /* This call returns a big structure.  */
--- 3871,3883 ----
      }
  
+   /* When calling a const function, we must pop the stack args right away,
+      so that the pop is deleted or moved with the call.  */
+   if (is_const)
+     NO_DEFER_POP;
+ 
    /* Set up a place to return a structure.  */
  
!   /* Cater to broken compilers.  */
!   if (aggregate_value_p (exp))
      {
        /* This call returns a big structure.  */
***************
*** 3777,3782 ****
  	    }
  	  else
! 	    /* Make room on the stack to hold the value.  */
! 	    structure_value_addr = get_structure_value_addr (expr_size (exp));
  	}
      }
--- 3898,3907 ----
  	    }
  	  else
! 	    {
! 	      /* Make room on the stack to hold the value.  */
! 	      structure_value_addr
! 		= get_structure_value_addr (expr_size (exp));
! 	      target = 0;
! 	    }
  	}
      }
***************
*** 3838,3841 ****
--- 3963,3967 ----
        frame_pointer_needed = 1;
        may_call_alloca = 1;
+       current_function_calls_alloca = 1;
      }
  
***************
*** 3854,3865 ****
    funtype = TREE_TYPE (funtype);
  
!   /* If the address for a structure value should be in memory,
!      and it would go in memory if treated as an extra parameter,
!      treat it that way.  */
!   if (structure_value_addr && GET_CODE (struct_value_rtx) == MEM
!       && (GET_CODE (XEXP (struct_value_rtx, 0)) == PRE_DEC
! 	  || GET_CODE (XEXP (struct_value_rtx, 0)) == PRE_INC
! 	  || GET_CODE (XEXP (struct_value_rtx, 0)) == POST_DEC
! 	  || GET_CODE (XEXP (struct_value_rtx, 0)) == POST_INC))
      {
        rtx tem;
--- 3980,3986 ----
    funtype = TREE_TYPE (funtype);
  
!   /* If struct_value_rtx is 0, it means pass the address
!      as if it were an extra parameter.  */
!   if (structure_value_addr && struct_value_rtx == 0)
      {
        rtx tem;
***************
*** 3885,3892 ****
  
    /* Compute number of named args.
!      This may actually be 1 too large, but that happens
!      only in the case when all args are named, so no trouble results.  */
    if (TYPE_ARG_TYPES (funtype) != 0)
!     n_named_args = list_length (TYPE_ARG_TYPES (funtype));
    else
      /* If we know nothing, treat all args as named.  */
--- 4006,4014 ----
  
    /* Compute number of named args.
!      Don't include the last named arg if anonymous args follow.
!      (If no anonymous args follow, the result of list_length
!      is actually one too large.)  */
    if (TYPE_ARG_TYPES (funtype) != 0)
!     n_named_args = list_length (TYPE_ARG_TYPES (funtype)) - 1;
    else
      /* If we know nothing, treat all args as named.  */
***************
*** 3900,3904 ****
    args_size.var = 0;
  #ifdef FIRST_PARM_CALLER_OFFSET
!   args_size.constant = FIRST_PARM_CALLER_OFFSET (fntype);
    stack_count_regparms = 1;
  #endif
--- 4022,4026 ----
    args_size.var = 0;
  #ifdef FIRST_PARM_CALLER_OFFSET
!   args_size.constant = FIRST_PARM_CALLER_OFFSET (funtype);
    stack_count_regparms = 1;
  #endif
***************
*** 3962,3969 ****
  	      /* If the previous args don't reach such a boundary,
  		 advance to the next one.  */
  	      args[i].offset.constant += boundary - 1;
! 	      args[i].offset.constant &= boundary - 1;
  	      args_size.constant += boundary - 1;
! 	      args_size.constant &= boundary - 1;
  
  	      if (args_size.var != 0)
--- 4084,4092 ----
  	      /* If the previous args don't reach such a boundary,
  		 advance to the next one.  */
+ 	      boundary /= BITS_PER_UNIT;
  	      args[i].offset.constant += boundary - 1;
! 	      args[i].offset.constant &= ~(boundary - 1);
  	      args_size.constant += boundary - 1;
! 	      args_size.constant &= ~(boundary - 1);
  
  	      if (args_size.var != 0)
***************
*** 4041,4045 ****
  		  /* If parameter's offset is variable, assume the worst.  */
  		  = (args[i].offset.var
! 		     ? FIRST_PARM_CALLER_OFFSET (fntype)
  		     : args[i].offset.constant);
  #endif
--- 4164,4168 ----
  		  /* If parameter's offset is variable, assume the worst.  */
  		  = (args[i].offset.var
! 		     ? FIRST_PARM_CALLER_OFFSET (funtype)
  		     : args[i].offset.constant);
  #endif
***************
*** 4288,4292 ****
    /* Pass the function the address in which to return a structure value.  */
    if (structure_value_addr && ! structure_value_addr_parm)
!     emit_move_insn (struct_value_rtx, force_reg (Pmode, structure_value_addr));
  
    /* Now set up any wholly-register parms.  They were computed already.  */
--- 4411,4416 ----
    /* Pass the function the address in which to return a structure value.  */
    if (structure_value_addr && ! structure_value_addr_parm)
!     emit_move_insn (struct_value_rtx,
! 		    force_reg (Pmode, force_operand (structure_value_addr, 0)));
  
    /* Now set up any wholly-register parms.  They were computed already.  */
***************
*** 4323,4327 ****
        }
  
!   if (structure_value_addr && GET_CODE (struct_value_rtx) == REG)
      emit_insn (gen_rtx (USE, VOIDmode, struct_value_rtx));
  
--- 4447,4452 ----
        }
  
!   if (structure_value_addr && ! structure_value_addr_parm
!       && GET_CODE (struct_value_rtx) == REG)
      emit_insn (gen_rtx (USE, VOIDmode, struct_value_rtx));
  
***************
*** 4337,4341 ****
    emit_call_1 (funexp, funtype, args_size.constant,
  	       FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
! 	       valreg, old_current_args_size);
  
  /* ???  Nothing has been done here to record control flow
--- 4462,4466 ----
    emit_call_1 (funexp, funtype, args_size.constant,
  	       FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
! 	       valreg, old_inhibit_defer_pop);
  
  /* ???  Nothing has been done here to record control flow
***************
*** 4435,4438 ****
--- 4560,4566 ----
        rtx note = 0;
  
+       /* Cancel the NO_DEFER_POP done at start of expand_call.  */
+       OK_DEFER_POP;
+ 
        /* Construct an "equal form" for the value
  	 which mentions all the arguments in order
***************
*** 4672,4676 ****
  	  /* PUSH_ROUNDING has no effect on us, because
  	     emit_push_insn for BLKmode is careful to avoid it.  */
! 	  excess = arg->size.constant - TREE_INT_CST_LOW (size);
  	  size_rtx = expand_expr (size, 0, VOIDmode, 0);
  	}
--- 4800,4805 ----
  	  /* PUSH_ROUNDING has no effect on us, because
  	     emit_push_insn for BLKmode is careful to avoid it.  */
! 	  excess = (arg->size.constant - TREE_INT_CST_LOW (size)
! 		    + arg->partial * UNITS_PER_WORD);
  	  size_rtx = expand_expr (size, 0, VOIDmode, 0);
  	}
***************
*** 5084,5087 ****
--- 5213,5218 ----
    register rtx comparison = 0;
    enum machine_mode compare_mode;
+   rtx prev_insn = get_last_insn ();
+   enum insn_code icode;
  
    switch (code)
***************
*** 5092,5095 ****
--- 5223,5227 ----
  	{
  	  comparison = compare (exp, EQ, EQ, EQ, EQ);
+ 	  icode = CODE_FOR_seq;
  	  compare_mode = insn_operand_mode[(int) CODE_FOR_seq][0];
  	}
***************
*** 5102,5105 ****
--- 5234,5238 ----
  	{
  	  comparison = compare (exp, NE, NE, NE, NE);
+ 	  icode = CODE_FOR_sne;
  	  compare_mode = insn_operand_mode[(int) CODE_FOR_sne][0];
  	}
***************
*** 5112,5115 ****
--- 5245,5249 ----
  	{
  	  comparison = compare (exp, LT, LTU, GT, GTU);
+ 	  icode = CODE_FOR_slt;
  	  compare_mode = insn_operand_mode[(int) CODE_FOR_slt][0];
  	}
***************
*** 5120,5123 ****
--- 5254,5258 ----
  	{
  	  comparison = compare (exp, GT, GTU, LT, LTU);
+ 	  icode = CODE_FOR_slt;
  	  compare_mode = insn_operand_mode[(int) CODE_FOR_slt][0];
  	}
***************
*** 5130,5133 ****
--- 5265,5269 ----
  	{
  	  comparison = compare (exp, LE, LEU, GE, GEU);
+ 	  icode = CODE_FOR_sle;
  	  compare_mode = insn_operand_mode[(int) CODE_FOR_sle][0];
  	}
***************
*** 5138,5141 ****
--- 5274,5278 ----
  	{
  	  comparison = compare (exp, GE, GEU, LE, LEU);
+ 	  icode = CODE_FOR_sle;
  	  compare_mode = insn_operand_mode[(int) CODE_FOR_sle][0];
  	}
***************
*** 5147,5151 ****
  
    if (target == 0 || GET_MODE (target) != mode
!       || (mode != compare_mode && GET_CODE (target) != REG))
      target = gen_reg_rtx (mode);
  
--- 5284,5293 ----
  
    if (target == 0 || GET_MODE (target) != mode
!       /* Don't use specified target unless the insn can handle it.  */
!       || ! (*insn_operand_predicate[(int) icode][0]) (target, mode)
!       /* When modes don't match, don't use specified target,
! 	 because it might be the same as an operand,
! 	 and then the CLOBBER output below would screw up.  */
!       || (mode != compare_mode && GET_CODE (comparison) != CONST_INT))
      target = gen_reg_rtx (mode);
  
***************
*** 5154,5159 ****
      emit_move_insn (target, comparison);
    else if (GET_MODE (target) != compare_mode)
!     emit_insn ((*setcc_gen_fctn[(int) GET_CODE (comparison)])
! 	       (gen_rtx (SUBREG, compare_mode, target, 0)));
    else
      emit_insn ((*setcc_gen_fctn[(int) GET_CODE (comparison)]) (target));
--- 5296,5314 ----
      emit_move_insn (target, comparison);
    else if (GET_MODE (target) != compare_mode)
!     {
!       /* We want a different mode: store result in its natural mode.
! 	 Combine the mode conversion with the truncation we must do anyway.  */
!       /* Put a CLOBBER before the compare, so we don't come between
! 	 the compare and the insn that uses the result.  */
!       emit_insn_after (gen_rtx (CLOBBER, VOIDmode, target), prev_insn);
!       emit_insn ((*setcc_gen_fctn[(int) GET_CODE (comparison)])
! 		 (gen_rtx (SUBREG, compare_mode, target, 0)));
!       /* If the desired mode is wider than what we got,
! 	 use an AND to convert it, but not if we will do one anyway.  */
! #if STORE_FLAG_VALUE == 1
!       if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (compare_mode))
! 	expand_bit_and (mode, target, const1_rtx, target);
! #endif
!     }
    else
      emit_insn ((*setcc_gen_fctn[(int) GET_CODE (comparison)]) (target));
***************
*** 5160,5164 ****
--- 5315,5325 ----
  
  #if STORE_FLAG_VALUE != 1
+ #if STORE_FLAG_VALUE & 1
    expand_bit_and (mode, target, const1_rtx, target);
+ #else
+   expand_shift (RSHIFT_EXPR, mode, target,
+ 		build_int_2 (GET_MODE_BITSIZE (mode) - 1, 0),
+ 		target, TRUE);
+ #endif
  #endif
    return target;
diff -rc2N gcc-1.35/expr.h gcc-1.36/expr.h
*** gcc-1.35/expr.h	Wed Mar 29 16:56:02 1989
--- gcc-1.36/expr.h	Thu Aug 24 14:40:45 1989
***************
*** 54,57 ****
--- 54,68 ----
     So we can mark them all live at the end of the function, if stupid.  */
  extern rtx save_expr_regs;
+ 
+ extern int current_function_calls_alloca;
+ 
+ /* Nonzero means stack pops must not be deferred, and deferred stack
+    pops must not be output.  It is nonzero inside a function call,
+    inside a conditional expression, inside a statement expression,
+    and in other cases as well.  */
+ extern int inhibit_defer_pop;
+ 
+ #define NO_DEFER_POP (inhibit_defer_pop += 1)
+ #define OK_DEFER_POP (inhibit_defer_pop -= 1)
  \f


  #ifdef TREE_CODE /* Don't lose if tree.h not included.  */
***************
*** 192,196 ****
     if the requested operation can't be open-coded on the requisite mode.
     Either OPTAB_LIB or OPTAB_LIB_WIDEN says try using a library call.
!    Either OPTAB_WIDEN or OPTAB_LIB_WIDEN says try using a wider mode.  */
  
  enum optab_methods
--- 203,208 ----
     if the requested operation can't be open-coded on the requisite mode.
     Either OPTAB_LIB or OPTAB_LIB_WIDEN says try using a library call.
!    Either OPTAB_WIDEN or OPTAB_LIB_WIDEN says try using a wider mode.
!    OPTAB_MUST_WIDEN says try widening and don't try anything else.  */
  
  enum optab_methods
***************
*** 200,203 ****
--- 212,216 ----
    OPTAB_WIDEN,
    OPTAB_LIB_WIDEN,
+   OPTAB_MUST_WIDEN,
  };
  \f


***************
*** 359,362 ****
--- 372,376 ----
  rtx expand_mult ();
  rtx expand_divmod ();
+ rtx expand_mult_add ();
  rtx get_structure_value_addr ();
  rtx expand_stmt_expr ();
diff -rc2N gcc-1.35/final.c gcc-1.36/final.c
*** gcc-1.35/final.c	Wed Mar 29 17:36:09 1989
--- gcc-1.36/final.c	Tue Aug 22 23:16:56 1989
***************
*** 54,57 ****
--- 54,58 ----
  #include "flags.h"
  #include "real.h"
+ #include "output.h"
  
  /* Get N_SLINE and N_SOL from stab.h if we can expect the file to exist.  */
***************
*** 76,79 ****
--- 77,81 ----
  #define min(A,B) ((A) < (B) ? (A) : (B))
  
+ rtx peephole ();
  void output_asm_insn ();
  rtx alter_subreg ();
***************
*** 84,87 ****
--- 86,90 ----
  void output_addr_const ();
  static void output_source_line ();
+ rtx final_scan_insn ();
  
  /* the sdb debugger needs the line given as an offset from the beginning
***************
*** 109,112 ****
--- 112,123 ----
  extern FILE *asm_out_file;
  
+ /* Compare optimization flag. */
+ 
+ static rtx last_ignored_compare = 0;
+ 
+ /* Flag indicating this insn is the start of a new basic block. */
+ 
+ static int new_block = 1;
+ 
  /* All the symbol-blocks (levels of scoping) in the compilation
     are assigned sequence numbers in order of appearance of the
***************
*** 191,194 ****
--- 202,210 ----
  
  static int app_on;
+ 
+ /* If we are outputting an insn sequence, this contains the sequence rtx.
+    Zero otherwise.  */
+ 
+ rtx final_sequence;
  \f


  /* Initialize data in final at the beginning of a compilation.  */
***************
*** 205,208 ****
--- 221,225 ----
    gdbfiles = 0;
    next_gdb_filenum = 0;
+   final_sequence = 0;
  }
  
***************
*** 252,255 ****
--- 269,277 ----
        assemble_string (filename, strlen (filename) + 1);
  
+       /* Realign data section.  */
+       ASM_OUTPUT_ALIGN (asm_out_file,
+ 			exact_log2 (min (UNITS_PER_WORD,
+ 					 BIGGEST_ALIGNMENT / BITS_PER_UNIT)));
+ 
        /* Make space for the table of counts.  */
        ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBX", 2);
***************
*** 299,302 ****
--- 321,344 ----
  }
  \f


+ /* Return the number of slots filled in the current 
+    delayed branch sequence. */
+ 
+ #ifdef HAVE_DELAYED_BRANCH
+ int
+ dbr_sequence_length ()
+ {
+   int i;
+   int slots = 0;
+   /* It's zero if we are not scheduling or not in a sequence. 
+      (We never count the first insn.)                  */
+   if (flag_delayed_branch && final_sequence != 0)
+     {
+       for (i = 1; i < XVECLEN (final_sequence, 0); i++)
+ 	slots += DBR_INSN_SLOTS (XVECEXP (final_sequence, 0, i));
+     }
+   return slots;
+ }
+ #endif
+ \f


  /* Output assembler code for the start of a function,
     and initialize some of the variables in this file
***************
*** 343,348 ****
  #ifdef SDB_DEBUGGING_INFO
    next_block_index = 1;
-   if (write_symbols == SDB_DEBUG)
-     sdbout_begin_function (last_linenum);
  #endif
  
--- 385,388 ----
***************
*** 479,486 ****
  {
    register rtx insn;
-   register int i;
-   rtx last_ignored_compare = 0;
-   int new_block = 1;
  
    init_recog ();
  
--- 519,526 ----
  {
    register rtx insn;
  
+   last_ignored_compare = 0;
+   new_block = 1;
+ 
    init_recog ();
  
***************
*** 487,926 ****
    CC_STATUS_INIT;
  
!   for (insn = NEXT_INSN (first); insn; insn = NEXT_INSN (insn))
!     {
!       switch (GET_CODE (insn))
! 	{
! 	case NOTE:
! 	  if (prescan > 0)
! 	    break;
! 	  if (write_symbols == NO_DEBUG)
! 	    break;
! 	  if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG)
! 	    abort ();		/* Obsolete; shouldn't appear */
! 	  if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
! 	      || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
! 	    break;
! 	  if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED)
! 	    break;		/* An insn that was "deleted" */
! 	  if (app_on)
! 	    {
! 	      fprintf (file, ASM_APP_OFF);
! 	      app_on = 0;
! 	    }
! 	  if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG)
! 	    {
! 	      /* Beginning of a symbol-block.  Assign it a sequence number
! 		 and push the number onto the stack PENDING_BLOCKS.  */
  
! 	      if (block_depth == max_block_depth)
! 		{
! 		  /* PENDING_BLOCKS is full; make it longer.  */
! 		  max_block_depth *= 2;
! 		  pending_blocks
! 		    = (int *) xrealloc (pending_blocks,
! 					max_block_depth * sizeof (int));
! 		}
! 	      pending_blocks[block_depth++] = next_block_index;
  
! 	      /* Output debugging info about the symbol-block beginning.  */
  
  #ifdef SDB_DEBUGGING_INFO
! 	      if (write_symbols == SDB_DEBUG)
! 		sdbout_begin_block (file, last_linenum, next_block_index);
  #endif
  #ifdef DBX_DEBUGGING_INFO
! 	      if (write_symbols == DBX_DEBUG)
! 		ASM_OUTPUT_INTERNAL_LABEL (file, "LBB", next_block_index);
  #endif
! 	      if (write_symbols == GDB_DEBUG)
! 		fprintf (file, "\t.gdbbeg %d\n", next_block_index);
! 
! 	      next_block_index++;
! 	    }
! 	  else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
! 	    {
! 	      /* End of a symbol-block.  Pop its sequence number off
! 		 PENDING_BLOCKS and output debugging info based on that.  */
  
! 	      --block_depth;
  
  #ifdef DBX_DEBUGGING_INFO
! 	      if (write_symbols == DBX_DEBUG && block_depth >= 0)
! 		ASM_OUTPUT_INTERNAL_LABEL (file, "LBE",
! 					   pending_blocks[block_depth]);
  #endif
  
! #ifdef SDB_DEBUGGING_INFO
! 	      if (write_symbols == SDB_DEBUG && block_depth >= 0)
! 		sdbout_end_block (file, last_linenum);
! #endif
! 
! 	      if (write_symbols == GDB_DEBUG)
! 		fprintf (file, "\t.gdbend %d\n", pending_blocks[block_depth]);
! 	    }
! 	  else if (NOTE_LINE_NUMBER (insn) > 0)
! 	    /* This note is a line-number.  */
! 	    output_source_line (file, insn, write_symbols);
! 	  break;
  
! 	case BARRIER:
  #ifdef ASM_OUTPUT_ALIGN_CODE
! 	  ASM_OUTPUT_ALIGN_CODE (file);
  #endif
! 	  break;
  
! 	case CODE_LABEL:
! 	  CC_STATUS_INIT;
! 	  if (prescan > 0)
! 	    break;
! 	  new_block = 1;
! 	  if (app_on)
! 	    {
! 	      fprintf (file, ASM_APP_OFF);
! 	      app_on = 0;
! 	    }
  #ifdef ASM_OUTPUT_CASE_LABEL
! 	  if (NEXT_INSN (insn) != 0
! 	      && GET_CODE (NEXT_INSN (insn)) == JUMP_INSN)
! 	    {
! 	      rtx nextbody = PATTERN (NEXT_INSN (insn));
! 
! 	      /* If this label is followed by a jump-table,
! 		 output the two of them together in a special way.  */
  
! 	      if (GET_CODE (nextbody) == ADDR_VEC
! 		  || GET_CODE (nextbody) == ADDR_DIFF_VEC)
! 		{
! 		  ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
! 					 NEXT_INSN (insn));
! 		  break;
! 		}
  	    }
  #endif
  
! 	  ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (insn));
  	  break;
  
! 	default:
  	  {
! 	    register rtx body = PATTERN (insn);
! 	    int insn_code_number;
! 	    char *template;
! 
! 	    /* An INSN, JUMP_INSN or CALL_INSN.
! 	       First check for special kinds that recog doesn't recognize.  */
! 
! 	    if (GET_CODE (body) == USE /* These are just declarations */
! 		|| GET_CODE (body) == CLOBBER)
! 	      break;
! 
! 	    if (profile_block_flag && new_block)
! 	      {
! 		new_block = 0;
! 		/* Enable the table of basic-block use counts
! 		   to point at the code it applies to.  */
! 		ASM_OUTPUT_INTERNAL_LABEL (file, "LPB", count_basic_blocks);
! 		/* Before first insn of this basic block, increment the
! 		   count of times it was entered.  */
  #ifdef BLOCK_PROFILER
! 		BLOCK_PROFILER (file, count_basic_blocks);
  #endif
! 		count_basic_blocks++;
! 	      }
  
! 	    if (GET_CODE (body) == ASM_INPUT)
  	      {
! 		/* There's no telling what that did to the condition codes.  */
! 		CC_STATUS_INIT;
! 		if (prescan > 0)
! 		  break;
! 		if (! app_on)
! 		  {
! 		    fprintf (file, ASM_APP_ON);
! 		    app_on = 1;
! 		  }
! 		fprintf (asm_out_file, "\t%s\n", XSTR (body, 0));
! 		break;
  	      }
  
! 	    /* Detect `asm' construct with operands.  */
! 	    if (asm_noperands (body) >= 0)
! 	      {
! 		int noperands = asm_noperands (body);
! 		rtx *ops;
! 		char *string;
  
! 		/* There's no telling what that did to the condition codes.  */
! 		CC_STATUS_INIT;
! 		if (prescan > 0)
! 		  break;
  
! 		/* alloca won't do here, since only return from `final'
! 		   would free it.  */
! 		if (noperands > 0)
! 		  ops = (rtx *) xmalloc (noperands * sizeof (rtx));
  
! 		if (! app_on)
! 		  {
! 		    fprintf (file, ASM_APP_ON);
! 		    app_on = 1;
! 		  }
  
! 		/* Get out the operand values.  */
! 		string = decode_asm_operands (body, ops, 0, 0, 0);
! 		/* Inhibit aborts on what would otherwise be compiler bugs.  */
! 		insn_noperands = noperands;
! 		this_is_asm_operands = insn;
! 		/* Output the insn using them.  */
! 		output_asm_insn (string, ops);
! 		this_is_asm_operands = 0;
! 		if (noperands > 0)
! 		  free (ops);
! 		break;
! 	      }
  
! 	    if (prescan <= 0 && app_on)
! 	      {
! 		fprintf (file, ASM_APP_OFF);
! 		app_on = 0;
! 	      }
! 
! 	    /* Detect insns that are really jump-tables
! 	       and output them as such.  */
! 
! 	    if (GET_CODE (body) == ADDR_VEC)
! 	      {
! 		register int vlen, idx;
  
! 		if (prescan > 0)
! 		  break;
  
! 		vlen = XVECLEN (body, 0);
! 		for (idx = 0; idx < vlen; idx++)
! 		  ASM_OUTPUT_ADDR_VEC_ELT (file,
! 			   CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0)));
  #ifdef ASM_OUTPUT_CASE_END
! 		ASM_OUTPUT_CASE_END (file,
! 				     CODE_LABEL_NUMBER (PREV_INSN (insn)),
! 				     insn);
  #endif
! 		break;
! 	      }
! 	    if (GET_CODE (body) == ADDR_DIFF_VEC)
! 	      {
! 		register int vlen, idx;
  
! 		if (prescan > 0)
! 		  break;
  
! 		vlen = XVECLEN (body, 1);
! 		for (idx = 0; idx < vlen; idx++)
! 		  ASM_OUTPUT_ADDR_DIFF_ELT (file,
! 			   CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 1, idx), 0)),
! 			   CODE_LABEL_NUMBER (XEXP (XEXP (body, 0), 0)));
  #ifdef ASM_OUTPUT_CASE_END
! 		ASM_OUTPUT_CASE_END (file,
! 				     CODE_LABEL_NUMBER (PREV_INSN (insn)),
! 				     insn);
  #endif
! 		break;
! 	      }
  
! 	    /* We have a real machine instruction as rtl.  */
  
! 	    body = PATTERN (insn);
  
! 	    /* Check for redundant test and compare instructions
! 	       (when the condition codes are already set up as desired).
! 	       This is done only when optimizing; if not optimizing,
! 	       it should be possible for the user to alter a variable
! 	       with the debugger in between statements
! 	       and the next statement should reexamine the variable
! 	       to compute the condition codes.  */
! 
! 	    if (optimize
! 		&& GET_CODE (body) == SET
! 		&& GET_CODE (SET_DEST (body)) == CC0)
! 	      {
! 		if (GET_CODE (SET_SRC (body)) == SUBREG)
! 		  SET_SRC (body) = alter_subreg (SET_SRC (body));
! 		if ((cc_status.value1 != 0
! 		     && rtx_equal_p (SET_SRC (body), cc_status.value1))
! 		    || (cc_status.value2 != 0
! 			&& rtx_equal_p (SET_SRC (body), cc_status.value2)))
  		  {
! 		    /* Don't delete insn if has an addressing side-effect */
! 		    if (! find_reg_note (insn, REG_INC, 0)
! 			/* or if anything in it is volatile.  */
! 			&& ! volatile_refs_p (PATTERN (insn)))
! 		      {
! 			/* We don't really delete the insn; just ignore it.  */
! 			last_ignored_compare = insn;
! 			break;
! 		      }
  		  }
  	      }
  
! 	  reinsert_compare:
  
! 	    /* Following a conditional branch, we have a new basic block.  */
! 	    if (GET_CODE (insn) == JUMP_INSN && GET_CODE (body) == SET
! 		&& GET_CODE (SET_SRC (body)) != LABEL_REF)
! 	      new_block = 1;
! 
! 	    /* If this is a conditional branch, maybe modify it
! 	       if the cc's are in a nonstandard state
! 	       so that it accomplishes the same thing that it would
! 	       do straightforwardly if the cc's were set up normally.  */
! 
! 	    if (cc_status.flags != 0
! 		&& GET_CODE (insn) == JUMP_INSN
! 		&& GET_CODE (body) == SET
! 		&& SET_DEST (body) == pc_rtx
! 		&& GET_CODE (SET_SRC (body)) == IF_THEN_ELSE
! 		/* This is done during prescan; it is not done again
! 		   in final scan when prescan has been done.  */
! 		&& prescan >= 0)
! 	      {
! 		/* This function may alter the contents of its argument
! 		   and clear some of the cc_status.flags bits.
! 		   It may also return 1 meaning condition now always true
! 		   or -1 meaning condition now always false
! 		   or 2 meaning condition nontrivial but altered.  */
! 		register int result = alter_cond (XEXP (SET_SRC (body), 0));
! 		/* If condition now has fixed value, replace the IF_THEN_ELSE
! 		   with its then-operand or its else-operand.  */
  		if (result == 1)
! 		  SET_SRC (body) = XEXP (SET_SRC (body), 1);
  		if (result == -1)
! 		  SET_SRC (body) = XEXP (SET_SRC (body), 2);
! 		/* The jump is now either unconditional or a no-op.
! 		   If it has become a no-op, don't try to output it.
! 		   (It would not be recognized.)  */
! 		if (SET_SRC (body) == pc_rtx)
! 		  {
! 		    PUT_CODE (insn, NOTE);
! 		    NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
! 		    NOTE_SOURCE_FILE (insn) = 0;
! 		    break;
! 		  }
! 		/* Rerecognize the instruction if it has changed.  */
  		if (result != 0)
  		  INSN_CODE (insn) = -1;
  	      }
! 
! #ifdef STORE_FLAG_VALUE
! 	    /* Make same adjustments to instructions that examine the
! 	       condition codes without jumping (if this machine has them).  */
! 
! 	    if (cc_status.flags != 0
! 		&& GET_CODE (body) == SET)
! 	      switch (GET_CODE (SET_SRC (body)))
! 		{
! 		case GTU:
! 		case GT:
! 		case LTU:
! 		case LT:
! 		case GEU:
! 		case GE:
! 		case LEU:
! 		case LE:
! 		case EQ:
! 		case NE:
! 		  {
! 		    register int result;
! 		    if (GET_CODE (XEXP (SET_SRC (body), 0)) != CC0)
! 		      break;
! 		    result = alter_cond (SET_SRC (body));
! 		    if (result == 1)
! 		      SET_SRC (body) = gen_rtx (CONST_INT, VOIDmode,
! 						STORE_FLAG_VALUE);
! 		    if (result == -1)
! 		      SET_SRC (body) = const0_rtx;
! 		    if (result != 0)
! 		      INSN_CODE (insn) = -1;
! 		  }
! 		}
! #endif /* STORE_FLAG_VALUE */
  
! 	    /* Do machine-specific peephole optimizations if desired.  */
  
! 	    if (optimize && !flag_no_peephole)
! 	      {
! 		peephole (insn);
! 
! 		/* PEEPHOLE might have changed this.  */
! 		body = PATTERN (insn);
! 	      }
! 
! 	    /* Try to recognize the instruction.
! 	       If successful, verify that the operands satisfy the
! 	       constraints for the instruction.  Crash if they don't,
! 	       since `reload' should have changed them so that they do.  */
! 
! 	    insn_code_number = recog_memoized (insn);
! 	    insn_extract (insn);
! 	    for (i = 0; i < insn_n_operands[insn_code_number]; i++)
  	      {
! 		if (GET_CODE (recog_operand[i]) == SUBREG)
! 		  recog_operand[i] = alter_subreg (recog_operand[i]);
  	      }
  
  #ifdef REGISTER_CONSTRAINTS
! 	    if (! constrain_operands (insn_code_number))
! 	      abort ();
  #endif
  
! 	    /* Some target machines need to prescan each insn before
! 	       it is output.  */
  
  #ifdef FINAL_PRESCAN_INSN
! 	    FINAL_PRESCAN_INSN (insn, recog_operand,
! 				insn_n_operands[insn_code_number]);
  #endif
  
! 	    cc_prev_status = cc_status;
! 
! 	    /* Update `cc_status' for this instruction.
! 	       The instruction's output routine may change it further.
! 	       If the output routine for a jump insn needs to depend
! 	       on the cc status, it should look at cc_prev_status.  */
! 
! 	    NOTICE_UPDATE_CC (body, insn);
  
! 	    /* If the proper template needs to be chosen by some C code,
! 	       run that code and get the real template.  */
  
! 	    template = insn_template[insn_code_number];
  	    if (template == 0)
  	      {
! 		template = (*insn_outfun[insn_code_number]) (recog_operand, insn);
! 
! 		/* If the C code returns 0, it means that it is a jump insn
! 		   which follows a deleted test insn, and that test insn
! 		   needs to be reinserted.  */
! 		if (template == 0)
! 		  {
! 		    if (PREV_INSN (insn) != last_ignored_compare)
! 		      abort ();
! 		    insn = PREV_INSN (insn);
! 		    body = PATTERN (insn);
! 		    new_block = 0;
! 		    goto reinsert_compare;
! 		  }
  	      }
  
! 	    if (prescan > 0)
! 	      break;
  
! 	    /* Output assembler code from the template.  */
  
! 	    output_asm_insn (template, recog_operand);
  
! 	    /* Mark this insn as having been output.  */
! 	    INSN_DELETED_P (insn) = 1;
! 	  }
! 	}
      }
  }
  \f


--- 527,1031 ----
    CC_STATUS_INIT;
  
!   for (insn = NEXT_INSN (first); insn;)
!     insn = final_scan_insn (insn, file, write_symbols, optimize,
! 			    prescan, 0);
! }
! \f


! /* The final scan for one insn, INSN.
!    Args are same as in `final', except that INSN
!    is the insn being scanned.
!    Value returned is the next insn to be scanned.
  
!    NOPEEPHOLES is the flag to disallow peephole processing (currently
!    used for within delayed branch sequence output).  */
  
! rtx
! final_scan_insn  (insn, file, write_symbols, optimize, prescan, nopeepholes)
!      rtx insn;
!      FILE *file;
!      enum debugger write_symbols;
!      int optimize;
!      int prescan;
!      int nopeepholes;
! {
!   register int i;
!   switch (GET_CODE (insn))
!     {
!     case NOTE:
!       if (prescan > 0)
! 	break;
!       if (write_symbols == NO_DEBUG)
! 	break;
!       if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG)
! 	{
! #ifdef SDB_DEBUGGING_INFO
! 	  if (write_symbols == SDB_DEBUG)
! 	    sdbout_begin_function (last_linenum);
! #endif
! 	  break;
! 	}
!       if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
! 	  || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
! 	break;
!       if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED)
! 	break;			/* An insn that was "deleted" */
!       if (app_on)
! 	{
! 	  fprintf (file, ASM_APP_OFF);
! 	  app_on = 0;
! 	}
!       if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG)
! 	{
! 	  /* Beginning of a symbol-block.  Assign it a sequence number
! 	     and push the number onto the stack PENDING_BLOCKS.  */
! 
! 	  if (block_depth == max_block_depth)
! 	    {
! 	      /* PENDING_BLOCKS is full; make it longer.  */
! 	      max_block_depth *= 2;
! 	      pending_blocks
! 		= (int *) xrealloc (pending_blocks,
! 				    max_block_depth * sizeof (int));
! 	    }
! 	  pending_blocks[block_depth++] = next_block_index;
! 
! 	  /* Output debugging info about the symbol-block beginning.  */
  
  #ifdef SDB_DEBUGGING_INFO
! 	  if (write_symbols == SDB_DEBUG)
! 	    sdbout_begin_block (file, last_linenum, next_block_index);
  #endif
  #ifdef DBX_DEBUGGING_INFO
! 	  if (write_symbols == DBX_DEBUG)
! 	    ASM_OUTPUT_INTERNAL_LABEL (file, "LBB", next_block_index);
  #endif
! 	  if (write_symbols == GDB_DEBUG)
! 	    fprintf (file, "\t.gdbbeg %d\n", next_block_index);
! 
! 	  next_block_index++;
! 	}
!       else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
! 	{
! 	  /* End of a symbol-block.  Pop its sequence number off
! 	     PENDING_BLOCKS and output debugging info based on that.  */
  
! 	  --block_depth;
  
  #ifdef DBX_DEBUGGING_INFO
! 	  if (write_symbols == DBX_DEBUG && block_depth >= 0)
! 	    ASM_OUTPUT_INTERNAL_LABEL (file, "LBE",
! 				       pending_blocks[block_depth]);
  #endif
  
! #ifdef SDB_DEBUGGING_INFO
! 	  if (write_symbols == SDB_DEBUG && block_depth >= 0)
! 	    sdbout_end_block (file, last_linenum);
! #endif
! 
! 	  if (write_symbols == GDB_DEBUG)
! 	    fprintf (file, "\t.gdbend %d\n", pending_blocks[block_depth]);
! 	}
!       else if (NOTE_LINE_NUMBER (insn) > 0)
! 	/* This note is a line-number.  */
! 	output_source_line (file, insn, write_symbols);
!       break;
  
!     case BARRIER:
  #ifdef ASM_OUTPUT_ALIGN_CODE
!       ASM_OUTPUT_ALIGN_CODE (file);
  #endif
!       break;
  
!     case CODE_LABEL:
!       CC_STATUS_INIT;
!       if (prescan > 0)
! 	break;
!       new_block = 1;
!       if (app_on)
! 	{
! 	  fprintf (file, ASM_APP_OFF);
! 	  app_on = 0;
! 	}
  #ifdef ASM_OUTPUT_CASE_LABEL
!       if (NEXT_INSN (insn) != 0
! 	  && GET_CODE (NEXT_INSN (insn)) == JUMP_INSN)
! 	{
! 	  rtx nextbody = PATTERN (NEXT_INSN (insn));
  
! 	  /* If this label is followed by a jump-table,
! 	     output the two of them together in a special way.  */
! 
! 	  if (GET_CODE (nextbody) == ADDR_VEC
! 	      || GET_CODE (nextbody) == ADDR_DIFF_VEC)
! 	    {
! 	      ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
! 				     NEXT_INSN (insn));
! 	      break;
  	    }
+ 	}
  #endif
  
!       ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (insn));
!       break;
! 
!     default:
!       {
! 	register rtx body = PATTERN (insn);
! 	int insn_code_number;
! 	char *template;
! 
! 	/* An INSN, JUMP_INSN or CALL_INSN.
! 	   First check for special kinds that recog doesn't recognize.  */
! 
! 	if (GET_CODE (body) == USE /* These are just declarations */
! 	    || GET_CODE (body) == CLOBBER)
  	  break;
  
! 	if (profile_block_flag && new_block)
  	  {
! 	    new_block = 0;
! 	    /* Enable the table of basic-block use counts
! 	       to point at the code it applies to.  */
! 	    ASM_OUTPUT_INTERNAL_LABEL (file, "LPB", count_basic_blocks);
! 	    /* Before first insn of this basic block, increment the
! 	       count of times it was entered.  */
  #ifdef BLOCK_PROFILER
! 	    BLOCK_PROFILER (file, count_basic_blocks);
  #endif
! 	    count_basic_blocks++;
! 	  }
  
! 	if (GET_CODE (body) == ASM_INPUT)
! 	  {
! 	    /* There's no telling what that did to the condition codes.  */
! 	    CC_STATUS_INIT;
! 	    if (prescan > 0)
! 	      break;
! 	    if (! app_on)
  	      {
! 		fprintf (file, ASM_APP_ON);
! 		app_on = 1;
  	      }
+ 	    fprintf (asm_out_file, "\t%s\n", XSTR (body, 0));
+ 	    break;
+ 	  }
  
! 	/* Detect `asm' construct with operands.  */
! 	if (asm_noperands (body) >= 0)
! 	  {
! 	    int noperands = asm_noperands (body);
! 	    rtx *ops;
! 	    char *string;
  
! 	    /* There's no telling what that did to the condition codes.  */
! 	    CC_STATUS_INIT;
! 	    if (prescan > 0)
! 	      break;
  
! 	    /* alloca won't do here, since only return from `final'
! 	       would free it.  */
! 	    if (noperands > 0)
! 	      ops = (rtx *) xmalloc (noperands * sizeof (rtx));
  
! 	    if (! app_on)
! 	      {
! 		fprintf (file, ASM_APP_ON);
! 		app_on = 1;
! 	      }
! 
! 	    /* Get out the operand values.  */
! 	    string = decode_asm_operands (body, ops, 0, 0, 0);
! 	    /* Inhibit aborts on what would otherwise be compiler bugs.  */
! 	    insn_noperands = noperands;
! 	    this_is_asm_operands = insn;
! 	    /* Output the insn using them.  */
! 	    output_asm_insn (string, ops);
! 	    this_is_asm_operands = 0;
! 	    if (noperands > 0)
! 	      free (ops);
! 	    break;
! 	  }
  
! 	if (prescan <= 0 && app_on)
! 	  {
! 	    fprintf (file, ASM_APP_OFF);
! 	    app_on = 0;
! 	  }
  
! 	/* Detect insns that are really jump-tables
! 	   and output them as such.  */
  
! 	if (GET_CODE (body) == ADDR_VEC)
! 	  {
! 	    register int vlen, idx;
! 
! 	    if (prescan > 0)
! 	      break;
  
! 	    vlen = XVECLEN (body, 0);
! 	    for (idx = 0; idx < vlen; idx++)
! 	      ASM_OUTPUT_ADDR_VEC_ELT (file,
! 				       CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0)));
  #ifdef ASM_OUTPUT_CASE_END
! 	    ASM_OUTPUT_CASE_END (file,
! 				 CODE_LABEL_NUMBER (PREV_INSN (insn)),
! 				 insn);
  #endif
! 	    break;
! 	  }
! 	if (GET_CODE (body) == ADDR_DIFF_VEC)
! 	  {
! 	    register int vlen, idx;
  
! 	    if (prescan > 0)
! 	      break;
  
! 	    vlen = XVECLEN (body, 1);
! 	    for (idx = 0; idx < vlen; idx++)
! 	      ASM_OUTPUT_ADDR_DIFF_ELT (file,
! 					CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 1, idx), 0)),
! 					CODE_LABEL_NUMBER (XEXP (XEXP (body, 0), 0)));
  #ifdef ASM_OUTPUT_CASE_END
! 	    ASM_OUTPUT_CASE_END (file,
! 				 CODE_LABEL_NUMBER (PREV_INSN (insn)),
! 				 insn);
  #endif
! 	    break;
! 	  }
! 
! 	if (recog_memoized (insn) == -1
! 	    && GET_CODE (body) == SEQUENCE) /* A delayed-branch sequence */
! 	  {
! 	    register int i;
! 	    if (prescan > 0)
! 	      break;
! 	    final_sequence = body;
! 	    for (i = 0; i < XVECLEN (body, 0); i++)
! 	      final_scan_insn (XVECEXP (body, 0, i), file, write_symbols,
! 			       optimize, prescan, 1);
! 	    final_sequence = 0;
! #ifdef DBR_OUTPUT_SEQEND
! 	    DBR_OUTPUT_SEQEND (file);
! #endif
! 	    break;
! 	  }
  
! 	/* We have a real machine instruction as rtl.  */
  
! 	body = PATTERN (insn);
  
! 	/* Check for redundant test and compare instructions
! 	   (when the condition codes are already set up as desired).
! 	   This is done only when optimizing; if not optimizing,
! 	   it should be possible for the user to alter a variable
! 	   with the debugger in between statements
! 	   and the next statement should reexamine the variable
! 	   to compute the condition codes.  */
! 
! 	if (optimize
! 	    && GET_CODE (body) == SET
! 	    && GET_CODE (SET_DEST (body)) == CC0
! 	    && insn != last_ignored_compare)
! 	  {
! 	    if (GET_CODE (SET_SRC (body)) == SUBREG)
! 	      SET_SRC (body) = alter_subreg (SET_SRC (body));
! 	    if ((cc_status.value1 != 0
! 		 && rtx_equal_p (SET_SRC (body), cc_status.value1))
! 		|| (cc_status.value2 != 0
! 		    && rtx_equal_p (SET_SRC (body), cc_status.value2)))
! 	      {
! 		/* Don't delete insn if has an addressing side-effect */
! 		if (! find_reg_note (insn, REG_INC, 0)
! 		    /* or if anything in it is volatile.  */
! 		    && ! volatile_refs_p (PATTERN (insn)))
  		  {
! 		    /* We don't really delete the insn; just ignore it.  */
! 		    last_ignored_compare = insn;
! 		    break;
  		  }
  	      }
+ 	  }
+ 
+       reinsert_compare:
+ 
+ 	/* Following a conditional branch, we have a new basic block.  */
+ 	if (GET_CODE (insn) == JUMP_INSN && GET_CODE (body) == SET
+ 	    && GET_CODE (SET_SRC (body)) != LABEL_REF)
+ 	  new_block = 1;
+ 
+ 	/* If this is a conditional branch, maybe modify it
+ 	   if the cc's are in a nonstandard state
+ 	   so that it accomplishes the same thing that it would
+ 	   do straightforwardly if the cc's were set up normally.  */
+ 
+ 	if (cc_status.flags != 0
+ 	    && GET_CODE (insn) == JUMP_INSN
+ 	    && GET_CODE (body) == SET
+ 	    && SET_DEST (body) == pc_rtx
+ 	    && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE
+ 	    /* This is done during prescan; it is not done again
+ 	       in final scan when prescan has been done.  */
+ 	    && prescan >= 0)
+ 	  {
+ 	    /* This function may alter the contents of its argument
+ 	       and clear some of the cc_status.flags bits.
+ 	       It may also return 1 meaning condition now always true
+ 	       or -1 meaning condition now always false
+ 	       or 2 meaning condition nontrivial but altered.  */
+ 	    register int result = alter_cond (XEXP (SET_SRC (body), 0));
+ 	    /* If condition now has fixed value, replace the IF_THEN_ELSE
+ 	       with its then-operand or its else-operand.  */
+ 	    if (result == 1)
+ 	      SET_SRC (body) = XEXP (SET_SRC (body), 1);
+ 	    if (result == -1)
+ 	      SET_SRC (body) = XEXP (SET_SRC (body), 2);
+ 	    /* The jump is now either unconditional or a no-op.
+ 	       If it has become a no-op, don't try to output it.
+ 	       (It would not be recognized.)  */
+ 	    if (SET_SRC (body) == pc_rtx)
+ 	      {
+ 		PUT_CODE (insn, NOTE);
+ 		NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
+ 		NOTE_SOURCE_FILE (insn) = 0;
+ 		break;
+ 	      }
+ 	    /* Rerecognize the instruction if it has changed.  */
+ 	    if (result != 0)
+ 	      INSN_CODE (insn) = -1;
+ 	  }
  
! #ifdef STORE_FLAG_VALUE
! 	/* Make same adjustments to instructions that examine the
! 	   condition codes without jumping (if this machine has them).  */
  
! 	if (cc_status.flags != 0
! 	    && GET_CODE (body) == SET)
! 	  switch (GET_CODE (SET_SRC (body)))
! 	    {
! 	    case GTU:
! 	    case GT:
! 	    case LTU:
! 	    case LT:
! 	    case GEU:
! 	    case GE:
! 	    case LEU:
! 	    case LE:
! 	    case EQ:
! 	    case NE:
! 	      {
! 		register int result;
! 		if (GET_CODE (XEXP (SET_SRC (body), 0)) != CC0)
! 		  break;
! 		result = alter_cond (SET_SRC (body));
  		if (result == 1)
! 		  SET_SRC (body) = gen_rtx (CONST_INT, VOIDmode,
! 					    STORE_FLAG_VALUE);
  		if (result == -1)
! 		  SET_SRC (body) = const0_rtx;
  		if (result != 0)
  		  INSN_CODE (insn) = -1;
  	      }
! 	    }
! #endif				/* STORE_FLAG_VALUE */
  
! 	/* Do machine-specific peephole optimizations if desired.  */
  
! 	if (optimize && !flag_no_peephole && !nopeepholes)
! 	  {
! 	    rtx next = peephole (insn);
! 	    /* When peepholing, if there were notes within the peephole,
! 	       emit them before the peephole.  */
! 	    if (next != 0 && next != NEXT_INSN (insn))
  	      {
! 		rtx note = NEXT_INSN (insn);
! 		rtx prev = PREV_INSN (insn);
! 		while (note != next)
! 		  {
! 		    final_scan_insn (note, file, write_symbols, optimize,
! 				     prescan, nopeepholes);
! 		    note = NEXT_INSN (note);
! 		  }
! 		/* In case this is prescan, put the notes
! 		   in proper position for later rescan.  */
! 		note = NEXT_INSN (insn);
! 		PREV_INSN (note) = prev;
! 		NEXT_INSN (prev) = note;
! 		NEXT_INSN (PREV_INSN (next)) = insn;
! 		PREV_INSN (insn) = PREV_INSN (next);
! 		NEXT_INSN (insn) = next;
! 		PREV_INSN (next) = insn;
  	      }
  
+ 	    /* PEEPHOLE might have changed this.  */
+ 	    body = PATTERN (insn);
+ 	  }
+ 
+ 	/* Try to recognize the instruction.
+ 	   If successful, verify that the operands satisfy the
+ 	   constraints for the instruction.  Crash if they don't,
+ 	   since `reload' should have changed them so that they do.  */
+ 
+ 	insn_code_number = recog_memoized (insn);
+ 	insn_extract (insn);
+ 	for (i = 0; i < insn_n_operands[insn_code_number]; i++)
+ 	  {
+ 	    if (GET_CODE (recog_operand[i]) == SUBREG)
+ 	      recog_operand[i] = alter_subreg (recog_operand[i]);
+ 	  }
+ 
  #ifdef REGISTER_CONSTRAINTS
! 	if (! constrain_operands (insn_code_number))
! 	  abort ();
  #endif
  
! 	/* Some target machines need to prescan each insn before
! 	   it is output.  */
  
  #ifdef FINAL_PRESCAN_INSN
! 	FINAL_PRESCAN_INSN (insn, recog_operand,
! 			    insn_n_operands[insn_code_number]);
  #endif
  
! 	cc_prev_status = cc_status;
! 
! 	/* Update `cc_status' for this instruction.
! 	   The instruction's output routine may change it further.
! 	   If the output routine for a jump insn needs to depend
! 	   on the cc status, it should look at cc_prev_status.  */
! 
! 	NOTICE_UPDATE_CC (body, insn);
! 
! 	/* If the proper template needs to be chosen by some C code,
! 	   run that code and get the real template.  */
  
! 	template = insn_template[insn_code_number];
! 	if (template == 0)
! 	  {
! 	    template = (*insn_outfun[insn_code_number]) (recog_operand, insn);
  
! 	    /* If the C code returns 0, it means that it is a jump insn
! 	       which follows a deleted test insn, and that test insn
! 	       needs to be reinserted.  */
  	    if (template == 0)
  	      {
! 		if (PREV_INSN (insn) != last_ignored_compare)
! 		  abort ();
! 		new_block = 0;
! 		return PREV_INSN (insn);
  	      }
+ 	  }
  
! 	if (prescan > 0)
! 	  break;
  
! 	/* Output assembler code from the template.  */
  
! 	output_asm_insn (template, recog_operand);
  
! 	/* Mark this insn as having been output.  */
! 	INSN_DELETED_P (insn) = 1;
!       }
      }
+   return NEXT_INSN (insn);
  }
  \f


***************
*** 981,988 ****
  #ifdef SDB_DEBUGGING_INFO
        if (write_symbols == SDB_DEBUG
  	  /* COFF can't handle multiple source files--lose, lose.  */
  	  && !strcmp (filename, main_input_filename)
! 	  /* COFF can't handle line #s before start-line of this function.  */
! 	  && last_linenum >= sdb_begin_function_line)
  	{
  #ifdef ASM_OUTPUT_SOURCE_LINE
--- 1086,1095 ----
  #ifdef SDB_DEBUGGING_INFO
        if (write_symbols == SDB_DEBUG
+ #if 0 /* People like having line numbers even in wrong file!  */
  	  /* COFF can't handle multiple source files--lose, lose.  */
  	  && !strcmp (filename, main_input_filename)
! #endif
! 	  /* COFF relative line numbers must be positive.  */
! 	  && last_linenum > sdb_begin_function_line)
  	{
  #ifdef ASM_OUTPUT_SOURCE_LINE
***************
*** 1360,1365 ****
  	     punctuation character alone, with no operand.
  	     The PRINT_OPERAND macro decides what is actually done.  */
! 	  else
  	    output_operand (0, *p++);
  	}
      }
--- 1467,1476 ----
  	     punctuation character alone, with no operand.
  	     The PRINT_OPERAND macro decides what is actually done.  */
! #ifdef PRINT_OPERAND_PUNCT_VALID_P
! 	  else if (PRINT_OPERAND_PUNCT_VALID_P (*p))
  	    output_operand (0, *p++);
+ #endif
+ 	  else
+ 	    output_operand_lossage ("invalid %%-code");
  	}
      }
***************
*** 1374,1378 ****
       rtx x;
  {
!   char buf[20];
  
    if (GET_CODE (x) == LABEL_REF)
--- 1485,1489 ----
       rtx x;
  {
!   char buf[256];
  
    if (GET_CODE (x) == LABEL_REF)
***************
*** 1427,1431 ****
       rtx x;
  {
!   char buf[20];
  
   restart:
--- 1538,1542 ----
       rtx x;
  {
!   char buf[256];
  
   restart:
diff -rc2N gcc-1.35/fixincludes gcc-1.36/fixincludes
*** gcc-1.35/fixincludes	Sun Apr 23 18:38:25 1989
--- gcc-1.36/fixincludes	Wed Jul 19 20:00:17 1989
***************
*** 7,12 ****
  
  # Directory in which to store the results.
! LIB=/usr/local/lib/gcc-include
  
  # Determine whether this system has symbolic links.
  if ln -s X $LIB/ShouldNotExist 2>/dev/null; then
--- 7,15 ----
  
  # Directory in which to store the results.
! LIB=${LIB-/usr/local/lib/gcc-include}
  
+ # Make sure it exists.
+ mkdir $LIB > /dev/null 2>&1
+ 
  # Determine whether this system has symbolic links.
  if ln -s X $LIB/ShouldNotExist 2>/dev/null; then
***************
*** 19,23 ****
  echo 'Making directories:'
  cd /usr/include
- mkdir $LIB > /dev/null 2>&1
  if $LINKS; then
    files=`ls -LR | sed -n s/:$//p`
--- 22,25 ----
***************
*** 39,43 ****
      dest=`ls -ld $file | sed -n 's/.*-> //p'`
      if [ "$dest" ]; then    
!       if expr $dest : '[^/].*' > /dev/null; then
  	rmdir ${LIB}/$file > /dev/null 2>&1
  	rm -f ${LIB}/$file > /dev/null 2>&1
--- 41,45 ----
      dest=`ls -ld $file | sed -n 's/.*-> //p'`
      if [ "$dest" ]; then    
!       if expr $dest : '[^/.].*' > /dev/null; then
  	rmdir ${LIB}/$file > /dev/null 2>&1
  	rm -f ${LIB}/$file > /dev/null 2>&1
***************
*** 53,57 ****
  while [ $# != 0 ]; do
    # $1 is an old directory to copy, and $2 is the new directory to copy to.
!   echo 'Finding header files in $1:'
    cd $1
    files=`find . -type f -print`
--- 55,60 ----
  while [ $# != 0 ]; do
    # $1 is an old directory to copy, and $2 is the new directory to copy to.
!   echo "Finding header files in $1:"
!   cd /usr/include
    cd $1
    files=`find . -type f -print`
***************
*** 58,62 ****
    echo 'Checking header files:'
    for file in $files; do
!     if egrep -s '[ 	]_IO[A-Z]*\(|#define._IO|CTRL' $file; then
        echo Fixing $file
        if [ -r $file ]; then
--- 61,65 ----
    echo 'Checking header files:'
    for file in $files; do
!     if egrep '[ 	]_IO[A-Z]*\(|#define._IO|CTRL' $file > /dev/null; then
        echo Fixing $file
        if [ -r $file ]; then
***************
*** 64,76 ****
  	|| echo "Can't copy $file"
  	chmod +w $2/$file
! 	ex $2/$file <<EOF
! 	g/[ 	]_IO[A-Z]*(/s/(\(.\),/('\1',/
!         g/[ 	]_IO[A-Z]*(.*\\$/.,+1s/(\(.\),/('\1',/
! 	g/#define._IO/s/'x'/x/g
!         g/#define._IO.*\\$/.,+1s/'x'/x/g
! 	g/[^A-Z]CTRL[ 	]*(/s/\(.\))/'\1')/
! 	g/#define.CTRL/s/'c'/c/g
! 	wq
! EOF
  	if cmp $file $2/$file >/dev/null 2>&1; then
  	   echo Deleting $2/$file\; no fixes were needed.
--- 67,80 ----
  	|| echo "Can't copy $file"
  	chmod +w $2/$file
! 	sed -e '
! 				   :loop
! 	  /\\$/			N
! 	  /\\$/			b loop
! 	  /[ 	]_IO[A-Z]*(/	s/(\(.\),/('\''\1'\'',/
! 	  /#define._IO/		s/'\''x'\''/x/g
! 	  /[^A-Z]CTRL[ 	]*(/	s/\(.\))/'\''\1'\'')/
! 	  /#define.CTRL/		s/'\''c'\''/c/g
! 	' $2/$file > $2/$file.sed
! 	mv $2/$file.sed $2/$file
  	if cmp $file $2/$file >/dev/null 2>&1; then
  	   echo Deleting $2/$file\; no fixes were needed.
***************
*** 83,86 ****
--- 87,92 ----
  done
  
+ cd /usr/include
+ 
  # Fix one other error in this file: a mismatched quote not inside a C comment.
  file=sundev/vuid_event.h
***************
*** 96,100 ****
    echo Fixing sundev/vuid_event.h comment
    ex ${LIB}/sundev/vuid_event.h <<EOF
!   g/doesn't/s/doesn't/doesn''t/
    wq
  EOF
--- 102,129 ----
    echo Fixing sundev/vuid_event.h comment
    ex ${LIB}/sundev/vuid_event.h <<EOF
!   g/doesn't/s/doesn't/does not/
!   wq
! EOF
! fi
! 
! # Deal with yet another challenge, this in X11/Xmu.h
! file=X11/Xmu.h
! if [ -r $file ]; then
!   if [ ! -r ${LIB}/$file ]; then
!     mkdir ${LIB}/X11 2>&-
!     cp $file ${LIB}/$file >/dev/null 2>&1	\
!     || echo "Can't copy $file"
!     chmod +w ${LIB}/$file
!   fi
! fi
! 
! if [ -r ${LIB}/$file ]; then
!   echo Fixing $file sprintf declaration
!   ex ${LIB}/$file <<EOF
!   /^extern char \*	sprintf();$/c
! #ifndef __STDC__
! extern char *	sprintf();
! #endif /* !defined __STDC__ */
! .
    wq
  EOF
***************
*** 108,109 ****
--- 137,154 ----
  done
  
+ if $LINKS; then
+   echo 'Making internal symbolic non-directory links'
+   cd /usr/include
+   files=`find . -type l -print`
+   for file in $files; do
+     dest=`ls -ld $file | sed -n 's/.*-> //p'`
+     if expr "$dest" : '[^/].*' > /dev/null; then    
+       target=${LIB}/`echo file | sed "s|[^/]*\$|$dest|"`
+       if [ -f $target ]; then
+         ln -s $dest ${LIB}/$file >/dev/null 2>&1
+       fi
+     fi
+   done
+ fi
+ 
+ exit 0
diff -rc2N gcc-1.35/flags.h gcc-1.36/flags.h
*** gcc-1.35/flags.h	Wed Mar 29 18:58:37 1989
--- gcc-1.36/flags.h	Fri Jul 14 21:11:28 1989
***************
*** 88,91 ****
--- 88,99 ----
  /* Now the symbols that are set with `-f' switches.  */
  
+ /* Nonzero means `char' should be signed.  */
+ 
+ extern int flag_signed_char;
+ 
+ /* Nonzero means give an enum type only as many bytes as it needs.  */
+ 
+ extern int flag_short_enums;
+ 
  /* Nonzero for -fcaller-saves: allocate values in regs that need to
     be saved across function calls, if that produces overall better code.
***************
*** 178,179 ****
--- 186,191 ----
  
  extern int flag_shared_data;
+ 
+ /* Nonzero means put things in delayed-branch slots if supported. */
+ 
+ extern int flag_delayed_branch;
diff -rc2N gcc-1.35/flow.c gcc-1.36/flow.c
*** gcc-1.35/flow.c	Tue Apr 25 16:53:31 1989
--- gcc-1.36/flow.c	Sun Jul 30 19:39:37 1989
***************
*** 85,89 ****
     life_analysis fills in certain vectors containing information about
     register usage: reg_n_refs, reg_n_deaths, reg_n_sets,
!    reg_live_length, reg_crosses_call and reg_basic_block.  */
  \f


  #include <stdio.h>
--- 85,89 ----
     life_analysis fills in certain vectors containing information about
     register usage: reg_n_refs, reg_n_deaths, reg_n_sets,
!    reg_live_length, reg_n_calls_crosses and reg_basic_block.  */
  \f


  #include <stdio.h>
***************
*** 95,98 ****
--- 95,105 ----
  #include "flags.h"
  
+ #include "obstack.h"
+ #define obstack_chunk_alloc xmalloc
+ #define obstack_chunk_free free
+ 
+ extern int xmalloc ();
+ extern void free ();
+ 
  /* Get the basic block number of an insn.
     This info should not be expected to remain available
***************
*** 577,580 ****
--- 584,591 ----
    rtx insn;
  
+   struct obstack flow_obstack;
+ 
+   obstack_init (&flow_obstack);
+ 
    max_regno = nregs;
  
***************
*** 593,597 ****
  
    basic_block_live_at_end = (regset *) alloca (n_basic_blocks * sizeof (regset));
!   tem = (regset) alloca (n_basic_blocks * regset_bytes);
    bzero (tem, n_basic_blocks * regset_bytes);
    init_regset_vector (basic_block_live_at_end, tem, n_basic_blocks, regset_bytes);
--- 604,612 ----
  
    basic_block_live_at_end = (regset *) alloca (n_basic_blocks * sizeof (regset));
!   /* Don't use alloca since that leads to a crash rather than an error message
!      if there isn't enough space.
!      Don't use oballoc since we may need to allocate other things during
!      this function on the temporary obstack.  */
!   tem = (regset) obstack_alloc (&flow_obstack, n_basic_blocks * regset_bytes);
    bzero (tem, n_basic_blocks * regset_bytes);
    init_regset_vector (basic_block_live_at_end, tem, n_basic_blocks, regset_bytes);
***************
*** 598,602 ****
  
    basic_block_new_live_at_end = (regset *) alloca (n_basic_blocks * sizeof (regset));
!   tem = (regset) alloca (n_basic_blocks * regset_bytes);
    bzero (tem, n_basic_blocks * regset_bytes);
    init_regset_vector (basic_block_new_live_at_end, tem, n_basic_blocks, regset_bytes);
--- 613,617 ----
  
    basic_block_new_live_at_end = (regset *) alloca (n_basic_blocks * sizeof (regset));
!   tem = (regset) obstack_alloc (&flow_obstack, n_basic_blocks * regset_bytes);
    bzero (tem, n_basic_blocks * regset_bytes);
    init_regset_vector (basic_block_new_live_at_end, tem, n_basic_blocks, regset_bytes);
***************
*** 603,607 ****
  
    basic_block_significant = (regset *) alloca (n_basic_blocks * sizeof (regset));
!   tem = (regset) alloca (n_basic_blocks * regset_bytes);
    bzero (tem, n_basic_blocks * regset_bytes);
    init_regset_vector (basic_block_significant, tem, n_basic_blocks, regset_bytes);
--- 618,622 ----
  
    basic_block_significant = (regset *) alloca (n_basic_blocks * sizeof (regset));
!   tem = (regset) obstack_alloc (&flow_obstack, n_basic_blocks * regset_bytes);
    bzero (tem, n_basic_blocks * regset_bytes);
    init_regset_vector (basic_block_significant, tem, n_basic_blocks, regset_bytes);
***************
*** 749,753 ****
  	    if (basic_block_drops_in[i])
  	      {
! 		register from_block = BLOCK_NUM (jump);
  		register int j;
  		for (j = 0; j < regset_size; j++)
--- 764,768 ----
  	    if (basic_block_drops_in[i])
  	      {
! 		register int from_block = BLOCK_NUM (jump);
  		register int j;
  		for (j = 0; j < regset_size; j++)
***************
*** 762,766 ****
  		   jump = LABEL_NEXTREF (jump))
  		{
! 		  register from_block = BLOCK_NUM (CONTAINING_INSN (jump));
  		  register int j;
  		  for (j = 0; j < regset_size; j++)
--- 777,781 ----
  		   jump = LABEL_NEXTREF (jump))
  		{
! 		  register int from_block = BLOCK_NUM (CONTAINING_INSN (jump));
  		  register int j;
  		  for (j = 0; j < regset_size; j++)
***************
*** 807,810 ****
--- 822,842 ----
  #endif
      }
+ 
+   /* Something live during a setjmp should not be put in a register
+      on certain machines which restore regs from stack frames
+      rather than from the jmpbuf.
+      But we don't need to do this for the user's variables, since
+      ANSI says only volatile variables need this.  */
+ #ifdef LONGJMP_RESTORE_FROM_STACK
+   for (i = FIRST_PSEUDO_REGISTER; i < nregs; i++)
+     if (regs_live_at_setjmp[i / REGSET_ELT_BITS] & (1 << (i % REGSET_ELT_BITS))
+ 	&& regno_reg_rtx[i] != 0 && ! REG_USERVAR_P (regno_reg_rtx[i]))
+       {
+ 	reg_live_length[i] = -1;
+ 	reg_basic_block[i] = -1;
+       }
+ #endif
+ 
+   obstack_free (&flow_obstack, 0);
  }
  \f


***************
*** 1579,1584 ****
  
        regno = REGNO (x);
!       if (regno != FRAME_POINTER_REGNUM
! 	  && regno != ARG_POINTER_REGNUM)
  	/* && regno != STACK_POINTER_REGNUM) -- let's try without this.  */
  	{
--- 1611,1616 ----
  
        regno = REGNO (x);
!       if (regno != FRAME_POINTER_REGNUM)
! 	  /* && regno != ARG_POINTER_REGNUM) -- and without this.  */
  	/* && regno != STACK_POINTER_REGNUM) -- let's try without this.  */
  	{
***************
*** 1594,1600 ****
  	      int n;
  
! 	      /* For stack ptr, nothing below here can be necessary,
! 		 so waste no more time.  */
! 	      if (regno == STACK_POINTER_REGNUM)
  		return;
  	      /* No death notes for global register variables;
--- 1626,1633 ----
  	      int n;
  
! 	      /* For stack ptr or arg pointer,
! 		 nothing below can be necessary, so waste no more time.  */
! 	      if (regno == STACK_POINTER_REGNUM
! 		  || regno == ARG_POINTER_REGNUM)
  		return;
  	      /* No death notes for global register variables;
***************
*** 1998,2002 ****
  		 jump = LABEL_NEXTREF (jump))
  	      {
! 		register from_block = BLOCK_NUM (CONTAINING_INSN (jump));
  		fprintf (file, " %d", from_block);
  	      }
--- 2031,2035 ----
  		 jump = LABEL_NEXTREF (jump))
  	      {
! 		register int from_block = BLOCK_NUM (CONTAINING_INSN (jump));
  		fprintf (file, " %d", from_block);
  	      }
diff -rc2N gcc-1.35/fold-const.c gcc-1.36/fold-const.c
*** gcc-1.35/fold-const.c	Sat Mar 11 17:44:20 1989
--- gcc-1.36/fold-const.c	Fri Sep 22 14:49:16 1989
***************
*** 208,211 ****
--- 208,249 ----
    register int i, j, k;
  
+   /* These two cases are used extensively, arising from pointer
+      combinations.  */
+   if (h2 == 0)
+     {
+       if (l2 == 2)
+ 	{
+ 	  unsigned temp = l1 + l1;
+ 	  *hv = h1 * 2 + (temp < l1);
+ 	  *lv = temp;
+ 	  return;
+ 	}
+       if (l2 == 4)
+ 	{
+ 	  unsigned temp = l1 + l1;
+ 	  h1 = h1 * 4 + (temp < l1) << 1;
+ 	  l1 = temp;
+ 	  temp += temp;
+ 	  h1 += (temp < l1);
+ 	  *lv = temp;
+ 	  *hv = h1;
+ 	  return;
+ 	}
+       if (l2 == 8)
+ 	{
+ 	  unsigned temp = l1 + l1;
+ 	  h1 = h1 * 8 + (temp < l1) << 2;
+ 	  l1 = temp;
+ 	  temp += temp;
+ 	  h1 += (temp < l1) << 1;
+ 	  l1 = temp;
+ 	  temp += temp;
+ 	  h1 += (temp < l1);
+ 	  *lv = temp;
+ 	  *hv = h1;
+ 	  return;
+ 	}
+     }
+ 
    encode (arg1, l1, h1);
    encode (arg2, l2, h2);
***************
*** 379,383 ****
     for a quotient (stored in *LQUO, *HQUO) and remainder (in *LREM, *HREM).
     CODE is a tree code for a kind of division, one of
!    TRUNC_DIV_EXPR, FLOOR_DIV_EXPR, CEIL_DIV_EXPR and ROUND_DIV_EXPR.
     It controls how the quotient is rounded to a integer.
     UNS nonzero says do unsigned division.  */
--- 417,422 ----
     for a quotient (stored in *LQUO, *HQUO) and remainder (in *LREM, *HREM).
     CODE is a tree code for a kind of division, one of
!    TRUNC_DIV_EXPR, FLOOR_DIV_EXPR, CEIL_DIV_EXPR, ROUND_DIV_EXPR
!    or EXACT_DIV_EXPR
     It controls how the quotient is rounded to a integer.
     UNS nonzero says do unsigned division.  */
***************
*** 576,579 ****
--- 615,619 ----
      case TRUNC_DIV_EXPR:
      case TRUNC_MOD_EXPR:	/* round toward zero */
+     case EXACT_DIV_EXPR:	/* for this one, it shouldn't matter */
        return;
  
***************
*** 604,612 ****
  
  	/* get absolute values */
! 	if (*hrem < 0) neg_double(*lrem, *hrem, &labs_rem, &habs_rem);
! 	if (hden < 0) neg_double(lden, hden, &labs_den, &habs_den);
  
  	/* if (2 * abs (lrem) >= abs (lden)) */
! 	mul_double(2, 0, labs_rem, habs_rem, &ltwice, &htwice);
  	if (((unsigned) habs_den < (unsigned) htwice)
  	    || (((unsigned) habs_den == (unsigned) htwice)
--- 644,652 ----
  
  	/* get absolute values */
! 	if (*hrem < 0) neg_double (*lrem, *hrem, &labs_rem, &habs_rem);
! 	if (hden < 0) neg_double (lden, hden, &labs_den, &habs_den);
  
  	/* if (2 * abs (lrem) >= abs (lden)) */
! 	mul_double (2, 0, labs_rem, habs_rem, &ltwice, &htwice);
  	if (((unsigned) habs_den < (unsigned) htwice)
  	    || (((unsigned) habs_den == (unsigned) htwice)
***************
*** 782,785 ****
--- 822,841 ----
  
  	case PLUS_EXPR:
+ 	  if (int1h == 0)
+ 	    {
+ 	      int2l += int1l;
+ 	      if ((unsigned) int2l < int1l)
+ 		int2h += 1;
+ 	      t = build_int_2 (int2l, int2h);
+ 	      break;
+ 	    }
+ 	  if (int2h == 0)
+ 	    {
+ 	      int1l += int2l;
+ 	      if ((unsigned) int1l < int2l)
+ 		int1h += 1;
+ 	      t = build_int_2 (int1l, int1h);
+ 	      break;
+ 	    }
  	  add_double (int1l, int1h, int2l, int2h, &low, &hi);
  	  t = build_int_2 (low, hi);
***************
*** 787,790 ****
--- 843,856 ----
  
  	case MINUS_EXPR:
+ 	  if (int1h == 0 && int1l == 0)
+ 	    {
+ 	      t = build_int_2 (- int2l, - int2h);
+ 	      break;
+ 	    }
+ 	  if (int2h == 0 && int2l == 0)
+ 	    {
+ 	      t = build_int_2 (int1l, int1h);
+ 	      break;
+ 	    }
  	  neg_double (int2l, int2h, &int2l, &int2h);
  	  add_double (int1l, int1h, int2l, int2h, &low, &hi);
***************
*** 793,796 ****
--- 859,923 ----
  
  	case MULT_EXPR:
+   /* Optimize simple cases.  */
+ 	  if (int1h == 0)
+ 	    {
+ 	      unsigned temp;
+ 
+ 	      switch (int1l)
+ 		{
+ 		case 0:
+ 		  t = build_int_2 (0, 0);
+ 		  goto got_it;
+ 		case 1:
+ 		  t = build_int_2 (int2l, int2h);
+ 		  goto got_it;
+ 		case 2:
+ 		  temp = int2l + int2l;
+ 		  int2h = int2h * 2 + (temp < int2l);
+ 		  t = build_int_2 (temp, int2h);
+ 		  goto got_it;
+ 		case 3:
+ 		  temp = int2l + int2l + int2l;
+ 		  int2h = int2h * 3 + (temp < int2l);
+ 		  t = build_int_2 (temp, int2h);
+ 		  goto got_it;
+ 		case 4:
+ 		  temp = int2l + int2l;
+ 		  int2h = int2h * 4 + (temp < int2l) << 1;
+ 		  int2l = temp;
+ 		  temp += temp;
+ 		  int2h += (temp < int2l);
+ 		  t = build_int_2 (temp, int2h);
+ 		  goto got_it;
+ 		case 8:
+ 		  temp = int2l + int2l;
+ 		  int2h = int2h * 8 + (temp < int2l) << 2;
+ 		  int2l = temp;
+ 		  temp += temp;
+ 		  int2h += (temp < int2l) << 1;
+ 		  int2l = temp;
+ 		  temp += temp;
+ 		  int2h += (temp < int2l);
+ 		  t = build_int_2 (temp, int2h);
+ 		  goto got_it;
+ 		default:
+ 		  break;
+ 		}
+ 	    }
+ 
+ 	  if (int2h == 0)
+ 	    {
+ 	      if (int2l == 0)
+ 		{
+ 		  t = build_int_2 (0, 0);
+ 		  break;
+ 		}
+ 	      if (int2l == 1)
+ 		{
+ 		  t = build_int_2 (int1l, int1h);
+ 		  break;
+ 		}
+ 	    }
+ 
  	  mul_double (int1l, int1h, int2l, int2h, &low, &hi);
  	  t = build_int_2 (low, hi);
***************
*** 799,802 ****
--- 926,942 ----
  	case TRUNC_DIV_EXPR: case ROUND_DIV_EXPR: 
  	case FLOOR_DIV_EXPR: case CEIL_DIV_EXPR:
+ 	case EXACT_DIV_EXPR:
+ 	  if (int2h == 0 && int2l == 1)
+ 	    {
+ 	      t = build_int_2 (int1l, int1h);
+ 	      break;
+ 	    }
+ 	  if (int1l == int2l && int1h == int2h)
+ 	    {
+ 	      if ((int1l | int1h) == 0)
+ 		abort ();
+ 	      t = build_int_2 (1, 0);
+ 	      break;
+ 	    }
  	  div_and_round_double (code, uns, int1l, int1h, int2l, int2h,
  				&low, &hi, &garbagel, &garbageh);
***************
*** 834,837 ****
--- 974,978 ----
  	  abort ();
  	}
+     got_it:
        TREE_TYPE (t) = TREE_TYPE (arg1);
        force_fit_type (t);
***************
*** 972,983 ****
        else if (TREE_CODE (arg1) == REAL_CST)
  	{
  #ifndef REAL_ARITHMETIC
! 	  t = build_int_2 ((int) TREE_REAL_CST (arg1),
! 			   (int) (TREE_REAL_CST (arg1) / 0x10000 / 0x10000));
  #else
! 	  int low, high;
! 	  REAL_VALUE_TO_INT (low, high, TREE_REAL_CST (arg1));
! 	  t = build_int_2 (low, high);
  #endif
  	}
  #endif /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */
--- 1113,1150 ----
        else if (TREE_CODE (arg1) == REAL_CST)
  	{
+ 	  if (REAL_VALUES_LESS (real_value_from_int_cst (TYPE_MAX_VALUE (type)),
+ 				TREE_REAL_CST (arg1))
+ 	      || REAL_VALUES_LESS (TREE_REAL_CST (arg1),
+ 				   real_value_from_int_cst (TYPE_MIN_VALUE (type))))
+ 	    {
+ 	      warning ("real constant out of range for integer conversion");
+ 	      return t;
+ 	    }
  #ifndef REAL_ARITHMETIC
! 	  {
! 	    REAL_VALUE_TYPE d;
! 	    int low, high;
! 	    int half_word = 1 << (HOST_BITS_PER_INT / 2);
! 
! 	    d = TREE_REAL_CST (arg1);
! 	    if (d < 0)
! 	      d = -d;
! 
! 	    high = (int) (d / half_word / half_word);
! 	    d -= (REAL_VALUE_TYPE) high * half_word * half_word;
! 	    low = (unsigned) d;
! 	    if (TREE_REAL_CST (arg1) < 0)
! 	      neg_double (low, high, &low, &high);
! 	    t = build_int_2 (low, high);
! 	  }
  #else
! 	  {
! 	    int low, high;
! 	    REAL_VALUE_TO_INT (low, high, TREE_REAL_CST (arg1));
! 	    t = build_int_2 (low, high);
! 	  }
  #endif
+ 	  TREE_TYPE (t) = type;
+ 	  force_fit_type (t);
  	}
  #endif /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */
***************
*** 1132,1135 ****
--- 1299,1321 ----
        return fold_convert (t);
  
+ #if 0  /* This loses on &"foo"[0].  */
+     case ARRAY_REF:
+ 	{
+ 	  int i;
+ 
+ 	  /* Fold an expression like: "foo"[2] */
+ 	  if (TREE_CODE (arg0) == STRING_CST
+ 	      && TREE_CODE (arg1) == INTEGER_CST
+ 	      && !TREE_INT_CST_HIGH (arg1)
+ 	      && (i = TREE_INT_CST_LOW (arg1)) < TREE_STRING_LENGTH (arg0))
+ 	    {
+ 	      t = build_int_2 (TREE_STRING_POINTER (arg0)[i], 0);
+ 	      TREE_TYPE (t) = TREE_TYPE (TREE_TYPE (arg0));
+ 	      force_fit_type (t);
+ 	    }
+ 	}
+       return t;
+ #endif /* 0 */
+ 
      case RANGE_EXPR:
        TREE_LITERAL (t) = wins;
***************
*** 1172,1176 ****
  	  else if (TREE_CODE (arg0) == REAL_CST)
  	    {
! 	      if (TREE_REAL_CST (arg0) < 0)
  		t = build_real (type,
  				REAL_VALUE_NEGATE (TREE_REAL_CST (arg0)));
--- 1358,1369 ----
  	  else if (TREE_CODE (arg0) == REAL_CST)
  	    {
! 	      if (
! #if defined (REAL_IS_NOT_DOUBLE)
! 		  REAL_VALUES_LESS (TREE_REAL_CST (arg0),
! 				    REAL_VALUE_ATOF ("0.0"))
! #else
! 		  REAL_VALUES_LESS (TREE_REAL_CST (arg0), 0)
! #endif
! 		  )
  		t = build_real (type,
  				REAL_VALUE_NEGATE (TREE_REAL_CST (arg0)));
***************
*** 1362,1365 ****
--- 1555,1559 ----
      case FLOOR_DIV_EXPR:
      case CEIL_DIV_EXPR:
+     case EXACT_DIV_EXPR:
      case RDIV_EXPR:
        if (integer_onep (arg1))
***************
*** 1475,1479 ****
  	      break;
  	    }
! 	  TREE_CODE (t) = code;
  	}
  
--- 1669,1673 ----
  	      break;
  	    }
! 	  TREE_SET_CODE (t, code);
  	}
  
***************
*** 1502,1506 ****
  		|| code == EQ_EXPR || code == NE_EXPR)
  	      {
! 		TREE_CODE (varop) = PREINCREMENT_EXPR;
  		*constoploc = newconst;
  		return t;
--- 1696,1700 ----
  		|| code == EQ_EXPR || code == NE_EXPR)
  	      {
! 		TREE_SET_CODE (varop, PREINCREMENT_EXPR);
  		*constoploc = newconst;
  		return t;
***************
*** 1516,1520 ****
  		|| code == EQ_EXPR || code == NE_EXPR)
  	      {
! 		TREE_CODE (varop) = PREDECREMENT_EXPR;
  		*constoploc = newconst;
  		return t;
--- 1710,1714 ----
  		|| code == EQ_EXPR || code == NE_EXPR)
  	      {
! 		TREE_SET_CODE (varop, PREDECREMENT_EXPR);
  		*constoploc = newconst;
  		return t;
***************
*** 1531,1535 ****
  	    {
  	    case GE_EXPR:
! 	      TREE_CODE (t) = code = GT_EXPR;
  	      arg1 = combine (MINUS_EXPR, arg1, integer_one_node);
  	      TREE_OPERAND (t, 1) = arg1;
--- 1725,1730 ----
  	    {
  	    case GE_EXPR:
! 	      code = GT_EXPR;
! 	      TREE_SET_CODE (t, code);
  	      arg1 = combine (MINUS_EXPR, arg1, integer_one_node);
  	      TREE_OPERAND (t, 1) = arg1;
***************
*** 1537,1541 ****
  
  	    case LT_EXPR:
! 	      TREE_CODE (t) = code = LE_EXPR;
  	      arg1 = combine (MINUS_EXPR, arg1, integer_one_node);
  	      TREE_OPERAND (t, 1) = arg1;
--- 1732,1737 ----
  
  	    case LT_EXPR:
! 	      code = LE_EXPR;
! 	      TREE_SET_CODE (t, code);
  	      arg1 = combine (MINUS_EXPR, arg1, integer_one_node);
  	      TREE_OPERAND (t, 1) = arg1;
***************
*** 1552,1559 ****
  	    {
  	    case GT_EXPR:
! 	      TREE_CODE (t) = NE_EXPR;
  	      break;
  	    case LE_EXPR:
! 	      TREE_CODE (t) = EQ_EXPR;
  	      break;
  	    case GE_EXPR:
--- 1748,1755 ----
  	    {
  	    case GT_EXPR:
! 	      TREE_SET_CODE (t, NE_EXPR);
  	      break;
  	    case LE_EXPR:
! 	      TREE_SET_CODE (t, EQ_EXPR);
  	      break;
  	    case GE_EXPR:
diff -rc2N gcc-1.35/gcc.1 gcc-1.36/gcc.1
*** gcc-1.35/gcc.1	Fri Jan 20 01:41:28 1989
--- gcc-1.36/gcc.1	Mon Jun 19 00:18:45 1989
***************
*** 1,6 ****
! .\	" ======================
! .\	" This version is 1.33.
! .\	" ======================
! .TH GCC 1 "19 January 1989" "Version 1.33"
  .SH NAME
  gcc \- GNU project C Compiler
--- 1,8 ----
! .TH GCC 1 "18 June 1989" "Version 1.36"
! .de BP
! .sp
! .ti -.2i
! \(**
! ..
  .SH NAME
  gcc \- GNU project C Compiler
***************
*** 7,16 ****
  .SH SYNOPSIS
  .B gcc
! [ option ] ... file ...
  .SH WARNING
  This man page is an extract of the documentation of the
! .I GNU\ C\ compiler
! and is limited to the meaning of the options.  It is updated only
! occasionally, because the GNU project does not use nroff.
  For complete, current documentation, refer to the Info file
  .B gcc
--- 9,18 ----
  .SH SYNOPSIS
  .B gcc
! [ options ] files
  .SH WARNING
  This man page is an extract of the documentation of the
! .I GNU C compiler
! and is limited to the meaning of the options.
! It is updated only occasionally, because the GNU project does not use nroff.
  For complete, current documentation, refer to the Info file
  .B gcc
***************
*** 18,49 ****
  .B gcc.dvi
  which are made from the Texinfo source file
! .B gcc.texinfo
! \.
  .SH DESCRIPTION
  The
! .I GNU\ C\ compiler
! uses a command syntax much like the Unix C compiler. The 
  .I gcc
! program accepts options and file names as operands. Multiple
! single-letter options may
  .I not
! be grouped: `\fB\-dr\fR'
! is very different from `\fB\-d\ \-r\fR'.
! When you invoke
! .I GNU\ CC,
! it normally does preprocessing, compilation,
! assembly and linking. File names which end in `\fB.c\fR'
! are taken as C
! source to be preprocessed and compiled; compiler output files plus any
! input files with names ending in `\fB.s\fR'
! are assembled; then the
! resulting object files, plus any other input files, are linked together to
! produce an executable.
  Command options allow you to stop this process at an intermediate stage.
! For example, the `\fB\-c\fR'
  option says not to run the linker.
  Then the output consists of object files output by the assembler.
! Other command options are passed on to one stage.
  Some options control the preprocessor and others the compiler itself.
  .SH OPTIONS
  Here are the options to control the overall compilation process,
--- 20,62 ----
  .B gcc.dvi
  which are made from the Texinfo source file
! .BR gcc.texinfo .
  .SH DESCRIPTION
  The
! .I GNU C compiler
! uses a command syntax much like the Unix C compiler.
! The
  .I gcc
! program accepts options and file names as operands.
! Multiple single-letter options may
  .I not
! be grouped:
! .B \-dr
! is very different from
! .BR "\-d \-r" .
! .P
! When you invoke GNU CC, it normally does preprocessing, compilation,
! assembly and linking.
! File names which end in
! .B .c
! are taken as C source to be preprocessed and compiled;
! file names ending in
! .B .i
! are taken as preprocessor output to be compiled;
! compiler output files plus any input files with names ending in
! .B .s
! are assembled;
! then the resulting object files, plus any other input files,
! are linked together to produce an executable.
! .P
  Command options allow you to stop this process at an intermediate stage.
! For example, the 
! .B \-c
  option says not to run the linker.
  Then the output consists of object files output by the assembler.
! .P
! Other command options are passed on to one stage of processing.
  Some options control the preprocessor and others the compiler itself.
+ Yet other options control the assembler and linker;
+ these are not documented here, but you rarely need to use any of them.
  .SH OPTIONS
  Here are the options to control the overall compilation process,
***************
*** 50,62 ****
  including those that say whether to link, whether to assemble, and so on.
  .TP
! .BI \-o "\ \ file"
! Place linker output in file \fIfile\fR.
  This applies regardless to whatever sort of output is being produced,
! whether it be an executable file, an object file, an assembler file or
! preprocessed C code.
! If `\fB\-o\fR'
! is not specified, the default is to put an executable file
! in `\fBa.out\fR', the object file `\fIsource\fB.c\fR' in `\fIsource\fB.o\fR',
! an assembler file in `\fIsource\fB.s\fR',
  and preprocessed C on standard output.
  .TP
--- 63,83 ----
  including those that say whether to link, whether to assemble, and so on.
  .TP
! .BI \-o " file"
! Place output in file
! .IR file .
  This applies regardless to whatever sort of output is being produced,
! whether it be an executable file, an object file,
! an assembler file or preprocessed C code.
! .sp
! If 
! .B \-o
! is not specified, the default is to put an executable file in
! .BR a.out ,
! the object file
! .IB source .c
! in
! .IB source .o\fR,
! an assembler file in
! .IB source .s\fR,
  and preprocessed C on standard output.
  .TP
***************
*** 63,69 ****
  .B \-c
  Compile or assemble the source files, but do not link.
! Produce object files with names made by replacing `\fB\.c\fR'
! or `\fB\.s\fR'
! with `\fB\.o\fR'
  at the end of the input file names.
  Do nothing at all for object files specified as input.
--- 84,93 ----
  .B \-c
  Compile or assemble the source files, but do not link.
! Produce object files with names made by replacing
! .B .c
! or
! .B .s
! with
! .B .o
  at the end of the input file names.
  Do nothing at all for object files specified as input.
***************
*** 71,84 ****
  .B \-S
  Compile into assembler code but do not assemble.
! The assembler output file name is made by replacing `\fB\.c\fR'
! with `\fB\.s\fR'
  at the end of the input file name.
! Do nothing at all for assembler source files or object files specified
! as input.
  .TP
  .B \-E
  Run only the C preprocessor.
! Preprocess all the C source files specified
! and output the results to standard output.
  .TP
  .B \-v
--- 95,110 ----
  .B \-S
  Compile into assembler code but do not assemble.
! The assembler output file name is made by replacing
! .B .c
! with
! .B .s
  at the end of the input file name.
! Do nothing at all for assembler source files or
! object files specified as input.
  .TP
  .B \-E
  Run only the C preprocessor.
! Preprocess all the C source files specified and output
! the results to standard output.
  .TP
  .B \-v
***************
*** 87,178 ****
  Some of these are directed to print their own version numbers.
  .TP
! .BI \-B "prefix"
! Compiler driver program tries \fIprefix\fR as a prefix for each program
! it tries to run. These programs are `\fBcpp\fR', `\fBcc1\fR',
! `\fBas\fR' and `\fBld\fR'.
! For each subprogram to be run, the compiler driver first tries
! the `\fB\-B\fR' prefix, if any.
! If that name is not found, or if `\fB\-B\fR' was not specified,
! the driver tries two standard prefixes,
! which are `\fB/usr/lib/gcc-\fR' and `\fB/usr/local/lib/gcc-\fR'.
! If neither of those results in a file name that is found,
! the unmodified program name is searched for using the directories
! specified in your `\fBPATH\fR' environment variable.
! The run-time support file `\fBgnulib\fR' is also searched for using
! the `\fB\-B\fR' prefix, if needed.
! If it is not found there, the two standard prefixes above are tried,
! and that is all. 
  The file is left out of the link if it is not found by those means.
  Most of the time, on most machines, you can do without it.
! .PP
! These options control the C preprocessor,
! which is run on each C source file before actual compilation.
! If you use the `\fB\-E\fR' option, nothing is done except C preprocessing.
! Some of these options make sense only together with `\fB\-E\fR'
! because they request preprocessor output that is not suitable
! for actual compilation.
! .TP
! .B \-C
! Tell the preprocessor not to discard comments. Used with the `\fB\-E\fR'
! option.
! .TP
! .BI \-I "dir"
! Search directory 
! .I dir
! for include files.
! .TP
! .B \-I\-
! Any directories specified with `\fB\-I\fR' options before the `\fB\-I\-\fR'
! option are searched only for the case of `\fB#include "\fIfile\fB"\fR';
! they are not searched for `\fB#include <\fIfile\fB>\fR'.
! If additional directories are specified with `\fB\-I\fR' options after
! the `\fB\-I\-\fR', these directories are searched for all `\fB#include\fR'
! directives. (Ordinally \fIall\fR `\fB\-I\fR' directories are used this
! way.)
! In addition, the `\fB\-I\-\fR' option inhibits the use of the current
! directory as the first search directory for `\fB#include "\fIfile\fB"\fR'.
! Therefore, the current directory is searched only if it is requested
! explicitly with `\fB\-I.\fR'.
! Specifying both `\fB\-I\-\fR' and `\fB\-I.\fR' allows you to control precisely
! which directories are searched before the current one and which are
! searched after.
! .TP
! .B \-nostdinc
! Do not search the standard system directories for header files.
! Only the directories you have specified with `\fB\-I\fR' options
! (and the current directory, if appropriate) are searched.
! Between `\fB\-nostdinc\fR' and `\fB\-I\-\fR', you can eliminate all
! directories from the search path except those you specify.
! .TP
! .B \-M
! Tell the preprocessor to output a rule suitable for \fBmake\fR
! describing the dependencies of each source file.
! For each source file, the preprocessor outputs one \fBmake\fR-rule
! whose target is the object file name for that source file and
! whose dependencies are all the files `\fB#include\fR'd in it.
! This rule may be a single line or may be continued `\fB\\\fR'-newline
! if it is long.`\fB\-M\fR' implies `\fB\-E\fR'.
! .TP
! .B \-MM
! Like `\fB\-M\fR' but the output mentions only the user-header files included
! with `\fB#include "\fIfile\fB"\fR'.
! System header files included with `\fB#include <\fIfile\fB>\fR'
! are omitted.`\fB\-MM\fR' implies `\fB\-E\fR'.
! .TP
! .BI \-D "macro"
! Define macro \fImacro\fR
! with the empty string as its definition.
! .TP
! .B \-D\fImacro=defn\fR
! Define macro \fImacro\fR as \fIdefn\fR.
! .TP
! .BI \-U "macro"
! Undefine macro \fImacro\fR.
! .TP
! .B \-T
! Support ANSI C trigraphs.
! You don't want to know about this brain-damage.
! The `\fB\-ansi\fR' option also has this effect.
! .PP
  These options control the details of C compilation itself.
  .TP
--- 113,203 ----
  Some of these are directed to print their own version numbers.
  .TP
! .B \-pipe
! Use pipes rather than temporary files for communication between the
! various stages of compilation.
! This fails to work on some systems where the assembler is unable
! to read from a pipe; but the GNU assembler has no trouble.
! .TP
! .BI \-B prefix
! Compiler driver program tries
! .I prefix
! as a prefix for each program it tries to run.
! These programs are
! .IR cpp ,
! .IR cc1 ,
! .I as
! and
! .IR ld .
! .sp
! For each subprogram to be run, the compiler driver first tries the
! .B \-B
! prefix, if any.
! If that name is not found, or if
! .B \-B
! was not specified, the driver tries two standard prefixes, which are
! .B /usr/lib/gcc-
! and
! .BR /usr/local/lib/gcc- .
! If neither of those results in a file name that is found, the
! unmodified program name is searched for using the directories
! specified in your
! .B PATH
! environment variable.
! .sp
! The run-time support file
! .B gnulib
! is also searched for using the
! .B \-B
! prefix, if needed.
! If it is not found there, the two standard prefixes above
! are tried, and that is all.
  The file is left out of the link if it is not found by those means.
  Most of the time, on most machines, you can do without it.
! .sp
! You can get a similar result from the environment variable
! .BR GCC_EXEC_PREFIX ;
! if it is defined, its value is used as a prefix in the same way.
! If both the
! .B \-B
! option and the
! .B GCC_EXEC_PREFIX
! variable are present, the
! .B \-B
! option is used first and the environment variable value second.
! .TP
! .BI -b prefix
! The argument
! .I prefix
! is used as a second prefix for the compiler executables and libraries.
! This prefix is optional: the compiler tries each file first with it,
! then without it.
! This prefix follows the prefix specified with
! .B \-B
! or the default prefixes.
! .sp
! Thus,
! .B \-bvax- \-Bcc/
! in the presence of environment variable
! .B GCC_EXEC_PREFIX
! with definition
! .B /u/foo/
! causes GNU CC to try the following file names for the preprocessor executable:
! .sp
! 	\fBcc/vax-cpp
! .br
! 	cc/cpp
! .br
! 	/u/foo/vax-cpp
! .br
! 	/u/foo/cpp
! .br
! 	/usr/local/lib/gcc-vax-cpp
! .br
! 	/usr/local/lib/gcc-cpp
! .br
! 	/usr/lib/gcc-vax-cpp
! .br
! 	/usr/lib/gcc-cpp\fR
! .P
  These options control the details of C compilation itself.
  .TP
***************
*** 179,192 ****
  .B \-ansi
  Support all ANSI standard C programs.
  This turns off certain features of GNU C that are incompatible with
! ANSI C, such as the \fBasm\fR, \fBinline\fR and \fBtypeof\fR keywords, and
! predefined macros such as \fBunix\fR and \fBvax\fR that identify
! the type of system you are using.
  It also enables the undesirable and rarely used ANSI trigraph feature.
! The `\fB\-ansi\fR' option does not cause non-ANSI programs to be rejected
! gratuitously.
! For that, `\fB\-pedantic\fR' is required in addition to `\fB\-ansi\fR'.
! The macro \fB__STRICT_ANSI__\fR
! is predefined when the `-ansi' option is used.
  Some header files may notice this macro and refrain from declaring
  certain functions or defining certain macros that the ANSI standard
--- 204,252 ----
  .B \-ansi
  Support all ANSI standard C programs.
+ .sp
  This turns off certain features of GNU C that are incompatible with
! ANSI C, such as the
! .BR asm ,
! .B inline
! and
! .B typeof
! keywords, and predefined macros such as
! .B unix
! and
! .B vax
! that identify the type of system you are using.
  It also enables the undesirable and rarely used ANSI trigraph feature.
! .sp
! The alternate keywords
! .BR __asm__ ,
! .B __inline__
! and
! .B __typeof__
! continue to work despite
! .BR \-ansi .
! You would not want to use them in an ANSI C program, of course,
! but it useful to put them in header files that might be included
! in compilations done with
! .BR \-ansi .
! Alternate predefined macros such as
! .B __unix__
! and
! .B __vax__
! are also available, with or without
! .BR \-ansi .
! .sp
! The
! .B \-ansi
! option does not cause non-ANSI programs to be rejected gratuitously.
! For that,
! .B \-pedantic
! is required in addition to
! .BR \-ansi .
! .sp
! The macro 
! .B __STRICT_ANSI__
! is predefined when the
! .B \-ansi
! option is used.
  Some header files may notice this macro and refrain from declaring
  certain functions or defining certain macros that the ANSI standard
***************
*** 197,244 ****
  Attempt to support some aspects of traditional C compilers.
  Specifically:
! .br
! \(** All \fBextern\fR declarations take effect globally even if 
! they are written inside of a function definition.
  This includes implicit declarations of functions.
! .br	
! \(** The keywords \fBtypeof\fR, \fBinline\fR, \fBsigned\fR, \fBconst\fR
! and \fBvolatile\fR are not recognized.
! .br	
! \(** Comparisons between pointers and integers are always allowed.
! .br
! \(** Integer types \fBunsigned short\fR and \fBunsigned char\fR
! promote to \fBunsigned int\fR.
! .br
! \(** Out-of-range floating point literals are not an error.
! .br
! \(** All automatic variables not declared \fBregister\fR are preserved by
! \fBlongjmp\fR.  Ordinarily, GNU C follows ANSI C: automatic variables
! not declared \fBvolatile\fR may be clobbered.
! .br
! \(** In the preprocessor, comments convert to nothing at all,
  rather than to a space.
  This allows traditional token concatenation.
! .br
! \(** In the preprocessor, macro arguments are recognized within string
! constants in a macro definition (and their values are stringified,
! though without additional quote marks, when they appear in such a
! context).  The preprocessor also considers a string constant to end
! at a newline.
! .br
! \(** The predefined macro \fB__STDC__\fR is not defined when you 
! use `\fB\-traditional\fR', but \fB__GNUC__\fR is (since the GNU extensions
! which \fB__GNUC__\fR indicates are not affected by `\fB\-traditional\fR').
! If you need to write header files that work
! differently depending on whether `\fB\-traditional\fR' is in use, by
! testing both of these predefined macros you can distinguish four
! situations: GNU C, traditional GNU C, other ANSI C compilers, and
  other old C compilers.
  .TP
  .B \-O
! Optimize.  Optimizing compilation takes somewhat more time, and a lot
! more memory for a large function.
! .br
! Without `\fB\-O\fR', the compiler's goal is to reduce the cost of
! compilation and to make debugging produce the expected results.
  Statements are independent: if you stop the program with a breakpoint
  between statements, you can then assign a new value to any variable or
--- 257,329 ----
  Attempt to support some aspects of traditional C compilers.
  Specifically:
! .BP
! All
! .B extern
! declarations take effect globally even if they are
! written inside of a function definition.
  This includes implicit declarations of functions.
! .BP
! The keywords
! .BR typeof ,
! .BR inline ,
! .BR signed ,
! .B const
! and
! .B volatile
! are not recognized.
! .BP
! Comparisons between pointers and integers are always allowed.
! .BP
! Integer types
! .B "unsigned short"
! and
! .B "unsigned char"
! promote to
! .BR "unsigned int" .
! .BP
! Out-of-range floating point literals are not an error.
! .BP
! All automatic variables not declared
! .B register
! are preserved by
! .IR longjmp (3C).
! Ordinarily, GNU C follows ANSI C: automatic variables not declared
! .B volatile
! may be clobbered.
! .BP
! In the preprocessor, comments convert to nothing at all,
  rather than to a space.
  This allows traditional token concatenation.
! .BP
! In the preprocessor, macro arguments are recognized within string
! constants in a macro definition (and their values are stringified, though
! without additional quote marks, when they appear in such a context).
! The preprocessor always considers a string constant to end at a newline.
! .BP
! The predefined macro
! .B __STDC__
! is not defined when you use
! .BR \-traditional ,
! but
! .B __GNUC__
! is (since the GNU extensions which
! .B __GNUC__
! indicates are not affected by
! .BR \-traditional ).
! If you need to write header files that work differently depending on whether
! .B \-traditional
! is in use, by testing both of these predefined macros you can distinguish
! four situations: GNU C, traditional GNU C, other ANSI C compilers, and
  other old C compilers.
  .TP
  .B \-O
! Optimize.
! Optimizing compilation takes somewhat more time,
! and a lot more memory for a large function.
! .sp
! Without
! .BR \-O ,
! the compiler's goal is to reduce the cost of compilation and
! to make debugging produce the expected results.
  Statements are independent: if you stop the program with a breakpoint
  between statements, you can then assign a new value to any variable or
***************
*** 245,264 ****
  change the program counter to any other statement in the function and
  get exactly the results you would expect from the source code.
! Without `\fB\-O\fR', only variables declared \fBregister\fR
  are allocated in registers.
! The resulting compiled code is
! a little worse than produced by PCC without `\fB\-O\fR'.
! .br
! With `\fB\-O\fR', the compiler tries to reduce code size and execution time.
! Some of the `\fB\-f\fR' options described below turn specific
! kinds of optimization on or off.
  .TP
  .B \-g
! Produce debugging information in the operating system's native format
! (for DBX or SDB).  GDB also can work with this debugging information.
! Unlike most other C compilers, GNU CC allows you to use `\fB\-g\fR' 
! with`\fB\-O\fR'.
! .br
! The short cuts taken by optimized code may occasionally
  produce surprising results: some variables you declared may not exist
  at all; flow of control may briefly move where you did not expect it;
--- 330,360 ----
  change the program counter to any other statement in the function and
  get exactly the results you would expect from the source code.
! .sp
! Without
! .BR \-O ,
! only variables declared
! .B register
  are allocated in registers.
! The resulting compiled code is a little worse than produced by PCC without
! .BR \-O .
! .sp
! With
! .BR \-O ,
! the compiler tries to reduce code size and execution time.
! .sp
! Some of the
! .B \-f
! options described below turn specific kinds of optimization on or off.
  .TP
  .B \-g
! Produce debugging information in the operating system's
! native format (for DBX or SDB).
! GDB also can work with this debugging information.
! .sp
! Unlike most other C compilers, GNU CC allows you to use
! .B \-g
! with
! .BR \-O .
! The shortcuts taken by optimized code may occasionally
  produce surprising results: some variables you declared may not exist
  at all; flow of control may briefly move where you did not expect it;
***************
*** 267,283 ****
  execute in different places because they were moved out of loops.
  Nevertheless it proves possible to debug optimized output.
! This makes it reasonable to use the optimizer for programs that might
! have bugs.
  .TP
  .B \-gg
! Produce debugging information in GDB's (the GNU Debugger's) own format.
! This requires the GNU assembler and linker
! in order to work.
! This feature will probably be eliminated.  It was intended to enable
! GDB to read the symbol table faster, but it doesn't result in enough
! of a speedup to be worth the larger object files and executables.  We
! are working on other ways of making GDB start even faster, which work
! with DBX format debugging information and could be made to work with
! SDB format.
  .TP
  .B \-w
--- 363,380 ----
  execute in different places because they were moved out of loops.
  Nevertheless it proves possible to debug optimized output.
! This makes it reasonable to use the optimizer for programs
! that might have bugs.
  .TP
  .B \-gg
! Produce debugging information in GDB's own format.
! This requires the GNU assembler and linker in order to work.
! .sp
! This feature will probably be eliminated.
! It was intended to enable GDB to read the symbol table faster,
! but it doesn't result in enough of a speedup to be worth the
! larger object files and executables.
! We are working on other ways of making GDB start even faster,
! which work with DBX format debugging information and could be
! made to work with SDB format.
  .TP
  .B \-w
***************
*** 286,327 ****
  .B \-W
  Print extra warning messages for these events:
! .br
! \(** An automatic variable is used without first being initialized.
! These warnings are possible only in optimizing compilation, because 
! they require data flow information that is computed only when
! optimizing. 
! They occur only for variables that are candidates for register
! allocation. Therefore, they do not occur for a variable that is
! declared
! .B volatile,
! or whose address is taken, or whose size is other than 
! 1,2,4 or 8 bytes. Also, they do not occur for structures,
! unions or arrays, even when they are in registers.
! Note that there may be no warning about a variable that is used
! only to compute a value that itself is never used, because such
! computations may be deleted by the flow analysis pass before the
! warnings are printed.
  These warnings are made optional because GNU CC is not smart
  enough to see all the reasons why the code might be correct
  despite appearing to have an error.
  .br
! \(** A nonvolatile automatic variable might be changed
! by a call to \fBlongjmp\fR.
  These warnings as well are possible only in optimizing compilation.
! The compiler sees only the calls to \fBsetjmp\fR.
! It cannot know where \fBlongjmp\fR
! will be called; in fact, a signal handler could call it at any point
! in the code. As a result, you may get a warning even when there is
! in fact no problem because \fBlongjmp\fR
  cannot in fact be called at the place which would cause a problem.
! .br
! \(** A function can return either with or without a value.
! (Falling off the end of the function body is considered returning
! without a value.)
! Spurious warning can occur because GNU CC does not realize that
! certain functions (including \fBabort\fR
! and \fBlongjmp\fR) will never return.
! .br
! \(** An expression-statement contains no side effects.
  .TP
  .B \-Wimplicit
--- 383,505 ----
  .B \-W
  Print extra warning messages for these events:
! .BP
! An automatic variable is used without first being initialized.
! .sp
! These warnings are possible only in optimizing compilation,
! because they require data flow information that is computed only
! when optimizing.
! If you don't specify
! .BR \-O ,
! you simply won't get these warnings.
! .sp
! These warnings occur only for variables that are candidates for
! register allocation.
! Therefore, they do not occur for a variable that is declared
! .BR volatile ,
! or whose address is taken, or whose size is other than 1, 2, 4 or 8 bytes.
! Also, they do not occur for structures, unions or arrays, even when
! they are in registers.
! .sp
! Note that there may be no warning about a variable that is used only
! to compute a value that itself is never used, because such
! computations may be deleted by data flow analysis before the warnings
! are printed.
! .sp
  These warnings are made optional because GNU CC is not smart
  enough to see all the reasons why the code might be correct
  despite appearing to have an error.
+ Here is one example of how this can happen:
+ .sp
+ 	{
  .br
! 	\ \ int x;
! .br
! 	\ \ switch (y)
! .br
! 	\ \ \ \ {
! .br
! 	\ \ \ \ case 1: x = 1;
! .br
! 	\ \ \ \ \ \ break;
! .br
! 	\ \ \ \ case 2: x = 4;
! .br
! 	\ \ \ \ \ \ break;
! .br
! 	\ \ \ \ case 3: x = 5;
! .br
! 	\ \ \ \ }
! .br
! 	\ \ foo (x);
! .br
! 	}
! .sp
! If the value of 
! .I y
! is always 1, 2 or 3, then
! .I x
! is always initialized, but GNU CC doesn't know this.
! Here is another common case:
! .sp
! 	{
! .br
! 	\ \ int save_y;
! .br
! 	\ \ if (change_y) save_y = y, y = new_y;
! .br
! 	\ \ ...
! .br
! 	\ \ if (change_y) y = save_y;
! .br
! 	}
! .sp
! This has no bug because
! .I save_y
! is used only if it is set.
! .sp
! Some spurious warnings can be avoided if you declare as
! .B volatile
! all the functions you use that never return.
! .BP
! A nonvolatile automatic variable might be changed by a call to
! .IR longjmp (3C).
  These warnings as well are possible only in optimizing compilation.
! .sp
! The compiler sees only the calls to
! .IR setjmp (3C).
! It cannot know where
! .IR longjmp (3C)
! will be called; in fact, a signal handler could
! call it at any point in the code.
! As a result, you may get a warning even when there is
! in fact no problem because
! .IR longjmp (3C)
  cannot in fact be called at the place which would cause a problem.
! .BP
! A function can return either with or without a value.
! (Falling off the end of the function body is considered returning without
! a value.)
! For example, this function would evoke such a warning:
! .sp
! 	foo (a)
! .br
! 	{
! .br
! 	\ \ if (a > 0)
! .br
! 	\ \ \ \ return a;
! .br
! 	}
! .sp
! Spurious warnings can occur because GNU CC does not realize that
! certain functions (including
! .IR abort (3C)
! and 
! .IR longjmp (3C))
! will never return.
! .BP
! An expression-statement contains no side effects.
! .sp
! In the future, other useful warnings may also be enabled by this option.
  .TP
  .B \-Wimplicit
***************
*** 329,707 ****
  .TP
  .B \-Wreturn-type
! Warn whenever a function is defined with a return-type that
! defaults to \fBint\fR. Also warn about any \fBreturn\fR
! statement with no return-value in a function whose return-type
! is not \fBvoid\fR.
  .TP
  .B \-Wunused
! Warn whenever a local variable is unused aside from its declaration.
  .TP
  .B \-Wcomment
! Warn whenever a comment-start sequence `/*' appears in a comment.
  .TP
  .B \-Wall
! All of the above \fB\-W\fR options combined.
  .TP
  .B \-Wwrite-strings
! Give string constants the type \fBconst char[\fIlength\fB]\fR so that
! copying the address of one into a non-\fBconst char *\fR
! pointer will get a warning.  These warnings will help you find at
! compile time code that can try to write into a string constant, but
! only if you have been very careful about using \fBconst\fR in
! declarations and prototypes.  Otherwise, it will just be a nuisance;
! this is why we did not make \fB\-Wall\fR request these warnings.
  .TP
  .B \-p
! Generate extra code to write profile information suitable for the
! analysis program \fBprof\fR.
  .TP
  .B \-pg
  Generate extra code to write profile information suitable for the
! analysis program \fBgprof\fR.
  .TP
! .BI \-l "library"
! Search a standard list of directories for a library named \fIlibrary\fR,
! which is actually a file named `\fBlib\fIlibrary\fB.a\fR'.
  The linker uses this file as if it had been specified precisely by name.
  The directories searched include several standard system directories
! plus any that you specify with `\fB\-L\fR'.
! Normally the files found this way are library files - archive files whose
! members are object files. The linker handles an archive file by scanning
! through it for members which define symbols that have so far been
! referenced but not defined. But if the file that is found is an ordinary
! object file, it is linked in the usual fashion. 
! The only difference between an `\fB\-l\fR' option and specifying
! a file name is that `\fB-l\fR' searches several directories.
  .TP
! .BI \-L "dir"
! Add directory \fIdir\fR to the list of directories to be searched
! for `\fB\-l\fR'.
  .TP
  .B \-nostdlib
! Don't use the standard system libraries and startup files when
! linking. Only the files you specify (plus `\fBgnulib\fR')
  will be passed to the linker.
  .TP
! .BI \-m "machinespec"
  Machine-dependent option specifying something about the type of target machine.
! These options are defined by the macro \fBTARGET_SWITCHES\fR
! in the machine description. The default for the options is also
! defined by that macro, which enables you to change the defaults.
! .IP
! These are the `\fB\-m\fR' options defined in the 68000 machine description:
! .TP 10
! .B \ \ \ \ \ \ \ \ \-m68020
! .TP 10
! .B \ \ \ \ \ \ \ \ \-mc68020
  Generate output for a 68020 (rather than a 68000).
  This is the default if you use the unmodified sources.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-m68000
! .TP 10
! .B \ \ \ \ \ \ \ \ \-mc68000
  Generate output for a 68000 (rather than a 68020).
! .TP 10
! .B \ \ \ \ \ \ \ \ \-m68881
  Generate output containing 68881 instructions for floating point.
  This is the default if you use the unmodified sources.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-mfpa
  Generate output containing Sun FPA instructions for floating point.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-msoft-float
  Generate output containing library calls for floating point.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-mshort
! Consider type \fBint\fR to be 16 bits wide, like \fBshort int\fR.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-mnobitfield
! Do not use the bit-field instructions. 
! .B `\-m68000'
  implies
! .B `\-mnobitfield'.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-mbitfield
! Do use the bit-field instructions. 
! .B `\-m68020'
  implies
! .B `\-mbitfield'.
  This is the default if you use the unmodified sources.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-mrtd
! Use a different function-calling convention, in which functions that
! take a fixed number of arguments return with the \fBrtd\fR
! instruction, which pops their arguments while returning.  This saves
! one instruction in the caller since there is no need to pop the
! arguments there.
! This calling convention is incompatible with the one normally used on
! Unix, so you cannot use it if you need to call libraries compiled with
! the Unix compiler.
! Also, you must provide function prototypes for all functions that take
! variable numbers of arguments (including \fBprintf\fR); otherwise
! incorrect code will be generated for calls to those functions.
  In addition, seriously incorrect code will result if you call a
! function with too many arguments.  (Normally, extra arguments are
! harmlessly ignored.)
! The \fBrtd\fR
! instruction is supported by the 68010 and 68020
! processors, but not by the 68000.
! .IP 
! These are the `\fB\-m\fR' options defined in the VAX 
! machine description:
! .TP 10
! .B \ \ \ \ \ \ \ \ \-munix
! Do not output certain jump instructions (\fBaobleq\fR and so on)
! that the Unix assembler
! for the VAX cannot handle across long ranges. 
! .TP 10
! .B \ \ \ \ \ \ \ \ \-mgnu
! Do output those jump instructions, on the assumption
! that you will assemble with the GNU assembler.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-mg
  Output code for g-format floating point numbers instead of d-format.
! .TP 5
! .BI \-f "flag"
! Specify machine-independent flags.  Most flags have both positive and
! negative forms; the negative form of `\fB\-ffoo\fR' would 
! be `\fB\-fno-foo\fR'.  In the table below, only one of the forms is
! listed---the one which is not the default.  You can figure out the
! other form by either removing `\fBno-\fR' or adding it.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-ffloat-store
  Do not store floating-point variables in registers.
! This prevents undesirable excess precision on machines such as the 68000
! where the floating registers (of the 68881) keep more precision
! than a \fBdouble\fR is supposed to have.
  For most programs, the excess precision does only good, but a few
  programs rely on the precise definition of IEEE floating point.
! Use `\fB\-ffloat-store\fP'
  for such programs.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-fno-asm
! Do not recognize \fBasm\fR, \fBinline\fR or \fBtypeof\fR
! as a keyword. These words may then be used as identifiers.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-fno-defer-pop
  Always pop the arguments to each function call as soon as that
  function returns.
! Normally the compiler (when optimizing) lets arguments accumulate on the
! stack for several function calls and pops them all at once.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-fstrength-reduce
  Perform the optimizations of loop strength reduction and
  elimination of iteration variables.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-fcombine-regs
  Allow the combine pass to combine an instruction that copies one
  register into another.
  This might or might not produce better code when used in addition to
! `\fB\-O\fP'.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-fforce-mem
  Force memory operands to be copied into registers before doing
  arithmetic on them.
! This may produce better code by making all
! memory references potential common subexpressions.
! When they are not common subexpressions,
! instruction combination should eliminate the separate register-load.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-fforce-addr
  Force memory address constants to be copied into registers before
  doing arithmetic on them.
! This may produce better code just as `\fB\-fforce-mem\fP' may.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-fomit-frame-pointer
! Don't keep the frame pointer in a register for functions that don't
! need one.  This avoids the instructions to save, set up and restore
! frame pointers; it also makes an extra register available in many
! functions. \fBIt\ also\ makes\ debugging\ impossible.\fR
! On some machines, such as the VAX, this flag has no effect,
! because the standard calling sequence automatically handles
! the frame pointer and nothing is saved by pretending it doesn't exist.
! The machine-description macro \fBFRAME_POINTER_REQUIRED\fR
  controls whether a target machine supports this flag.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-finline-functions
  Integrate all simple functions into their callers.
! The compiler heuristically decides which functions are simple enough
! to be worth integrating in this way.
! If all calls to a given function are integrated, and the function
! is declared \fBstatic\fR,
! then the function is normally not output as assembler code in its
! own right.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-fkeep-inline-functions
! Even if all calls to a given function are integrated, and the
! function is declared \fBstatic\fR,
! nevertheless output a separate run-time callable version of
! the function.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-fwritable-strings
  Store string constants in the writable data segment and don't uniquize them.
! This is for compatibility with old programs which assume
! they can write into string constants.  Writing into string constants
! is a very bad idea; ``constants'' should be constant.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-fcond-mismatch
  Allow conditional expressions with mismatched types in the second and
! third arguments.  The value of such an expression is void.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-fno-function-cse
  Do not put function addresses in registers; make each instruction that
  calls a constant function contain the function's address explicitly.
! This option results in less efficient code, but some strange hacks
! that alter the assembler output may be confused by the optimizations
! performed when this option is not used.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-fvolatile
  Consider all memory references through pointers to be volatile.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-fshared-data
! Requests that the data and non-\fBconst\fR variables of this
! compilation be shared data rather than private data.  The distinction
! makes sense only on certain operating systems, where shared data is
! shared between processes running the same program, while private data
! exists in one copy per process.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-funsigned-char
! Let the type \fBchar\f be the unsigned, like \fBunsigned char\fR.
! Each kind of machine has a default for what \fBchar\fR
! should be. It is either like \fBunsigned char\fR
! by default of like \fBsigned char\fR
! by default. (Actually, at present, the default is always signed.)
! The type \fBchar\fR
! is always a distinct type from either \fBsigned char\fR
! or \fBunsigned char\fR,
  even though its behavior is always just like one of those two.
! Note that this is equivalent to `\fB\-fno-signed-char\fR', which is the
! negative form of `\fB\-fsigned-char\fR'.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-fsigned-char
! Let the type \fBchar\fR be the same as \fBsigned char\fR.
! Note that this is equivalent to `\fB\-fno-unsigned-char\fR', which is
! the negative form of `\fB\-funsigned-char\fR'.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-ffixed-\fIreg\fR
! Treat the register named \fIreg\fR as a fixed register; generated
! code should never refer to it (except perhaps as a stack pointer,
! frame pointer or in some other fixed role). \fIreg\fR
  must be the name of a register.
! The register names accepted are machine-specific and are defined in
! the \fBREGISTER_NAMES\fR
  macro in the machine description macro file.
  This flag does not have a negative form, because it specifies a
  three-way choice.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-fcall-used-\fIreg\fR
! Treat the register named \fIreg\fR
  as an allocatable register that is clobbered by function calls.
! It may be allocated for temporaries or variables
! that do not live across a call.
! Functions compiled this way will not save and restore the
! register \fIreg\fR.
  Use of this flag for a register that has a fixed pervasive role
  in the machine's execution model, such as the stack pointer or
  frame pointer, will produce disastrous results.
  This flag does not have a negative form, because it specifies a
  three-way choice.
! .TP 10
! .B \ \ \ \ \ \ \ \ \-fcall-saved-\fIreg\fR
! Treat the register named \fIreg\fR
  as an allocatable register saved by functions.
! It may be allocated even for temporaries or
! variables that live across a call.  Functions compiled this way
! will save and restore the register \fIreg\fR if they use it.
  Use of this flag for a register that has a fixed pervasive role
  in the machine's execution model, such as the stack pointer or
  frame pointer, will produce disastrous results.
  A different sort of disaster will result from the use of this
  flag for a register in which function values may be returned.
  This flag does not have a negative form, because it specifies a
  three-way choice.
  .TP
! .BI \-d "letters"
! Says to make debugging dumps at times specified by \fIletters\fR.
  Here are the possible letters:
! .TP 10
! .B \ \ \ \ \ \ \ \ r
  Dump after RTL generation.
! .TP 10
! .B \ \ \ \ \ \ \ \ j
  Dump after first jump optimization.
! .TP 10
! .B \ \ \ \ \ \ \ \ J
  Dump after last jump optimization.
! .TP 10
! .B \ \ \ \ \ \ \ \ s
! Dump after CSE (including the jump optimization that sometimes
! follows CSE).
! .TP 10
! .B \ \ \ \ \ \ \ \ L
  Dump after loop optimization.
! .TP 10
! .B \ \ \ \ \ \ \ \ f
  Dump after flow analysis.
! .TP 10
! .B \ \ \ \ \ \ \ \ c
  Dump after instruction combination.
! .TP 10
! .B \ \ \ \ \ \ \ \ l
  Dump after local register allocation.
! .TP 10
! .B \ \ \ \ \ \ \ \ g
  Dump after global register allocation.
! .TP 10
! .B \ \ \ \ \ \ \ \ m
  Print statistics on memory usage, at the end of the run.
  .TP
  .B \-pedantic
! Issue all the warnings demanded by strict ANSI standard C;
! reject all programs that use forbidden extensions.
! Valid ANSI standard C programs should compile properly with or
! without this option (though a rare few will require `\fB\-ansi\fR'.
! However, without this option, certain GNU extensions and
! traditional C features are supported as well.
  With this option, they are rejected.
! There is no reason to \fIuse\fR
! this option; it exists only to satisfy pedants.
  .SH FILES
! .ta \w'/usr/local/lib/gcc-gnulib 'u
! file.c	input file
  .br
  file.o	object file
  .br
! a.out	loaded output
  .br
! /tmp/cc?	temporary
  .br
! /usr/local/lib/gcc-cpp	preprocessor
! .br
! /usr/local/lib/gcc-cc1	compiler
! .br
! /usr/local/lib/gcc-gnulib	library need by GCC on some machines
  .br
! /lib/crt0.o	runtime startoff
  .br
! /lib/libc.a	standard library, see
  .IR intro (3)
  .br
! /usr/include	standard directory for `#include' files
! .br
! /usr/include/gcc-include	standard gcc directory for `#include' files
  .br
  .SH "SEE ALSO"
! adb(1), ld(1), dbx(1), as(1)
  .SH BUGS
! Bugs should be reported to bug-gcc@prep.ai.mit.edu. Bugs tend actually to be
! fixed if they can be isolated, so it is in your interest to report them
! in such a way that they can be easily reproduced.
  .SH COPYING
  Copyright (c) 1988 Free Software Foundation, Inc.
! .br
  Permission is granted to make and distribute verbatim copies of
  this manual provided the copyright notice and this permission notice
  are preserved on all copies.
! .br
  Permission is granted to copy and distribute modified versions of this
  manual under the conditions for verbatim copying, provided that the
--- 507,1311 ----
  .TP
  .B \-Wreturn-type
! Warn whenever a function is defined with a return-type that defaults to
! .BR int .
! Also warn about any
! .B return
! statement with no return-value in a function whose return-type is not
! .BR void .
  .TP
  .B \-Wunused
! Warn whenever a local variable is unused aside from its declaration,
! and whenever a function is declared static but never defined.
  .TP
+ .B \-Wswitch
+ Warn whenever a
+ .B switch
+ statement has an index of enumeral type and lacks a
+ .B case
+ for one or more of the named codes of that enumeration.
+ (The presence of a
+ .B default
+ label prevents this warning.)
+ .B case
+ labels outside the enumeration range also provoke
+ warnings when this option is used.
+ .TP
  .B \-Wcomment
! Warn whenever a comment-start sequence
! .B /\(**
! appears in a comment.
! .TP
! .B \-Wtrigraphs
! Warn if any trigraphs are encountered (assuming they are enabled).
  .TP
  .B \-Wall
! All of the above 
! .B \-W
! options combined.
! These are all the options which pertain to usage that we do not recommend and
! that we believe is always easy to avoid, even in conjunction with macros.
! .sp 
! The other
! .BR \-W ...
! options below are not implied by
! .B \-Wall
! because certain kinds of useful macros are almost impossible to write
! without causing those warnings.
  .TP
+ .B \-Wshadow
+ Warn whenever a local variable shadows another local variable.
+ .TP
+ .BI \-Wid-clash- len
+ Warn whenever two distinct identifiers match in the first
+ .I len
+ characters.
+ This may help you prepare a program that will compile with certain obsolete,
+ brain-damaged compilers.
+ .TP
+ .B \-Wpointer-arith
+ Warn about anything that depends on the size of a function type or of
+ .BR void .
+ GNU C assigns these types a size of 1, for convenience in calculations with
+ .B void \(**
+ pointers and pointers to functions.
+ .TP
+ .B \-Wcast-qual
+ Warn whenever a pointer is cast so as to remove a type qualifier from
+ the target type.
+ For example, warn if a 
+ .B const char \(**
+ is cast to an ordinary
+ .BR "char \(**" .
+ .TP
  .B \-Wwrite-strings
! Give string constants the type
! .B const char[\fIlength\fB]
! so that copying the address of one into a
! .RB non- "const char \(**"
! pointer will get a warning.
! These warnings will help you find at compile time
! code that can try to write into a string constant,
! but only if you have been very careful about using
! .B const
! in declarations and prototypes.
! Otherwise, it will just be a nuisance; this is why we did not make
! .B \-Wall
! request these warnings.
  .TP
  .B \-p
! Generate extra code to write profile information suitable
! for the analysis program
! .IR prof (1).
  .TP
  .B \-pg
  Generate extra code to write profile information suitable for the
! analysis program
! .IR gprof (1).
  .TP
! .B \-a
! Generate extra code to write profile information for basic blocks,
! suitable for the analysis program
! .IR tcov (1).
! Eventually GNU
! .IR gprof (1)
! should be extended to process this data.
! .TP
! .BI \-l library
! Search a standard list of directories for a library named
! .IR library ,
! which is actually a file named
! .BR lib\fIlibrary\fB.a .
  The linker uses this file as if it had been specified precisely by name.
+ .sp
  The directories searched include several standard system directories
! plus any that you specify with
! .BR \-L .
! .sp
! Normally the files found this way are library files--archive files
! whose members are object files.
! The linker handles an archive file by scanning through it for members
! which define symbols that have so far been referenced but not defined.
! But if the file that is found is an ordinary object file, it is linked
! in the usual fashion.
! The only difference between using an
! .B \-l
! option and specifying a file name is that
! .B \-l
! searches several directories.
  .TP
! .BI \-L dir
! Add directory
! .I dir
! to the list of directories to be searched for
! .BR \-l .
  .TP
  .B \-nostdlib
! Don't use the standard system libraries and startup files when linking.
! Only the files you specify (plus 
! .BR gnulib )
  will be passed to the linker.
  .TP
! .BI \-m machinespec
  Machine-dependent option specifying something about the type of target machine.
! These options are defined by the macro
! .B TARGET_SWITCHES
! in the machine description.
! The default for the options is also defined by that macro,
! which enables you to change the defaults.
! .sp
! These are the
! .B \-m
! options defined in the 68000 machine description:
! .sp
! .B \-m68020
! .br
! .B \-mc68020
! .in +.5i
  Generate output for a 68020 (rather than a 68000).
  This is the default if you use the unmodified sources.
! .in -.5i
! .sp
! .B \-m68000
! .br
! .B \-mc68000
! .in +.5i
  Generate output for a 68000 (rather than a 68020).
! .in -.5i
! .sp
! .B \-m68881
! .in +.5i
  Generate output containing 68881 instructions for floating point.
  This is the default if you use the unmodified sources.
! .in -.5i
! .sp
! .B \-mfpa
! .in +.5i
  Generate output containing Sun FPA instructions for floating point.
! .in -.5i
! .sp
! .B \-msoft-float
! .in +.5i
  Generate output containing library calls for floating point.
! .in -.5i
! .sp
! .B \-mshort
! .in +.5i
! Consider type
! .B int
! to be 16 bits wide, like
! .BR "short int" .
! .in -.5i
! .sp
! .B \-mnobitfield
! .in +.5i
! Do not use the bit-field instructions.
! .B \-m68000
  implies
! .BR \-mnobitfield .
! .in -.5i
! .sp
! .B \-mbitfield
! .in +.5i
! Do use the bit-field instructions.
! .B \-m68020
  implies
! .BR \-mbitfield .
  This is the default if you use the unmodified sources.
! .in -.5i
! .sp
! .B \-mrtd
! .in +.5i
! Use a different function-calling convention, in which functions
! that take a fixed number of arguments return with the
! .B rtd
! instruction, which pops their arguments while returning.
! This saves one instruction in the caller since there is no need to pop
! the arguments there.
! .sp
! This calling convention is incompatible with the one normally
! used on Unix, so you cannot use it if you need to call libraries
! compiled with the Unix compiler.
! .sp
! Also, you must provide function prototypes for all functions that
! take variable numbers of arguments (including 
! .BR printf (3S));
! otherwise incorrect code will be generated for calls to those functions.
! .sp
  In addition, seriously incorrect code will result if you call a
! function with too many arguments.
! (Normally, extra arguments are harmlessly ignored.)
! .sp
! The
! .B rtd
! instruction is supported by the 68010 and 68020 processors,
! but not by the 68000.
! .in -.5i
! .sp
! These
! .B \-m
! options are defined in the Vax machine description:
! .sp
! .B \-munix
! .in +.5i
! Do not output certain jump instructions 
! .RB ( aobleq
! and so on) that the Unix assembler for the Vax
! cannot handle across long ranges.
! .in -.5i
! .sp
! .B \-mgnu
! .in +.5i
! Do output those jump instructions, on the assumption that you
! will assemble with the GNU assembler.
! .in -.5i
! .sp
! .B \-mg
! .in +.5i
  Output code for g-format floating point numbers instead of d-format.
! .in -.5i
! .sp
! These
! .B \-m
! switches are supported on the Sparc:
! .sp
! .B \-mfpu
! .in +.5i
! Generate output containing floating point instructions.
! This is the default if you use the unmodified sources.
! .in -.5i
! .sp
! .B \-msoft-float
! .in +.5i
! Generate output containing library calls for floating point.
! .in -.5i
! .sp
! .B \-mno-epilogue
! .in +.5i
! Generate separate return instructions for
! .B return
! statements.
! This has both advantages and disadvantages; I don't recall what they are.
! .in -.5i
! .sp
! These
! .B \-m
! options are defined in the Convex machine description:
! .sp
! .B \-mc1
! .in +.5i
! Generate output for a C1.
! This is the default when the compiler is configured for a C1.
! .in -.5i
! .sp
! .B \-mc2
! .in +.5i
! Generate output for a C2.
! This is the default when the compiler is configured for a C2.
! .in -.5i
! .sp
! .B \-margcount
! .in +.5i
! Generate code which puts an argument count in the word preceding each
! argument list.
! Some nonportable Convex and Vax programs need this word.
! (Debuggers don't; this info is in the symbol table.)
! .in -.5i
! .sp
! .B \-mnoargcount
! .in +.5i
! Omit the argument count word.
! This is the default if you use the unmodified sources.
! .in -.5i
! .TP
! .BI \-f flag
! Specify machine-independent flags.
! Most flags have both positive and negative forms; the negative form of
! .B \-ffoo
! would be
! .BR \-fno-foo .
! In the table below, only one of the forms is listed--the one which
! is not the default.
! You can figure out the other form by either removing
! .B no-
! or adding it.
! .TP
! .B \-fpcc-struct-return
! Use the same convention for returning
! .B struct
! and
! .B union
! values that is used by the usual C compiler on your system.
! This convention is less efficient for small structures, and on many
! machines it fails to be reentrant; but it has the advantage of allowing
! intercallability between GCC-compiled code and PCC-compiled code.
! .TP
! .B \-ffloat-store
  Do not store floating-point variables in registers.
! This prevents undesirable excess precision on machines such as the
! 68000 where the floating registers (of the 68881) keep more
! precision than a 
! .B double
! is supposed to have.
! .sp
  For most programs, the excess precision does only good, but a few
  programs rely on the precise definition of IEEE floating point.
! Use
! .B \-ffloat-store
  for such programs.
! .TP
! .B \-fno-asm
! Do not recognize
! .BR asm ,
! .B inline
! or
! .B typeof
! as a keyword.
! These words may then be used as identifiers.
! You can use
! .BR __asm__ ,
! .B __inline__
! and
! .B __typeof__
! instead.
! .TP
! .B \-fno-defer-pop
  Always pop the arguments to each function call as soon as that
  function returns.
! Normally the compiler (when optimizing) lets arguments accumulate
! on the stack for several function calls and pops them all at once.
! .TP
! .B \-fstrength-reduce
  Perform the optimizations of loop strength reduction and
  elimination of iteration variables.
! .TP
! .B \-fcombine-regs
  Allow the combine pass to combine an instruction that copies one
  register into another.
  This might or might not produce better code when used in addition to
! .BR \-O .
! I am interested in hearing about the difference this makes.
! .TP
! .B \-fforce-mem
  Force memory operands to be copied into registers before doing
  arithmetic on them.
! This may produce better code by making all memory references
! potential common subexpressions.
! When they are not common subexpressions, instruction combination should
! eliminate the separate register-load.
! I am interested in hearing about the difference this makes.
! .TP
! .B \-fforce-addr
  Force memory address constants to be copied into registers before
  doing arithmetic on them.
! This may produce better code just as
! .B \-fforce-mem
! may.
! I am interested in hearing about the difference this makes.
! .TP
! .B \-fomit-frame-pointer
! Don't keep the frame pointer in a register for functions that
! don't need one.
! This avoids the instructions to save, set up and restore frame pointers;
! it also makes an extra register available in many functions.
! .B "It also makes debugging impossible."
! .sp
! On some machines, such as the Vax, this flag has no effect, because
! the standard calling sequence automatically handles the frame pointer
! and nothing is saved by pretending it doesn't exist.
! The machine-description macro
! .B FRAME_POINTER_REQUIRED
  controls whether a target machine supports this flag.
! .TP
! .B \-finline-functions
  Integrate all simple functions into their callers.
! The compiler heuristically decides which functions are simple
! enough to be worth integrating in this way.
! .sp
! If all calls to a given function are integrated, and the function is declared
! .BR static ,
! then the function is normally not output as assembler code in its own right.
! .TP
! .B \-fcaller-saves
! Enable values to be allocated in registers that will be clobbered by
! function calls, by emitting extra instructions to save and restore the
! registers around such calls.
! Such allocation is done only when it seems to result in better code than
! would otherwise be produced.
! .sp
! This option is enabled by default on certain machines, usually those
! which have no call-preserved registers to use instead.
! .TP
! .B \-fkeep-inline-functions
! Even if all calls to a given function are integrated, and the function is
! declared
! .BR static ,
! nevertheless output a separate run-time callable version of the function.
! .TP
! .B \-fwritable-strings
  Store string constants in the writable data segment and don't uniquize them.
! This is for compatibility with old programs which assume they can write
! into string constants.
! Writing into string constants is a very bad idea;
! constants should be constant.
! .TP
! .B \-fcond-mismatch
  Allow conditional expressions with mismatched types in the second and
! third arguments.
! The value of such an expression is void.
! .TP
! .B \-fno-function-cse
  Do not put function addresses in registers; make each instruction that
  calls a constant function contain the function's address explicitly.
! .sp
! This option results in less efficient code, but some strange hacks that
! alter the assembler output may be confused by the optimizations performed
! when this option is not used.
! .TP
! .B \-fvolatile
  Consider all memory references through pointers to be volatile.
! .TP
! .B \-fshared-data
! Requests that the data and
! .RB non- const
! variables of this compilation be shared data rather than private data.
! The distinction makes sense only on certain operating systems, where
! shared data is shared between processes running the same program, while
! private data exists in one copy per process.
! .TP
! .B \-funsigned-char
! Let the type
! .B char
! be the unsigned, like
! .BR "unsigned char" .
! .sp
! Each kind of machine has a default for what
! .B char
! should be.
! It is either like
! .B "unsigned char"
! by default or like
! .B "signed char"
! by default.
! (Actually, at present, the default is always signed.)
! .sp
! The type
! .B char
! is always a distinct type from either
! .B "signed char"
! or
! .BR "unsigned char" ,
  even though its behavior is always just like one of those two.
! .sp
! Note that this is equivalent to
! .BR \-fno-signed-char ,
! which is the negative form of
! .BR \-fsigned-char .
! .TP
! .B \-fsigned-char
! Let the type
! .B char
! be signed, like
! .BR "signed char" .
! .sp
! Note that this is equivalent to
! .BR \-fno-unsigned-char ,
! which is the negative form of
! .BR \-funsigned-char .
! .TP
! .B \-fdelayed-branch
! If supported for the target machine, attempt to reorder instructions to
! exploit instruction slots available after delayed branch instructions.
! .TP
! .BI \-ffixed- reg
! Treat the register named
! .I reg
! as a fixed register; generated code should never refer to it
! (except perhaps as a stack pointer, frame pointer or in some other fixed role).
! .sp
! .I reg
  must be the name of a register.
! The register names accepted are machine-specific and are defined in the
! .B REGISTER_NAMES
  macro in the machine description macro file.
+ .sp
  This flag does not have a negative form, because it specifies a
  three-way choice.
! .TP
! .BI \-fcall-used- reg
! Treat the register named
! .I reg
  as an allocatable register that is clobbered by function calls.
! It may be allocated for temporaries or variables that do not live
! across a call.
! Functions compiled this way will not save and restore the register REG.
! .sp
  Use of this flag for a register that has a fixed pervasive role
  in the machine's execution model, such as the stack pointer or
  frame pointer, will produce disastrous results.
+ .sp
  This flag does not have a negative form, because it specifies a
  three-way choice.
! .TP
! .BI \-fcall-saved- reg
! Treat the register named
! .I reg
  as an allocatable register saved by functions.
! It may be allocated even for temporaries or variables that live across a call.
! Functions compiled this way will save and restore the register
! .I reg
! if they use it.
! .sp
  Use of this flag for a register that has a fixed pervasive role
  in the machine's execution model, such as the stack pointer or
  frame pointer, will produce disastrous results.
+ .sp
  A different sort of disaster will result from the use of this
  flag for a register in which function values may be returned.
+ .sp
  This flag does not have a negative form, because it specifies a
  three-way choice.
  .TP
! .BI \-d letters
! Says to make debugging dumps at times specified by
! .IR letters .
  Here are the possible letters:
! .sp
! .B r
! .in +.5i
  Dump after RTL generation.
! .in -.5i
! .B j
! .in +.5i
  Dump after first jump optimization.
! .in -.5i
! .B J
! .in +.5i
  Dump after last jump optimization.
! .in -.5i
! .B s
! .in +.5i
! Dump after CSE (including the jump optimization that sometimes follows CSE).
! .in -.5i
! .B L
! .in +.5i
  Dump after loop optimization.
! .in -.5i
! .B f
! .in +.5i
  Dump after flow analysis.
! .in -.5i
! .B c
! .in +.5i
  Dump after instruction combination.
! .in -.5i
! .B l
! .in +.5i
  Dump after local register allocation.
! .in -.5i
! .B g
! .in +.5i
  Dump after global register allocation.
! .in -.5i
! .B d
! .in +.5i
! Dump after delayed branch scheduling.
! .in -.5i
! .B m
! .in +.5i
  Print statistics on memory usage, at the end of the run.
+ .in -.5i
  .TP
  .B \-pedantic
! Issue all the warnings demanded by strict ANSI standard C; reject
! all programs that use forbidden extensions.
! .sp
! Valid ANSI standard C programs should compile properly with or without
! this option (though a rare few will require
! .BR \-ansi ).
! However, without this option, certain GNU extensions and traditional C
! features are supported as well.
  With this option, they are rejected.
! There is no reason to use this option; it exists only to satisfy pedants.
! .sp
! .B \-pedantic
! does not cause warning messages for use of the alternate keywords whose
! names begin and end with
! .BR __ .
! .TP
! .B \-static
! On Suns running version 4, this prevents linking with the shared
! libraries.
! .RB ( \-g
! has the same effect.)
! .P
! These options control the C preprocessor, which is run on each C source
! file before actual compilation.  If you use the `-E' option, nothing
! is done except C preprocessing.  Some of these options make sense only
! together with `-E' because they request preprocessor output that is
! not suitable for actual compilation.
! .TP
! .B \-C
! Tell the preprocessor not to discard comments.
! Used with the
! .B \-E
! option.
! .TP
! .BI \-I dir
! Search directory
! .I dir
! for include files.
! .TP
! .B \-I-
! Any directories specified with
! .B \-I
! options before the
! .B \-I-
! option are searched only for the case of
! .B #include
! \fB"\fIfile\fB"\fR; they are not searched for
! .BR "#include <\fIfile\fB>" .
! .sp
! If additional directories are specified with
! .B \-I
! options after the
! .BR \-I- ,
! these directories are searched for all
! .B #include
! directives.
! (Ordinarily
! .I all
! .B \-I
! directories are used this way.)
! .sp
! In addition, the
! .B \-I-
! option inhibits the use of the current directory as the first
! search directory for
! .B #include
! \fB"\fIfile\fB"\fR.
! Therefore, the current directory is searched only if it is requested
! explicitly with
! .BR \-I. .
! Specifying both
! .B \-I-
! and
! .B -I.
! allows you to control precisely which directories are searched before
! the current one and which are searched after.
! .TP
! .B \-nostdinc
! Do not search the standard system directories for header files.
! Only the directories you have specified with
! .B \-I
! options (and the current directory, if appropriate) are searched.
! .sp
! Between
! .B \-nostdinc
! and
! .BR \-I- ,
! you can eliminate all directories from the search path
! except those you specify.
! .TP
! .B \-M
! Tell the preprocessor to output a rule suitable for
! .BI make (1)
! describing the dependencies of each source file.
! For each source file, the preprocessor outputs one
! .BR make -rule
! whose target is the object file name for that source file and whose
! dependencies are all the files
! .BR #include d
! in it.
! This rule may be a single line or may be continued with
! .B \\\\-newline
! if it is long.
! .sp
! .B \-M
! implies
! .BR \-E .
! .TP
! .B \-MM
! Like
! .B \-M
! but the output mentions only the user-header files included with
! .B #include
! \fB"\fIfile\fB"\fR.
! System header files included with
! .B "#include <\fIfile\fB>"
! are omitted.
! .sp
! .B \-MM
! implies
! .BR \-E .
! .TP
! .BI \-D macro
! Define macro
! .I macro
! with the empty string as its definition.
! .TP
! .BI \-D macro\fR=\fIdefn
! Define macro
! .I macro
! as
! .IR defn .
! .TP
! .BI \-U macro
! Undefine macro
! .IR macro .
! .TP
! .B \-trigraphs
! Support ANSI C trigraphs.
! You don't want to know about this brain-damage.
! The
! .B \-ansi
! option also has this effect.
  .SH FILES
! .ta \w'LIBDIR/gcc-include 'u
! file.c	C source file
  .br
+ file.s	assembly language file
+ .br
  file.o	object file
  .br
! a.out	link edited output
  .br
! /tmp/cc\(**	temporary files
  .br
! \fILIBDIR\fR/gcc-cpp	preprocessor
! .br
! \fILIBDIR\fR/gcc-cc1	compiler
! .br
! \fILIBDIR\fR/gcc-gnulib	library needed by GCC on some machines
  .br
! /lib/crt[01n].o	start-up routine
  .br
! /lib/libc.a	standard C library, see
  .IR intro (3)
  .br
! /usr/include	standard directory for 
! .B #include
! files
  .br
+ \fILIBDIR\fR/gcc-include	standard gcc directory for
+ .B #include
+ files
+ .sp
+ .I LIBDIR
+ is usually
+ .BR /usr/local/lib .
  .SH "SEE ALSO"
! as(1), ld(1), adb(1), dbx(1), sdb(1).
  .SH BUGS
! Bugs should be reported to
! .BR bug-gcc@prep.ai.mit.edu .
! Bugs tend actually to be fixed if they can be isolated, so it is in your
! interest to report them in such a way that they can be easily reproduced.
  .SH COPYING
  Copyright (c) 1988 Free Software Foundation, Inc.
! .P
  Permission is granted to make and distribute verbatim copies of
  this manual provided the copyright notice and this permission notice
  are preserved on all copies.
! .P
  Permission is granted to copy and distribute modified versions of this
  manual under the conditions for verbatim copying, provided that the
***************
*** 708,712 ****
  entire resulting derived work is distributed under the terms of a
  permission notice identical to this one.
! .br
  Permission is granted to copy and distribute translations of this
  manual into another language, under the above conditions for modified
--- 1312,1316 ----
  entire resulting derived work is distributed under the terms of a
  permission notice identical to this one.
! .P
  Permission is granted to copy and distribute translations of this
  manual into another language, under the above conditions for modified
***************
*** 716,718 ****
  .SH AUTHORS
  See the GNU CC Manual for the contributors to GNU CC.
- 
--- 1320,1321 ----
diff -rc2N gcc-1.35/gcc.c gcc-1.36/gcc.c
*** gcc-1.35/gcc.c	Fri Apr 21 23:50:14 1989
--- gcc-1.36/gcc.c	Sun Sep 17 16:51:58 1989
***************
*** 21,25 ****
  The number of chars here seems crucial!!!!  */
  
! 
  /* This program is the user interface to the C compiler and possibly to
  other compilers.  It is used because compilation is a complicated procedure
--- 21,26 ----
  The number of chars here seems crucial!!!!  */
  
! void record_temp_file ();
! \f


  /* This program is the user interface to the C compiler and possibly to
  other compilers.  It is used because compilation is a complicated procedure
***************
*** 117,132 ****
  */
  
- /* This defines which switch letters take arguments.  */
- 
- #define SWITCH_TAKES_ARG(CHAR)      \
-   ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \
-    || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \
-    || (CHAR) == 'I' || (CHAR) == 'Y' || (CHAR) == 'm' \
-    || (CHAR) == 'L')
- 
- /* This defines which multi-letter switches take arguments.  */
- 
- #define WORD_SWITCH_TAKES_ARG(STR) (!strcmp (STR, "Tdata"))
- 
  #include <stdio.h>
  #include <sys/types.h>
--- 118,121 ----
***************
*** 133,140 ****
  #include <signal.h>
  #include <sys/file.h>
- #include <varargs.h>
  
  #include "config.h"
  #include "obstack.h"
  
  #ifdef USG
--- 122,129 ----
  #include <signal.h>
  #include <sys/file.h>
  
  #include "config.h"
  #include "obstack.h"
+ #include "gvarargs.h"
  
  #ifdef USG
***************
*** 168,171 ****
--- 157,161 ----
  void validate_switches ();
  void validate_all_switches ();
+ void fancy_abort ();
  
  /* config.h can define ASM_SPEC to provide extra args to the assembler
***************
*** 209,212 ****
--- 199,218 ----
     : "%{!fsigned-char:-D__CHAR_UNSIGNED__}")
  
+ /* This defines which switch letters take arguments.  */
+ 
+ #ifndef SWITCH_TAKES_ARG
+ #define SWITCH_TAKES_ARG(CHAR)      \
+   ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \
+    || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \
+    || (CHAR) == 'I' || (CHAR) == 'Y' || (CHAR) == 'm' \
+    || (CHAR) == 'L' || (CHAR) == 'i' || (CHAR) == 'A')
+ #endif
+ 
+ /* This defines which multi-letter switches take arguments.  */
+ 
+ #ifndef WORD_SWITCH_TAKES_ARG
+ #define WORD_SWITCH_TAKES_ARG(STR) (!strcmp (STR, "Tdata"))
+ #endif
+ 
  /* This structure says how to run one compiler, and when to do so.  */
  
***************
*** 226,230 ****
  {
    {".c",
!    "cpp %{nostdinc} %{C} %{v} %{D*} %{U*} %{I*} %{M*} %{trigraphs} -undef \
          -D__GNUC__ %{ansi:-trigraphs -$ -D__STRICT_ANSI__} %{!ansi:%p} %P\
          %c %{O:-D__OPTIMIZE__} %{traditional} %{pedantic}\
--- 232,236 ----
  {
    {".c",
!    "cpp %{nostdinc} %{C} %{v} %{D*} %{U*} %{I*} %{M*} %{i*} %{trigraphs} -undef \
          -D__GNUC__ %{ansi:-trigraphs -$ -D__STRICT_ANSI__} %{!ansi:%p} %P\
          %c %{O:-D__OPTIMIZE__} %{traditional} %{pedantic}\
***************
*** 241,245 ****
                        %{!pipe:%g.s}\n }}}"},
    {".cc",
!    "cpp -+ %{nostdinc} %{C} %{v} %{D*} %{U*} %{I*} %{M*} \
          -undef -D__GNUC__ %p %P\
          %c %{O:-D__OPTIMIZE__} %{traditional} %{pedantic}\
--- 247,251 ----
                        %{!pipe:%g.s}\n }}}"},
    {".cc",
!    "cpp -+ %{nostdinc} %{C} %{v} %{D*} %{U*} %{I*} %{M*} %{i*} \
          -undef -D__GNUC__ %p %P\
          %c %{O:-D__OPTIMIZE__} %{traditional} %{pedantic}\
***************
*** 270,274 ****
          %c %{O:-D__OPTIMIZE__} %{traditional} %{pedantic}\
  	%{Wcomment*} %{Wtrigraphs} %{Wall} %C\
!         %i %{!M*:%{!E:%{!pipe:%g.cpp}}}%{E:%{o*}}%{M*:%{o*}} |\n\
      %{!M*:%{!E:%{!S:as %{R} %{j} %{J} %{h} %{d2} %a \
                      %{c:%{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%b.o}\
--- 276,280 ----
          %c %{O:-D__OPTIMIZE__} %{traditional} %{pedantic}\
  	%{Wcomment*} %{Wtrigraphs} %{Wall} %C\
!         %i %{!M*:%{!E:%{!pipe:%g.s}}}%{E:%{o*}}%{M*:%{o*}} |\n\
      %{!M*:%{!E:%{!S:as %{R} %{j} %{J} %{h} %{d2} %a \
                      %{c:%{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%b.o}\
***************
*** 281,287 ****
  char *link_spec = "%{!c:%{!M*:%{!E:%{!S:ld %{o*} %l\
   %{A} %{d} %{e*} %{N} %{n} %{r} %{s} %{S} %{T*} %{t} %{u*} %{X} %{x} %{z}\
!  %{y*} %{!nostdlib:%S} \
   %{L*} %o %{!nostdlib:gnulib%s %{g:-lg} %L}\n }}}}";
  \f


  /* Record the names of temporary files we tell compilers to write,
     and delete them at the end of the run.  */
--- 287,382 ----
  char *link_spec = "%{!c:%{!M*:%{!E:%{!S:ld %{o*} %l\
   %{A} %{d} %{e*} %{N} %{n} %{r} %{s} %{S} %{T*} %{t} %{u*} %{X} %{x} %{z}\
!  %{y*} %{!A:%{!nostdlib:%S}} \
   %{L*} %o %{!nostdlib:gnulib%s %{g:-lg} %L}\n }}}}";
  \f


+ /* Accumulate a command (program name and args), and run it.  */
+ 
+ /* Vector of pointers to arguments in the current line of specifications.  */
+ 
+ char **argbuf;
+ 
+ /* Number of elements allocated in argbuf.  */
+ 
+ int argbuf_length;
+ 
+ /* Number of elements in argbuf currently in use (containing args).  */
+ 
+ int argbuf_index;
+ 
+ /* Number of commands executed so far.  */
+ 
+ int execution_count;
+ 
+ /* Flag indicating whether we should print the command and arguments */
+ 
+ unsigned char vflag;
+ 
+ /* Name with which this program was invoked.  */
+ 
+ char *programname;
+ 
+ /* User-specified -B prefix to attach to command names,
+    or 0 if none specified.  */
+ 
+ char *user_exec_prefix = 0;
+ 
+ /* Environment-specified prefix to attach to command names,
+    or 0 if none specified.  */
+ 
+ char *env_exec_prefix = 0;
+ 
+ /* Suffix to attach to directories searched for commands.  */
+ 
+ char *machine_suffix = 0;
+ 
+ /* Default prefixes to attach to command names.  */
+ 
+ #ifndef STANDARD_EXEC_PREFIX
+ #define STANDARD_EXEC_PREFIX "/usr/local/lib/gcc-"
+ #endif /* !defined STANDARD_EXEC_PREFIX */
+ 
+ char *standard_exec_prefix = STANDARD_EXEC_PREFIX;
+ char *standard_exec_prefix_1 = "/usr/lib/gcc-";
+ 
+ #ifndef STANDARD_STARTFILE_PREFIX
+ #define STANDARD_STARTFILE_PREFIX "/usr/local/lib/"
+ #endif /* !defined STANDARD_STARTFILE_PREFIX */
+ 
+ char *standard_startfile_prefix = STANDARD_STARTFILE_PREFIX;
+ char *standard_startfile_prefix_1 = "/lib/";
+ char *standard_startfile_prefix_2 = "/usr/lib/";
+ 
+ /* Clear out the vector of arguments (after a command is executed).  */
+ 
+ void
+ clear_args ()
+ {
+   argbuf_index = 0;
+ }
+ 
+ /* Add one argument to the vector at the end.
+    This is done when a space is seen or at the end of the line.
+    If DELETE_ALWAYS is nonzero, the arg is a filename
+     and the file should be deleted eventually.
+    If DELETE_FAILURE is nonzero, the arg is a filename
+     and the file should be deleted if this compilation fails.  */
+ 
+ void
+ store_arg (arg, delete_always, delete_failure)
+      char *arg;
+      int delete_always, delete_failure;
+ {
+   if (argbuf_index + 1 == argbuf_length)
+     {
+       argbuf = (char **) realloc (argbuf, (argbuf_length *= 2) * sizeof (char *));
+     }
+ 
+   argbuf[argbuf_index++] = arg;
+   argbuf[argbuf_index] = 0;
+ 
+   if (delete_always || delete_failure)
+     record_temp_file (arg, delete_always, delete_failure);
+ }
+ \f


  /* Record the names of temporary files we tell compilers to write,
     and delete them at the end of the run.  */
***************
*** 292,297 ****
     Thus, all temp file names contain this prefix.
     In practice, all temp file names start with this prefix.
-    The prefix starts with `/tmp'.  */
  
  char *temp_filename;
  
--- 387,395 ----
     Thus, all temp file names contain this prefix.
     In practice, all temp file names start with this prefix.
  
+    This prefix comes from the envvar TMPDIR if it is defined;
+    otherwise, from the P_tmpdir macro if that is defined;
+    otherwise, in /usr/tmp or /tmp.  */
+ 
  char *temp_filename;
  
***************
*** 332,335 ****
--- 430,436 ----
      {
        register struct temp_file *temp;
+       for (temp = always_delete_queue; temp; temp = temp->next)
+ 	if (! strcmp (name, temp->name))
+ 	  goto already1;
        temp = (struct temp_file *) xmalloc (sizeof (struct temp_file));
        temp->next = always_delete_queue;
***************
*** 336,339 ****
--- 437,441 ----
        temp->name = name;
        always_delete_queue = temp;
+     already1:;
      }
  
***************
*** 341,344 ****
--- 443,449 ----
      {
        register struct temp_file *temp;
+       for (temp = failure_delete_queue; temp; temp = temp->next)
+ 	if (! strcmp (name, temp->name))
+ 	  goto already2;
        temp = (struct temp_file *) xmalloc (sizeof (struct temp_file));
        temp->next = failure_delete_queue;
***************
*** 345,357 ****
        temp->name = name;
        failure_delete_queue = temp;
      }
  }
  
! /* Delete all the temporary files whose names we previously recorded.
!    SUCCESS zero means "delete on failure only" files should be deleted.  */
  
  void
! delete_temp_files (success)
!      int success;
  {
    register struct temp_file *temp;
--- 450,461 ----
        temp->name = name;
        failure_delete_queue = temp;
+     already2:;
      }
  }
  
! /* Delete all the temporary files whose names we previously recorded.  */
  
  void
! delete_temp_files ()
  {
    register struct temp_file *temp;
***************
*** 368,391 ****
        if (i == 'y' || i == 'Y')
  #endif /* DEBUG */
! 	unlink (temp->name);
      }
  
!   if (! success)
!     for (temp = failure_delete_queue; temp; temp = temp->next)
!       {
  #ifdef DEBUG
! 	int i;
! 	printf ("Delete %s? (y or n) ", temp->name);
! 	fflush (stdout);
! 	i = getchar ();
! 	if (i != '\n')
! 	  while (getchar () != '\n') ;
! 	if (i == 'y' || i == 'Y')
  #endif /* DEBUG */
! 	  unlink (temp->name);
!       }
! 
!   always_delete_queue = 0;
!   failure_delete_queue = 0;
  }
  
--- 472,509 ----
        if (i == 'y' || i == 'Y')
  #endif /* DEBUG */
! 	{
! 	  if (unlink (temp->name) < 0)
! 	    if (vflag)
! 	      perror_with_name (temp->name);
! 	}
      }
  
!   always_delete_queue = 0;
! }
! 
! /* Delete all the files to be deleted on error.  */
! 
! void
! delete_failure_queue ()
! {
!   register struct temp_file *temp;
! 
!   for (temp = failure_delete_queue; temp; temp = temp->next)
!     {
  #ifdef DEBUG
!       int i;
!       printf ("Delete %s? (y or n) ", temp->name);
!       fflush (stdout);
!       i = getchar ();
!       if (i != '\n')
! 	while (getchar () != '\n') ;
!       if (i == 'y' || i == 'Y')
  #endif /* DEBUG */
! 	{
! 	  if (unlink (temp->name) < 0)
! 	    if (vflag)
! 	      perror_with_name (temp->name);
! 	}
!     }
  }
  
***************
*** 402,491 ****
  choose_temp_base ()
  {
!   register char *foo = "/tmp/ccXXXXXX";
!   temp_filename = (char *) xmalloc (strlen (foo) + 1);
!   strcpy (temp_filename, foo);
!   mktemp (temp_filename);
!   temp_filename_length = strlen (temp_filename);
! }
! \f


! /* Accumulate a command (program name and args), and run it.  */
! 
! /* Vector of pointers to arguments in the current line of specifications.  */
! 
! char **argbuf;
! 
! /* Number of elements allocated in argbuf.  */
! 
! int argbuf_length;
! 
! /* Number of elements in argbuf currently in use (containing args).  */
! 
! int argbuf_index;
! 
! /* Flag indicating whether we should print the command and arguments */
! 
! unsigned char vflag;
! 
! /* Name with which this program was invoked.  */
! 
! char *programname;
! 
! /* User-specified -B prefix to attach to command names,
!    or 0 if none specified.  */
! 
! char *user_exec_prefix = 0;
! 
! /* Environment-specified prefix to attach to command names,
!    or 0 if none specified.  */
! 
! char *env_exec_prefix = 0;
! 
! /* Default prefixes to attach to command names.  */
! 
! #ifndef STANDARD_EXEC_PREFIX
! #define STANDARD_EXEC_PREFIX "/usr/local/lib/gcc-"
! #endif /* !defined STANDARD_EXEC_PREFIX */
! 
! char *standard_exec_prefix = STANDARD_EXEC_PREFIX;
! char *standard_exec_prefix_1 = "/usr/lib/gcc-";
! 
! #ifndef STANDARD_STARTFILE_PREFIX
! #define STANDARD_STARTFILE_PREFIX "/usr/local/lib/"
! #endif /* !defined STANDARD_STARTFILE_PREFIX */
! 
! char *standard_startfile_prefix = STANDARD_STARTFILE_PREFIX;
! char *standard_startfile_prefix_1 = "/lib/";
! char *standard_startfile_prefix_2 = "/usr/lib/";
! 
! /* Clear out the vector of arguments (after a command is executed).  */
! 
! void
! clear_args ()
! {
!   argbuf_index = 0;
! }
! 
! /* Add one argument to the vector at the end.
!    This is done when a space is seen or at the end of the line.
!    If DELETE_ALWAYS is nonzero, the arg is a filename
!     and the file should be deleted eventually.
!    If DELETE_FAILURE is nonzero, the arg is a filename
!     and the file should be deleted if this compilation fails.  */
  
! void
! store_arg (arg, delete_always, delete_failure)
!      char *arg;
!      int delete_always, delete_failure;
! {
!   if (argbuf_index + 1 == argbuf_length)
      {
!       argbuf = (char **) realloc (argbuf, (argbuf_length *= 2) * sizeof (char *));
      }
  
!   argbuf[argbuf_index++] = arg;
!   argbuf[argbuf_index] = 0;
  
!   if (delete_always || delete_failure)
!     record_temp_file (arg, delete_always, delete_failure);
  }
  \f


--- 520,551 ----
  choose_temp_base ()
  {
!   extern char *getenv ();
!   char *base = getenv ("TMPDIR");
!   int len;
  
!   if (base == (char *)0)
      {
! #ifdef P_tmpdir
!       if (access (P_tmpdir, R_OK | W_OK) == 0)
! 	base = P_tmpdir;
! #endif
!       if (base == (char *)0)
! 	{
! 	  if (access ("/usr/tmp", R_OK | W_OK) == 0)
! 	    base = "/usr/tmp/";
! 	  else
! 	    base = "/tmp/";
! 	}
      }
  
!   len = strlen (base);
!   temp_filename = (char *) xmalloc (len + sizeof("/ccXXXXXX"));
!   strcpy (temp_filename, base);
!   if (len > 0 && temp_filename[len-1] != '/')
!     temp_filename[len++] = '/';
!   strcpy (temp_filename + len, "ccXXXXXX");
  
!   mktemp (temp_filename);
!   temp_filename_length = strlen (temp_filename);
  }
  \f


***************
*** 509,512 ****
--- 569,574 ----
      size = strlen (standard_exec_prefix_1);
    size += strlen (prog) + 1;
+   if (machine_suffix)
+     size += strlen (machine_suffix) + 1;
    temp = (char *) xmalloc (size);
  
***************
*** 515,521 ****
    if (user_exec_prefix)
      {
!       strcpy (temp, user_exec_prefix);
!       strcat (temp, prog);
!       win = (access (temp, X_OK) == 0);
      }
  
--- 577,593 ----
    if (user_exec_prefix)
      {
!       if (machine_suffix)
! 	{
! 	  strcpy (temp, user_exec_prefix);
! 	  strcat (temp, machine_suffix);
! 	  strcat (temp, prog);
! 	  win = (access (temp, X_OK) == 0);
! 	}
!       if (!win)
! 	{
! 	  strcpy (temp, user_exec_prefix);
! 	  strcat (temp, prog);
! 	  win = (access (temp, X_OK) == 0);
! 	}
      }
  
***************
*** 522,542 ****
    if (!win && env_exec_prefix)
      {
!       strcpy (temp, env_exec_prefix);
!       strcat (temp, prog);
!       win = (access (temp, X_OK) == 0);
!     }
! 
!   if (!win)
!     {
!       strcpy (temp, standard_exec_prefix);
!       strcat (temp, prog);
!       win = (access (temp, X_OK) == 0);
!     }
! 
!   if (!win)
!     {
!       strcpy (temp, standard_exec_prefix_1);
!       strcat (temp, argbuf[0]);
!       win = (access (temp, X_OK) == 0);
      }
  
--- 594,644 ----
    if (!win && env_exec_prefix)
      {
!       if (machine_suffix)
! 	{
! 	  strcpy (temp, env_exec_prefix);
! 	  strcat (temp, machine_suffix);
! 	  strcat (temp, prog);
! 	  win = (access (temp, X_OK) == 0);
! 	}
!       if (!win)
! 	{
! 	  strcpy (temp, env_exec_prefix);
! 	  strcat (temp, prog);
! 	  win = (access (temp, X_OK) == 0);
! 	}
!     }
! 
!   if (!win)
!     {
!       if (machine_suffix)
! 	{
! 	  strcpy (temp, standard_exec_prefix);
! 	  strcat (temp, machine_suffix);
! 	  strcat (temp, prog);
! 	  win = (access (temp, X_OK) == 0);
! 	}
!       if (!win)
! 	{
! 	  strcpy (temp, standard_exec_prefix);
! 	  strcat (temp, prog);
! 	  win = (access (temp, X_OK) == 0);
! 	}
!     }
! 
!   if (!win)
!     {
!       if (machine_suffix)
! 	{
! 	  strcpy (temp, standard_exec_prefix_1);
! 	  strcat (temp, machine_suffix);
! 	  strcat (temp, prog);
! 	  win = (access (temp, X_OK) == 0);
! 	}
!       if (!win)
! 	{
! 	  strcpy (temp, standard_exec_prefix_1);
! 	  strcat (temp, prog);
! 	  win = (access (temp, X_OK) == 0);
! 	}
      }
  
***************
*** 740,743 ****
--- 842,847 ----
      }
  
+   execution_count++;
+ 
    /* Wait for all the subprocesses to finish.
       We don't care what order they finish in;
***************
*** 831,834 ****
--- 935,942 ----
  	  switch (c)
  	    {
+ 	    case 'b':
+ 	      machine_suffix = p + 1;
+ 	      break;
+ 
  	    case 'B':
  	      user_exec_prefix = p + 1;
***************
*** 872,876 ****
  	  register int c = *p;
  
! 	  if (c == 'B')
  	    continue;
  	  switches[n_switches].part1 = p;
--- 980,984 ----
  	  register int c = *p;
  
! 	  if (c == 'B' || c == 'b')
  	    continue;
  	  switches[n_switches].part1 = p;
***************
*** 1178,1183 ****
  		      *x++ = '-';
  		      *x++ = 'D';
- 		      *x++ = '_';
  		      *x++ = '_';
  		      y += 2;
  		    }
--- 1286,1291 ----
  		      *x++ = '-';
  		      *x++ = 'D';
  		      *x++ = '_';
+ 		      *x++ = '_';
  		      y += 2;
  		    }
***************
*** 1322,1326 ****
  	  /* Here if a %{|...} conditional fails: output a minus sign,
  	     which means "standard output" or "standard input".  */
! 	  do_spec_1 ("-");
  	}
      }
--- 1430,1434 ----
  	  /* Here if a %{|...} conditional fails: output a minus sign,
  	     which means "standard output" or "standard input".  */
! 	  do_spec_1 ("-", 0);
  	}
      }
***************
*** 1378,1381 ****
--- 1486,1491 ----
    if (strlen (standard_startfile_prefix_2) > size)
      size = strlen (standard_startfile_prefix_2);
+   if (machine_suffix)
+     size += strlen (machine_suffix) + 1;
    size += strlen (name) + 1;
  
***************
*** 1384,1390 ****
    if (user_exec_prefix)
      {
!       strcpy (temp, user_exec_prefix);
!       strcat (temp, name);
!       win = (access (temp, R_OK) == 0);
      }
  
--- 1494,1510 ----
    if (user_exec_prefix)
      {
!       if (machine_suffix)
! 	{
! 	  strcpy (temp, user_exec_prefix);
! 	  strcat (temp, machine_suffix);
! 	  strcat (temp, name);
! 	  win = (access (temp, R_OK) == 0);
! 	}
!       if (!win)
! 	{
! 	  strcpy (temp, user_exec_prefix);
! 	  strcat (temp, name);
! 	  win = (access (temp, R_OK) == 0);
! 	}
      }
  
***************
*** 1391,1439 ****
    if (!win && env_exec_prefix)
      {
!       strcpy (temp, env_exec_prefix);
!       strcat (temp, name);
!       win = (access (temp, R_OK) == 0);
!     }
! 
!   if (!win)
!     {
!       strcpy (temp, standard_exec_prefix);
!       strcat (temp, name);
!       win = (access (temp, R_OK) == 0);
!     }
! 
!   if (!win)
!     {
!       strcpy (temp, standard_exec_prefix_1);
!       strcat (temp, name);
!       win = (access (temp, R_OK) == 0);
!     }
! 
!   if (!win)
!     {
!       strcpy (temp, standard_startfile_prefix);
!       strcat (temp, name);
!       win = (access (temp, R_OK) == 0);
!     }
! 
!   if (!win)
!     {
!       strcpy (temp, standard_startfile_prefix_1);
!       strcat (temp, name);
!       win = (access (temp, R_OK) == 0);
!     }
! 
!   if (!win)
!     {
!       strcpy (temp, standard_startfile_prefix_2);
!       strcat (temp, name);
!       win = (access (temp, R_OK) == 0);
!     }
! 
!   if (!win)
!     {
!       strcpy (temp, "./");
!       strcat (temp, name);
!       win = (access (temp, R_OK) == 0);
      }
  
--- 1511,1629 ----
    if (!win && env_exec_prefix)
      {
!       if (machine_suffix)
! 	{
! 	  strcpy (temp, env_exec_prefix);
! 	  strcat (temp, machine_suffix);
! 	  strcat (temp, name);
! 	  win = (access (temp, R_OK) == 0);
! 	}
!       if (!win)
! 	{
! 	  strcpy (temp, env_exec_prefix);
! 	  strcat (temp, name);
! 	  win = (access (temp, R_OK) == 0);
! 	}
!     }
! 
!   if (!win)
!     {
!       if (machine_suffix)
! 	{
! 	  strcpy (temp, standard_exec_prefix);
! 	  strcat (temp, machine_suffix);
! 	  strcat (temp, name);
! 	  win = (access (temp, R_OK) == 0);
! 	}
!       if (!win)
! 	{
! 	  strcpy (temp, standard_exec_prefix);
! 	  strcat (temp, name);
! 	  win = (access (temp, R_OK) == 0);
! 	}
!     }
! 
!   if (!win)
!     {
!       if (machine_suffix)
! 	{
! 	  strcpy (temp, standard_exec_prefix_1);
! 	  strcat (temp, machine_suffix);
! 	  strcat (temp, name);
! 	  win = (access (temp, R_OK) == 0);
! 	}
!       if (!win)
! 	{
! 	  strcpy (temp, standard_exec_prefix_1);
! 	  strcat (temp, name);
! 	  win = (access (temp, R_OK) == 0);
! 	}
!     }
! 
!   if (!win)
!     {
!       if (machine_suffix)
! 	{
! 	  strcpy (temp, standard_startfile_prefix);
! 	  strcat (temp, machine_suffix);
! 	  strcat (temp, name);
! 	  win = (access (temp, R_OK) == 0);
! 	}
!       if (!win)
! 	{
! 	  strcpy (temp, standard_startfile_prefix);
! 	  strcat (temp, name);
! 	  win = (access (temp, R_OK) == 0);
! 	}
!     }
! 
!   if (!win)
!     {
!       if (machine_suffix)
! 	{
! 	  strcpy (temp, standard_startfile_prefix_1);
! 	  strcat (temp, machine_suffix);
! 	  strcat (temp, name);
! 	  win = (access (temp, R_OK) == 0);
! 	}
!       if (!win)
! 	{
! 	  strcpy (temp, standard_startfile_prefix_1);
! 	  strcat (temp, name);
! 	  win = (access (temp, R_OK) == 0);
! 	}
!     }
! 
!   if (!win)
!     {
!       if (machine_suffix)
! 	{
! 	  strcpy (temp, standard_startfile_prefix_2);
! 	  strcat (temp, machine_suffix);
! 	  strcat (temp, name);
! 	  win = (access (temp, R_OK) == 0);
! 	}
!       if (!win)
! 	{
! 	  strcpy (temp, standard_startfile_prefix_2);
! 	  strcat (temp, name);
! 	  win = (access (temp, R_OK) == 0);
! 	}
!     }
! 
!   if (!win)
!     {
!       if (machine_suffix)
! 	{
! 	  strcpy (temp, "./");
! 	  strcat (temp, machine_suffix);
! 	  strcat (temp, name);
! 	  win = (access (temp, R_OK) == 0);
! 	}
!       if (!win)
! 	{
! 	  strcpy (temp, "./");
! 	  strcat (temp, name);
! 	  win = (access (temp, R_OK) == 0);
! 	}
      }
  
***************
*** 1450,1454 ****
  {
    signal (signum, SIG_DFL);
!   delete_temp_files (0);
    /* Get the same signal again, this time not handled,
       so its normal effect occurs.  */
--- 1640,1645 ----
  {
    signal (signum, SIG_DFL);
!   delete_failure_queue ();
!   delete_temp_files ();
    /* Get the same signal again, this time not handled,
       so its normal effect occurs.  */
***************
*** 1463,1468 ****
    register int i;
    int value;
-   int nolink = 0;
    int error_count = 0;
  
    programname = argv[0];
--- 1654,1660 ----
    register int i;
    int value;
    int error_count = 0;
+   int linker_was_run = 0;
+   char *explicit_link_files;
  
    programname = argv[0];
***************
*** 1504,1510 ****
--- 1696,1708 ----
    bzero (outfiles, n_infiles * sizeof (char *));
  
+   /* Record which files were specified explicitly as link input.  */
+ 
+   explicit_link_files = (char *) xmalloc (n_infiles);
+   bzero (explicit_link_files, n_infiles);
+ 
    for (i = 0; i < n_infiles; i++)
      {
        register struct compiler *cp;
+       int this_file_error = 0;
  
        /* Tell do_spec what to substitute for %i.  */
***************
*** 1539,1543 ****
  	      value = do_spec (cp->spec);
  	      if (value < 0)
! 		error_count = 1;
  	      break;
  	    }
--- 1737,1741 ----
  	      value = do_spec (cp->spec);
  	      if (value < 0)
! 		this_file_error = 1;
  	      break;
  	    }
***************
*** 1545,1561 ****
  
        /* If this file's name does not contain a recognized suffix,
! 	 don't do anything to it, but do feed it to the link spec
! 	 since its name is in outfiles.  */
  
!       if (! cp->spec && nolink)
  	{
! 	  /* But if this happens, and we aren't going to run the linker,
! 	     warn the user.  */
! 	  error ("%s: linker input file unused since linking not done",
! 		 input_filename);
  	}
! 
!       /* Failure of one compilation should not delete the delete-on-failure
! 	 files of previous compilations.  */
        clear_failure_queue ();
      }
--- 1743,1760 ----
  
        /* If this file's name does not contain a recognized suffix,
! 	 record it as explicit linker input.  */
  
!       if (! cp->spec)
! 	explicit_link_files[i] = 1;
! 
!       /* Clear the delete-on-failure queue, deleting the files in it
! 	 if this compilation failed.  */
! 
!       if (this_file_error)
  	{
! 	  delete_failure_queue ();
! 	  error_count++;
  	}
!       /* If this compilation succeeded, don't delete those files later.  */
        clear_failure_queue ();
      }
***************
*** 1563,1573 ****
    /* Run ld to link all the compiler output files.  */
  
!   if (! nolink && error_count == 0)
      {
        value = do_spec (link_spec);
        if (value < 0)
  	error_count = 1;
      }
  
    /* Set the `valid' bits for switches that match anything in any spec.  */
  
--- 1762,1783 ----
    /* Run ld to link all the compiler output files.  */
  
!   if (error_count == 0)
      {
+       int tmp = execution_count;
        value = do_spec (link_spec);
        if (value < 0)
  	error_count = 1;
+       linker_was_run = (tmp != execution_count);
      }
  
+   /* If options said don't run linker,
+      complain about input files to be given to the linker.  */
+ 
+   if (! linker_was_run && error_count == 0)
+     for (i = 0; i < n_infiles; i++)
+       if (explicit_link_files[i])
+ 	error ("%s: linker input file unused since linking not done",
+ 	       outfiles[i]);
+ 
    /* Set the `valid' bits for switches that match anything in any spec.  */
  
***************
*** 1582,1586 ****
    /* Delete some or all of the temporary files we made.  */
  
!   delete_temp_files (error_count == 0);
  
    exit (error_count);
--- 1792,1798 ----
    /* Delete some or all of the temporary files we made.  */
  
!   if (error_count)
!     delete_failure_queue ();
!   delete_temp_files ();
  
    exit (error_count);
***************
*** 1676,1679 ****
--- 1888,1900 ----
    error (s, name);
  }
+ 
+ /* More 'friendly' abort that prints the line and file.
+    config.h can #define abort fancy_abort if you like that sort of thing.  */
+ 
+ void
+ fancy_abort ()
+ {
+   fatal ("Internal gcc abort.");
+ }
  \f


  #ifdef HAVE_VPRINTF
***************
*** 1754,1757 ****
--- 1975,2036 ----
        /* We have a switch spec.  */
        validate_switches (p + 1);
+ 
+   /* Now notice switches mentioned in the machine-specific specs.  */
+ 
+ #ifdef ASM_SPEC
+   p = ASM_SPEC;
+   while (c = *p++)
+     if (c == '%' && *p == '{')
+       /* We have a switch spec.  */
+       validate_switches (p + 1);
+ #endif
+ 
+ #ifdef CPP_SPEC
+   p = CPP_SPEC;
+   while (c = *p++)
+     if (c == '%' && *p == '{')
+       /* We have a switch spec.  */
+       validate_switches (p + 1);
+ #endif
+ 
+ #ifdef SIGNED_CHAR_SPEC
+   p = SIGNED_CHAR_SPEC;
+   while (c = *p++)
+     if (c == '%' && *p == '{')
+       /* We have a switch spec.  */
+       validate_switches (p + 1);
+ #endif
+ 
+ #ifdef CC1_SPEC
+   p = CC1_SPEC;
+   while (c = *p++)
+     if (c == '%' && *p == '{')
+       /* We have a switch spec.  */
+       validate_switches (p + 1);
+ #endif
+ 
+ #ifdef LINK_SPEC
+   p = LINK_SPEC;
+   while (c = *p++)
+     if (c == '%' && *p == '{')
+       /* We have a switch spec.  */
+       validate_switches (p + 1);
+ #endif
+ 
+ #ifdef LIB_SPEC
+   p = LIB_SPEC;
+   while (c = *p++)
+     if (c == '%' && *p == '{')
+       /* We have a switch spec.  */
+       validate_switches (p + 1);
+ #endif
+ 
+ #ifdef STARTFILE_SPEC
+   p = STARTFILE_SPEC;
+   while (c = *p++)
+     if (c == '%' && *p == '{')
+       /* We have a switch spec.  */
+       validate_switches (p + 1);
+ #endif
  }
diff -rc2N gcc-1.35/gcc.texinfo gcc-1.36/gcc.texinfo
*** gcc-1.35/gcc.texinfo	Mon Apr 24 02:27:30 1989
--- gcc-1.36/gcc.texinfo	Sun Sep 24 01:05:54 1989
***************
*** 40,46 ****
  @center Richard M. Stallman
  @sp 3
! @center last updated 22 April 1989
  @sp 1
! @center for version 1.35
  @page
  @vskip 0pt plus 1filll
--- 40,46 ----
  @center Richard M. Stallman
  @sp 3
! @center last updated 12 September 1989
  @sp 1
! @center for version 1.36
  @page
  @vskip 0pt plus 1filll
***************
*** 89,92 ****
--- 89,93 ----
  * Machine Desc::    How to write machine description instruction patterns.
  * Machine Macros::  How to write the machine description C macros.
+ * Config::          Writing the @file{xm-@var{machine}.h} file.
  @end menu
  
***************
*** 419,423 ****
  @item
  Nobuyuki Hikichi of Software Research Associates, Tokyo, contributed
! the support for the SONY NEWS machine.
  
  @item
--- 420,424 ----
  @item
  Nobuyuki Hikichi of Software Research Associates, Tokyo, contributed
! the support for the Sony NEWS machine.
  
  @item
***************
*** 461,465 ****
  
  @item
! Alain Lichnewsky ported GNU CC to the MIPS cpu.
  @end itemize
  
--- 462,473 ----
  
  @item
! Alain Lichnewsky ported GNU CC to the Mips cpu.
! 
! @item
! Devon Bowen, Dale Wiles and Kevin Zachmann ported GNU CC to the Tahoe.
! 
! @item
! Jonathan Stone wrote the machine description for the Pyramid computer.
! Note that this machine description does not fully work.
  @end itemize
  
***************
*** 470,474 ****
  The @code{gcc} program accepts options and file names as operands.
  Multiple single-letter options may @emph{not} be grouped: @samp{-dr} is
! very different from @samp{-d -r}.
  
  When you invoke GNU CC, it normally does preprocessing, compilation,
--- 478,482 ----
  The @code{gcc} program accepts options and file names as operands.
  Multiple single-letter options may @emph{not} be grouped: @samp{-dr} is
! very different from @w{@samp{-d -r}}.
  
  When you invoke GNU CC, it normally does preprocessing, compilation,
***************
*** 554,557 ****
--- 562,586 ----
  @code{GCC_EXEC_PREFIX} variable are present, the @samp{-B} option is
  used first and the environment variable value second.
+ 
+ @item -b@var{prefix}
+ The argument @var{prefix} is used as a second prefix for the compiler
+ executables and libraries.  This prefix is optional: the compiler tries
+ each file first with it, then without it.  This prefix follows the
+ prefix specified with @samp{-B} or the default prefixes.
+ 
+ Thus, @samp{-bvax- -Bcc/} in the presence of environment variable
+ @code{GCC_EXEC_PREFIX} with definition @file{/u/foo/} causes GNU CC to
+ try the following file names for the preprocessor executable:
+ 
+ @example
+ cc/vax-cpp
+ cc/cpp
+ /u/foo/vax-cpp
+ /u/foo/cpp
+ /usr/local/lib/gcc-vax-cpp
+ /usr/local/lib/gcc-cpp
+ /usr/lib/gcc-vax-cpp
+ /usr/lib/gcc-cpp
+ @end example
  @end table
  
***************
*** 568,577 ****
  undesirable and rarely used ANSI trigraph feature.
  
! The alternate keywords @code{__asm}, @code{__inline} and
! @code{__typeof} continue to work despite @samp{-ansi}.  You would not
  want to use them in an ANSI C program, of course, but it useful to put
  them in header files that might be included in compilations done with
! @samp{-ansi}.  Alternate predefined macros such as @code{__unix} and
! @code{__vax} are also available, with or without @samp{-ansi}.
  
  The @samp{-ansi} option does not cause non-ANSI programs to be
--- 597,606 ----
  undesirable and rarely used ANSI trigraph feature.
  
! The alternate keywords @code{__asm__}, @code{__inline__} and
! @code{__typeof__} continue to work despite @samp{-ansi}.  You would not
  want to use them in an ANSI C program, of course, but it useful to put
  them in header files that might be included in compilations done with
! @samp{-ansi}.  Alternate predefined macros such as @code{__unix__} and
! @code{__vax__} are also available, with or without @samp{-ansi}.
  
  The @samp{-ansi} option does not cause non-ANSI programs to be
***************
*** 610,613 ****
--- 639,647 ----
  
  @item
+ String ``constants'' are not necessarily constant; they are stored in
+ writable space, and identical looking constants are allocated
+ separately.
+ 
+ @item
  All automatic variables not declared @code{register} are preserved by
  @code{longjmp}.  Ordinarily, GNU C follows ANSI C: automatic variables
***************
*** 672,684 ****
  
  @item -gg
! Produce debugging information in GDB's own format.  This requires the
! GNU assembler and linker in order to work.
! 
! This feature will probably be eliminated.  It was intended to enable
! GDB to read the symbol table faster, but it doesn't result in enough
! of a speedup to be worth the larger object files and executables.  We
! are working on other ways of making GDB start even faster, which work
! with DBX format debugging information and could be made to work with
! SDB format.
  
  @item -w
--- 706,710 ----
  
  @item -gg
! Produce debugging information in the old GDB format.  This is obsolete.
  
  @item -w
***************
*** 795,807 ****
  @item -Wunused
  Warn whenever a local variable is unused aside from its declaration,
! and whenever a function is declared static but never defined.
! 
! @item -Wshadow
! Warn whenever a local variable shadows another local variable.
! 
! @item -Wid-clash-@var{len}
! Warn whenever two distinct identifiers match in the first @var{len}
! characters.  This may help you prepare a program that will compile
! with certain obsolete, brain-damaged compilers.
  
  @item -Wswitch
--- 821,826 ----
  @item -Wunused
  Warn whenever a local variable is unused aside from its declaration,
! whenever a function is declared static but never defined, and whenever
! a statement computes a result that is explicitly not used.
  
  @item -Wswitch
***************
*** 819,824 ****
  
  @item -Wall
! All of the above @samp{-W} options combined.
  
  @item -Wcast-qual
  Warn whenever a pointer is cast so as to remove a type qualifier from
--- 838,863 ----
  
  @item -Wall
! All of the above @samp{-W} options combined.  These are all the
! options which pertain to usage that we recommend avoiding and that we
! believe is easy to avoid, even in conjunction with macros.
  
+ The other @samp{-W@dots{}} options below are not implied by @samp{-Wall}
+ because certain kinds of useful macros are almost impossible to write
+ without causing those warnings.
+ 
+ @item -Wshadow
+ Warn whenever a local variable shadows another local variable.
+ 
+ @item -Wid-clash-@var{len}
+ Warn whenever two distinct identifiers match in the first @var{len}
+ characters.  This may help you prepare a program that will compile
+ with certain obsolete, brain-damaged compilers.
+ 
+ @item -Wpointer-arith
+ Warn about anything that depends on the ``size of'' a function type or
+ of @code{void}.  GNU C assigns these types a size of 1, for
+ convenience in calculations with @code{void *} pointers and pointers
+ to functions.
+ 
  @item -Wcast-qual
  Warn whenever a pointer is cast so as to remove a type qualifier from
***************
*** 844,849 ****
  
  @item -a
! Generate extra code to write profile information for basic blocks,
! suitable for the analysis program @code{tcov}.  Eventually GNU
  @code{gprof} should be extended to process this data.
  
--- 883,890 ----
  
  @item -a
! Generate extra code to write profile information for basic blocks, which
! will record the number of times each basic block is executed.  This data
! could be analyzed by a program like @code{tcov}.  Note, however, that
! the format of the data is not what @code{tcov} expects.  Eventually GNU
  @code{gprof} should be extended to process this data.
  
***************
*** 1022,1026 ****
  Do not recognize @code{asm}, @code{inline} or @code{typeof} as a
  keyword.  These words may then be used as identifiers.  You can
! use @code{__asm}, @code{__inline} and @code{__typeof} instead.
  
  @item -fno-defer-pop
--- 1063,1067 ----
  Do not recognize @code{asm}, @code{inline} or @code{typeof} as a
  keyword.  These words may then be used as identifiers.  You can
! use @code{__asm__}, @code{__inline__} and @code{__typeof__} instead.
  
  @item -fno-defer-pop
***************
*** 1091,1098 ****
  
  @item -fwritable-strings
! Store string constants in the writable data segment and don't
! uniquize them.  This is for compatibility with old programs which
! assume they can write into string constants.  Writing into string
! constants is a very bad idea; ``constants'' should be constant.
  
  @item -fcond-mismatch
--- 1132,1141 ----
  
  @item -fwritable-strings
! Store string constants in the writable data segment and don't uniquize
! them.  This is for compatibility with old programs which assume they can
! write into string constants.  @samp{-traditional} also has this effect.
! 
! Writing into string constants is a very bad idea; ``constants'' should
! be constant.
  
  @item -fcond-mismatch
***************
*** 1140,1143 ****
--- 1183,1191 ----
  the negative form of @samp{-funsigned-char}.
  
+ @item -fdelayed-branch
+ If supported for the target machine, attempt to reorder instructions
+ to exploit instruction slots available after delayed branch
+ instructions.
+ 
  @item -ffixed-@var{reg}
  Treat the register named @var{reg} as a fixed register; generated
***************
*** 1193,1198 ****
  @item j
  Dump after first jump optimization.
- @item J
- Dump after last jump optimization.
  @item s
  Dump after CSE (including the jump optimization that sometimes
--- 1241,1244 ----
***************
*** 1208,1211 ****
--- 1254,1261 ----
  @item g
  Dump after global register allocation.
+ @item d
+ Dump after delayed branch scheduling.
+ @item J
+ Dump after last jump optimization.
  @item m
  Print statistics on memory usage, at the end of the run.
***************
*** 1222,1225 ****
--- 1272,1279 ----
  no reason to @i{use} this option; it exists only to satisfy pedants.
  
+ @samp{-pedantic} does not cause warning messages for use of the
+ alternate keywords whose names begin and end with @samp{__}.
+ @xref{Alternate Keywords}.
+ 
  @item -static
  On Suns running version 4, this prevents linking with the shared
***************
*** 1252,1261 ****
  
  In addition, the @samp{-I-} option inhibits the use of the current
! directory as the first search directory for @samp{#include
! "@var{file}"}.  Therefore, the current directory is searched only if
! it is requested explicitly with @samp{-I.}.  Specifying both
! @samp{-I-} and @samp{-I.} allows you to control precisely which
! directories are searched before the current one and which are searched
! after.
  
  @item -nostdinc
--- 1306,1326 ----
  
  In addition, the @samp{-I-} option inhibits the use of the current
! directory (where the current input file came from) as the first search
! directory for @samp{#include "@var{file}"}.  There is no way to override
! this effect of @samp{-I-}.  With @samp{-I.} you can specify searching
! the directory which was current when the compiler was invoked.  That is
! not exactly the same as what the preprocessor does by default, but it is
! often satisfactory.
! 
! @samp{-I-} does not inhibit the use of the standard system directories
! for header files.  Thus, @samp{-I-} and @samp{-nostdinc} are
! independent.
! 
! @item -i @var{file}
! Process @var{file} as input, discarding the resulting output, before
! processing the regular input file.  Because the output generated from
! @var{file} is discarded, the only effect of @samp{-i @var{file}} is to
! make the macros defined in @var{file} available for use in the main
! input.
  
  @item -nostdinc
***************
*** 1285,1289 ****
  
  @item -D@var{macro}
! Define macro @var{macro} with the empty string as its definition.
  
  @item -D@var{macro}=@var{defn}
--- 1350,1354 ----
  
  @item -D@var{macro}
! Define macro @var{macro} with the  string @samp{1} as its definition.
  
  @item -D@var{macro}=@var{defn}
***************
*** 1302,1310 ****
  
  Here is the procedure for installing GNU CC on a Unix system.
  @menu
  * VMS Install::   See below for installation on VMS.
  @end menu
  @iftex
! (See below for VMS.)
  @end iftex
  
--- 1367,1382 ----
  
  Here is the procedure for installing GNU CC on a Unix system.
+ 
  @menu
+ * Other Dir::     Compiling in a separate directory (not where the source is).
+ * Sun Install::   See below for installation on the Sun.
+ * 3B1 Install::   See below for installation on the 3B1.
  * VMS Install::   See below for installation on VMS.
  @end menu
  @iftex
! See below for VMS systems, and modified procedures needed on Sun systems
! and 3b1 machines.  The following section says how to compile in a
! separate directory on Unix; here we assume you compile in the same
! directory that contains the source files.
  @end iftex
  
***************
*** 1320,1325 ****
  @item
  Choose configuration files.  The easy way to do this is to run the
! command file @file{config.gcc} with a single argument, which is the
! name of the machine (and operating system, in some cases).
  
  Here is a list of the possible arguments:
--- 1392,1397 ----
  @item
  Choose configuration files.  The easy way to do this is to run the
! command file @file{config.gcc} with a single argument, which specifies
! the type of machine (and in some cases which operating system).
  
  Here is a list of the possible arguments:
***************
*** 1339,1342 ****
--- 1411,1416 ----
  @item sequent-i386
  Sequent with Intel 386 processors.
+ @item i386-aix
+ Intel 386 PCs or PS/2s running AIX.
  @item sun2
  Sun 2 running system version 2 or 3.
***************
*** 1343,1349 ****
  @item sun3
  Sun 3 running system version 2 or 3, with 68881.
- 
  Note there we do not provide a configuration file to use an FPA
! by default because programs that establish signal handlers for
  floating point traps inherently cannot work with the FPA.
  @item sun3-nfp
--- 1417,1422 ----
  @item sun3
  Sun 3 running system version 2 or 3, with 68881.
  Note there we do not provide a configuration file to use an FPA
! by default, because programs that establish signal handlers for
  floating point traps inherently cannot work with the FPA.
  @item sun3-nfp
***************
*** 1350,1354 ****
  Sun 3 running system version 2 or 3, without 68881.
  @item sun4
! Sun 4 running system version 2 or 3.
  @item sun2-os4
  Sun 2 running system version 4.
--- 1423,1428 ----
  Sun 3 running system version 2 or 3, without 68881.
  @item sun4
! Sun 4 running system version 2 or 3.  @xref{Incompatibilities},
! for calling convention incompatibilities on the Sun 4 (sparc).
  @item sun2-os4
  Sun 2 running system version 4.
***************
*** 1358,1372 ****
  Sun 3 running system version 4, without 68881.
  @item sun4-os4
! Sun 4 running system version 4.
  @item sun386
  Sun 386 (``roadrunner'').
  @item alliant
! Alliant FX/8 computer.  Currently, there are bugs in the support
! for floating point.  Also note that Alliant's version of dbx does
! not manage to work with the output from GNU CC.
  @item mips
! Some variant of MIPS computer (but not the one from DEC).  Note
! that this machine description was written for GNU CC version 1.32
! and may require some updating to work with the current version.
  @item convex-c1
  Convex C1 computer.
--- 1432,1479 ----
  Sun 3 running system version 4, without 68881.
  @item sun4-os4
! Sun 4 running system version 4.  @xref{Incompatibilities},
! for calling convention incompatibilities on the Sun 4 (sparc).
  @item sun386
  Sun 386 (``roadrunner'').
  @item alliant
! Alliant FX/8 computer.  Note that the standard installed C compiler in
! Concentrix 5.0 has a bug which prevent it from compiling GNU CC
! correctly.  You can patch the compiler bug as follows:
! 
! @example
! cp /bin/pcc ./pcc
! adb -w ./pcc - << 'EOF'
! 15f6?w 6610
! EOF
! @end example
! 
! Then you must use the @samp{-ip12} option when compiling GNU CC
! with the patched compiler, as shown here:
! 
! @example
! make CC="./pcc -ip12" CFLAGS=-w
! @end example
! 
! Note also that Alliant's version of DBX does not manage to work with the
! output from GNU CC.
! @item tahoe
! The tahoe computer (running BSD, and using DBX).
! @item decstation
! The DEC 3100 Mips machine (``pmax'').  Note that GNU CC cannot generate
! debugging information in the unusual format used on the Mips.
! @item mips-sysv
! The Mips computer, RS series, with the System V environment as default.
! Note that GNU CC cannot generate debugging information in the unusual
! format used on the Mips.
! @item mips-bsd43
! The Mips computer, RS series, with the BSD 4.3 environment as default.
! Note that GNU CC cannot generate debugging information in the unusual
! format used on the Mips.
  @item mips
! The Mips computer, M series.  Note that GNU CC cannot generate debugging
! information in the unusual format used on the Mips.
! @item iris
! The Mips computer, as delivered by Iris.  Note that GNU CC cannot
! generate debugging information in the unusual format used on the Mips.
  @item convex-c1
  Convex C1 computer.
***************
*** 1373,1376 ****
--- 1480,1485 ----
  @item convex-c2
  Convex C2 computer.
+ @item pyramid
+ Pyramid computer.
  @item hp9k320
  HP 9000 series 300 using HPUX assembler.  Note there is no
***************
*** 1377,1381 ****
  support in GNU CC for HP's debugger; thus, @samp{-g} is not
  available in this configuration.
! @item hp9k320g
  HP 9000 series 300 using GNU assembler, linker and debugger.
  This requires the HP-adapt package, which is available along with
--- 1486,1490 ----
  support in GNU CC for HP's debugger; thus, @samp{-g} is not
  available in this configuration.
! @item hp9k320-gas
  HP 9000 series 300 using GNU assembler, linker and debugger.
  This requires the HP-adapt package, which is available along with
***************
*** 1382,1387 ****
  the GNU linker as part of the ``binutils'' distribution.
  This is on the GNU CC distribution tape.
  @item isi68
! ISI 68000 or 68020 system.
  @item news800
  Sony NEWS 68020 system.
--- 1491,1504 ----
  the GNU linker as part of the ``binutils'' distribution.
  This is on the GNU CC distribution tape.
+ @item hp9k320-old
+ HP 9000 series 300 using HPUX assembler, in operating system versions
+ older than 6.5.  Note there is no support in GNU CC for HP's debugger;
+ thus, @samp{-g} is not available in this configuration.
+ @item hp9k320-bsd
+ HP 9000 series 300 running BSD.
  @item isi68
! ISI 68000 or 68020 system with a 68881.
! @item isi68-nfp
! ISI 68000 or 68020 system without a 68881.
  @item news800
  Sony NEWS 68020 system.
***************
*** 1393,1401 ****
  bug.  Details in the file @file{ALTOS-README}.
  @item 3b1
! AT&T 3b1, a.k.a. 7300 PC.  Note that the current version of GNU
! CC cannot be compiled with the Unix compiler on this machine, due
! to bugs in the Unix comiler.  GNU CC does work correctly,
! however, if you can compile it with older version of GNU CC or
! cross-compile it.
  @item sequent-ns32k
  Sequent containing ns32000 processors.
--- 1510,1517 ----
  bug.  Details in the file @file{ALTOS-README}.
  @item 3b1
! AT&T 3b1, a.k.a. 7300 PC.  Note that special procedures are needed
! to compile GNU CC with this machine's standard C compiler, due to
! bugs in that compiler.  @xref{3b1 Install}.  You can bootstrap it
! more easily with previous versions of GNU CC if you have them.
  @item sequent-ns32k
  Sequent containing ns32000 processors.
***************
*** 1427,1433 ****
  @item xm-i386v.h
  for Intel 80386's running system V.
- @item xm-sunos4.h
- for Suns (model 2, 3 or 4) running @emph{operating system} version 4.
- (Use @file{xm-m68k.h} or @file{xm-sparc.h} for version 3.)
  @item xm-sun386i.h
  for Sun roadrunner running any version of the operating system.
--- 1543,1546 ----
***************
*** 1455,1458 ****
--- 1568,1576 ----
  @item tm-sun3-nfp.h
  for Sun 3 machines with no hardware floating point.
+ @item tm-sun3os3.h
+ for Sun 3 machines with 68881, running Sunos version 3.
+ @item tm-sun3os3nf.h
+ for Sun 3 machines with no hardware floating point, running Sunos
+ version 3.
  @item tm-sun2.h
  for Sun 2 machines.
***************
*** 1462,1467 ****
  for Integrated Solutions systems.  This file assumes you
  use the GNU assembler.
  @item tm-news800.h
! for SONY News systems.
  @item tm-hp9k320.h
  for HPUX systems, if you are using GNU CC with the system's
--- 1580,1588 ----
  for Integrated Solutions systems.  This file assumes you
  use the GNU assembler.
+ @item tm-isi68-nfp.h
+ for Integrated Solutions systems without a 68881.  This file assumes you
+ use the GNU assembler.
  @item tm-news800.h
! for Sony NEWS systems.
  @item tm-hp9k320.h
  for HPUX systems, if you are using GNU CC with the system's
***************
*** 1489,1492 ****
--- 1610,1619 ----
  386 system.
  
+ For the Mips computer, there are five choices: @file{tm-mips.h} for the
+ M series, @file{tm-mips-bsd.h} for the RS series with BSD,
+ @file{tm-mips-sysv.h} for the RS series with System V, @file{tm-iris.h}
+ for the Iris version of the machine, and @file{tm-decstatn.h} for the
+ Decstation.
+ 
  For the 32000, use @file{tm-sequent.h} if you are using a Sequent
  machine, or @file{tm-encore.h} for an Encore machine, or
***************
*** 1526,1536 ****
  
  @item
- If you are using a Sun, make sure the environment variable
- @code{FLOAT_OPTION} is not set.  If this option were set to
- @code{f68881} when @file{gnulib} is compiled, the resulting code would
- demand to be linked with a special startup file and will not link
- properly without special pains.
- 
- @item
  Build the compiler.  Just type @samp{make} in the compiler directory.
  
--- 1653,1656 ----
***************
*** 1667,1671 ****
  by setting the Make variable @code{libdir} when you make GNU CC.
  
! @node VMS Install,, Installation, Installation
  @section Installing GNU CC on VMS
  
--- 1787,1898 ----
  by setting the Make variable @code{libdir} when you make GNU CC.
  
! @node Other Dir, Sun Install, Installation, Installation
! @section Compilation in a Separate Directory
! 
! If you wish to build the object files and executables in a directory
! other than the one containing the source files, here is what you must
! do differently:
! 
! @enumerate
! @item
! Go to that directory before running @file{config.gcc}:
! 
! @example
! mkdir gcc-sun3
! cd gcc-sun3
! @end example
! 
! On systems that do not support symbolic links, this directory must be
! on the same file system as the source code directory.
! 
! @item
! Specify where to find @file{config.gcc} when you run it:
! 
! @example
! ../gcc-1.36/config.gcc @dots{}
! @end example
! 
! @item
! Specify where to find the sources, as an argument to @file{config.gcc}:
! 
! @example
! ../gcc-1.36/config.gcc -srcdir=../gcc-1.36 sun3
! @end example
! 
! The @samp{-srcdir=@var{dir}} option is not needed when the source
! directory is the parent of the current directory, because
! @file{config.gcc} detects that case automatically.
! @end enumerate
! 
! Now, you can run @code{make} in that directory.  You need not repeat the
! configuration steps shown above, when ordinary source files change.  You
! must, however, run @code{config.gcc} again when the configuration files
! change, if your system does not support symbolic links.
! 
! @node Sun Install, 3b1 Install, Other Dir, Installation
! @section Installing GNU CC on the Sun
! 
! Make sure the environment variable @code{FLOAT_OPTION} is not set when
! you compile @file{gnulib}.  If this option were set to @code{f68881}
! when @file{gnulib} is compiled, the resulting code would demand to be
! linked with a special startup file and would not link properly without
! special pains.  
! 
! There is a bug in @code{alloca} in certain versions of the Sun library. 
! To avoid this bug, install the binaries of GNU CC that were compiled by
! GNU CC.  They use @code{alloca} as a built-in function and never the one
! in the library.  
! 
! Some versions of the Sun compiler crash when compiling GNU CC.
! The problem is a segmentation fault in cpp.
! 
! This problem seems to be due to the bulk of data in the environment
! variables.  You may be able to avoid it by using the following
! command to compile GNU CC with Sun CC:
! 
! @example
! make CC="TERMCAP=x OBJS=x LIBFUNCS=x STAGESTUFF=x cc"
! @end example
! 
! @node 3b1 Install, VMS Install, Sun Install, Installation
! @section Installing GNU CC on the 3b1
! 
! Installing GNU CC on the 3b1 is difficult if you do not already have
! GNU CC running, due to bugs in the installed C compiler.  However,
! the following procedure might work.  We are unable to test it.
! 
! @enumerate
! @item
! Comment out the @samp{#include "config.h"} line on line 37 of
! @file{cccp.c} and do @samp{make cpp}.  This makes a preliminary version
! of GNU cpp.  
! 
! @item
! Save the old @file{/lib/cpp} and copy the preliminary GNU cpp to that
! file name.  
! 
! @item
! Undo your change in @file{cccp.c}, or reinstall the original version,
! and do @samp{make cpp} again.  
! 
! @item
! Copy this final version of GNU cpp into @file{/lib/cpp}.
! 
! @item
! Replace every occurance of @code{obstack_free} in @file{tree.c}
! with @code{_obstack_free}.  
! 
! @item
! Run @code{make} to get the first-stage GNU CC.
! 
! @item
! Reinstall the original version of @file{/lib/cpp}.
! 
! @item
! Now you can compile GNU CC with itself and install it in the normal
! fashion.
! @end enumerate
! 
! @node VMS Install,, 3B1 Install, Installation
  @section Installing GNU CC on VMS
  
***************
*** 1673,1698 ****
  both source code and precompiled binaries.
  
! Sometimes the binaries will be from an older version that the sources,
! because we don't always have time to update them.  In this case, you
! should use the binaries you get to recompile the sources.  If you must
! recompile, here is how:
! 
! @enumerate
! @item
! Copy the file @file{tm-vms.h} to @file{tm.h}, @file{xm-vms.h} to
! @file{config.h}, @file{vax.md} to @file{md.} and @file{output-vax.c}
! to @file{aux-output.c}.@refill
! 
! @item
! Type @samp{@@make} to do recompile everything.
! 
! If you are compiling with a version of GCC older than 1.33, specify
! @samp{/DEFINE=("inline=")} as an option in all the compilations.  This
! requires editing all the @code{gcc} commands in @file{make-cc1.com}.
! (The older versions had problems supporting @code{inline}.)  Once you
! have a working 1.33 or newer GCC, you can change this file back.
! @end enumerate
! 
! To install the @samp{GCC} command so you can use the compiler easily, in
  the same manner as you use the VMS C compiler, you must install the VMS CLD
  file for GNU CC as follows:
--- 1900,1904 ----
  both source code and precompiled binaries.
  
! To install the @file{gcc} command so you can use the compiler easily, in
  the same manner as you use the VMS C compiler, you must install the VMS CLD
  file for GNU CC as follows:
***************
*** 1702,1711 ****
  Define the VMS logical names @samp{GNU_CC} and @samp{GNU_CC_INCLUDE}
  to point to the directories where the GNU CC executables
! (@samp{gcc-cpp}, @samp{gcc-cc1}, etc.) and the C include files are
  kept.  This should be done with the commands:@refill
  
  @example
! $ assign /super /system disk:[gcc] gnu_cc
! $ assign /super /system disk:[gcc.include] gnu_cc_include
  @end example
  
--- 1908,1917 ----
  Define the VMS logical names @samp{GNU_CC} and @samp{GNU_CC_INCLUDE}
  to point to the directories where the GNU CC executables
! (@file{gcc-cpp}, @file{gcc-cc1}, etc.) and the C include files are
  kept.  This should be done with the commands:@refill
  
  @example
! $ assign /super /system disk:[gcc.] gnu_cc
! $ assign /super /system disk:[gcc.include.] gnu_cc_include
  @end example
  
***************
*** 1713,1723 ****
  with the appropriate disk and directory names.  These commands can be
  placed in your system startup file so they will be executed whenever
! the machine is rebooted.
  
  @item
! Install the @samp{GCC} command with the command line:
  
  @example
! $ set command /table=sys$library:dcltables gnu_cc:gcc
  @end example
  
--- 1919,1930 ----
  with the appropriate disk and directory names.  These commands can be
  placed in your system startup file so they will be executed whenever
! the machine is rebooted.  You may, if you choose, do this via the
! @file{GCC_INSTALL.COM} script in the @file{[GCC]} directory.
  
  @item
! Install the @file{GCC} command with the command line:
  
  @example
! $ set command /table=sys$library:dcltables gnu_cc:[000000]gcc
  @end example
  
***************
*** 1735,1738 ****
--- 1942,1991 ----
  @end enumerate
  
+ We try to put corresponding binaries and sources on the VMS distribution
+ tape.  But sometimes the binaries will be from an older version that the
+ sources, because we don't always have time to update them.  (Use the
+ @samp{/verbose} option to determine the version number of the binaries and
+ compare it with the source file @file{version.c} to tell whether this is
+ so.)  In this case, you should use the binaries you get to recompile the
+ sources.  If you must recompile, here is how:
+ 
+ @enumerate
+ @item
+ Copy the file @file{tm-vms.h} to @file{tm.h}, @file{xm-vms.h} to
+ @file{config.h}, @file{vax.md} to @file{md.} and @file{out-vax.c}
+ to @file{aux-output.c}.  The files to be copied are found in the
+ subdirectory named @file{config}; they should be copied to the
+ main directory of GNU CC.@refill
+ 
+ @item
+ Setup the logical names and command tables as defined above.  In
+ addition, define the vms logical name @samp{GNU_BISON} to point at the
+ to the directories where the Bison executable is kept.  This should be
+ done with the command:@refill
+ 
+ @example
+ $ assign /super /system disk:[bison.] gnu_bison
+ @end example
+ 
+ You may, if you choose, use the @file{INSTALL_BISON.COM} script in the
+ @file{[BISON]} directory.
+ 
+ @item
+ Install the @samp{BISON} command with the command line:@refill
+ 
+ @example
+ $ set command /table=sys$library:dcltables gnu_bison:[000000]bison
+ @end example
+ 
+ @item
+ Type @samp{@@make} to do recompile everything.
+ 
+ If you are compiling with a version of GNU CC older than 1.33, specify
+ @samp{/DEFINE=("inline=")} as an option in all the compilations.  This
+ requires editing all the @code{gcc} commands in @file{make-cc1.com}.
+ (The older versions had problems supporting @code{inline}.)  Once you
+ have a working 1.33 or newer GNU CC, you can change this file back.
+ @end enumerate
+ 
  There is a known problem on VMS: @code{const} global variables don't
  work compatibly with the VMS C compiler; we don't know a way to get
***************
*** 1754,1758 ****
  @item
  On certain systems, defining certain environment variables such as
! @samp{CC} can interfere with the functioning of @code{make}.
  
  @item
--- 2007,2011 ----
  @item
  On certain systems, defining certain environment variables such as
! @code{CC} can interfere with the functioning of @code{make}.
  
  @item
***************
*** 1863,1866 ****
--- 2116,2120 ----
  you can use the @samp{-fwritable-strings} flag, which directs GNU CC
  to handle string constants the same way most C compilers do.
+ @samp{-traditional} also has this effect, among others.
  
  @item
***************
*** 1873,1877 ****
  
  @noindent
! will produce output @samp{"a"} regardless of what the argument @var{a} is.
  
  The @samp{-traditional} option directs GNU CC to handle such cases
--- 2127,2131 ----
  
  @noindent
! will produce output @code{"a"} regardless of what the argument @var{a} is.
  
  The @samp{-traditional} option directs GNU CC to handle such cases
***************
*** 1989,1992 ****
--- 2243,2258 ----
  You can tell GNU CC to use the PCC convention with the option
  @samp{-fpcc-struct-return}.
+ 
+ @item
+ On the Sparc, GNU CC uses an incompatible calling convention for
+ structures.  It passes them by including their contents in the argument
+ list, whereas the standard compiler passes them effectively by
+ reference.
+ 
+ This really ought to be fixed, but such calling conventions are not
+ yet supported in GNU CC, so it isn't straightforward to fix it.
+ 
+ The convention for structure returning is also incompatible, and
+ @samp{-fpcc-struct-return} does not help.
  @end itemize
  
***************
*** 2021,2026 ****
  			 (With them you can define ``built-in'' functions.)
  * Asm Labels::		Specifying the assembler name to use for a C symbol.
! * Global Reg Vars::     Defining global variables which reside in registers.
! * Alternate Keywords::  @code{__const}, @code{__asm}, etc., for header files.
  @end menu
  
--- 2287,2292 ----
  			 (With them you can define ``built-in'' functions.)
  * Asm Labels::		Specifying the assembler name to use for a C symbol.
! * Explicit Reg Vars::   Defining variables residing in specified registers.
! * Alternate Keywords::  @code{__const__}, @code{__asm__}, etc., for header files.
  @end menu
  
***************
*** 2128,2132 ****
  
  If you are writing a header file that must work when included in ANSI C
! programs, write @code{__typedef} instead of @code{typedef}.
  @xref{Alternate Keywords}.
  
--- 2394,2398 ----
  
  If you are writing a header file that must work when included in ANSI C
! programs, write @code{__typeof__} instead of @code{typeof}.
  @xref{Alternate Keywords}.
  
***************
*** 2180,2184 ****
  
  @noindent
! Thus, @samp{array (pointer (char), 4)} is the type of arrays of 4
  pointers to @code{char}.
  @end itemize
--- 2446,2450 ----
  
  @noindent
! Thus, @code{array (pointer (char), 4)} is the type of arrays of 4
  pointers to @code{char}.
  @end itemize
***************
*** 2220,2225 ****
  the cast is the same as taking the address without a cast, except for the
  type of the result.  For example, these two expressions are equivalent (but
! the second may be valid when the type of @samp{a} does not permit a cast to
! @samp{int *}).
  
  @example
--- 2486,2491 ----
  the cast is the same as taking the address without a cast, except for the
  type of the result.  For example, these two expressions are equivalent (but
! the second may be valid when the type of @code{a} does not permit a cast to
! @code{int *}).
  
  @example
***************
*** 2232,2236 ****
  left-hand side expression.  After this is stored, the value is converter
  back to the specified type to become the value of the assignment.  Thus, if
! @samp{a} has type @samp{char *}, the following two expressions are
  equivalent:
  
--- 2498,2502 ----
  left-hand side expression.  After this is stored, the value is converter
  back to the specified type to become the value of the assignment.  Thus, if
! @code{a} has type @code{char *}, the following two expressions are
  equivalent:
  
***************
*** 2380,2389 ****
  and on function types, and returns 1.
  
  @node Initializers, Constructors, Pointer Arith, Extensions
  @section Non-Constant Initializers
  
! The elements of an aggregate initializer are not required to be constant
! expressions in GNU C.  Here is an example of an initializer with run-time
! varying elements:
  
  @example
--- 2646,2658 ----
  and on function types, and returns 1.
  
+ The option @samp{-Wpointer-arith} requests a warning if these extensions
+ are used.
+ 
  @node Initializers, Constructors, Pointer Arith, Extensions
  @section Non-Constant Initializers
  
! The elements of an aggregate initializer for an automatic variable are
! not required to be constant expressions in GNU C.  Here is an example of
! an initializer with run-time varying elements:
  
  @example
***************
*** 2410,2414 ****
  
  @noindent
! Here is an example of constructing a @samp{struct foo} with a constructor:
  
  @example
--- 2679,2683 ----
  
  @noindent
! Here is an example of constructing a @code{struct foo} with a constructor:
  
  @example
***************
*** 2445,2449 ****
  @end example
  
! @node Function Attributes, Dollar Signs, Constructors
  @section Declaring Attributes of Functions
  
--- 2714,2718 ----
  @end example
  
! @node Function Attributes, Dollar Signs, Constructors, Extensions
  @section Declaring Attributes of Functions
  
***************
*** 2506,2510 ****
  @section Inquiring about the Alignment of a Type or Variable
  
! The keyword @code{__alignof} allows you to inquire about how an object
  is aligned, or the minimum alignment usually required by a type.  Its
  syntax is just like @code{sizeof}.
--- 2775,2779 ----
  @section Inquiring about the Alignment of a Type or Variable
  
! The keyword @code{__alignof__} allows you to inquire about how an object
  is aligned, or the minimum alignment usually required by a type.  Its
  syntax is just like @code{sizeof}.
***************
*** 2511,2523 ****
  
  For example, if the target machine requires a @code{double} value to be
! aligned on an 8-byte boundary, then @code{__alignof (double)} is 8.  This
! is true on many RISC machines.  On more traditional machine designs,
! @code{__alignof (double)} is 4 or even 2.
  
  Some machines never actually require alignment; they allow reference to any
! data type even at an odd addresses.  For these machines, @code{__alignof}
  reports the @emph{recommended} alignment of a type.
  
! When the operand of @code{__alignof} is an lvalue rather than a type, the
  value is the largest alignment that the lvalue is known to have.  It may
  have this alignment as a result of its data type, or because it is part of
--- 2780,2792 ----
  
  For example, if the target machine requires a @code{double} value to be
! aligned on an 8-byte boundary, then @code{__alignof__ (double)} is 8.
! This is true on many RISC machines.  On more traditional machine
! designs, @code{__alignof__ (double)} is 4 or even 2.
  
  Some machines never actually require alignment; they allow reference to any
! data type even at an odd addresses.  For these machines, @code{__alignof__}
  reports the @emph{recommended} alignment of a type.
  
! When the operand of @code{__alignof__} is an lvalue rather than a type, the
  value is the largest alignment that the lvalue is known to have.  It may
  have this alignment as a result of its data type, or because it is part of
***************
*** 2530,2536 ****
  
  @noindent
! the value of @code{__alignof (foo1.y)} is probably 2 or 4, the same as
! @code{__alignof (int)}, even though the data type of @code{foo1.y} does not
! itself demand any alignment.@refill
  
  @node Inline, Extended Asm, Alignment, Extensions
--- 2799,2805 ----
  
  @noindent
! the value of @code{__alignof__ (foo1.y)} is probably 2 or 4, the same as
! @code{__alignof__ (int)}, even though the data type of @code{foo1.y}
! does not itself demand any alignment.@refill
  
  @node Inline, Extended Asm, Alignment, Extensions
***************
*** 2556,2560 ****
  
  (If you are writing a header file to be included in ANSI C programs, write
! @code{__inline} instead of @code{inline}.  @xref{Alternate Keywords}.)
  
  You can also make all ``simple enough'' functions inline with the option
--- 2825,2829 ----
  
  (If you are writing a header file to be included in ANSI C programs, write
! @code{__inline__} instead of @code{inline}.  @xref{Alternate Keywords}.)
  
  You can also make all ``simple enough'' functions inline with the option
***************
*** 2563,2574 ****
  
  When a function is both inline and @code{static}, if all calls to the
! function are integrated into the caller, then the function's own assembler
! code is never referenced.  In this case, GNU CC does not actually output
! assembler code for the function, unless you specify the option
! @samp{-fkeep-inline-functions}.  Some calls cannot be integrated for
! various reasons (in particular, calls that precede the function's
! definition cannot be integrated, and neither can recursive calls within the
! definition).  If there is a nonintegrated call, then the function is
! compiled to assembler code as usual.
  
  When an inline function is not @code{static}, then the compiler must assume
--- 2832,2845 ----
  
  When a function is both inline and @code{static}, if all calls to the
! function are integrated into the caller, and the function's address is
! never used, then the function's own assembler code is never referenced.
! In this case, GNU CC does not actually output assembler code for the
! function, unless you specify the option @samp{-fkeep-inline-functions}.
! Some calls cannot be integrated for various reasons (in particular,
! calls that precede the function's definition cannot be integrated, and
! neither can recursive calls within the definition).  If there is a
! nonintegrated call, then the function is compiled to assembler code as
! usual.  The function must also be compiled as usual if the program
! refers to its address, because that can't be inlined.
  
  When an inline function is not @code{static}, then the compiler must assume
***************
*** 2579,2582 ****
--- 2850,2867 ----
  own in the usual fashion.
  
+ If you specify both @code{inline} and @code{extern} in the function
+ definition, then the definition is used only for inlining.  In no case
+ is the function compiled on its own, not even if you refer to its
+ address explicitly.  Such an address becomes an external reference, as
+ if you had only declared the function, and had not defined it.
+ 
+ This combination of @code{inline} and @code{extern} has almost the
+ effect of a macro.  The way to use it is to put a function definition in
+ a header file with these keywords, and put another copy of the
+ definition (lacking @code{inline} and @code{extern}) in a library file.
+ The definition in the header file will cause most calls to the function
+ to be inlined.  If any uses of the function remain, they will refer to
+ the single copy in the library.
+ 
  @node Extended Asm, Asm Labels, Inline, Extensions
  @section Assembler Instructions with C Expression Operands
***************
*** 2626,2638 ****
  The output operands must be write-only; GNU CC will assume that the values
  in these operands before the instruction are dead and need not be
! generated.  For an operand that is read-write, or in which not all bits are
! written and the other bits contain useful information, you must logically
  split its function into two separate operands, one input operand and one
  write-only output operand.  The connection between them is expressed by
  constraints which say they need to be in the same location when the
! instruction executes.  You can use the same C expression for both operands,
! or different expressions.  For example, here we write the (fictitious)
! @samp{combine} instruction with @code{bar} as its read-only source operand
! and @code{foo} as its read-write destination:
  
  @example
--- 2911,2927 ----
  The output operands must be write-only; GNU CC will assume that the values
  in these operands before the instruction are dead and need not be
! generated.  Extended asm does not support input-output or read-write
! operands.  For this reason, the constraint character @samp{+}, which
! indicates such an operand, may not be used.
! 
! When the assembler instruction has a read-write operand, or an operand
! in which only some of the bits are to be changed, you must logically
  split its function into two separate operands, one input operand and one
  write-only output operand.  The connection between them is expressed by
  constraints which say they need to be in the same location when the
! instruction executes.  You can use the same C expression for both
! operands, or different expressions.  For example, here we write the
! (fictitious) @samp{combine} instruction with @code{bar} as its read-only
! source operand and @code{foo} as its read-write destination:
  
  @example
***************
*** 2767,2779 ****
  
  If you are writing a header file that should be includable in ANSI C
! programs, write @code{__asm} instead of @code{asm}.  @xref{Alternate
  Keywords}.
  
! @node Asm Labels, Global Reg Vars, Extended Asm, Extensions
  @section Controlling Names Used in Assembler Code
  
! You can specify the name to be used in the assembler code for a C function
! or variable by writing the @code{asm} (or @code{__asm}) keyword after the
! declarator as follows:
  
  @example
--- 3056,3068 ----
  
  If you are writing a header file that should be includable in ANSI C
! programs, write @code{__asm__} instead of @code{asm}.  @xref{Alternate
  Keywords}.
  
! @node Asm Labels, Explicit Reg Vars, Extended Asm, Extensions
  @section Controlling Names Used in Assembler Code
  
! You can specify the name to be used in the assembler code for a C
! function or variable by writing the @code{asm} (or @code{__asm__})
! keyword after the declarator as follows:
  
  @example
***************
*** 2808,2817 ****
  Perhaps that will be added.
  
! @node Global Reg Vars, Alternate Keywords, Asm Labels, Extensions
! @section Global Variables in Registers
  
! A few programs, such as programming language interpreters, may have a
! couple of global variables that are accessed so often that it is worth
! while to reserve registers throughout the program just for them.
  
  You can define a global register variable in GNU C like this:
--- 3097,3130 ----
  Perhaps that will be added.
  
! @node Explicit Reg Vars, Alternate Keywords, Asm Labels, Extensions
! @section Variables in Specified Registers
! 
! GNU C allows you to put a few global variables into specified hardware
! registers.  You can also specify the register in which an ordinary
! register variable should be allocated.
! 
! @itemize @bullet
! @item
! Global register variables reserve registers throughout the program.
! This may be useful in programs such as programming language
! interpreters which have a couple of global variables that are accessed
! very often.
! 
! @item
! Local register variables in specific registers do not reserve the
! registers.  The compiler's data flow analysis is capable of
! determining where the specified registers contain live values, and
! where they are available for other uses.  These local variables are
! sometimes convenient for use with the extended @code{asm} feature
! (@pxref{Extended Asm}).
! @end itemize
! 
! @menu
! * Global Reg Vars::
! * Local Reg Vars::
! @end menu
  
! @node Global Reg Vars, Local Reg Vars, Explicit Reg Vars, Explicit Reg Vars
! @subsection Defining Global Register Variables
  
  You can define a global register variable in GNU C like this:
***************
*** 2830,2834 ****
  @code{a5} would be a good choice on a 68000 for a variable of pointer
  type.  On machines with register windows, be sure to choose a ``global''
! register that is not affected by the function call mechanism.
  
  In addition, operating systems on one type of cpu may differ in how they
--- 3143,3147 ----
  @code{a5} would be a good choice on a 68000 for a variable of pointer
  type.  On machines with register windows, be sure to choose a ``global''
! register that is not affected magically by the function call mechanism.
  
  In addition, operating systems on one type of cpu may differ in how they
***************
*** 2893,2897 ****
  executable file has no means to supply initial contents for a register.
  
! @node Alternate Keywords,, Global Reg Vars, Extensions
  @section Alternate Keywords
  
--- 3206,3246 ----
  executable file has no means to supply initial contents for a register.
  
! @node Local Reg Vars,, Local Reg Vars, Explicit Reg Vars
! @subsection Specifying Registers for Local Variables
! 
! You can define a local register variable with a specified register
! like this:
! 
! @example
! register int *foo asm ("a5");
! @end example
! 
! @noindent
! Here @code{a5} is the name of the register which should be used.  Note
! that this is the same syntax used for defining global register
! variables, but for a local variable it would appear within a function.
! 
! Naturally the register name is cpu-dependent, but this is not a
! problem, since specific registers are most often useful with explicit
! assembler instructions (@pxref{Extended Asm}).  Both of these things
! generally require that you conditionalize your program according to
! cpu type.
! 
! In addition, operating systems on one type of cpu may differ in how they
! name the registers; then you would need additional conditionals.  For
! example, some 68000 operating systems call this register @code{%a5}.
! 
! Eventually there may be a way of asking the compiler to choose a register
! automatically, but first we need to figure out how it should choose and
! how to enable you to guide the choice.  No solution is evident.
! 
! Defining such a register variable does not reserve the register; it
! remains available for other uses in places where flow control
! determines the variable's value is not live.  However, these registers
! made unavailable for use in the reload pass.  I would not be surprised
! if excessive use of this feature leaves the compiler too few available
! registers to compile certain functions.
! 
! @node Alternate Keywords,, Explicit Reg Vars, Extensions
  @section Alternate Keywords
  
***************
*** 2906,2913 ****
  @samp{-traditional}.@refill
  
! The way to solve these problems is to put @samp{__} in front of each
! problematical keyword.  For example, use @code{__asm} instead of @code{asm},
! @code{__const} instead of @code{const}, and @code{__inline} instead of
! @code{inline}.
  
  Other C compilers won't accept these alternative keywords; if you want to
--- 3255,3262 ----
  @samp{-traditional}.@refill
  
! The way to solve these problems is to put @samp{__} at the beginning and
! end of each problematical keyword.  For example, use @code{__asm__}
! instead of @code{asm}, @code{__const__} instead of @code{const}, and
! @code{__inline__} instead of @code{inline}.
  
  Other C compilers won't accept these alternative keywords; if you want to
***************
*** 2917,2921 ****
  @example
  #ifndef __GNUC__
! #define __asm asm
  #endif
  @end example
--- 3266,3270 ----
  @example
  #ifndef __GNUC__
! #define __asm__ asm
  #endif
  @end example
***************
*** 2969,2979 ****
  For example, in many nonoptimizing compilers, you can write @samp{x;}
  at the end of a function instead of @samp{return x;}, with the same
! results.  But the value of the function is undefined if @samp{return}
  is omitted; it is not a bug when GNU CC produces different results.
  
  Problems often result from expressions with two increment operators,
! as in @samp{f (*p++, *p++)}.  Your previous compiler might have
  interpreted that expression the way you intended; GNU CC might
! interpret it another way; neither compiler is wrong.
  
  After you have localized the error to a single source line, it should
--- 3318,3329 ----
  For example, in many nonoptimizing compilers, you can write @samp{x;}
  at the end of a function instead of @samp{return x;}, with the same
! results.  But the value of the function is undefined if @code{return}
  is omitted; it is not a bug when GNU CC produces different results.
  
  Problems often result from expressions with two increment operators,
! as in @code{f (*p++, *p++)}.  Your previous compiler might have
  interpreted that expression the way you intended; GNU CC might
! interpret it another way.  Neither compiler is wrong.  The bug is
! in your code.
  
  After you have localized the error to a single source line, it should
***************
*** 3023,3028 ****
  @end example
  
! As a last resort, snail them to:
  
  @example
  GNU Compiler Bugs
--- 3373,3391 ----
  @end example
  
! @strong{Do not send bug reports to @samp{info-gcc}, or to the newsgroup
! @samp{gnu.gcc}.} Most users of GNU CC do not want to receive bug
! reports.  Those that do, have asked to be on @samp{bug-gcc}.
! 
! The mailing list @samp{bug-gcc} has a newsgroup which serves as a
! repeater.  The mailing list and the newsgroup carry exactly the same
! messages.  Often people think of posting bug reports to the newsgroup
! instead of mailing them.  This appears to work, but it has one problem
! which can be crucial: a newsgroup posting does not contain a mail path
! back to the sender.  Thus, if I need to ask for more information, I
! may be unable to reach you.  For this reason, it is better to send bug
! reports to the mailing list.
  
+ As a last resort, send bug reports on paper to:
+ 
  @example
  GNU Compiler Bugs
***************
*** 3032,3037 ****
  
  The fundamental principle of reporting bugs usefully is this:
! @strong{report all the facts}.  If you are not sure whether to mention a
! fact or leave it out, mention it!
  
  Often people omit facts because they think they know what causes the
--- 3395,3400 ----
  
  The fundamental principle of reporting bugs usefully is this:
! @strong{report all the facts}.  If you are not sure whether to state a
! fact or leave it out, state it!
  
  Often people omit facts because they think they know what causes the
***************
*** 3042,3049 ****
  name is stored in memory; perhaps, if the name were different, the contents
  of that location would fool the compiler into doing the right thing despite
! the bug.  Play it safe and give an exact example.
  
! If you want to enable me to fix the bug, you should include all these
! things:
  
  @itemize @bullet
--- 3405,3422 ----
  name is stored in memory; perhaps, if the name were different, the contents
  of that location would fool the compiler into doing the right thing despite
! the bug.  Play it safe and give a specific, complete example.  That is the
! easiest thing for you to do, and the most helpful.
! 
! Keep in mind that the purpose of a bug report is to enable me to fix
! the bug if it is not known.  It isn't very important what happens if
! the bug is already known.  Therefore, always write your bug reports on
! the assumption that the bug is not known.
! 
! Sometimes people give a few sketchy facts and ask, ``Does this ring a
! bell?''  Those bug reports are useless, and I urge everyone to
! @emph{refuse to respond to them} except to chide the sender to report
! bugs properly.
  
! To enable me to fix the bug, you should include all these things:
  
  @itemize @bullet
***************
*** 3111,3121 ****
  would not be able to draw any conclusion from my observations.
  
! In cases where GNU CC generates incorrect code, if you send me a small
! complete sample program I will find the error myself by running the
! program under a debugger.  If you send me a large example or a part of
! a larger program, I cannot do this; you must debug the compiled
! program and narrow the problem down to one source line.  Tell me which
! source line it is, and what you believe is incorrect about the code
! generated for that line.
  
  @item
--- 3484,3495 ----
  would not be able to draw any conclusion from my observations.
  
! Often the observed symptom is incorrect output when your program is run.
! Sad to say, this is not enough information for me unless the program is
! short and simple.  If you send me a large program, I don't have time to
! figure out how it would work if compiled correctly, much less which line
! of it was compiled wrong.  So you will have to do that.  Tell me which
! source line it is, and what incorrect result happens when that line is
! executed.  A person who understands the test program can find this as
! easily as a bug in the program itself.
  
  @item
***************
*** 3152,3156 ****
  In addition, most compiler passes consist of one or more loops that
  scan the RTL insn sequence.  The most vital piece of information about
! such a loop--which insn it has reached--is usually in a local variable,
  not in an argument.
  
--- 3526,3530 ----
  In addition, most compiler passes consist of one or more loops that
  scan the RTL insn sequence.  The most vital piece of information about
! such a loop---which insn it has reached---is usually in a local variable,
  not in an argument.
  
***************
*** 3182,3185 ****
--- 3556,3560 ----
  will find the bug is by running a single example under the debugger
  with breakpoints, not by pure deduction from a series of examples.
+ I recommend that you save your time for something else.
  
  Of course, if you can find a simpler example to report @emph{instead}
***************
*** 3190,3197 ****
  function definitions except the one where the bug occurs.  Those
  earlier in the file may be replaced by external declarations if the
! crucial function depends on them.
  
  However, simplification is not vital; if you don't want to do this,
! report the bug anyway.
  
  @item
--- 3565,3573 ----
  function definitions except the one where the bug occurs.  Those
  earlier in the file may be replaced by external declarations if the
! crucial function depends on them.  (Exception: inline functions may
! affect compilation of functions defined later in the file.)
  
  However, simplification is not vital; if you don't want to do this,
! report the bug anyway and send me the entire test case you used.
  
  @item
***************
*** 3199,3204 ****
  
  A patch for the bug does help me if it is a good one.  But don't omit
! the necessary information, such as the test case, because I might see
! problems with your patch and decide to fix the problem another way.
  
  Sometimes with a program as complicated as GNU CC it is very hard to
--- 3575,3581 ----
  
  A patch for the bug does help me if it is a good one.  But don't omit
! the necessary information, such as the test case, on the assumption that
! a patch is all I need.  I might see problems with your patch and decide
! to fix the problem another way, or I might not understand it at all.
  
  Sometimes with a program as complicated as GNU CC it is very hard to
***************
*** 3207,3210 ****
--- 3584,3591 ----
  to construct one, so I won't be able to verify that the bug is fixed.
  
+ And if I can't understand what bug you are trying to fix, or why your
+ patch should be an improvement, I won't install it.  A test case will
+ help me to understand.
+ 
  @item
  A guess about what the bug is or what it depends on.
***************
*** 3211,3215 ****
  
  Such guesses are usually wrong.  Even I can't guess right about such
! things without using the debugger to find the facts.
  @end itemize
  
--- 3592,3596 ----
  
  Such guesses are usually wrong.  Even I can't guess right about such
! things without first using the debugger to find the facts.
  @end itemize
  
***************
*** 3463,3468 ****
  
  @item
! Loop optimization.  This pass moves constant expressions out of loops.
! Its source file is @file{loop.c}.
  
  The option @samp{-dL} causes a debugging dump of the RTL code after
--- 3844,3850 ----
  
  @item
! Loop optimization.  This pass moves constant expressions out of loops,
! and optionally does strength-reduction as well.  Its source file is
! @file{loop.c}.
  
  The option @samp{-dL} causes a debugging dump of the RTL code after
***************
*** 3550,3553 ****
--- 3932,3943 ----
  
  @item
+ Delayed branch scheduling may be done at this point.  The source file
+ name is @file{dbranch.c}.
+ 
+ The option @samp{-dd} causes a debugging dump of the RTL code after
+ this pass.  This dump file's name is made by appending @samp{.dbr}
+ to the input file name.
+ 
+ @item
  Final.  This pass outputs the assembler code for the function.  It is
  also responsible for identifying spurious test and compare
***************
*** 3648,3652 ****
  
  An integer is simply an @code{int}, and a string is a @code{char *}.
! Within RTL code, strings appear only inside @samp{symbol_ref} expressions,
  but they appear in other contexts in the RTL expressions that make up
  machine descriptions.  Their written form uses decimal digits.
--- 4038,4042 ----
  
  An integer is simply an @code{int}, and a string is a @code{char *}.
! Within RTL code, strings appear only inside @code{symbol_ref} expressions,
  but they appear in other contexts in the RTL expressions that make up
  machine descriptions.  Their written form uses decimal digits.
***************
*** 3677,3684 ****
  by looking at an operand what kind of object it is.  Instead, you must know
  from its context---from the expression code of the containing expression.
! For example, in an expression of code @samp{subreg}, the first operand is
  to be regarded as an expression and the second operand as an integer.  In
! an expression of code @samp{plus}, there are two operands, both of which
! are to be regarded as expressions.  In a @samp{symbol_ref} expression,
  there is one operand, which is to be regarded as a string.
  
--- 4067,4074 ----
  by looking at an operand what kind of object it is.  Instead, you must know
  from its context---from the expression code of the containing expression.
! For example, in an expression of code @code{subreg}, the first operand is
  to be regarded as an expression and the second operand as an integer.  In
! an expression of code @code{plus}, there are two operands, both of which
! are to be regarded as expressions.  In a @code{symbol_ref} expression,
  there is one operand, which is to be regarded as a string.
  
***************
*** 3689,3693 ****
  Expression code names in the @samp{md} file are written in lower case,
  but when they appear in C code they are written in upper case.  In this
! manual, they are shown as follows: @samp{const_int}.
  
  In a few contexts a null pointer is valid where an expression is normally
--- 4079,4083 ----
  Expression code names in the @samp{md} file are written in lower case,
  but when they appear in C code they are written in upper case.  In this
! manual, they are shown as follows: @code{const_int}.
  
  In a few contexts a null pointer is valid where an expression is normally
***************
*** 3702,3706 ****
  string, and @samp{E} for vector of expressions.  The sequence of letters
  for an expression code is called its @dfn{format}.  Thus, the format of
! @samp{subreg} is @samp{ei}.@refill
  
  Two other format characters are used occasionally: @samp{u} and @samp{0}.
--- 4092,4096 ----
  string, and @samp{E} for vector of expressions.  The sequence of letters
  for an expression code is called its @dfn{format}.  Thus, the format of
! @code{subreg} is @samp{ei}.@refill
  
  Two other format characters are used occasionally: @samp{u} and @samp{0}.
***************
*** 3747,3751 ****
  operands there are.
  
! For example, if @var{x} is a @samp{subreg} expression, you know that it has
  two operands which can be correctly accessed as @code{XEXP (@var{x}, 0)}
  and @code{XINT (@var{x}, 1)}.  If you did @code{XINT (@var{x}, 0)}, you
--- 4137,4141 ----
  operands there are.
  
! For example, if @var{x} is a @code{subreg} expression, you know that it has
  two operands which can be correctly accessed as @code{XEXP (@var{x}, 0)}
  and @code{XINT (@var{x}, 1)}.  If you did @code{XINT (@var{x}, 0)}, you
***************
*** 3793,3801 ****
  @table @code
  @item MEM_VOLATILE_P (@var{x})
! In @samp{mem} expressions, nonzero for volatile memory references.
  Stored in the @code{volatil} field and printed as @samp{/v}.
  
  @item MEM_IN_STRUCT_P (@var{x})
! In @samp{mem} expressions, nonzero for reference to an entire
  structure, union or array, or to a component of one.  Zero for
  references to a scalar variable or through a pointer to a scalar.
--- 4183,4191 ----
  @table @code
  @item MEM_VOLATILE_P (@var{x})
! In @code{mem} expressions, nonzero for volatile memory references.
  Stored in the @code{volatil} field and printed as @samp{/v}.
  
  @item MEM_IN_STRUCT_P (@var{x})
! In @code{mem} expressions, nonzero for reference to an entire
  structure, union or array, or to a component of one.  Zero for
  references to a scalar variable or through a pointer to a scalar.
***************
*** 3803,3807 ****
  
  @item REG_USER_VAR_P (@var{x})
! In a @samp{reg}, nonzero if it corresponds to a variable present in
  the user's source code.  Zero for temporaries generated internally by
  the compiler.  Stored in the @code{volatil} field and printed as
--- 4193,4197 ----
  
  @item REG_USER_VAR_P (@var{x})
! In a @code{reg}, nonzero if it corresponds to a variable present in
  the user's source code.  Zero for temporaries generated internally by
  the compiler.  Stored in the @code{volatil} field and printed as
***************
*** 3809,3813 ****
  
  @item REG_FUNCTION_VALUE_P (@var{x})
! Nonzero in a @samp{reg} if it is the place in which this function's
  value is going to be returned.  (This happens only in a hard
  register.)  Stored in the @code{integrated} field and printed as
--- 4199,4203 ----
  
  @item REG_FUNCTION_VALUE_P (@var{x})
! Nonzero in a @code{reg} if it is the place in which this function's
  value is going to be returned.  (This happens only in a hard
  register.)  Stored in the @code{integrated} field and printed as
***************
*** 3819,3823 ****
  
  @item RTX_UNCHANGING_P (@var{x})
! Nonzero in a @samp{reg} or @samp{mem} if the value is not changed
  explicitly by the current function.  (If it is a memory reference then
  it may be changed by other functions or by aliasing.)  Stored in the
--- 4209,4213 ----
  
  @item RTX_UNCHANGING_P (@var{x})
! Nonzero in a @code{reg} or @code{mem} if the value is not changed
  explicitly by the current function.  (If it is a memory reference then
  it may be changed by other functions or by aliasing.)  Stored in the
***************
*** 3834,3838 ****
  
  @item CONSTANT_POOL_ADDRESS_P (@var{x})
! Nonzero in a @samp{symbol_ref} if it refers to part of the current
  function's ``constants pool''.  These are addresses close to the
  beginning of the function, and GNU CC assumes they can be addressed
--- 4224,4228 ----
  
  @item CONSTANT_POOL_ADDRESS_P (@var{x})
! Nonzero in a @code{symbol_ref} if it refers to part of the current
  function's ``constants pool''.  These are addresses close to the
  beginning of the function, and GNU CC assumes they can be addressed
***************
*** 3851,3861 ****
  
  @item volatil
! This flag is used in @samp{mem} and @samp{reg} expressions and in insns.
  In RTL dump files, it is printed as @samp{/v}.
  
! In a @samp{mem} expression, it is 1 if the memory reference is volatile.
  Volatile memory references may not be deleted, reordered or combined.
  
! In a @samp{reg} expression, it is 1 if the value is a user-level variable.
  0 indicates an internal compiler temporary.
  
--- 4241,4251 ----
  
  @item volatil
! This flag is used in @code{mem} and @code{reg} expressions and in insns.
  In RTL dump files, it is printed as @samp{/v}.
  
! In a @code{mem} expression, it is 1 if the memory reference is volatile.
  Volatile memory references may not be deleted, reordered or combined.
  
! In a @code{reg} expression, it is 1 if the value is a user-level variable.
  0 indicates an internal compiler temporary.
  
***************
*** 3863,3867 ****
  
  @item in_struct
! This flag is used in @samp{mem} expressions.  It is 1 if the memory
  datum referred to is all or part of a structure or array; 0 if it is (or
  might be) a scalar variable.  A reference through a C pointer has 0
--- 4253,4257 ----
  
  @item in_struct
! This flag is used in @code{mem} expressions.  It is 1 if the memory
  datum referred to is all or part of a structure or array; 0 if it is (or
  might be) a scalar variable.  A reference through a C pointer has 0
***************
*** 3874,3878 ****
  
  @item unchanging
! This flag is used in @samp{reg} and @samp{mem} expressions.  1 means
  that the value of the expression never changes (at least within the
  current function).
--- 4264,4268 ----
  
  @item unchanging
! This flag is used in @code{reg} and @code{mem} expressions.  1 means
  that the value of the expression never changes (at least within the
  current function).
***************
*** 3884,3888 ****
  rtl was produced by procedure integration.
  
! In a @samp{reg} expression, this flag indicates the register
  containing the value to be returned by the current function.  On
  machines that pass parameters in registers, the same register number
--- 4274,4278 ----
  rtl was produced by procedure integration.
  
! In a @code{reg} expression, this flag indicates the register
  containing the value to be returned by the current function.  On
  machines that pass parameters in registers, the same register number
***************
*** 3903,3907 ****
  expression is written after the expression code with a colon to separate
  them.  The letters @samp{mode} which appear at the end of each machine mode
! name are omitted.  For example, @code{(reg:SI 38)} is a @samp{reg}
  expression with machine mode @code{SImode}.  If the mode is
  @code{VOIDmode}, it is not written at all.
--- 4293,4297 ----
  expression is written after the expression code with a colon to separate
  them.  The letters @samp{mode} which appear at the end of each machine mode
! name are omitted.  For example, @code{(reg:SI 38)} is a @code{reg}
  expression with machine mode @code{SImode}.  If the mode is
  @code{VOIDmode}, it is not written at all.
***************
*** 3960,3964 ****
  @item VOIDmode
  Void mode means the absence of a mode or an unspecified mode.
! For example, RTL expressions of code @samp{const_int} have mode
  @code{VOIDmode} because they can be taken to have whatever mode the context
  requires.  In debugging dumps of RTL, @code{VOIDmode} is expressed by
--- 4350,4354 ----
  @item VOIDmode
  Void mode means the absence of a mode or an unspecified mode.
! For example, RTL expressions of code @code{const_int} have mode
  @code{VOIDmode} because they can be taken to have whatever mode the context
  requires.  In debugging dumps of RTL, @code{VOIDmode} is expressed by
***************
*** 4081,4085 ****
  it is the value of the variable @code{const0_rtx}.  Likewise, the
  only expression for integer value one is found in @code{const1_rtx}.
! Any attempt to create an expression of code @samp{const_int} and
  value zero or one will return @code{const0_rtx} or @code{const1_rtx}
  as appropriate.
--- 4471,4475 ----
  it is the value of the variable @code{const0_rtx}.  Likewise, the
  only expression for integer value one is found in @code{const1_rtx}.
! Any attempt to create an expression of code @code{const_int} and
  value zero or one will return @code{const0_rtx} or @code{const1_rtx}
  as appropriate.
***************
*** 4097,4102 ****
  @example
  union @{ double d; int i[2];@} u;
! u.i[0] = XINT (x, 0);
! u.i[1] = XINT (x, 1);
  @end example
  
--- 4487,4492 ----
  @example
  union @{ double d; int i[2];@} u;
! u.i[0] = CONST_DOUBLE_LOW(x);
! u.i[1] = CONST_DOUBLE_HIGH(x);
  @end example
  
***************
*** 4105,4111 ****
  
  The global variables @code{dconst0_rtx} and @code{fconst0_rtx} hold
! @samp{const_double} expressions with value 0, in modes @code{DFmode}
  and @code{SFmode}, respectively.  The macro @code{CONST0_RTX
! (@var{mode})} refers to a @samp{const_double} expression with value 0
  in mode @var{mode}.  The mode @var{mode} must be of mode class
  @code{MODE_FLOAT}.
--- 4495,4501 ----
  
  The global variables @code{dconst0_rtx} and @code{fconst0_rtx} hold
! @code{const_double} expressions with value 0, in modes @code{DFmode}
  and @code{SFmode}, respectively.  The macro @code{CONST0_RTX
! (@var{mode})} refers to a @code{const_double} expression with value 0
  in mode @var{mode}.  The mode @var{mode} must be of mode class
  @code{MODE_FLOAT}.
***************
*** 4120,4124 ****
  @item (label_ref @var{label})
  Represents the value of an assembler label for code.  It contains one
! operand, an expression, which must be a @samp{code_label} that appears
  in the instruction sequence to identify the place where the label
  should go.
--- 4510,4514 ----
  @item (label_ref @var{label})
  Represents the value of an assembler label for code.  It contains one
! operand, an expression, which must be a @code{code_label} that appears
  in the instruction sequence to identify the place where the label
  should go.
***************
*** 4130,4136 ****
  Represents a constant that is the result of an assembly-time
  arithmetic computation.  The operand, @var{exp}, is an expression that
! contains only constants (@samp{const_int}, @samp{symbol_ref} and
! @samp{label_ref} expressions) combined with @samp{plus} and
! @samp{minus}.  However, not all combinations are valid, since the
  assembler cannot do arbitrary arithmetic on relocatable symbols.
  @end table
--- 4520,4526 ----
  Represents a constant that is the result of an assembly-time
  arithmetic computation.  The operand, @var{exp}, is an expression that
! contains only constants (@code{const_int}, @code{symbol_ref} and
! @code{label_ref} expressions) combined with @code{plus} and
! @code{minus}.  However, not all combinations are valid, since the
  assembler cannot do arbitrary arithmetic on relocatable symbols.
  @end table
***************
*** 4161,4165 ****
  
  Each pseudo register number used in a function's RTL code is
! represented by a unique @samp{reg} expression.
  
  @var{m} is the machine mode of the reference.  It is necessary because
--- 4551,4555 ----
  
  Each pseudo register number used in a function's RTL code is
! represented by a unique @code{reg} expression.
  
  @var{m} is the machine mode of the reference.  It is necessary because
***************
*** 4176,4183 ****
  function, but each pseudo register is given a natural mode
  and is accessed only in that mode.  When it is necessary to describe
! an access to a pseudo register using a nonnatural mode, a @samp{subreg}
  expression is used.
  
! A @samp{reg} expression with a machine mode that specifies more than
  one word of data may actually stand for several consecutive registers.
  If in addition the register number specifies a hardware register, then
--- 4566,4573 ----
  function, but each pseudo register is given a natural mode
  and is accessed only in that mode.  When it is necessary to describe
! an access to a pseudo register using a nonnatural mode, a @code{subreg}
  expression is used.
  
! A @code{reg} expression with a machine mode that specifies more than
  one word of data may actually stand for several consecutive registers.
  If in addition the register number specifies a hardware register, then
***************
*** 4185,4189 ****
  with the specified one.
  
! Such multi-word hardware register @samp{reg} expressions must not be live
  across the boundary of a basic block.  The lifetime analysis pass does not
  know how to record properly that several consecutive registers are
--- 4575,4579 ----
  with the specified one.
  
! Such multi-word hardware register @code{reg} expressions must not be live
  across the boundary of a basic block.  The lifetime analysis pass does not
  know how to record properly that several consecutive registers are
***************
*** 4193,4211 ****
  
  @item (subreg:@var{m} @var{reg} @var{wordnum})
! @samp{subreg} expressions are used to refer to a register in a machine
  mode other than its natural one, or to refer to one register of
! a multi-word @samp{reg} that actually refers to several registers.
  
  Each pseudo-register has a natural mode.  If it is necessary to
  operate on it in a different mode---for example, to perform a fullword
! move instruction on a pseudo-register that contains a single byte---
! the pseudo-register must be enclosed in a @samp{subreg}.  In such
! a case, @var{wordnum} is zero.
  
! The other use of @samp{subreg} is to extract the individual registers
  of a multi-register value.  Machine modes such as @code{DImode} and
  @code{EPmode} indicate values longer than a word, values which usually
  require two consecutive registers.  To access one of the registers,
! use a @samp{subreg} with mode @code{SImode} and a @var{wordnum} that
  says which register.
  
--- 4583,4601 ----
  
  @item (subreg:@var{m} @var{reg} @var{wordnum})
! @code{subreg} expressions are used to refer to a register in a machine
  mode other than its natural one, or to refer to one register of
! a multi-word @code{reg} that actually refers to several registers.
  
  Each pseudo-register has a natural mode.  If it is necessary to
  operate on it in a different mode---for example, to perform a fullword
! move instruction on a pseudo-register that contains a single
! byte---the pseudo-register must be enclosed in a @code{subreg}.  In
! such a case, @var{wordnum} is zero.
  
! The other use of @code{subreg} is to extract the individual registers
  of a multi-register value.  Machine modes such as @code{DImode} and
  @code{EPmode} indicate values longer than a word, values which usually
  require two consecutive registers.  To access one of the registers,
! use a @code{subreg} with mode @code{SImode} and a @var{wordnum} that
  says which register.
  
***************
*** 4215,4224 ****
  
  Between the combiner pass and the reload pass, it is possible to have
! a @samp{subreg} which contains a @samp{mem} instead of a @samp{reg} as
  its first operand.  The reload pass eliminates these cases by
! reloading the @samp{mem} into a suitable register.
  
  Note that it is not valid to access a @code{DFmode} value in @code{SFmode}
! using a @samp{subreg}.  On some machines the most significant part of a
  @code{DFmode} value does not have the same format as a single-precision
  floating value.
--- 4605,4614 ----
  
  Between the combiner pass and the reload pass, it is possible to have
! a @code{subreg} which contains a @code{mem} instead of a @code{reg} as
  its first operand.  The reload pass eliminates these cases by
! reloading the @code{mem} into a suitable register.
  
  Note that it is not valid to access a @code{DFmode} value in @code{SFmode}
! using a @code{subreg}.  On some machines the most significant part of a
  @code{DFmode} value does not have the same format as a single-precision
  floating value.
***************
*** 4229,4238 ****
  only two contexts: as the destination of an assignment (in test and
  compare instructions) and in comparison operators comparing against
! zero (@samp{const_int} with value zero; that is to say,
  @code{const0_rtx}).
  
! There is only one expression object of code @samp{cc0}; it is the
  value of the variable @code{cc0_rtx}.  Any attempt to create an
! expression of code @samp{cc0} will return @code{cc0_rtx}.
  
  One special thing about the condition code register is that
--- 4619,4628 ----
  only two contexts: as the destination of an assignment (in test and
  compare instructions) and in comparison operators comparing against
! zero (@code{const_int} with value zero; that is to say,
  @code{const0_rtx}).
  
! There is only one expression object of code @code{cc0}; it is the
  value of the variable @code{cc0_rtx}.  Any attempt to create an
! expression of code @code{cc0} will return @code{cc0_rtx}.
  
  One special thing about the condition code register is that
***************
*** 4251,4257 ****
  certain specific contexts in jump instructions.
  
! There is only one expression object of code @samp{pc}; it is the value
  of the variable @code{pc_rtx}.  Any attempt to create an expression of
! code @samp{pc} will return @code{pc_rtx}.
  
  All instructions that do not jump alter the program counter implicitly
--- 4641,4647 ----
  certain specific contexts in jump instructions.
  
! There is only one expression object of code @code{pc}; it is the value
  of the variable @code{pc_rtx}.  Any attempt to create an expression of
! code @code{pc} will return @code{pc_rtx}.
  
  All instructions that do not jump alter the program counter implicitly
***************
*** 4274,4278 ****
  
  @item (minus:@var{m} @var{x} @var{y})
! Like @samp{plus} but represents subtraction.
  
  @item (compare @var{x} @var{y})
--- 4664,4668 ----
  
  @item (minus:@var{m} @var{x} @var{y})
! Like @code{plus} but represents subtraction.
  
  @item (compare @var{x} @var{y})
***************
*** 4279,4283 ****
  Represents the result of subtracting @var{y} from @var{x}
  for purposes of comparison.  The absence of a machine mode
! in the @samp{compare} expression indicates that the result is
  computed without overflow, as if with infinite precision.
  
--- 4669,4673 ----
  Represents the result of subtracting @var{y} from @var{x}
  for purposes of comparison.  The absence of a machine mode
! in the @code{compare} expression indicates that the result is
  computed without overflow, as if with infinite precision.
  
***************
*** 4304,4314 ****
  support one but not the other.@refill
  
! @samp{mult} may be used for floating point multiplication as well.
  Then @var{m} is a floating point machine mode.
  
  @item (umult:@var{m} @var{x} @var{y})
! Like @samp{mult} but represents unsigned multiplication.  It may be
! used in both same-size and widening forms, like @samp{mult}.
! @samp{umult} is used only for fixed-point multiplication.
  
  @item (div:@var{m} @var{x} @var{y})
--- 4694,4704 ----
  support one but not the other.@refill
  
! @code{mult} may be used for floating point multiplication as well.
  Then @var{m} is a floating point machine mode.
  
  @item (umult:@var{m} @var{x} @var{y})
! Like @code{mult} but represents unsigned multiplication.  It may be
! used in both same-size and widening forms, like @code{mult}.
! @code{umult} is used only for fixed-point multiplication.
  
  @item (div:@var{m} @var{x} @var{y})
***************
*** 4319,4331 ****
  this is ordinary size-preserving division.  Some machines have
  division instructions in which the operands and quotient widths are
! not all the same; such instructions are represented by @samp{div}
  expressions in which the machine modes are not all the same.
  
  @item (udiv:@var{m} @var{x} @var{y})
! Like @samp{div} but represents unsigned division.
  
  @item (mod:@var{m} @var{x} @var{y})
  @itemx (umod:@var{m} @var{x} @var{y})
! Like @samp{div} and @samp{udiv} but represent the remainder instead of
  the quotient.
  
--- 4709,4721 ----
  this is ordinary size-preserving division.  Some machines have
  division instructions in which the operands and quotient widths are
! not all the same; such instructions are represented by @code{div}
  expressions in which the machine modes are not all the same.
  
  @item (udiv:@var{m} @var{x} @var{y})
! Like @code{div} but represents unsigned division.
  
  @item (mod:@var{m} @var{x} @var{y})
  @itemx (umod:@var{m} @var{x} @var{y})
! Like @code{div} and @code{udiv} but represent the remainder instead of
  the quotient.
  
***************
*** 4369,4377 ****
  
  @item (ashift:@var{m} @var{x} @var{c})
! Like @samp{lshift} but for arithmetic left shift.
  
  @item (lshiftrt:@var{m} @var{x} @var{c})
  @itemx (ashiftrt:@var{m} @var{x} @var{c})
! Like @samp{lshift} and @samp{ashift} but for right shift.
  
  @item (rotate:@var{m} @var{x} @var{c})
--- 4759,4767 ----
  
  @item (ashift:@var{m} @var{x} @var{c})
! Like @code{lshift} but for arithmetic left shift.
  
  @item (lshiftrt:@var{m} @var{x} @var{c})
  @itemx (ashiftrt:@var{m} @var{x} @var{c})
! Like @code{lshift} and @code{ashift} but for right shift.
  
  @item (rotate:@var{m} @var{x} @var{c})
***************
*** 4407,4411 ****
  
  Inequality comparisons come in two flavors, signed and unsigned.  Thus,
! there are distinct expression codes @samp{gt} and @samp{gtu} for signed and
  unsigned greater-than.  These can produce different results for the same
  pair of integer values: for example, 1 is signed greater-than -1 but not
--- 4797,4801 ----
  
  Inequality comparisons come in two flavors, signed and unsigned.  Thus,
! there are distinct expression codes @code{gt} and @code{gtu} for signed and
  unsigned greater-than.  These can produce different results for the same
  pair of integer values: for example, 1 is signed greater-than -1 but not
***************
*** 4439,4455 ****
  
  @item (gtu @var{x} @var{y})
! Like @samp{gt} but does unsigned comparison, on fixed-point numbers only.
  
  @item (lt @var{x} @var{y})
  @item (ltu @var{x} @var{y})
! Like @samp{gt} and @samp{gtu} but test for ``less than''.
  
  @item (ge @var{x} @var{y})
  @item (geu @var{x} @var{y})
! Like @samp{gt} and @samp{gtu} but test for ``greater than or equal''.
  
  @item (le @var{x} @var{y})
  @item (leu @var{x} @var{y})
! Like @samp{gt} and @samp{gtu} but test for ``less than or equal''.
  
  @item (if_then_else @var{cond} @var{then} @var{else})
--- 4829,4845 ----
  
  @item (gtu @var{x} @var{y})
! Like @code{gt} but does unsigned comparison, on fixed-point numbers only.
  
  @item (lt @var{x} @var{y})
  @item (ltu @var{x} @var{y})
! Like @code{gt} and @code{gtu} but test for ``less than''.
  
  @item (ge @var{x} @var{y})
  @item (geu @var{x} @var{y})
! Like @code{gt} and @code{gtu} but test for ``greater than or equal''.
  
  @item (le @var{x} @var{y})
  @item (leu @var{x} @var{y})
! Like @code{gt} and @code{gtu} but test for ``less than or equal''.
  
  @item (if_then_else @var{cond} @var{then} @var{else})
***************
*** 4460,4464 ****
  represented by @var{then} and the one represented by @var{else}.
  
! On most machines, @samp{if_then_else} expressions are valid only
  to express conditional jumps.
  @end table
--- 4850,4854 ----
  represented by @var{then} and the one represented by @var{else}.
  
! On most machines, @code{if_then_else} expressions are valid only
  to express conditional jumps.
  @end table
***************
*** 4485,4489 ****
  
  @item (zero_extract:SI @var{loc} @var{size} @var{pos})
! Like @samp{sign_extract} but refers to an unsigned or zero-extended
  bit field.  The same sequence of bits are extracted, but they
  are filled to an entire word with zeros instead of by sign-extension.
--- 4875,4879 ----
  
  @item (zero_extract:SI @var{loc} @var{size} @var{pos})
! Like @code{sign_extract} but refers to an unsigned or zero-extended
  bit field.  The same sequence of bits are extracted, but they
  are filled to an entire word with zeros instead of by sign-extension.
***************
*** 4496,4500 ****
  explicit conversion operations.  For example, an expression
  which is the sum of a byte and a full word cannot be written as
! @code{(plus:SI (reg:QI 34) (reg:SI 80))} because the @samp{plus}
  operation requires two operands of the same machine mode.
  Therefore, the byte-sized operand is enclosed in a conversion
--- 4886,4890 ----
  explicit conversion operations.  For example, an expression
  which is the sum of a byte and a full word cannot be written as
! @code{(plus:SI (reg:QI 34) (reg:SI 80))} because the @code{plus}
  operation requires two operands of the same machine mode.
  Therefore, the byte-sized operand is enclosed in a conversion
***************
*** 4571,4578 ****
  @item (strict_low_part (subreg:@var{m} (reg:@var{n} @var{r}) 0))
  This expression code is used in only one context: operand 0 of a
! @samp{set} expression.  In addition, the operand of this expression
! must be a @samp{subreg} expression.
  
! The presence of @samp{strict_low_part} says that the part of the
  register which is meaningful in mode @var{n}, but is not part of
  mode @var{m}, is not to be altered.  Normally, an assignment to such
--- 4961,4968 ----
  @item (strict_low_part (subreg:@var{m} (reg:@var{n} @var{r}) 0))
  This expression code is used in only one context: operand 0 of a
! @code{set} expression.  In addition, the operand of this expression
! must be a @code{subreg} expression.
  
! The presence of @code{strict_low_part} says that the part of the
  register which is meaningful in mode @var{n}, but is not part of
  mode @var{m}, is not to be altered.  Normally, an assignment to such
***************
*** 4597,4617 ****
  Represents the action of storing the value of @var{x} into the place
  represented by @var{lval}.  @var{lval} must be an expression
! representing a place that can be stored in: @samp{reg} (or
! @samp{subreg} or @samp{strict_low_part}), @samp{mem}, @samp{pc} or
! @samp{cc0}.@refill
  
! If @var{lval} is a @samp{reg}, @samp{subreg} or @samp{mem}, it has a
  machine mode; then @var{x} must be valid for that mode.@refill
  
! If @var{lval} is a @samp{reg} whose machine mode is less than the full
  width of the register, then it means that the part of the register
  specified by the machine mode is given the specified value and the
  rest of the register receives an undefined value.  Likewise, if
! @var{lval} is a @samp{subreg} whose machine mode is narrower than
  @code{SImode}, the rest of the register can be changed in an undefined way.
  
! If @var{lval} is a @samp{strict_low_part} of a @samp{subreg}, then the
  part of the register specified by the machine mode of the
! @samp{subreg} is given the value @var{x} and the rest of the register
  is not changed.@refill
  
--- 4987,5007 ----
  Represents the action of storing the value of @var{x} into the place
  represented by @var{lval}.  @var{lval} must be an expression
! representing a place that can be stored in: @code{reg} (or
! @code{subreg} or @code{strict_low_part}), @code{mem}, @code{pc} or
! @code{cc0}.@refill
  
! If @var{lval} is a @code{reg}, @code{subreg} or @code{mem}, it has a
  machine mode; then @var{x} must be valid for that mode.@refill
  
! If @var{lval} is a @code{reg} whose machine mode is less than the full
  width of the register, then it means that the part of the register
  specified by the machine mode is given the specified value and the
  rest of the register receives an undefined value.  Likewise, if
! @var{lval} is a @code{subreg} whose machine mode is narrower than
  @code{SImode}, the rest of the register can be changed in an undefined way.
  
! If @var{lval} is a @code{strict_low_part} of a @code{subreg}, then the
  part of the register specified by the machine mode of the
! @code{subreg} is given the value @var{x} and the rest of the register
  is not changed.@refill
  
***************
*** 4621,4631 ****
  If @var{lval} is @code{(pc)}, we have a jump instruction, and the
  possibilities for @var{x} are very limited.  It may be a
! @samp{label_ref} expression (unconditional jump).  It may be an
! @samp{if_then_else} (conditional jump), in which case either the
  second or the third operand must be @code{(pc)} (for the case which
! does not jump) and the other of the two must be a @samp{label_ref}
! (for the case which does jump).  @var{x} may also be a @samp{mem} or
! @code{(plus:SI (pc) @var{y})}, where @var{y} may be a @samp{reg} or a
! @samp{mem}; these unusual patterns are used to represent jumps through
  branch tables.@refill
  
--- 5011,5021 ----
  If @var{lval} is @code{(pc)}, we have a jump instruction, and the
  possibilities for @var{x} are very limited.  It may be a
! @code{label_ref} expression (unconditional jump).  It may be an
! @code{if_then_else} (conditional jump), in which case either the
  second or the third operand must be @code{(pc)} (for the case which
! does not jump) and the other of the two must be a @code{label_ref}
! (for the case which does jump).  @var{x} may also be a @code{mem} or
! @code{(plus:SI (pc) @var{y})}, where @var{y} may be a @code{reg} or a
! @code{mem}; these unusual patterns are used to represent jumps through
  branch tables.@refill
  
***************
*** 4635,4643 ****
  multi-instruction ``epilogue'' must be executed in order to return
  from the function, returning is done by jumping to a label which
! precedes the epilogue, and the @samp{return} expression code is never
  used.
  
  @item (call @var{function} @var{nargs})
! Represents a function call.  @var{function} is a @samp{mem} expression
  whose address is the address of the function to be called.
  @var{nargs} is an expression which can be used for two purposes: on
--- 5025,5033 ----
  multi-instruction ``epilogue'' must be executed in order to return
  from the function, returning is done by jumping to a label which
! precedes the epilogue, and the @code{return} expression code is never
  used.
  
  @item (call @var{function} @var{nargs})
! Represents a function call.  @var{function} is a @code{mem} expression
  whose address is the address of the function to be called.
  @var{nargs} is an expression which can be used for two purposes: on
***************
*** 4654,4659 ****
  @item (clobber @var{x})
  Represents the storing or possible storing of an unpredictable,
! undescribed value into @var{x}, which must be a @samp{reg} or
! @samp{mem} expression.
  
  One place this is used is in string instructions that store standard
--- 5044,5049 ----
  @item (clobber @var{x})
  Represents the storing or possible storing of an unpredictable,
! undescribed value into @var{x}, which must be a @code{reg} or
! @code{mem} expression.
  
  One place this is used is in string instructions that store standard
***************
*** 4670,4679 ****
  ``call-clobbered''.  All function call instructions are assumed by
  default to clobber these registers, so there is no need to use
! @samp{clobber} expressions to indicate this fact.  Also, each function
  call is assumed to have the potential to alter any memory location,
  unless the function is declared @code{const}.
  
! When a @samp{clobber} expression for a register appears inside a
! @samp{parallel} with other side effects, GNU CC guarantees that the
  register is unoccupied both before and after that insn.  Therefore, it
  is safe for the assembler code produced by the insn to use the
--- 5060,5069 ----
  ``call-clobbered''.  All function call instructions are assumed by
  default to clobber these registers, so there is no need to use
! @code{clobber} expressions to indicate this fact.  Also, each function
  call is assumed to have the potential to alter any memory location,
  unless the function is declared @code{const}.
  
! When a @code{clobber} expression for a register appears inside a
! @code{parallel} with other side effects, GNU CC guarantees that the
  register is unoccupied both before and after that insn.  Therefore, it
  is safe for the assembler code produced by the insn to use the
***************
*** 4683,4686 ****
--- 5073,5085 ----
  temporary.
  
+ If you clobber a pseudo register in this way, use a pseudo register
+ which appears nowhere else---generate a new one each time.  Otherwise,
+ you may confuse CSE.
+ 
+ There is one other known use for clobbering a pseudo register in a
+ @code{parallel}: when one of the input operands of the insn is also
+ clobbered by the insn.  In this case, using the same pseudo register in
+ the clobber and elsewhere in the insn produces the expected results.
+ 
  @item (use @var{x})
  Represents the use of the value of @var{x}.  It indicates that the
***************
*** 4688,4699 ****
  it may not be apparent why this is so.  Therefore, the compiler will
  not attempt to delete previous instructions whose only effect is to
! store a value in @var{x}.  @var{x} must be a @samp{reg} expression.
  
  @item (parallel [@var{x0} @var{x1} @dots{}])
  Represents several side effects performed in parallel.  The square
! brackets stand for a vector; the operand of @samp{parallel} is a
  vector of expressions.  @var{x0}, @var{x1} and so on are individual
! side effect expressions---expressions of code @samp{set}, @samp{call},
! @samp{return}, @samp{clobber} or @samp{use}.@refill
  
  ``In parallel'' means that first all the values used in the individual
--- 5087,5098 ----
  it may not be apparent why this is so.  Therefore, the compiler will
  not attempt to delete previous instructions whose only effect is to
! store a value in @var{x}.  @var{x} must be a @code{reg} expression.
  
  @item (parallel [@var{x0} @var{x1} @dots{}])
  Represents several side effects performed in parallel.  The square
! brackets stand for a vector; the operand of @code{parallel} is a
  vector of expressions.  @var{x0}, @var{x1} and so on are individual
! side effect expressions---expressions of code @code{set}, @code{call},
! @code{return}, @code{clobber} or @code{use}.@refill
  
  ``In parallel'' means that first all the values used in the individual
***************
*** 4712,4717 ****
  in register 1 @emph{before} the execution of the insn.
  
! It follows that it is @emph{incorrect} to use @samp{parallel} and
! expect the result of one @samp{set} to be available for the next one.
  For example, people sometimes attempt to represent a jump-if-zero
  instruction this way:
--- 5111,5116 ----
  in register 1 @emph{before} the execution of the insn.
  
! It follows that it is @emph{incorrect} to use @code{parallel} and
! expect the result of one @code{set} to be available for the next one.
  For example, people sometimes attempt to represent a jump-if-zero
  instruction this way:
***************
*** 4731,4737 ****
  
  Peephole optimization, which takes place in together with final assembly
! code output, can produce insns whose patterns consist of a @samp{parallel}
  whose elements are the operands needed to output the resulting
! assembler code--often @samp{reg}, @samp{mem} or constant expressions.
  This would not be well-formed RTL at any other stage in compilation,
  but it is ok then because no further optimization remains to be done.
--- 5130,5136 ----
  
  Peephole optimization, which takes place in together with final assembly
! code output, can produce insns whose patterns consist of a @code{parallel}
  whose elements are the operands needed to output the resulting
! assembler code---often @code{reg}, @code{mem} or constant expressions.
  This would not be well-formed RTL at any other stage in compilation,
  but it is ok then because no further optimization remains to be done.
***************
*** 4742,4753 ****
  Represents a sequence of insns.  Each of the @var{insns} that appears
  in the vector is suitable for appearing in the chain of insns, so it
! must be an @samp{insn}, @samp{jump_insn}, @samp{call_insn},
! @samp{code_label}, @samp{barrier} or @samp{note}.
  
! A @samp{sequence} RTX never appears in an actual insn.  It represents
! the sequence of insns that result from a @samp{define_expand}
  @emph{before} those insns are passed to @code{emit_insn} to insert
  them in the chain of insns.  When actually inserted, the individual
! sub-insns are separated out and the @samp{sequence} is forgotten.
  @end table
  
--- 5141,5152 ----
  Represents a sequence of insns.  Each of the @var{insns} that appears
  in the vector is suitable for appearing in the chain of insns, so it
! must be an @code{insn}, @code{jump_insn}, @code{call_insn},
! @code{code_label}, @code{barrier} or @code{note}.
  
! A @code{sequence} RTX never appears in an actual insn.  It represents
! the sequence of insns that result from a @code{define_expand}
  @emph{before} those insns are passed to @code{emit_insn} to insert
  them in the chain of insns.  When actually inserted, the individual
! sub-insns are separated out and the @code{sequence} is forgotten.
  @end table
  
***************
*** 4761,4765 ****
  @item (addr_vec:@var{m} [@var{lr0} @var{lr1} @dots{}])
  Represents a table of jump addresses.  The vector elements @var{lr0},
! etc., are @samp{label_ref} expressions.  The mode @var{m} specifies
  how much space is given to each address; normally @var{m} would be
  @code{Pmode}.
--- 5160,5164 ----
  @item (addr_vec:@var{m} [@var{lr0} @var{lr1} @dots{}])
  Represents a table of jump addresses.  The vector elements @var{lr0},
! etc., are @code{label_ref} expressions.  The mode @var{m} specifies
  how much space is given to each address; normally @var{m} would be
  @code{Pmode}.
***************
*** 4767,4771 ****
  @item (addr_diff_vec:@var{m} @var{base} [@var{lr0} @var{lr1} @dots{}])
  Represents a table of jump addresses expressed as offsets from
! @var{base}.  The vector elements @var{lr0}, etc., are @samp{label_ref}
  expressions and so is @var{base}.  The mode @var{m} specifies how much
  space is given to each address-difference.@refill
--- 5166,5170 ----
  @item (addr_diff_vec:@var{m} @var{base} [@var{lr0} @var{lr1} @dots{}])
  Represents a table of jump addresses expressed as offsets from
! @var{base}.  The vector elements @var{lr0}, etc., are @code{label_ref}
  expressions and so is @var{base}.  The mode @var{m} specifies how much
  space is given to each address-difference.@refill
***************
*** 4781,4786 ****
  Represents the side effect of decrementing @var{x} by a standard
  amount and represents also the value that @var{x} has after being
! decremented.  @var{x} must be a @samp{reg} or @samp{mem}, but most
! machines allow only a @samp{reg}.  @var{m} must be the machine mode
  for pointers on the machine in use.  The amount @var{x} is decremented
  by is the length in bytes of the machine mode of the containing memory
--- 5180,5185 ----
  Represents the side effect of decrementing @var{x} by a standard
  amount and represents also the value that @var{x} has after being
! decremented.  @var{x} must be a @code{reg} or @code{mem}, but most
! machines allow only a @code{reg}.  @var{m} must be the machine mode
  for pointers on the machine in use.  The amount @var{x} is decremented
  by is the length in bytes of the machine mode of the containing memory
***************
*** 4800,4804 ****
  
  @item (post_dec:@var{m} @var{x})
! Represents the same side effect as @samp{pre_decrement} but a different
  value.  The value represented here is the value @var{x} has @i{before}
  being decremented.
--- 5199,5203 ----
  
  @item (post_dec:@var{m} @var{x})
! Represents the same side effect as @code{pre_dec} but a different
  value.  The value represented here is the value @var{x} has @i{before}
  being decremented.
***************
*** 4821,4826 ****
  
  An instruction that can be represented with an embedded side effect
! could also be represented using @samp{parallel} containing an additional
! @samp{set} to describe how the address register is altered.  This is not
  done because machines that allow these operations at all typically
  allow them wherever a memory address is called for.  Describing them as
--- 5220,5225 ----
  
  An instruction that can be represented with an embedded side effect
! could also be represented using @code{parallel} containing an additional
! @code{set} to describe how the address register is altered.  This is not
  done because machines that allow these operations at all typically
  allow them wherever a memory address is called for.  Describing them as
***************
*** 4831,4835 ****
  @section Assembler Instructions as Expressions
  
! The RTX code @samp{asm_operands} represents a value produced by a
  user-specified assembler instruction.  It is used to represent
  an @code{asm} statement with arguments.  An @code{asm} statement with
--- 5230,5234 ----
  @section Assembler Instructions as Expressions
  
! The RTX code @code{asm_operands} represents a value produced by a
  user-specified assembler instruction.  It is used to represent
  an @code{asm} statement with arguments.  An @code{asm} statement with
***************
*** 4841,4845 ****
  
  @noindent
! is represented using a single @samp{asm_operands} RTX which represents
  the value that is stored in @code{outputvar}:
  
--- 5240,5244 ----
  
  @noindent
! is represented using a single @code{asm_operands} RTX which represents
  the value that is stored in @code{outputvar}:
  
***************
*** 4853,4857 ****
  
  @noindent
! Here the operands of the @samp{asm_operands} RTX are the assembler
  template string, the output-operand's constraint, the index-number of the
  output operand among the output operands specified, a vector of input
--- 5252,5256 ----
  
  @noindent
! Here the operands of the @code{asm_operands} RTX are the assembler
  template string, the output-operand's constraint, the index-number of the
  output operand among the output operands specified, a vector of input
***************
*** 4861,4866 ****
  
  When an @code{asm} statement has multiple output values, its insn has
! several such @samp{set} RTX's inside of a @samp{parallel}.  Each @samp{set}
! contains a @samp{asm_operands}; all of these share the same assembler
  template and vectors, but each contains the constraint for the respective
  output operand.  They are also distinguished by the output-operand index
--- 5260,5265 ----
  
  When an @code{asm} statement has multiple output values, its insn has
! several such @code{set} RTX's inside of a @code{parallel}.  Each @code{set}
! contains a @code{asm_operands}; all of these share the same assembler
  template and vectors, but each contains the constraint for the respective
  output operand.  They are also distinguished by the output-operand index
***************
*** 4909,4916 ****
  Every insn has one of the following six expression codes:
  
! @table @samp
  @item insn
! The expression code @samp{insn} is used for instructions that do not jump
! and do not do function calls.  Insns with code @samp{insn} have four
  additional fields beyond the three mandatory ones listed above.
  These four are described in a table below.
--- 5308,5315 ----
  Every insn has one of the following six expression codes:
  
! @table @code
  @item insn
! The expression code @code{insn} is used for instructions that do not jump
! and do not do function calls.  Insns with code @code{insn} have four
  additional fields beyond the three mandatory ones listed above.
  These four are described in a table below.
***************
*** 4917,4927 ****
  
  @item jump_insn
! The expression code @samp{jump_insn} is used for instructions that may jump
! (or, more generally, may contain @samp{label_ref} expressions).
! @samp{jump_insn} insns have the same extra fields as @samp{insn} insns,
  accessed in the same way.
  
  @item call_insn
! The expression code @samp{call_insn} is used for instructions that may do
  function calls.  It is important to distinguish these instructions because
  they imply that certain registers and memory locations may be altered
--- 5316,5326 ----
  
  @item jump_insn
! The expression code @code{jump_insn} is used for instructions that may jump
! (or, more generally, may contain @code{label_ref} expressions).
! @code{jump_insn} insns have the same extra fields as @code{insn} insns,
  accessed in the same way.
  
  @item call_insn
! The expression code @code{call_insn} is used for instructions that may do
  function calls.  It is important to distinguish these instructions because
  they imply that certain registers and memory locations may be altered
***************
*** 4928,4936 ****
  unpredictably.
  
! @samp{call_insn} insns have the same extra fields as @samp{insn} insns,
  accessed in the same way.
  
  @item code_label
! A @samp{code_label} insn represents a label that a jump insn can jump to.
  It contains one special field of data in addition to the three standard ones.
  It is used to hold the @dfn{label number}, a number that identifies this
--- 5327,5335 ----
  unpredictably.
  
! @code{call_insn} insns have the same extra fields as @code{insn} insns,
  accessed in the same way.
  
  @item code_label
! A @code{code_label} insn represents a label that a jump insn can jump to.
  It contains one special field of data in addition to the three standard ones.
  It is used to hold the @dfn{label number}, a number that identifies this
***************
*** 4945,4949 ****
  
  @item note
! @samp{note} insns are used to represent additional debugging and
  declarative information.  They contain two nonstandard fields, an
  integer which is accessed with the macro @code{NOTE_LINE_NUMBER} and a
--- 5344,5348 ----
  
  @item note
! @code{note} insns are used to represent additional debugging and
  declarative information.  They contain two nonstandard fields, an
  integer which is accessed with the macro @code{NOTE_LINE_NUMBER} and a
***************
*** 4993,4998 ****
  reload pass sets it to @code{QImode} if the insn needs reloading.
  
! Here is a table of the extra fields of @samp{insn}, @samp{jump_insn}
! and @samp{call_insn} insns:
  
  @table @code
--- 5392,5397 ----
  reload pass sets it to @code{QImode} if the insn needs reloading.
  
! Here is a table of the extra fields of @code{insn}, @code{jump_insn}
! and @code{call_insn} insns:
  
  @table @code
***************
*** 5005,5013 ****
  
  Such matching is never attempted and this field is not used on an insn
! whose pattern consists of a single @samp{use}, @samp{clobber},
! @samp{asm}, @samp{addr_vec} or @samp{addr_diff_vec} expression.
  
  @item LOG_LINKS (@var{i})
! A list (chain of @samp{insn_list} expressions) of previous ``related''
  insns: insns which store into registers values that are used for the
  first time in this insn.  (An additional constraint is that neither a
--- 5404,5412 ----
  
  Such matching is never attempted and this field is not used on an insn
! whose pattern consists of a single @code{use}, @code{clobber},
! @code{asm}, @code{addr_vec} or @code{addr_diff_vec} expression.
  
  @item LOG_LINKS (@var{i})
! A list (chain of @code{insn_list} expressions) of previous ``related''
  insns: insns which store into registers values that are used for the
  first time in this insn.  (An additional constraint is that neither a
***************
*** 5016,5020 ****
  
  @item REG_NOTES (@var{i})
! A list (chain of @samp{expr_list} expressions) giving information
  about the usage of registers in this insn.  This list is set up by the
  flow analysis pass; it is a null pointer until then.
--- 5415,5419 ----
  
  @item REG_NOTES (@var{i})
! A list (chain of @code{expr_list} expressions) giving information
  about the usage of registers in this insn.  This list is set up by the
  flow analysis pass; it is a null pointer until then.
***************
*** 5021,5038 ****
  @end table
  
! The @code{LOG_LINKS} field of an insn is a chain of @samp{insn_list}
  expressions.  Each of these has two operands: the first is an insn,
! and the second is another @samp{insn_list} expression (the next one in
! the chain).  The last @samp{insn_list} in the chain has a null pointer
  as second operand.  The significant thing about the chain is which
! insns appear in it (as first operands of @samp{insn_list}
  expressions).  Their order is not significant.
  
  The @code{REG_NOTES} field of an insn is a similar chain but of
! @samp{expr_list} expressions instead of @samp{insn_list}.  There are
  several kinds of register notes, which are distinguished by the machine
! mode of the @samp{expr_list}, which in a register note is really
  understood as being an @code{enum reg_note}.  The first operand @var{op}
! of the @samp{expr_list} is data whose meaning depends on the kind of
  note.  Here are the kinds of register note:
  
--- 5420,5437 ----
  @end table
  
! The @code{LOG_LINKS} field of an insn is a chain of @code{insn_list}
  expressions.  Each of these has two operands: the first is an insn,
! and the second is another @code{insn_list} expression (the next one in
! the chain).  The last @code{insn_list} in the chain has a null pointer
  as second operand.  The significant thing about the chain is which
! insns appear in it (as first operands of @code{insn_list}
  expressions).  Their order is not significant.
  
  The @code{REG_NOTES} field of an insn is a similar chain but of
! @code{expr_list} expressions instead of @code{insn_list}.  There are
  several kinds of register notes, which are distinguished by the machine
! mode of the @code{expr_list}, which in a register note is really
  understood as being an @code{enum reg_note}.  The first operand @var{op}
! of the @code{expr_list} is data whose meaning depends on the kind of
  note.  Here are the kinds of register note:
  
***************
*** 5046,5051 ****
  The register @var{op} is incremented (or decremented; at this level
  there is no distinction) by an embedded side effect inside this insn.
! This means it appears in a @code{POST_INC}, @code{PRE_INC},
! @code{POST_DEC} or @code{PRE_DEC} RTX.
  
  @item REG_EQUIV
--- 5445,5450 ----
  The register @var{op} is incremented (or decremented; at this level
  there is no distinction) by an embedded side effect inside this insn.
! This means it appears in a @code{post_inc}, @code{pre_inc},
! @code{post_dec} or @code{pre_dec} RTX.
  
  @item REG_EQUIV
***************
*** 5102,5112 ****
  @end table
  
! For convenience, the machine mode in an @samp{insn_list} or
! @samp{expr_list} is printed using these symbolic codes in debugging dumps.
  
! The only difference between the expression codes @samp{insn_list} and
! @samp{expr_list} is that the first operand of an @samp{insn_list} is
  assumed to be an insn and is printed in debugging dumps as the insn's
! unique id; the first operand of an @samp{expr_list} is printed in the
  ordinary way as an expression.
  
--- 5501,5511 ----
  @end table
  
! For convenience, the machine mode in an @code{insn_list} or
! @code{expr_list} is printed using these symbolic codes in debugging dumps.
  
! The only difference between the expression codes @code{insn_list} and
! @code{expr_list} is that the first operand of an @code{insn_list} is
  assumed to be an insn and is printed in debugging dumps as the insn's
! unique id; the first operand of an @code{expr_list} is printed in the
  ordinary way as an expression.
  
***************
*** 5114,5122 ****
  @section RTL Representation of Function-Call Insns
  
! Insns that call subroutines have the RTL expression code @samp{call_insn}.
  These insns must satisfy special rules, and their bodies must use a special
! RTL expression code, @samp{call}.
  
! A @samp{call} expression has two operands, as follows:
  
  @example
--- 5513,5521 ----
  @section RTL Representation of Function-Call Insns
  
! Insns that call subroutines have the RTL expression code @code{call_insn}.
  These insns must satisfy special rules, and their bodies must use a special
! RTL expression code, @code{call}.
  
! A @code{call} expression has two operands, as follows:
  
  @example
***************
*** 5131,5135 ****
  subroutine.
  
! For a subroutine that returns no value, the @samp{call} RTX as shown above
  is the entire body of the insn.
  
--- 5530,5534 ----
  subroutine.
  
! For a subroutine that returns no value, the @code{call} RTX as shown above
  is the entire body of the insn.
  
***************
*** 5169,5173 ****
  @noindent
  Between the call insn and this following insn there may intervene only a
! stack-adjustment insn (and perhaps some @samp{note} insns).
  
  When a subroutine returns a @code{BLKmode} value, it is handled by
--- 5568,5572 ----
  @noindent
  Between the call insn and this following insn there may intervene only a
! stack-adjustment insn (and perhaps some @code{note} insns).
  
  When a subroutine returns a @code{BLKmode} value, it is handled by
***************
*** 5191,5213 ****
  @itemize @bullet
  @item
! Each pseudo-register has only a single @samp{reg} object to represent it,
  and therefore only a single machine mode.
  
  @item
! For any symbolic label, there is only one @samp{symbol_ref} object
  referring to it.
  
  @item
! There is only one @samp{const_int} expression with value zero,
  and only one with value one.
  
  @item
! There is only one @samp{pc} expression.
  
  @item
! There is only one @samp{cc0} expression.
  
  @item
! There is only one @samp{const_double} expression with mode
  @code{SFmode} and value zero, and only one with mode @code{DFmode} and
  value zero.
--- 5590,5612 ----
  @itemize @bullet
  @item
! Each pseudo-register has only a single @code{reg} object to represent it,
  and therefore only a single machine mode.
  
  @item
! For any symbolic label, there is only one @code{symbol_ref} object
  referring to it.
  
  @item
! There is only one @code{const_int} expression with value zero,
  and only one with value one.
  
  @item
! There is only one @code{pc} expression.
  
  @item
! There is only one @code{cc0} expression.
  
  @item
! There is only one @code{const_double} expression with mode
  @code{SFmode} and value zero, and only one with mode @code{DFmode} and
  value zero.
***************
*** 5214,5224 ****
  
  @item
! No @samp{label_ref} appears in more than one place in the RTL
  structure; in other words, it is safe to do a tree-walk of all the
! insns in the function and assume that each time a @samp{label_ref} is
  seen it is distinct from all others that are seen.
  
  @item
! Only one @samp{mem} object is normally created for each static
  variable or stack slot, so these objects are frequently shared in all
  the places they appear.  However, separate but equal objects for these
--- 5613,5623 ----
  
  @item
! No @code{label_ref} appears in more than one place in the RTL
  structure; in other words, it is safe to do a tree-walk of all the
! insns in the function and assume that each time a @code{label_ref} is
  seen it is distinct from all others that are seen.
  
  @item
! Only one @code{mem} object is normally created for each static
  variable or stack slot, so these objects are frequently shared in all
  the places they appear.  However, separate but equal objects for these
***************
*** 5249,5253 ****
  temporarily.  However, the shared structure is copied before the
  combiner is finished with the insn.  This is done by
! @code{copy_substitutions} in @samp{combine.c}.
  @end itemize
  
--- 5648,5652 ----
  temporarily.  However, the shared structure is copied before the
  combiner is finished with the insn.  This is done by
! @code{copy_substitutions} in @file{combine.c}.
  @end itemize
  
***************
*** 5268,5272 ****
  @menu
  * Patterns::            How to write instruction patterns.
! * Example::             An explained example of a @samp{define_insn} pattern.
  * RTL Template::        The RTL template defines what insns match a pattern.
  * Output Template::     The output template says how to make assembler code
--- 5667,5671 ----
  @menu
  * Patterns::            How to write instruction patterns.
! * Example::             An explained example of a @code{define_insn} pattern.
  * RTL Template::        The RTL template defines what insns match a pattern.
  * Output Template::     The output template says how to make assembler code
***************
*** 5290,5296 ****
  to be filled in later, operand constraints that restrict how the pieces can
  be filled in, and an output pattern or C code to generate the assembler
! output, all wrapped up in a @samp{define_insn} expression.
  
! A @samp{define_insn} is an RTL expression containing four or five operands:
  
  @enumerate
--- 5689,5695 ----
  to be filled in later, operand constraints that restrict how the pieces can
  be filled in, and an output pattern or C code to generate the assembler
! output, all wrapped up in a @code{define_insn} expression.
  
! A @code{define_insn} is an RTL expression containing four or five operands:
  
  @enumerate
***************
*** 5313,5318 ****
  The @dfn{RTL template} (@pxref{RTL Template}) is a vector of
  incomplete RTL expressions which show what the instruction should look
! like.  It is incomplete because it may contain @samp{match_operand}
! and @samp{match_dup} expressions that stand for operands of the
  instruction.
  
--- 5712,5717 ----
  The @dfn{RTL template} (@pxref{RTL Template}) is a vector of
  incomplete RTL expressions which show what the instruction should look
! like.  It is incomplete because it may contain @code{match_operand}
! and @code{match_dup} expressions that stand for operands of the
  instruction.
  
***************
*** 5319,5323 ****
  If the vector has only one element, that element is what the
  instruction should look like.  If the vector has multiple elements,
! then the instruction looks like a @samp{parallel} expression
  containing that many elements as described.
  
--- 5718,5722 ----
  If the vector has only one element, that element is what the
  instruction should look like.  If the vector has multiple elements,
! then the instruction looks like a @code{parallel} expression
  containing that many elements as described.
  
***************
*** 5357,5361 ****
  
  @node Example, RTL Template, Patterns, Machine Desc
! @section Example of @samp{define_insn}
  
  Here is an actual example of an instruction pattern, for the 68000/68020.
--- 5756,5760 ----
  
  @node Example, RTL Template, Patterns, Machine Desc
! @section Example of @code{define_insn}
  
  Here is an actual example of an instruction pattern, for the 68000/68020.
***************
*** 5399,5403 ****
  
  @table @code
! @item (match_operand:@var{m} @var{n} @var{testfn} @var{constraint})
  This expression is a placeholder for operand number @var{n} of
  the insn.  When constructing an insn, operand number @var{n}
--- 5798,5802 ----
  
  @table @code
! @item (match_operand:@var{m} @var{n} @var{pred} @var{constraint})
  This expression is a placeholder for operand number @var{n} of
  the insn.  When constructing an insn, operand number @var{n}
***************
*** 5404,5430 ****
  will be substituted at this point.  When matching an insn, whatever
  appears at this position in the insn will be taken as operand
! number @var{n}; but it must satisfy @var{testfn} or this instruction
  pattern will not match at all.
  
  Operand numbers must be chosen consecutively counting from zero in
! each instruction pattern.  There may be only one @samp{match_operand}
  expression in the pattern for each operand number.  Usually operands
! are numbered in the order of appearance in @samp{match_operand}
  expressions.
  
! @var{testfn} is a string that is the name of a C function that accepts
! two arguments, a machine mode and an expression.  During matching,
! the function will be called with @var{m} as the mode argument
! and the putative operand as the other argument.  If it returns zero,
! this instruction pattern fails to match.  @var{testfn} may be
! an empty string; then it means no test is to be done on the operand.
! 
! @var{constraint} is explained later (@pxref{Constraints}).
! 
! Most often, @var{testfn} is @code{"general_operand"}.  It checks
! that the putative operand is either a constant, a register or a
! memory reference, and that it is valid for mode @var{m}.
  
! For an operand that must be a register, @var{testfn} should be
  @code{"register_operand"}.  It would be valid to use
  @code{"general_operand"}, since the reload pass would copy any
--- 5803,5836 ----
  will be substituted at this point.  When matching an insn, whatever
  appears at this position in the insn will be taken as operand
! number @var{n}; but it must satisfy @var{pred} or this instruction
  pattern will not match at all.
  
  Operand numbers must be chosen consecutively counting from zero in
! each instruction pattern.  There may be only one @code{match_operand}
  expression in the pattern for each operand number.  Usually operands
! are numbered in the order of appearance in @code{match_operand}
  expressions.
  
! @var{pred} is a string that is the name of a C function that accepts
! two arguments, an expression and a machine mode.  During matching, the
! function will be called with the putative operand as the expression
! and @var{m} as the mode argument.  If it returns zero, this
! instruction pattern fails to match.  @var{pred} may be an empty
! string; then it means no test is to be done on the operand,
! so anything which occurs in this position is valid.
! 
! @var{constraint} controls reloading and the choice of the best register
! class to use for a value, as explained later (@pxref{Constraints}).
! 
! People are often unclear on the difference between the constraint and the
! predicate.  The predicate helps decide whether a given insn matches the
! pattern.  The constraint plays no role in this decision; instead, it
! controls various decisions in the case of an insn which does match.
! 
! Most often, @var{pred} is @code{"general_operand"}.  This function checks
! that the putative operand is either a constant, a register or a memory
! reference, and that it is valid for mode @var{m}.
  
! For an operand that must be a register, @var{pred} should be
  @code{"register_operand"}.  It would be valid to use
  @code{"general_operand"}, since the reload pass would copy any
***************
*** 5433,5437 ****
  best possible job.
  
! For an operand that must be a constant, either @var{testfn} should be
  @code{"immediate_operand"}, or the instruction pattern's extra
  condition should check for constants, or both.  You cannot expect the
--- 5839,5843 ----
  best possible job.
  
! For an operand that must be a constant, either @var{pred} should be
  @code{"immediate_operand"}, or the instruction pattern's extra
  condition should check for constants, or both.  You cannot expect the
***************
*** 5445,5453 ****
  insn.
  
! In construction, @samp{match_dup} behaves exactly like
! @samp{match_operand}: the operand is substituted into the insn being
! constructed.  But in matching, @samp{match_dup} behaves differently.
  It assumes that operand number @var{n} has already been determined by
! a @samp{match_operand} appearing earlier in the recognition template,
  and it matches only an identical-looking expression.
  
--- 5851,5859 ----
  insn.
  
! In construction, @code{match_dup} behaves exactly like
! @code{match_operand}: the operand is substituted into the insn being
! constructed.  But in matching, @code{match_dup} behaves differently.
  It assumes that operand number @var{n} has already been determined by
! a @code{match_operand} appearing earlier in the recognition template,
  and it matches only an identical-looking expression.
  
***************
*** 5496,5505 ****
  When this pattern does match, the two operands of the commutative
  operator are recorded as operands 3 and 4 of the insn.  (This is done
! by the two instances of @samp{match_operand}.)  Operand 2 of the insn
  will be the entire commutative expression: use @code{GET_CODE
  (operands[2])} to see which commutative operator was used.
  
! The machine mode @var{m} of @samp{match_operator} works like that of
! @samp{match_operand}: it is passed as the second argument to the
  predicate function, and that function is solely responsible for
  deciding whether the expression to be matched ``has'' that mode.
--- 5902,5911 ----
  When this pattern does match, the two operands of the commutative
  operator are recorded as operands 3 and 4 of the insn.  (This is done
! by the two instances of @code{match_operand}.)  Operand 2 of the insn
  will be the entire commutative expression: use @code{GET_CODE
  (operands[2])} to see which commutative operator was used.
  
! The machine mode @var{m} of @code{match_operator} works like that of
! @code{match_operand}: it is passed as the second argument to the
  predicate function, and that function is solely responsible for
  deciding whether the expression to be matched ``has'' that mode.
***************
*** 5512,5520 ****
  only its expression code matters.
  
! There is no way to specify constraints in @samp{match_operator}.  The
! operand of the insn which corresponds to the @samp{match_operator}
  never has any constraints because it is never reloaded as a whole.
  However, if parts of its @var{operands} are matched by
! @samp{match_operand} patterns, those parts may have constraints of
  their own.
  
--- 5918,5926 ----
  only its expression code matters.
  
! There is no way to specify constraints in @code{match_operator}.  The
! operand of the insn which corresponds to the @code{match_operator}
  never has any constraints because it is never reloaded as a whole.
  However, if parts of its @var{operands} are matched by
! @code{match_operand} patterns, those parts may have constraints of
  their own.
  
***************
*** 5526,5530 ****
  location.
  
! @samp{address} expressions never appear in RTL code, only in machine
  descriptions.  And they are used only in machine descriptions that do
  not use the operand constraint feature.  When operand constraints are
--- 5932,5936 ----
  location.
  
! @code{address} expressions never appear in RTL code, only in machine
  descriptions.  And they are used only in machine descriptions that do
  not use the operand constraint feature.  When operand constraints are
***************
*** 5535,5543 ****
  always the same on a given target machine (it is @code{Pmode}, which
  normally is @code{SImode}), so there is no point in mentioning it;
! thus, no machine mode is written in the @samp{address} expression.  If
  some day support is added for machines in which addresses of different
  kinds of objects appear differently or are used differently (such as
  the PDP-10), different formats would perhaps need different machine
! modes and these modes might be written in the @samp{address}
  expression.
  @end table
--- 5941,5949 ----
  always the same on a given target machine (it is @code{Pmode}, which
  normally is @code{SImode}), so there is no point in mentioning it;
! thus, no machine mode is written in the @code{address} expression.  If
  some day support is added for machines in which addresses of different
  kinds of objects appear differently or are used differently (such as
  the PDP-10), different formats would perhaps need different machine
! modes and these modes might be written in the @code{address}
  expression.
  @end table
***************
*** 5580,5584 ****
  does not use an operand.  Only one case is standard: @samp{%%} outputs a
  @samp{%} into the assembler code.  Other nonstandard cases can be
! defined in the @code{PRINT_OPERAND} macro.
  
  The template may generate multiple assembler instructions.  Write the text
--- 5986,5992 ----
  does not use an operand.  Only one case is standard: @samp{%%} outputs a
  @samp{%} into the assembler code.  Other nonstandard cases can be
! defined in the @code{PRINT_OPERAND} macro.  You must also define
! which punctuation characters are valid with the
! @code{PRINT_OPERAND_PUNCT_VALID_P} macro.
  
  The template may generate multiple assembler instructions.  Write the text
***************
*** 5652,5656 ****
  @section Operand Constraints
  
! Each @samp{match_operand} in an instruction pattern can specify a
  constraint for the type of operands allowed.  Constraints can say whether
  an operand may be in a register, and which kinds of register; whether the
--- 6060,6064 ----
  @section Operand Constraints
  
! Each @code{match_operand} in an instruction pattern can specify a
  constraint for the type of operands allowed.  Constraints can say whether
  an operand may be in a register, and which kinds of register; whether the
***************
*** 5681,5685 ****
  @item @samp{o}
  A memory operand is allowed, but only if the address is
! @dfn{offsetable}.  This means that adding a small integer (actually,
  the width in bytes of the operand, as determined by its machine mode)
  may be added to the address and the result is also a valid memory
--- 6089,6093 ----
  @item @samp{o}
  A memory operand is allowed, but only if the address is
! @dfn{offsettable}.  This means that adding a small integer (actually,
  the width in bytes of the operand, as determined by its machine mode)
  may be added to the address and the result is also a valid memory
***************
*** 5686,5695 ****
  address.
  
! For example, an address which is constant is offsetable; so is an
  address that is the sum of a register and a constant (as long as a
  slightly larger constant is also within the range of address-offsets
  supported by the machine); but an autoincrement or autodecrement
! address is not offsetable.  More complicated indirect/indexed
! addresses may or may not be offsetable depending on the other
  addressing modes that the machine supports.
  
--- 6094,6103 ----
  address.
  
! For example, an address which is constant is offsettable; so is an
  address that is the sum of a register and a constant (as long as a
  slightly larger constant is also within the range of address-offsets
  supported by the machine); but an autoincrement or autodecrement
! address is not offsettable.  More complicated indirect/indexed
! addresses may or may not be offsettable depending on the other
  addressing modes that the machine supports.
  
***************
*** 5700,5706 ****
  
  When the constraint letter @samp{o} is used, the reload pass may
! generate instructions which copy a nonoffsetable address into an index
  register.  The idea is that the register can be used as a replacement
! offsetable address.  But this method requires that there be patterns
  to copy any kind of address into a register.  Auto-increment
  and auto-decrement addresses are an exception; there need not be an
--- 6108,6114 ----
  
  When the constraint letter @samp{o} is used, the reload pass may
! generate instructions which copy a nonoffsettable address into an index
  register.  The idea is that the register can be used as a replacement
! offsettable address.  But this method requires that there be patterns
  to copy any kind of address into a register.  Auto-increment
  and auto-decrement addresses are an exception; there need not be an
***************
*** 5751,5755 ****
  
  @item @samp{F}
! An immediate floating operand (expression code @samp{const_double}) is
  allowed.
  
--- 6159,6163 ----
  
  @item @samp{F}
! An immediate floating operand (expression code @code{const_double}) is
  allowed.
  
***************
*** 5808,5813 ****
  for ``load address'' and ``push address'' instructions.
  
! If @samp{p} is used in the constraint, the test-function in the
! @samp{match_operand} must be @code{address_operand}.
  @end table
  
--- 6216,6221 ----
  for ``load address'' and ``push address'' instructions.
  
! @samp{p} in the constraint must be accompanies by @code{address_operand}
! as the predicate in the @code{match_operand}.
  @end table
  
***************
*** 5903,5907 ****
  
  @item
! A nonoffsetable memory reference can be reloaded by copying the
  address into a register.  So if the constraint uses the letter
  @samp{o}, all memory references are taken care of.
--- 6311,6315 ----
  
  @item
! A nonoffsettable memory reference can be reloaded by copying the
  address into a register.  So if the constraint uses the letter
  @samp{o}, all memory references are taken care of.
***************
*** 5908,5914 ****
  
  @item
! A constant operand can be reloaded by storing it in memory; it then
! becomes an offsetable memory reference.  So if the constraint uses the
! letters @samp{o} or @samp{m}, constant operands are not a problem.
  @end itemize
  
--- 6316,6323 ----
  
  @item
! A constant operand can be reloaded by allocating space in memory to
! hold it as preinitialized data.  Then the memory reference can be used
! in place of the constant.  So if the constraint uses the letters
! @samp{o} or @samp{m}, constant operands are not a problem.
  @end itemize
  
***************
*** 6096,6102 ****
  For such machines, instead of writing @samp{g} and @samp{p} for all
  the constraints, you can choose to write a description with empty constraints.
! Then you write @samp{""} for the constraint in every @samp{match_operand}.
! Address operands are identified by writing an @samp{address} expression
! around the @samp{match_operand}, not by their constraints.
  
  When the machine description has just empty constraints, certain parts
--- 6505,6511 ----
  For such machines, instead of writing @samp{g} and @samp{p} for all
  the constraints, you can choose to write a description with empty constraints.
! Then you write @samp{""} for the constraint in every @code{match_operand}.
! Address operands are identified by writing an @code{address} expression
! around the @code{match_operand}, not by their constraints.
  
  When the machine description has just empty constraints, certain parts
***************
*** 6115,6124 ****
  @table @asis
  @item @samp{mov@var{m}}
! Here @var{m} is a two-letter machine mode name, in lower case.  This
! instruction pattern moves data with that machine mode from operand 1 to
! operand 0.  For example, @samp{movsi} moves full-word data.
  
! If operand 0 is a @samp{subreg} with mode @var{m} of a register whose
! natural mode is wider than @var{m}, the effect of this instruction is
  to store the specified value in the part of the register that corresponds
  to mode @var{m}.  The effect on the rest of the register is undefined.
--- 6524,6533 ----
  @table @asis
  @item @samp{mov@var{m}}
! Here @var{m} stands for a two-letter machine mode name, in lower case.
! This instruction pattern moves data with that machine mode from operand
! 1 to operand 0.  For example, @samp{movsi} moves full-word data.
  
! If operand 0 is a @code{subreg} with mode @var{m} of a register whose
! own mode is wider than @var{m}, the effect of this instruction is
  to store the specified value in the part of the register that corresponds
  to mode @var{m}.  The effect on the rest of the register is undefined.
***************
*** 6130,6142 ****
  Second, these patterns are not used solely in the RTL generation pass.
  Even the reload pass can generate move insns to copy values from stack
! slots into temporary registers.  When it does so, one of the operands
! is a hard register and the other is an operand that can have a reload.
  
! Therefore, when given such a pair of operands, the pattern must
! generate RTL which needs no temporary registers---no registers other
! than the operands.  For example, if you support the pattern with a
! @code{define_expand}, then in such a case you mustn't call
! @code{force_reg} or any other such function which might generate new
! pseudo registers.
  
  This requirement exists even for subword modes on a RISC machine where
--- 6539,6552 ----
  Second, these patterns are not used solely in the RTL generation pass.
  Even the reload pass can generate move insns to copy values from stack
! slots into temporary registers.  When it does so, one of the operands is
! a hard register and the other is an operand that can need to be reloaded
! into a register.
  
! Therefore, when given such a pair of operands, the pattern must generate
! RTL which needs no reloading and needs no temporary registers---no
! registers other than the operands.  For example, if you support the
! pattern with a @code{define_expand}, then in such a case the
! @code{define_expand} mustn't call @code{force_reg} or any other such
! function which might generate new pseudo registers.
  
  This requirement exists even for subword modes on a RISC machine where
***************
*** 6143,6147 ****
  fetching those modes from memory normally requires several insns and
  some temporary registers.  Look in @file{spur.md} to see how the
! requirement is satisfied.
  
  The variety of operands that have reloads depends on the rest of the
--- 6553,6557 ----
  fetching those modes from memory normally requires several insns and
  some temporary registers.  Look in @file{spur.md} to see how the
! requirement can be satisfied.
  
  The variety of operands that have reloads depends on the rest of the
***************
*** 6155,6159 ****
  
  @item @samp{movstrict@var{m}}
! Like @samp{mov@var{m}} except that if operand 0 is a @samp{subreg}
  with mode @var{m} of a register whose natural mode is wider,
  the @samp{movstrict@var{m}} instruction is guaranteed not to alter
--- 6565,6569 ----
  
  @item @samp{movstrict@var{m}}
! Like @samp{mov@var{m}} except that if operand 0 is a @code{subreg}
  with mode @var{m} of a register whose natural mode is wider,
  the @samp{movstrict@var{m}} instruction is guaranteed not to alter
***************
*** 6350,6354 ****
  Value stored is nonzero iff the condition @var{cond} is true.
  @var{cond} is the name of a comparison operation expression code, such
! as @samp{eq}, @samp{lt} or @samp{leu}.
  
  You specify the mode that the operand must have when you write the
--- 6760,6764 ----
  Value stored is nonzero iff the condition @var{cond} is true.
  @var{cond} is the name of a comparison operation expression code, such
! as @code{eq}, @code{lt} or @code{leu}.
  
  You specify the mode that the operand must have when you write the
***************
*** 6356,6366 ****
  which mode you have used and supplies an operand of that mode.
  
! The value stored for a true condition must have 1 as its low bit.
! Otherwise the instruction is not suitable and must be omitted from the
! machine description.  You must tell the compiler exactly which value
! is stored by defining the macro @code{STORE_FLAG_VALUE}.
  
  @item @samp{b@var{cond}}
! Conditional branch instruction.  Operand 0 is a @samp{label_ref}
  that refers to the label to jump to.  Jump if the condition codes
  meet condition @var{cond}.
--- 6766,6777 ----
  which mode you have used and supplies an operand of that mode.
  
! The value stored for a true condition must have 1 as its low bit, or
! else must be negative.  Otherwise the instruction is not suitable and
! must be omitted from the machine description.  You must tell the
! compiler exactly which value is stored by defining the macro
! @code{STORE_FLAG_VALUE}.
  
  @item @samp{b@var{cond}}
! Conditional branch instruction.  Operand 0 is a @code{label_ref}
  that refers to the label to jump to.  Jump if the condition codes
  meet condition @var{cond}.
***************
*** 6369,6373 ****
  Subroutine call instruction returning no value.  Operand 0 is the
  function to call; operand 1 is the number of bytes of arguments pushed
! (in mode @code{SImode}, except it is normally a @samp{const_int});
  operand 2 is the number of registers used as operands.
  
--- 6780,6784 ----
  Subroutine call instruction returning no value.  Operand 0 is the
  function to call; operand 1 is the number of bytes of arguments pushed
! (in mode @code{SImode}, except it is normally a @code{const_int});
  operand 2 is the number of registers used as operands.
  
***************
*** 6377,6381 ****
  the RTL instead of operand 1.
  
! Operand 0 should be a @samp{mem} RTX whose address is the address of
  the function.
  
--- 6788,6792 ----
  the RTL instead of operand 1.
  
! Operand 0 should be a @code{mem} RTX whose address is the address of
  the function.
  
***************
*** 6394,6397 ****
--- 6805,6813 ----
  from a function.
  
+ @item @samp{nop}
+ No-op instruction.  This instruction pattern name should always be defined
+ to output a no-op in assembler code.  @code{(const_int 0)} will do as an
+ RTL pattern.
+ 
  @item @samp{casesi}
  Instruction to jump through a dispatch table, including bounds checking.
***************
*** 6421,6426 ****
  @end enumerate
  
! The table is a @samp{addr_vec} or @samp{addr_diff_vec} inside of a
! @samp{jump_insn}.  The number of elements in the table is one plus the
  difference between the upper bound and the lower bound.
  
--- 6837,6842 ----
  @end enumerate
  
! The table is a @code{addr_vec} or @code{addr_diff_vec} inside of a
! @code{jump_insn}.  The number of elements in the table is one plus the
  difference between the upper bound and the lower bound.
  
***************
*** 6590,6596 ****
  
  When an instruction has the constraint letter @samp{o}, the reload
! pass may generate instructions which copy a nonoffsetable address into
  an index register.  The idea is that the register can be used as a
! replacement offsetable address.  In order for these generated
  instructions to work, there must be patterns to copy any kind of valid
  address into a register.
--- 7006,7012 ----
  
  When an instruction has the constraint letter @samp{o}, the reload
! pass may generate instructions which copy a nonoffsettable address into
  an index register.  The idea is that the register can be used as a
! replacement offsettable address.  In order for these generated
  instructions to work, there must be patterns to copy any kind of valid
  address into a register.
***************
*** 6674,6678 ****
  The last string operand may be omitted if you are not using any
  machine-specific information in this machine description.  If present,
! it must obey the same rules as in a @samp{define_insn}.
  
  In this skeleton, @var{insn-pattern-1} and so on are patterns to match
--- 7090,7094 ----
  The last string operand may be omitted if you are not using any
  machine-specific information in this machine description.  If present,
! it must obey the same rules as in a @code{define_insn}.
  
  In this skeleton, @var{insn-pattern-1} and so on are patterns to match
***************
*** 6681,6691 ****
  the next, and so on.@refill
  
! @var{insn-pattern-1} and so on look @emph{almost} like the second operand
! of @code{define_insn}.  There is one important difference: this pattern is
! an RTX, not a vector.  If the @code{define_insn} pattern would be a vector
! of one element, the @var{insn-pattern} should be just that element, no
! vector.  If the @code{define_insn} pattern would have multiple elements
! then the @var{insn-pattern} must place the vector inside an explicit
! @code{parallel} RTX.@refill
  
  The operands of the insns are matched with @code{match_operands} and
--- 7097,7106 ----
  the next, and so on.@refill
  
! Each of the insns matched by a peephole must also match a
! @code{define_insn}.  Peepholes are checked only at the last stage just
! before code generation, and only optionally.  Therefore, any insn which
! would match a peephole but no @code{define_insn} will cause a crash in code
! generation in an unoptimized compilation, or at various optimization
! stages.
  
  The operands of the insns are matched with @code{match_operands} and
***************
*** 6696,6703 ****
  
  The operand constraints used in @code{match_operand} patterns do not have
! any direct effect on the applicability of the optimization, but they will
! be validated afterward, so write constraints that are sure to fit whenever
! the optimization is applied.  It is safe to use @code{"g"} for each
! operand.
  
  Once a sequence of insns matches the patterns, the @var{condition} is
--- 7111,7122 ----
  
  The operand constraints used in @code{match_operand} patterns do not have
! any direct effect on the applicability of the peephole, but they will
! be validated afterward, so make sure your constraints are general enough
! to apply whenever the peephole matches.  If the peephole matches
! but the constraints are not satisfied, the compiler will crash.
! 
! It is safe to omit constraints in all the operands of the peephole; or
! you can write constraints which serve as a double-check on the criteria
! previously tested.
  
  Once a sequence of insns matches the patterns, the @var{condition} is
***************
*** 6717,6721 ****
  @code{(match_operand @var{i} @dots{})}).  Use the variable @code{insn} to
  refer to the last of the insns being matched; use @code{PREV_INSN} to find
! the preceding insns (but be careful to skip over any @samp{note} insns that
  intervene).@refill
  
--- 7136,7140 ----
  @code{(match_operand @var{i} @dots{})}).  Use the variable @code{insn} to
  refer to the last of the insns being matched; use @code{PREV_INSN} to find
! the preceding insns (but be careful to skip over any @code{note} insns that
  intervene).@refill
  
***************
*** 6799,6802 ****
--- 7218,7258 ----
  @end ignore
  
+ @var{insn-pattern-1} and so on look @emph{almost} like the second
+ operand of @code{define_insn}.  There is one important difference: the
+ second operand of @code{define_insn} consists of one or more RTX's
+ enclosed in square brackets.  Usually, there is only one: then the same
+ action can be written as an element of a @code{define_peephole}.  But
+ when there are multiple actions in a @code{define_insn}, they are
+ implicitly enclosed in a @code{parallel}.  Then you must explicitly
+ write the @code{parallel}, and the square brackets within it, in the
+ @code{define_peephole}.  Thus, if an insn pattern looks like this,
+ 
+ @example
+ (define_insn "divmodsi4"
+   [(set (match_operand:SI 0 "general_operand" "=d")
+         (div:SI (match_operand:SI 1 "general_operand" "0")
+                 (match_operand:SI 2 "general_operand" "dmsK")))
+    (set (match_operand:SI 3 "general_operand" "=d")
+         (mod:SI (match_dup 1) (match_dup 2)))]
+   "TARGET_68020"
+   "divsl%.l %2,%3:%0")
+ @end example
+ 
+ @noindent
+ then the way to mention this insn in a peephole is as follows:
+ 
+ @example
+ (define_peephole
+   [@dots{}
+    (parallel
+     [(set (match_operand:SI 0 "general_operand" "=d")
+           (div:SI (match_operand:SI 1 "general_operand" "0")
+                   (match_operand:SI 2 "general_operand" "dmsK")))
+      (set (match_operand:SI 3 "general_operand" "=d")
+           (mod:SI (match_dup 1) (match_dup 2)))])
+    @dots{}]
+   @dots{})
+ @end example
+ 
  @node Expander Definitions,, Peephole Definitions, Machine Desc
  @section Defining RTL Sequences for Code Generation
***************
*** 6805,6819 ****
  cannot be handled with single insn, but a sequence of RTL insns can
  represent them.  For these target machines, you can write a
! @samp{define_expand} to specify how to generate the sequence of RTL.
  
! A @samp{define_expand} is an RTL expression that looks almost like a
! @samp{define_insn}; but, unlike the latter, a @samp{define_expand} is used
  only for RTL generation and it can produce more than one RTL insn.
  
! A @samp{define_expand} RTX has four operands:
  
  @itemize @bullet
  @item
! The name.  Each @samp{define_expand} must have a name, since the only
  use for it is to refer to it by name.
  
--- 7261,7275 ----
  cannot be handled with single insn, but a sequence of RTL insns can
  represent them.  For these target machines, you can write a
! @code{define_expand} to specify how to generate the sequence of RTL.
  
! A @code{define_expand} is an RTL expression that looks almost like a
! @code{define_insn}; but, unlike the latter, a @code{define_expand} is used
  only for RTL generation and it can produce more than one RTL insn.
  
! A @code{define_expand} RTX has four operands:
  
  @itemize @bullet
  @item
! The name.  Each @code{define_expand} must have a name, since the only
  use for it is to refer to it by name.
  
***************
*** 6820,6824 ****
  @item
  The RTL template.  This is just like the RTL template for a
! @samp{define_peephole} in that it is a vector of RTL expressions
  each being one insn.
  
--- 7276,7280 ----
  @item
  The RTL template.  This is just like the RTL template for a
! @code{define_peephole} in that it is a vector of RTL expressions
  each being one insn.
  
***************
*** 6828,6832 ****
  subclasses of target machine, selected by command-line options when
  GNU CC is run.  This is just like the condition of a
! @samp{define_insn} that has a standard name.
  
  @item
--- 7284,7288 ----
  subclasses of target machine, selected by command-line options when
  GNU CC is run.  This is just like the condition of a
! @code{define_insn} that has a standard name.
  
  @item
***************
*** 6837,6844 ****
  Usually these statements prepare temporary registers for use as
  internal operands in the RTL template, but they can also generate RTL
! insns directly by calling routines such as @samp{emit_insn}, etc.
  Any such insns precede the ones that come from the RTL template.
  @end itemize
  
  The RTL template, in addition to controlling generation of RTL insns,
  also describes the operands that need to be specified when this pattern
--- 7293,7305 ----
  Usually these statements prepare temporary registers for use as
  internal operands in the RTL template, but they can also generate RTL
! insns directly by calling routines such as @code{emit_insn}, etc.
  Any such insns precede the ones that come from the RTL template.
  @end itemize
  
+ Every RTL insn emitted by a @code{define_expand} must match some
+ @code{define_insn} in the machine description.  Otherwise, the compiler
+ will crash when trying to generate code for the insn or trying to optimize
+ it.
+ 
  The RTL template, in addition to controlling generation of RTL insns,
  also describes the operands that need to be specified when this pattern
***************
*** 6846,6850 ****
  
  A true operand, which need to be specified in order to generate RTL from
! the pattern, should be described with a @samp{match_operand} in its first
  occurrence in the RTL template.  This enters information on the operand's
  predicate into the tables that record such things.  GNU CC uses the
--- 7307,7311 ----
  
  A true operand, which need to be specified in order to generate RTL from
! the pattern, should be described with a @code{match_operand} in its first
  occurrence in the RTL template.  This enters information on the operand's
  predicate into the tables that record such things.  GNU CC uses the
***************
*** 6851,6860 ****
  information to preload the operand into a register if that is required for
  valid RTL code.  If the operand is referred to more than once, subsequent
! references should use @samp{match_dup}.
  
  The RTL template may also refer to internal ``operands'' which are
  temporary registers or labels used only within the sequence made by the
! @samp{define_expand}.  Internal operands are substituted into the RTL
! template with @samp{match_dup}, never with @samp{match_operand}.  The
  values of the internal operands are not passed in as arguments by the
  compiler when it requests use of this pattern.  Instead, they are computed
--- 7312,7321 ----
  information to preload the operand into a register if that is required for
  valid RTL code.  If the operand is referred to more than once, subsequent
! references should use @code{match_dup}.
  
  The RTL template may also refer to internal ``operands'' which are
  temporary registers or labels used only within the sequence made by the
! @code{define_expand}.  Internal operands are substituted into the RTL
! template with @code{match_dup}, never with @code{match_operand}.  The
  values of the internal operands are not passed in as arguments by the
  compiler when it requests use of this pattern.  Instead, they are computed
***************
*** 6861,6865 ****
  within the pattern, in the preparation statements.  These statements
  compute the values and store them into the appropriate elements of
! @code{operands} so that @samp{match_dup} can find them.
  
  There are two special macros defined for use in the preparation statements:
--- 7322,7326 ----
  within the pattern, in the preparation statements.  These statements
  compute the values and store them into the appropriate elements of
! @code{operands} so that @code{match_dup} can find them.
  
  There are two special macros defined for use in the preparation statements:
***************
*** 6903,6907 ****
  
  @noindent
! This example uses @samp{define_expand} so that it can generate an RTL insn
  for shifting when the shift-count is in the supported range of 0 to 3 but
  fail in other cases where machine insns aren't available.  When it fails,
--- 7364,7368 ----
  
  @noindent
! This example uses @code{define_expand} so that it can generate an RTL insn
  for shifting when the shift-count is in the supported range of 0 to 3 but
  fail in other cases where machine insns aren't available.  When it fails,
***************
*** 6910,6916 ****
  
  If the compiler were able to handle nontrivial condition-strings in
! patterns with names, then there would be possible to use a
! @samp{define_insn} in that case.  Here is another case (zero-extension on
! the 68000) which makes more use of the power of @samp{define_expand}:
  
  @example
--- 7371,7377 ----
  
  If the compiler were able to handle nontrivial condition-strings in
! patterns with names, then it would be possible to use a
! @code{define_insn} in that case.  Here is another case (zero-extension
! on the 68000) which makes more use of the power of @code{define_expand}:
  
  @example
***************
*** 6920,6924 ****
     (set (strict_low_part 
            (subreg:HI
!             (match_operand:SI 0 "general_operand" "")
              0))
          (match_operand:HI 1 "general_operand" ""))]
--- 7381,7385 ----
     (set (strict_low_part 
            (subreg:HI
!             (match_dup 0)
              0))
          (match_operand:HI 1 "general_operand" ""))]
***************
*** 6937,6945 ****
  
  Finally, a third example shows the use of an internal operand.
! Zero-extension on the SPUR chip is done by @samp{and}-ing the result
  against a halfword mask.  But this mask cannot be represented by a
! @samp{const_int} because the constant value is too large to be legitimate
  on this machine.  So it must be copied into a register with
! @code{force_reg} and then the register used in the @samp{and}.
  
  @example
--- 7398,7406 ----
  
  Finally, a third example shows the use of an internal operand.
! Zero-extension on the SPUR chip is done by @code{and}-ing the result
  against a halfword mask.  But this mask cannot be represented by a
! @code{const_int} because the constant value is too large to be legitimate
  on this machine.  So it must be copied into a register with
! @code{force_reg} and then the register used in the @code{and}.
  
  @example
***************
*** 6956,6959 ****
--- 7417,7425 ----
  @end example
  
+ @strong{Note:} If the @code{define_expand} is used to serve a standard
+ binary or unary arithmetic operation, then the last insn it generates
+ must not be a @code{code_label}, @code{barrier} or @code{note}.  It must
+ be an @code{insn}, @code{jump_insn} or @code{call_insn}.
+ 
  @node Machine Macros, Config, Machine Desc, Top
  @chapter Machine Description Macros
***************
*** 6972,6975 ****
--- 7438,7442 ----
  * Library Names::       Specifying names of subroutines to call automatically.
  * Addressing Modes::    Defining addressing modes valid for memory operands.
+ * Delayed Branch::      Do branches execute the following instruction?
  * Condition Code::      Defining how insns update the condition code.
  * Assembler Format::    Defining how to write insns and pseudo-ops to output.
***************
*** 6999,7005 ****
  @end example
  
! The result is to define the macros @samp{__mc68000__}, @samp{__sun__}
! and @samp{__unix__} unconditionally, and the macros @samp{mc68000},
! @samp{sun} and @samp{unix} provided @samp{-ansi} is not specified.
  
  @item CPP_SPEC
--- 7466,7472 ----
  @end example
  
! The result is to define the macros @code{__mc68000__}, @code{__sun__}
! and @code{__unix__} unconditionally, and the macros @code{mc68000},
! @code{sun} and @code{unix} provided @samp{-ansi} is not specified.
  
  @item CPP_SPEC
***************
*** 7090,7093 ****
--- 7557,7563 ----
  macro is irrelevant.
  
+ This macro does not affect the way structure fields are packed into
+ bytes or words; that is controlled by @code{BYTES_BIG_ENDIAN}.
+ 
  @item BYTES_BIG_ENDIAN
  Define this macro if the most significant byte in a word has the
***************
*** 7139,7142 ****
--- 7609,7624 ----
  Biggest alignment that any data type can require on this machine, in bits.
  
+ @item CONSTANT_ALIGNMENT (@var{code}, @var{typealign})
+ A C expression to compute the alignment for a constant.  The argument
+ @var{typealign} is the alignment required for the constant's data type.
+ @var{code} is the tree code of the constant itself.
+ 
+ If this macro is not defined, the default is to use @var{typealign}.  If
+ you do define this macro, the value must be a multiple of
+ @var{typealign}.
+ 
+ The purpose of defining this macro is usually to cause string constants
+ to be word aligned so that @file{dhrystone} can be made to run faster.
+ 
  @item EMPTY_FIELD_BOUNDARY
  Alignment in bits to be given to a structure bit field that follows an
***************
*** 7227,7231 ****
  
  @item DEFAULT_CALLER_SAVES
! Define this macro if the target machine if function calls do not preserve
  any registers; in other words, if @code{CALL_USED_REGISTERS} has 1
  for all registers.  This macro enables @samp{-fcaller-saves} by default.
--- 7709,7713 ----
  
  @item DEFAULT_CALLER_SAVES
! Define this macro if function calls on the target machine do not preserve
  any registers; in other words, if @code{CALL_USED_REGISTERS} has 1
  for all registers.  This macro enables @samp{-fcaller-saves} by default.
***************
*** 7287,7296 ****
  involved.
  
! You would arrange to preserve death info for a register when some
! of the code in the machine description which is executed to write
! the assembler code looks at the the death notes.  This is
! necessary only when the actual hardware feature which GNU CC
! thinks of as a register is not actually a register of the usual sort.
! (It might, for example, be a hardware stack.)
  
  If this macro is not defined, it means that no death notes need to be
--- 7769,7778 ----
  involved.
  
! You would arrange to preserve death info for a register when some of the
! code in the machine description which is executed to write the assembler
! code looks at the death notes.  This is necessary only when the actual
! hardware feature which GNU CC thinks of as a register is not actually a
! register of the usual sort.  (It might, for example, be a hardware
! stack.)
  
  If this macro is not defined, it means that no death notes need to be
***************
*** 7321,7326 ****
  @end example
  
! It is not necessary for this macro to check for fixed register numbers
! because the allocation mechanism considers them to be always occupied.
  
  Many machines have special registers for floating point arithmetic.
--- 7803,7818 ----
  @end example
  
! It is not necessary for this macro to check for the numbers of fixed
! registers, because the allocation mechanism considers them to be always
! occupied.
! 
! On some machines, double-precision values must be kept in even/odd
! register pairs.  The way to implement that is to define this macro
! to reject odd register numbers for such modes.
! 
! GNU CC assumes that it can always move values between registers and
! (suitably addressed) memory locations.  If it is impossible to move a
! value of a certain mode between memory and certain registers, then
! @code{HARD_REGNO_MODE_OK} must not allow this mode in those registers.
  
  Many machines have special registers for floating point arithmetic.
***************
*** 7331,7335 ****
  registers.
  
! The true significance of special floating registers is rather than
  non-floating-point machine modes @emph{may not} go in those registers.
  This is true if the floating registers normalize any value stored in
--- 7823,7827 ----
  registers.
  
! The true significance of special floating registers is rather that
  non-floating-point machine modes @emph{may not} go in those registers.
  This is true if the floating registers normalize any value stored in
***************
*** 7348,7353 ****
  It is obligatory to support floating point `move' instructions into
  and out of any registers that can hold fixed point values, because
! unions and structures (which have modes @samp{SImode} or
! @samp{DImode}) can be in those registers and they may have floating
  point members.
  
--- 7840,7845 ----
  It is obligatory to support floating point `move' instructions into
  and out of any registers that can hold fixed point values, because
! unions and structures (which have modes @code{SImode} or
! @code{DImode}) can be in those registers and they may have floating
  point members.
  
***************
*** 7435,7439 ****
  If the structure value address is not passed in a register, define
  @code{STRUCT_VALUE} as an expression returning an RTX for the place
! where the address is passed.  If it returns a @samp{mem} RTX, the
  address is passed as an ``invisible'' first argument.
  
--- 7927,7931 ----
  If the structure value address is not passed in a register, define
  @code{STRUCT_VALUE} as an expression returning an RTX for the place
! where the address is passed.  If it returns a @code{mem} RTX, the
  address is passed as an ``invisible'' first argument.
  
***************
*** 7451,7456 ****
  @code{STRUCT_VALUE_INCOMING} as an expression for an RTX for where the
  called function should find the value.  If it should find the value on
! the stack, define this to create a @samp{mem} which refers to the
! frame pointer.  If the value is a @samp{mem}, the compiler assumes it
  is for an invisible first argument, and leaves space for it when
  finding the first real argument.
--- 7943,7948 ----
  @code{STRUCT_VALUE_INCOMING} as an expression for an RTX for where the
  called function should find the value.  If it should find the value on
! the stack, define this to create a @code{mem} which refers to the
! frame pointer.  If the value is a @code{mem}, the compiler assumes it
  is for an invisible first argument, and leaves space for it when
  finding the first real argument.
***************
*** 7510,7513 ****
--- 8002,8011 ----
  in their union.
  
+ When a value occupying several consecutive registers is expected in a
+ certain class, all the registers used must belong to that class.
+ Therefore, register classes cannot be used to enforce a requirement for
+ a register pair to start with an even-numbered register.  The way to
+ specify this requirement is with @code{HARD_REGNO_MODE_OK}.
+ 
  Register classes used for input-operands of bitwise-and or shift
  instructions have a special requirement: each such class must have, for
***************
*** 7617,7621 ****
  Requiring a data register guarantees that a @samp{moveq} will be used.
  
! If @var{x} is a @samp{const_double}, by returning @code{NO_REGS}
  you can force @var{x} into a memory constant.  This is useful on
  certain machines where immediate floating values cannot be loaded into
--- 8115,8119 ----
  Requiring a data register guarantees that a @samp{moveq} will be used.
  
! If @var{x} is a @code{const_double}, by returning @code{NO_REGS}
  you can force @var{x} into a memory constant.  This is useful on
  certain machines where immediate floating values cannot be loaded into
***************
*** 7667,7671 ****
  letters that specify particular ranges of floating values.  If @var{c} is
  one of those letters, the expression should check that @var{value}, an RTX
! of code @samp{const_double}, is in the appropriate range and return 1 if
  so, 0 otherwise.  If @var{c} is not one of those letters, the value should
  be 0 regardless of @var{value}.
--- 8165,8169 ----
  letters that specify particular ranges of floating values.  If @var{c} is
  one of those letters, the expression should check that @var{value}, an RTX
! of code @code{const_double}, is in the appropriate range and return 1 if
  so, 0 otherwise.  If @var{c} is not one of those letters, the value should
  be 0 regardless of @var{value}.
***************
*** 7867,7873 ****
  (which happens for C support library functions); and @var{named},
  which is 1 for an ordinary argument and 0 for nameless arguments that
! correspond to @samp{...} in the called function's prototype.
  
! The value of the expression should either be a @samp{reg} RTX for the
  hard register in which to pass the argument, or zero to pass the
  argument on the stack.
--- 8365,8371 ----
  (which happens for C support library functions); and @var{named},
  which is 1 for an ordinary argument and 0 for nameless arguments that
! correspond to @samp{@dots{}} in the called function's prototype.
  
! The value of the expression should either be a @code{reg} RTX for the
  hard register in which to pass the argument, or zero to pass the
  argument on the stack.
***************
*** 7876,7879 ****
--- 8374,8382 ----
  suffices as a definition.
  
+ The usual way to make the ANSI library @file{stdarg.h} work on a machine
+ where some arguments are usually passed in registers, is to cause
+ nameless arguments to be passed on the stack instead.  This is done
+ by making @code{FUNCTION_ARG} return 0 whenever @var{named} is 0.
+ 
  @item FUNCTION_INCOMING_ARG (@var{cum}, @var{mode}, @var{type}, @var{named})
  Define this macro if the target machine has ``register windows'', so
***************
*** 7979,7982 ****
--- 8482,8499 ----
  time in a function that needs a frame pointer.
  
+ On machines where arguments may be passed in registers, and not have
+ stack space allocated, this macro must examine the variable
+ @code{current_function_pretend_args_size}, and allocate that many bytes
+ of uninitialized space on the stack just underneath the first argument
+ arriving on the stack.  (This may not be at the very end of the stack,
+ if the calling sequence has pushed anything else since pushing the stack
+ arguments.  But usually, on such machines, nothing else has been pushed
+ yet, because the function prologue itself does all the pushing.)
+ 
+ This ``pretend argument'' space is allocated in functions that use the
+ ANSI library @file{stdarg.h} to accept anonymous arguments of
+ unspecified types; the last named argument is copied into the space, so
+ that the anonymous arguments follow it consecutively.
+ 
  @item FUNCTION_PROFILER (@var{file}, @var{labelno})
  A C statement or compound statement to output to @var{file} some
***************
*** 8039,8046 ****
  adjust the stack pointer before a return from the function.
  
! Note that this macro's value is relevant only for for which frame
! pointers are maintained.  It is never possible to delete a final stack
! adjustment in a function that has no frame pointer, and the compiler
! knows this regardless of @code{EXIT_IGNORES_STACK}.
  
  @item FUNCTION_EPILOGUE (@var{file}, @var{size})
--- 8556,8563 ----
  adjust the stack pointer before a return from the function.
  
! Note that this macro's value is relevant only for functions for which
! frame pointers are maintained.  It is never safe to delete a final
! stack adjustment in a function that has no frame pointer, and the
! compiler knows this regardless of @code{EXIT_IGNORES_STACK}.
  
  @item FUNCTION_EPILOGUE (@var{file}, @var{size})
***************
*** 8100,8103 ****
--- 8617,8626 ----
  @code{FIX_FRAME_POINTER_ADDRESS}, but the definition will never be
  executed at run time, so it may be empty.
+ 
+ @item LONGJMP_RESTORE_FROM_STACK
+ Define this macro if the @code{longjmp} function restores registers
+ from the stack frames, rather than from those saved specifically by
+ @code{setjmp}.  Certain quantities must not be kept in registers
+ across a call to @code{setjmp} on such machines.
  @end table
  
***************
*** 8148,8152 ****
  @end table
  
! @node Addressing Modes, Cross-compilation, Library Names, Machine Macros
  @section Addressing Modes
  
--- 8671,8675 ----
  @end table
  
! @node Addressing Modes, Delayed Branch, Library Names, Machine Macros
  @section Addressing Modes
  
***************
*** 8163,8168 ****
  A C expression that is 1 if the RTX @var{x} is a constant whose value
  is an integer.  This includes integers whose values are not explicitly
! known, such as @samp{symbol_ref} and @samp{label_ref} expressions and
! @samp{const} arithmetic expressions.
  
  On most machines, this can be defined as @code{CONSTANT_P (@var{x})},
--- 8686,8691 ----
  A C expression that is 1 if the RTX @var{x} is a constant whose value
  is an integer.  This includes integers whose values are not explicitly
! known, such as @code{symbol_ref} and @code{label_ref} expressions and
! @code{const} arithmetic expressions.
  
  On most machines, this can be defined as @code{CONSTANT_P (@var{x})},
***************
*** 8206,8209 ****
--- 8729,8743 ----
  whether strict or not.@refill
  
+ Normally, constant addresses which are the sum of a @code{symbol_ref}
+ and an integer are stored inside a @code{const} RTX to mark them as
+ constant.  Therefore, there is no need to recognize such sums as
+ legitimate addresses.
+ 
+ Usually @code{PRINT_OPERAND_ADDRESS} is not prepared to handle constant
+ sums that are not marked with  @code{const}.  It assumes that a naked
+ @code{plus} indicates indexing.  If so, then you @emph{must} reject such
+ naked constant sums as illegitimate addresses, so that none of them will
+ be given to @code{PRINT_OPERAND_ADDRESS}.@refill
+ 
  @item REG_OK_FOR_BASE_P (@var{x})
  A C expression that is nonzero if @var{x} (assumed to be a @code{reg}
***************
*** 8269,8279 ****
  A C expression that is nonzero if @var{x} is a legitimate constant for
  an immediate operand on the target machine.  You can assume that
! either @var{x} is a @samp{const_double} or it satisfies
  @code{CONSTANT_P}, so you need not check these things.  In fact,
  @samp{1} is a suitable definition for this macro on machines where any
! @samp{const_double} is valid and anything @code{CONSTANT_P} is valid.@refill
  @end table
  
! @node Cross-compilation, Misc, Addressing Modes, Machine Macros
  @section Cross Compilation and Floating-Point Format
  
--- 8803,8929 ----
  A C expression that is nonzero if @var{x} is a legitimate constant for
  an immediate operand on the target machine.  You can assume that
! either @var{x} is a @code{const_double} or it satisfies
  @code{CONSTANT_P}, so you need not check these things.  In fact,
  @samp{1} is a suitable definition for this macro on machines where any
! @code{const_double} is valid and anything @code{CONSTANT_P} is valid.@refill
! @end table
! 
! @node Delayed Branch, Condition Code, Addressing Modes, Machine Macros
! @section Parameters for Delayed Branch Optimization
! 
! @table @code
! @item HAVE_DELAYED_BRANCH
! Define this macro if the target machine has delayed branches, that is,
! a branch does not take effect immediately, and the actual branch
! instruction may be followed by one or more instructions that will be
! issued before the PC is actually changed.
! 
! If defined, this allows a special scheduling pass to be run after the
! second jump optimization to attempt to reorder instructions to exploit
! this.  Defining this macro also requires the definition of certain
! other macros described below.
! 
! @item DBR_SLOTS_AFTER (@var{insn})
! This macro must be defined if @code{HAVE_DELAYED_BRANCH} is defined.
! Its definition should be a C expression returning the number of
! available delay slots following the instruction(s) output by the
! pattern for @var{insn}.  The definition of ``slot'' is
! machine-dependent, and may denote instructions, bytes, or whatever.
! 
! @item DBR_INSN_SLOTS (@var{insn})
! This macro must be defined if @code{HAVE_DELAYED_BRANCH} is defined.
! It should be a C expression returning the number of slots (typically
! the number of machine instructions) consumed by @var{insn}.
! 
! You may assume that @var{insn} is truly an insn, not a note, label,
! barrier, dispatch table, @code{use}, or @code{clobber}.
! 
! @item DBR_INSN_ELIGIBLE_P (@var{insn}, @var{dinsn})
! A C expression whose value is non-zero if it is legitimate to put
! @var{insn} in the delay slot following @var{dinsn}.
! 
! You do not need to take account of data flow considerations in the
! definition of this macro, because the delayed branch optimizer always
! does that.  This macro is needed only when certain insns may not be
! placed in certain delay slots for reasons not evident from the RTL
! expressions themselves.  If there are no such problems, you don't need
! to define this macro.
! 
! You may assume that @var{insn} is truly an insn, not a note, label,
! barrier, dispatch table, @code{use}, or @code{clobber}.  You may
! assume that @var{dinsn} is a jump insn with a delay slot.
! 
! @item DBR_OUTPUT_SEQEND(@var{file})
! A C statement, to be executed after all slot-filler instructions have
! been output.  If necessary, call @code{dbr_sequence_length} to
! determine the number of slots filled in a sequence (zero if not
! currently outputting a sequence), to decide how many no-ops to output,
! or whatever.
! 
! Don't define this macro if it has nothing to do, but it is helpful in
! reading assembly output if the extent of the delay sequence is made
! explicit (e.g. with white space).
! 
! Note that output routines for instructions with delay slots must be
! prepared to deal with not being output as part of a sequence (i.e.
! when the scheduling pass is not run, or when no slot fillers could be
! found.)  The variable @code{final_sequence} is null when not
! processing a sequence, otherwise it contains the @code{sequence} rtx
! being output.
! @end table
! 
! @node Condition Code, Misc, Delayed Branch, Machine Macros
! @section Condition Code Information
! 
! The file @file{conditions.h} defines a variable @code{cc_status} to
! describe how the condition code was computed (in case the interpretation of
! the condition code depends on the instruction that it was set by).  This
! variable contains the RTL expressions on which the condition code is
! currently based, and several standard flags.
! 
! Sometimes additional machine-specific flags must be defined in the machine
! description header file.  It can also add additional machine-specific
! information by defining @code{CC_STATUS_MDEP}.
! 
! @table @code
! @item CC_STATUS_MDEP
! C code for a data type which is used for declaring the @code{mdep}
! component of @code{cc_status}.  It defaults to @code{int}.
! 
! @item CC_STATUS_MDEP_INIT
! A C expression for the initial value of the @code{mdep} field.  It
! defaults to 0.
! 
! @item NOTICE_UPDATE_CC (@var{exp}, @var{insn})
! A C compound statement to set the components of @code{cc_status}
! appropriately for an insn @var{insn} whose body is @var{exp}.  It is
! this macro's responsibility to recognize insns that set the condition
! code as a byproduct of other activity as well as those that explicitly
! set @code{(cc0)}.
! 
! If there are insn that do not set the condition code but do alter
! other machine registers, this macro must check to see whether they
! invalidate the expressions that the condition code is recorded as
! reflecting.  For example, on the 68000, insns that store in address
! registers do not set the condition code, which means that usually
! @code{NOTICE_UPDATE_CC} can leave @code{cc_status} unaltered for such
! insns.  But suppose that the previous insn set the condition code
! based on location @samp{a4@@(102)} and the current insn stores a new
! value in @samp{a4}.  Although the condition code is not changed by
! this, it will no longer be true that it reflects the contents of
! @samp{a4@@(102)}.  Therefore, @code{NOTICE_UPDATE_CC} must alter
! @code{cc_status} in this case to say that nothing is known about the
! condition code value.
! 
! The definition of @code{NOTICE_UPDATE_CC} must be prepared to deal
! with the results of peephole optimization: insns whose patterns are
! @code{parallel} RTXs containing various @code{reg}, @code{mem} or
! constants which are just the operands.  The RTL structure of these
! insns is not sufficient to indicate what the insns actually do.  What
! @code{NOTICE_UPDATE_CC} should do when it sees one is just to run
! @code{CC_STATUS_INIT}.
  @end table
  
! @node Cross-compilation, Misc, Condition Code, Machine Macros
  @section Cross Compilation and Floating-Point Format
  
***************
*** 8374,8378 ****
  @end table
  
! @node Misc, Condition Code, Cross-compilation, Machine Macros
  @section Miscellaneous Parameters
  
--- 9024,9028 ----
  @end table
  
! @node Misc, Assembler Format, Cross-compilation, Machine Macros
  @section Miscellaneous Parameters
  
***************
*** 8429,8434 ****
  @item INT_TYPE_SIZE
  A C expression for the size in bits of the type @code{int} on the
! target machine.
  
  @item SLOW_BYTE_ACCESS
  Define this macro as a C expression which is nonzero if accessing less
--- 9079,9119 ----
  @item INT_TYPE_SIZE
  A C expression for the size in bits of the type @code{int} on the
! target machine.  If you don't define this, the default is one word.
  
+ @item SHORT_TYPE_SIZE
+ A C expression for the size in bits of the type @code{short} on the
+ target machine.  If you don't define this, the default is half a word.
+ (If this would be less than one storage unit, it is rounded up to one
+ unit.)
+ 
+ @item LONG_TYPE_SIZE
+ A C expression for the size in bits of the type @code{long} on the
+ target machine.  If you don't define this, the default is one word.
+ 
+ @item LONG_LONG_TYPE_SIZE
+ A C expression for the size in bits of the type @code{long long} on the
+ target machine.  If you don't define this, the default is two
+ words.
+ 
+ @item CHAR_TYPE_SIZE
+ A C expression for the size in bits of the type @code{char} on the
+ target machine.  If you don't define this, the default is one quarter
+ of a word.  (If this would be less than one storage unit, it is rounded up
+ to one unit.)
+ 
+ @item FLOAT_TYPE_SIZE
+ A C expression for the size in bits of the type @code{float} on the
+ target machine.  If you don't define this, the default is one word.
+ 
+ @item DOUBLE_TYPE_SIZE
+ A C expression for the size in bits of the type @code{double} on the
+ target machine.  If you don't define this, the default is two
+ words.
+ 
+ @item LONG_DOUBLE_TYPE_SIZE
+ A C expression for the size in bits of the type @code{long double} on
+ the target machine.  If you don't define this, the default is two
+ words.
+ 
  @item SLOW_BYTE_ACCESS
  Define this macro as a C expression which is nonzero if accessing less
***************
*** 8492,8496 ****
  @item FUNCTION_MODE
  An alias for the machine mode used for memory references to functions
! being called, in @samp{call} RTL expressions.  On most machines this
  should be @code{QImode}.
  
--- 9177,9181 ----
  @item FUNCTION_MODE
  An alias for the machine mode used for memory references to functions
! being called, in @code{call} RTL expressions.  On most machines this
  should be @code{QImode}.
  
***************
*** 8498,8503 ****
  This macro should expand into a C structure type to use for the
  machine-dependent info field specified with the optional last argument
! in @samp{define_insn} and @samp{define_peephole} patterns.  For example,
! it might expand into @samp{struct machine_info}; then it would be up
  to you to define this structure in the @file{tm.h} file.
  
--- 9183,9188 ----
  This macro should expand into a C structure type to use for the
  machine-dependent info field specified with the optional last argument
! in @code{define_insn} and @code{define_peephole} patterns.  For example,
! it might expand into @code{struct machine_info}; then it would be up
  to you to define this structure in the @file{tm.h} file.
  
***************
*** 8505,8513 ****
  last argument in any of the patterns in the machine description.
  
  @item CONST_COSTS (@var{x}, @var{code})
  A part of a C @code{switch} statement that describes the relative
  costs of constant RTL expressions.  It must contain @code{case} labels
! for expression codes @samp{const_int}, @samp{const}, @samp{symbol_ref}, @samp{label_ref}
! and @samp{const_double}.  Each case must ultimately reach a
  @code{return} statement to return the relative cost of the use of that
  kind of constant value in an expression.  The cost may depend on the
--- 9190,9205 ----
  last argument in any of the patterns in the machine description.
  
+ @item DEFAULT_MACHINE_INFO
+ This macro should expand into a C initializer to use to initialize
+ the machine-dependent info for one insn pattern.  It is used for patterns
+ that do not specify the machine-dependent info.
+ 
+ If you do not define this macro, zero is used.
+ 
  @item CONST_COSTS (@var{x}, @var{code})
  A part of a C @code{switch} statement that describes the relative
  costs of constant RTL expressions.  It must contain @code{case} labels
! for expression codes @code{const_int}, @code{const}, @code{symbol_ref}, @code{label_ref}
! and @code{const_double}.  Each case must ultimately reach a
  @code{return} statement to return the relative cost of the use of that
  kind of constant value in an expression.  The cost may depend on the
***************
*** 8531,8535 ****
  running on, rather than the one the compiler is compiling for.
  Therefore, it should be set in the @file{xm-@var{machine}.h} file
! rather than in the @file{xm-@var{machine}.h} file.
  
  If you do define this macro, you should probably do it as follows:
--- 9223,9227 ----
  running on, rather than the one the compiler is compiling for.
  Therefore, it should be set in the @file{xm-@var{machine}.h} file
! rather than in the @file{tm-@var{machine}.h} file.
  
  If you do define this macro, you should probably do it as follows:
***************
*** 8539,8543 ****
  #define USE_C_ALLOCA
  #else
! #deifne alloca __builtin_alloca
  #endif
  @end example
--- 9231,9235 ----
  #define USE_C_ALLOCA
  #else
! #define alloca __builtin_alloca
  #endif
  @end example
***************
*** 8548,8604 ****
  @end table
  
! @node Condition Code, Assembler Format, Misc, Machine Macros
! @section Condition Code Information
! 
! The file @file{conditions.h} defines a variable @code{cc_status} to
! describe how the condition code was computed (in case the interpretation of
! the condition code depends on the instruction that it was set by).  This
! variable contains the RTL expressions on which the condition code is
! currently based, and several standard flags.
! 
! Sometimes additional machine-specific flags must be defined in the machine
! description header file.  It can also add additional machine-specific
! information by defining @code{CC_STATUS_MDEP}.
! 
! @table @code
! @item CC_STATUS_MDEP
! C code for a data type which is used for declaring the @code{mdep}
! component of @code{cc_status}.  It defaults to @code{int}.
! 
! @item CC_STATUS_MDEP_INIT
! A C expression for the initial value of the @code{mdep} field.  It
! defaults to 0.
! 
! @item NOTICE_UPDATE_CC (@var{exp}, @var{insn})
! A C compound statement to set the components of @code{cc_status}
! appropriately for an insn @var{insn} whose body is @var{exp}.  It is
! this macro's responsibility to recognize insns that set the condition
! code as a byproduct of other activity as well as those that explicitly
! set @code{(cc0)}.
! 
! If there are insn that do not set the condition code but do alter
! other machine registers, this macro must check to see whether they
! invalidate the expressions that the condition code is recorded as
! reflecting.  For example, on the 68000, insns that store in address
! registers do not set the condition code, which means that usually
! @code{NOTICE_UPDATE_CC} can leave @code{cc_status} unaltered for such
! insns.  But suppose that the previous insn set the condition code
! based on location @samp{a4@@(102)} and the current insn stores a new
! value in @samp{a4}.  Although the condition code is not changed by
! this, it will no longer be true that it reflects the contents of
! @samp{a4@@(102)}.  Therefore, @code{NOTICE_UPDATE_CC} must alter
! @code{cc_status} in this case to say that nothing is known about the
! condition code value.
! 
! The definition of @code{NOTICE_UPDATE_CC} must be prepared to deal
! with the results of peephole optimization: insns whose patterns are
! @samp{parallel} RTXs containing various @samp{reg}, @samp{mem} or
! constants which are just the operands.  The RTL structure of these
! insns is not sufficient to indicate what the insns actually do.  What
! @code{NOTICE_UPDATE_CC} should do when it sees one is just to run
! @code{CC_STATUS_INIT}.
! @end table
! 
! @node Assembler Format,, Condition Code, Machine Macros
  @section Output of Assembler Code
  
--- 9240,9244 ----
  @end table
  
! @node Assembler Format,, Misc, Machine Macros
  @section Output of Assembler Code
  
***************
*** 8667,8670 ****
--- 9307,9336 ----
  see @file{tm-attasm.h}.
  
+ @item ASM_FILE_END (@var{stream})
+ A C expression which outputs to the stdio stream @var{stream}
+ some appropriate text to go at the end of an assembler file.
+ 
+ If this macro is not defined, the default is to output nothing
+ special at the end of the file.  Most systems don't require any
+ definition.
+ 
+ On systems that use SDB, it is necessary to output certain commands;
+ see @file{tm-attasm.h}.
+ 
+ @item ASM_IDENTIFY_GCC (@var{file})
+ A C statement to output assembler commands which will identify
+ the object file as having been compiled with GNU CC (or another
+ GNU compiler).
+ 
+ If you don't define this macro, the string @samp{gcc_compiled.:}
+ is output.  This string is calculated to define a symbol which,
+ on BSD systems, will never be defined for any other reason.
+ GDB checks for the presence of this symbol when reading the
+ symbol table of an executable.
+ 
+ On non-BSD systems, you must arrange communication with GDB in
+ some other fashion.  If GDB is not used on your system, you can
+ define this macro with an empty body.
+ 
  @item ASM_APP_ON
  A C string constant for text to be output before each @code{asm}
***************
*** 8689,8692 ****
--- 9355,9390 ----
  is right.
  
+ @item EXTRA_SECTIONS
+ A list of names for sections other than the standard two, which are
+ @code{in_text} and @code{in_data}.  You need not define this macro
+ on a system with no other sections (that GCC needs to use).
+ 
+ @item EXTRA_SECTION_FUNCTIONS
+ One or more functions to be defined in @file{varasm.c}.  These
+ functions should do jobs analogous to those of @code{text_section} and
+ @code{data_section}, for your additional sections.  Do not define this
+ macro if you do not define @code{EXTRA_SECTIONS}.
+ 
+ @item SELECT_SECTION (@var{exp})
+ A C statement or statements to switch to the appropriate section for
+ output of @var{exp}.  You can assume that @var{exp} is either a
+ @code{VAR_DECL} node or a constant of some sort.  Select the section
+ by calling @code{text_section} or one of the alternatives for other
+ sections.
+ 
+ Do not define this macro if you use only the standard two sections
+ and put all read-only variables and constants in the text section.
+ 
+ @item SELECT_RTX_SECTION (@var{mode}, @var{rtx})
+ A C statement or statements to switch to the appropriate section for
+ output of @var{rtx} in mode @var{mode}.  You can assume that @var{rtx}
+ is some kind of constant in RTL.  The argument @var{mode} is redundant
+ except in the case of a @code{const_int} rtx.  Select the section by
+ calling @code{text_section} or one of the alternatives for other
+ sections.  
+ 
+ Do not define this macro if you use only the standard two sections and
+ put all constants in the text section.  
+ 
  @item REGISTER_NAMES
  A C initializer containing the assembler's names for the machine
***************
*** 8743,8751 ****
  if backslash is correct for your system.
  
  @item ASM_OUTPUT_LABEL (@var{stream}, @var{name})
  A C statement (sans semicolon) to output to the stdio stream
! @var{stream} the assembler definition of a label named @var{name}.  Use
! the expression @code{assemble_name (@var{stream}, @var{name})} to output
! the name itself; before and after that, output the additional
  assembler syntax for defining the name, and a newline.
  
--- 9441,9454 ----
  if backslash is correct for your system.
  
+ @item DBX_STATIC_STAB_DATA_SECTION
+ Define this macro if it is necessary to go to the data section before
+ outputting the @samp{.stabs} pseudo-op for a non-global static
+ variable.
+ 
  @item ASM_OUTPUT_LABEL (@var{stream}, @var{name})
  A C statement (sans semicolon) to output to the stdio stream
! @var{stream} the assembler definition of a label named @var{name}.
! Use the expression @code{assemble_name (@var{stream}, @var{name})} to
! output the name itself; before and after that, output the additional
  assembler syntax for defining the name, and a newline.
  
***************
*** 8769,8773 ****
  for making that name global, and a newline.
  
! @item ASM_OUTPUT_EXTERNAL (@var{stream}, @var{name}, @var{decl})
  A C statement (sans semicolon) to output to the stdio stream
  @var{stream} any text necessary for declaring the name of an external
--- 9472,9476 ----
  for making that name global, and a newline.
  
! @item ASM_OUTPUT_EXTERNAL (@var{stream}, @var{decl}, @var{name})
  A C statement (sans semicolon) to output to the stdio stream
  @var{stream} any text necessary for declaring the name of an external
***************
*** 8780,8792 ****
  
  @item ASM_OUTPUT_LABELREF (@var{stream}, @var{name})
! A C statement to output to the stdio stream @var{stream} a reference in
! assembler syntax to a label named @var{name}.  The character @samp{_}
! should be added to the front of the name, if that is customary on your
! operating system, as it is in most Berkeley Unix systems.  This macro
! is used in @code{assemble_name}.
  
  @item ASM_GENERATE_INTERNAL_LABEL (@var{string}, @var{prefix}, @var{num})
! A C statement to store into the string @var{string} a label whose
! name is made from the string @var{prefix} and the number @var{num}.
  
  This string, when output subsequently by @code{ASM_OUTPUT_LABELREF},
--- 9483,9495 ----
  
  @item ASM_OUTPUT_LABELREF (@var{stream}, @var{name})
! A C statement to output to the stdio stream @var{stream} a reference
! in assembler syntax to a label named @var{name}.  The character
! @samp{_} should be added to the front of the name, if that is
! customary on your operating system, as it is in most Berkeley Unix
! systems.  This macro is used in @code{assemble_name}.
  
  @item ASM_GENERATE_INTERNAL_LABEL (@var{string}, @var{prefix}, @var{num})
! A C statement to store into the string @var{string} a label whose name
! is made from the string @var{prefix} and the number @var{num}.
  
  This string, when output subsequently by @code{ASM_OUTPUT_LABELREF},
***************
*** 8810,8815 ****
  specially.  The first three arguments are the same as for
  @code{ASM_OUTPUT_INTERNAL_LABEL}; the fourth argument is the
! jump-table which follows (a @samp{jump_insn} containing an
! @samp{addr_vec} or @samp{addr_diff_vec}).
  
  This feature is used on system V to output a @code{swbeg} statement
--- 9513,9518 ----
  specially.  The first three arguments are the same as for
  @code{ASM_OUTPUT_INTERNAL_LABEL}; the fourth argument is the
! jump-table which follows (a @code{jump_insn} containing an
! @code{addr_vec} or @code{addr_diff_vec}).
  
  This feature is used on system V to output a @code{swbeg} statement
***************
*** 8820,8828 ****
  
  @item ASM_OUTPUT_CASE_END (@var{stream}, @var{num}, @var{table})
! Define this if something special must be output at the end of a jump-table.
! The definition should be a C statement to be executed after the assembler
! code for the table is written.  It should write the appropriate code to
! stdio stream @var{stream}.  The argument @var{table} is the jump-table
! insn, and @var{num} is the label-number of the preceding label.
  
  If this macro is not defined, nothing special is output at the end of
--- 9523,9532 ----
  
  @item ASM_OUTPUT_CASE_END (@var{stream}, @var{num}, @var{table})
! Define this if something special must be output at the end of a
! jump-table.  The definition should be a C statement to be executed
! after the assembler code for the table is written.  It should write
! the appropriate code to stdio stream @var{stream}.  The argument
! @var{table} is the jump-table insn, and @var{num} is the label-number
! of the preceding label.
  
  If this macro is not defined, nothing special is output at the end of
***************
*** 8919,8922 ****
--- 9623,9634 ----
  assembler expression.@refill
  
+ @item ASM_OUTPUT_DOUBLE_INT (@var{stream}, @var{exp})
+ A C statement to output to the stdio stream @var{stream} an assembler
+ instruction to assemble a @code{long long} constant whose value is
+ @var{exp}.  The argument @var{exp} will be an RTL expression which
+ represents a constant value.  It may be a @code{const_double} RTX,
+ or it may be an ordinary single-precision constant.  In the latter
+ case, you should zero-extend it.
+ 
  @item ASM_OUTPUT_BYTE (@var{stream}, @var{value})
  A C statement to output to the stdio stream @var{stream} an assembler
***************
*** 8969,8972 ****
--- 9681,9692 ----
  static variables are output.
  
+ @item ASM_OUTPUT_SOURCE_FILENAME (@var{stream}, @var{name})
+ A C statment to output DBX or SDB debugging information which indicates
+ that filename @var{name} is the current source file to the stdio stream
+ @var{stream}.
+ 
+ This macro need not be defined if the standard form of debugging
+ information for the debugger in use is appropriate.
+ 
  @item ASM_OUTPUT_SOURCE_LINE (@var{stream}, @var{line})
  A C statment to output DBX or SDB debugging information before code
***************
*** 9017,9020 ****
--- 9737,9743 ----
  @var{ptr} over whatever text should not be output normally.
  
+ If you need to look at the operand values, they can be found as the
+ elements of @code{recog_operand}.
+ 
  If the macro definition does nothing, the instruction is output
  in the usual way.
***************
*** 9063,9066 ****
--- 9786,9796 ----
  with a null pointer for @var{x} and the punctuation character for
  @var{code}.
+ 
+ @item PRINT_OPERAND_PUNCT_VALID_P (@var{code})
+ A C expression which evaluates to true if @var{code} is a valid
+ punctuation character for use in the @code{PRINT_OPERAND} macro.  If
+ @code{PRINT_OPERAND_PUNCT_VALID_P} is not defined, it means that no
+ punctuation characters (except for the standard one, @samp{%}) are used
+ in this way.
  
  @item PRINT_OPERAND_ADDRESS (@var{stream}, @var{x})
diff -rc2N gcc-1.35/gencodes.c gcc-1.36/gencodes.c
*** gcc-1.35/gencodes.c	Wed Feb 22 11:53:57 1989
--- gcc-1.36/gencodes.c	Thu Sep  7 23:17:44 1989
***************
*** 36,39 ****
--- 36,40 ----
  
  void fatal ();
+ void fancy_abort ();
  
  int insn_code_number;
***************
*** 73,76 ****
--- 74,78 ----
  void
  fatal (s, a1, a2)
+      char *s;
  {
    fprintf (stderr, "gencodes: ");
***************
*** 78,81 ****
--- 80,92 ----
    fprintf (stderr, "\n");
    exit (FATAL_EXIT_CODE);
+ }
+ 
+ /* More 'friendly' abort that prints the line and file.
+    config.h can #define abort fancy_abort if you like that sort of thing.  */
+ 
+ void
+ fancy_abort ()
+ {
+   fatal ("Internal gcc abort.");
  }
  \f


diff -rc2N gcc-1.35/genconfig.c gcc-1.36/genconfig.c
*** gcc-1.35/genconfig.c	Wed Feb 22 11:53:55 1989
--- gcc-1.36/genconfig.c	Thu Sep  7 23:17:57 1989
***************
*** 44,47 ****
--- 44,48 ----
  
  void fatal ();
+ void fancy_abort ();
  
  void
***************
*** 190,193 ****
--- 191,195 ----
  void
  fatal (s, a1, a2)
+      char *s;
  {
    fprintf (stderr, "genconfig: ");
***************
*** 196,199 ****
--- 198,210 ----
    exit (FATAL_EXIT_CODE);
  }
+ 
+ /* More 'friendly' abort that prints the line and file.
+    config.h can #define abort fancy_abort if you like that sort of thing.  */
+ 
+ void
+ fancy_abort ()
+ {
+   fatal ("Internal gcc abort.");
+ }
  \f


  int
***************
*** 242,246 ****
      }
  
!   printf ("\n#define MAX_RECOG_OPERANDS %d\n", max_recog_operands_flag + 1);
  
    if (max_dup_operands_flag == 0)
--- 253,258 ----
      }
  
!   /* 3 more than needed for this md file, for the sake of asm constructs.  */
!   printf ("\n#define MAX_RECOG_OPERANDS %d\n", max_recog_operands_flag + 4);
  
    if (max_dup_operands_flag == 0)
***************
*** 247,252 ****
      max_dup_operands_flag = 1;
    printf ("\n#define MAX_DUP_OPERANDS %d\n", max_dup_operands_flag);
- 
-   printf ("#define MAX_CLOBBERS_PER_INSN %d\n", max_clobbers_per_insn_flag);
  
    if (register_constraint_flag)
--- 259,262 ----
diff -rc2N gcc-1.35/genemit.c gcc-1.36/genemit.c
*** gcc-1.35/genemit.c	Wed Feb 22 11:53:52 1989
--- gcc-1.36/genemit.c	Thu Sep  7 23:18:12 1989
***************
*** 33,36 ****
--- 33,37 ----
  
  void fatal ();
+ void fancy_abort ();
  
  int max_opno;
***************
*** 388,391 ****
--- 389,393 ----
  void
  fatal (s, a1, a2)
+      char *s;
  {
    fprintf (stderr, "genemit: ");
***************
*** 394,397 ****
--- 396,408 ----
    exit (FATAL_EXIT_CODE);
  }
+ 
+ /* More 'friendly' abort that prints the line and file.
+    config.h can #define abort fancy_abort if you like that sort of thing.  */
+ 
+ void
+ fancy_abort ()
+ {
+   fatal ("Internal gcc abort.");
+ }
  \f


  int
***************
*** 432,438 ****
    printf ("#include \"real.h\"\n");
    printf ("#include \"insn-config.h\"\n\n");
    printf ("extern char *insn_operand_constraint[][MAX_RECOG_OPERANDS];\n\n");
    printf ("extern rtx recog_operand[];\n");
!   printf ("#define operands recog_operand\n\n");
    printf ("#define FAIL do { end_sequence (); return 0;} while (0)\n\n");
    printf ("#define DONE goto _done\n\n");
--- 443,450 ----
    printf ("#include \"real.h\"\n");
    printf ("#include \"insn-config.h\"\n\n");
+   printf ("#include \"insn-flags.h\"\n\n");
    printf ("extern char *insn_operand_constraint[][MAX_RECOG_OPERANDS];\n\n");
    printf ("extern rtx recog_operand[];\n");
!   printf ("#define operands emit_operand\n\n");
    printf ("#define FAIL do { end_sequence (); return 0;} while (0)\n\n");
    printf ("#define DONE goto _done\n\n");
diff -rc2N gcc-1.35/genextract.c gcc-1.36/genextract.c
*** gcc-1.35/genextract.c	Wed Feb 22 11:53:51 1989
--- gcc-1.36/genextract.c	Sun Sep 24 01:26:59 1989
***************
*** 32,39 ****
  extern void free ();
  
- void walk_rtx ();
- void print_path ();
- void fatal ();
- 
  /* Number instruction patterns handled, starting at 0 for first one.  */
  
--- 32,35 ----
***************
*** 58,61 ****
--- 54,62 ----
  };
  
+ void walk_rtx ();
+ void print_path ();
+ void fatal ();
+ void fancy_abort ();
+ \f


  void
  gen_insn (insn)
***************
*** 107,111 ****
    printf ("}\n\n");
  }
! 
  void
  walk_rtx (x, path)
--- 108,112 ----
    printf ("}\n\n");
  }
! \f


  void
  walk_rtx (x, path)
***************
*** 236,239 ****
--- 237,241 ----
  void
  fatal (s, a1, a2)
+      char *s;
  {
    fprintf (stderr, "genextract: ");
***************
*** 242,245 ****
--- 244,256 ----
    exit (FATAL_EXIT_CODE);
  }
+ 
+ /* More 'friendly' abort that prints the line and file.
+    config.h can #define abort fancy_abort if you like that sort of thing.  */
+ 
+ void
+ fancy_abort ()
+ {
+   fatal ("Internal gcc abort.");
+ }
  \f


  int
***************
*** 327,333 ****
    printf ("\n};\n\n");
  
    printf ("void\ninsn_extract (insn)\n");
    printf ("     rtx insn;\n");
!   printf ("{\n  if (INSN_CODE (insn) == -1) abort ();\n");
    printf ("  (*insn_extract_fn[INSN_CODE (insn)]) (PATTERN (insn));\n}\n");
  
--- 338,345 ----
    printf ("\n};\n\n");
  
+   printf ("void fatal_insn_not_found ();\n\n");
    printf ("void\ninsn_extract (insn)\n");
    printf ("     rtx insn;\n");
!   printf ("{\n  if (INSN_CODE (insn) == -1) fatal_insn_not_found (insn);\n");
    printf ("  (*insn_extract_fn[INSN_CODE (insn)]) (PATTERN (insn));\n}\n");
  
diff -rc2N gcc-1.35/genflags.c gcc-1.36/genflags.c
*** gcc-1.35/genflags.c	Wed Feb 22 11:53:49 1989
--- gcc-1.36/genflags.c	Thu Sep  7 23:18:05 1989
***************
*** 36,39 ****
--- 36,40 ----
  
  void fatal ();
+ void fancy_abort ();
  
  void
***************
*** 75,78 ****
--- 76,80 ----
  void
  fatal (s, a1, a2)
+      char *s;
  {
    fprintf (stderr, "genflags: ");
***************
*** 80,83 ****
--- 82,94 ----
    fprintf (stderr, "\n");
    exit (FATAL_EXIT_CODE);
+ }
+ 
+ /* More 'friendly' abort that prints the line and file.
+    config.h can #define abort fancy_abort if you like that sort of thing.  */
+ 
+ void
+ fancy_abort ()
+ {
+   fatal ("Internal gcc abort.");
  }
  \f


diff -rc2N gcc-1.35/genoutput.c gcc-1.36/genoutput.c
*** gcc-1.35/genoutput.c	Thu Apr  6 11:14:26 1989
--- gcc-1.36/genoutput.c	Mon Sep 11 20:44:23 1989
***************
*** 111,114 ****
--- 111,115 ----
  
  void fatal ();
+ void fancy_abort ();
  void error ();
  void mybcopy ();
***************
*** 328,332 ****
    printf ("  };\n");
  
!   printf ("\nconst INSN_MACHINE_INFO insn_machine_info[] =\n  {\n");
    for (d = insn_data; d; d = d->next)
      {
--- 329,334 ----
    printf ("  };\n");
  
!   printf ("\n#ifndef DEFAULT_MACHINE_INFO\n#define DEFAULT_MACHINE_INFO 0\n");
!   printf ("#endif\n\nconst INSN_MACHINE_INFO insn_machine_info[] =\n  {\n");
    for (d = insn_data; d; d = d->next)
      {
***************
*** 334,338 ****
  	printf ("    {%s},\n", d->machine_info);
        else
! 	printf("     {0},\n");
      }
    printf("  };\n");
--- 336,340 ----
  	printf ("    {%s},\n", d->machine_info);
        else
! 	printf("     { DEFAULT_MACHINE_INFO },\n");
      }
    printf("  };\n");
***************
*** 517,521 ****
    d->outfun = 1;
  
!   printf ("\nchar *\n");
    printf ("output_%d (operands, insn)\n", d->code_number);
    printf ("     rtx *operands;\n");
--- 519,523 ----
    d->outfun = 1;
  
!   printf ("\nstatic char *\n");
    printf ("output_%d (operands, insn)\n", d->code_number);
    printf ("     rtx *operands;\n");
***************
*** 592,596 ****
    d->outfun = 1;
  
!   printf ("\nchar *\n");
    printf ("output_%d (operands, insn)\n", d->code_number);
    printf ("     rtx *operands;\n");
--- 594,598 ----
    d->outfun = 1;
  
!   printf ("\nstatic char *\n");
    printf ("output_%d (operands, insn)\n", d->code_number);
    printf ("     rtx *operands;\n");
***************
*** 695,698 ****
--- 697,701 ----
  void
  fatal (s, a1, a2)
+      char *s;
  {
    fprintf (stderr, "genoutput: ");
***************
*** 702,707 ****
--- 705,720 ----
  }
  
+ /* More 'friendly' abort that prints the line and file.
+    config.h can #define abort fancy_abort if you like that sort of thing.  */
+ 
+ void
+ fancy_abort ()
+ {
+   fatal ("Internal gcc abort.");
+ }
+ 
  void
  error (s, a1, a2)
+      char *s;
  {
    fprintf (stderr, "genoutput: ");
diff -rc2N gcc-1.35/genpeep.c gcc-1.36/genpeep.c
*** gcc-1.35/genpeep.c	Wed Feb 22 11:53:45 1989
--- gcc-1.36/genpeep.c	Thu Sep  7 23:18:26 1989
***************
*** 32,42 ****
  extern void free ();
  
- void match_rtx ();
- void gen_exp ();
- void fatal ();
- 
- 
- int max_opno;
- 
  /* While tree-walking an instruction pattern, we keep a chain
     of these `struct link's to record how to get down to the
--- 32,35 ----
***************
*** 52,55 ****
--- 45,55 ----
  };
  
+ void match_rtx ();
+ void gen_exp ();
+ void fatal ();
+ void fancy_abort ();
+ 
+ int max_opno;
+ 
  /* Number of operands used in current peephole definition.  */
  
***************
*** 138,142 ****
      printf ("  delete_for_peephole (NEXT_INSN (ins1), insn);\n");
  
!   printf ("  return 1;\n");
  
    printf (" L%d:\n\n", insn_code_number);
--- 138,144 ----
      printf ("  delete_for_peephole (NEXT_INSN (ins1), insn);\n");
  
!   /* See reload1.c for insertion of NOTE which guarantees that this
!      cannot be zero.  */
!   printf ("  return NEXT_INSN (insn);\n");
  
    printf (" L%d:\n\n", insn_code_number);
***************
*** 202,205 ****
--- 204,214 ----
  	printf ("  if (! %s (x, %smode)) goto L%d;\n",
  		XSTR (x, 1), GET_MODE_NAME (GET_MODE (x)), fail_label);
+       link.next = path;
+       link.vecelt = -1;
+       for (i = 0; i < XVECLEN (x, 2); i++)
+ 	{
+ 	  link.pos = i;
+ 	  match_rtx (XVECEXP (x, 2, i), &link, fail_label);
+ 	}
        return;
  
***************
*** 333,336 ****
--- 342,346 ----
  void
  fatal (s, a1, a2)
+      char *s;
  {
    fprintf (stderr, "genpeep: ");
***************
*** 339,342 ****
--- 349,361 ----
    exit (FATAL_EXIT_CODE);
  }
+ 
+ /* More 'friendly' abort that prints the line and file.
+    config.h can #define abort fancy_abort if you like that sort of thing.  */
+ 
+ void
+ fancy_abort ()
+ {
+   fatal ("Internal gcc abort.");
+ }
  \f


  int
***************
*** 377,381 ****
    printf ("#define operands peep_operand\n\n");
  
!   printf ("int\npeephole (ins1)\n     rtx ins1;\n{\n");
    printf ("  rtx insn, x, pat;\n");
    printf ("  int i;\n\n");
--- 396,400 ----
    printf ("#define operands peep_operand\n\n");
  
!   printf ("rtx\npeephole (ins1)\n     rtx ins1;\n{\n");
    printf ("  rtx insn, x, pat;\n");
    printf ("  int i;\n\n");
diff -rc2N gcc-1.35/genrecog.c gcc-1.36/genrecog.c
*** gcc-1.35/genrecog.c	Wed Feb 22 11:53:39 1989
--- gcc-1.36/genrecog.c	Thu Sep  7 23:18:33 1989
***************
*** 131,134 ****
--- 131,135 ----
  char *concat ();
  void fatal ();
+ void fancy_abort ();
  void mybzero ();
  \f


***************
*** 992,995 ****
--- 993,997 ----
  void
  fatal (s, a1, a2)
+      char *s;
  {
    fprintf (stderr, "genrecog: ");
***************
*** 1000,1003 ****
--- 1002,1014 ----
    exit (FATAL_EXIT_CODE);
  }
+ 
+ /* More 'friendly' abort that prints the line and file.
+    config.h can #define abort fancy_abort if you like that sort of thing.  */
+ 
+ void
+ fancy_abort ()
+ {
+   fatal ("Internal gcc abort.");
+ }
  \f


  int
***************
*** 1051,1054 ****
--- 1062,1066 ----
    printf ("#include \"insn-config.h\"\n");
    printf ("#include \"recog.h\"\n");
+   printf ("#include \"real.h\"\n");
    printf ("\n\
  /* `recog' contains a decision tree\n\
diff -rc2N gcc-1.35/global-alloc.c gcc-1.36/global-alloc.c
*** gcc-1.35/global-alloc.c	Wed Feb 22 11:53:41 1989
--- gcc-1.36/global-alloc.c	Thu Aug 24 15:47:49 1989
***************
*** 331,335 ****
  	/ (reg_live_length[r2] * allocno_size[*v2]))
         * 10000);
!   return pri2 - pri1;
  }
  \f


--- 331,340 ----
  	/ (reg_live_length[r2] * allocno_size[*v2]))
         * 10000);
!   if (pri2 - pri1)
!     return pri2 - pri1;
! 
!   /* If regs are equally good, sort by allocno,
!      so that the results of qsort leave nothing to chance.  */
!   return *v1 - *v2;
  }
  \f


***************
*** 343,346 ****
--- 348,354 ----
    short *block_start_allocnos;
  
+   /* Make a vector that mark_reg_{store,clobber} will store in.  */
+   regs_set = (rtx *) alloca (max_parallel * sizeof (rtx) * 2);
+ 
    block_start_allocnos = (short *) alloca (max_allocno * sizeof (short));
  
***************
*** 410,415 ****
  	  register rtx link;
  
! 	  /* Make a vector that mark_reg_{store,clobber} will store in.  */
! 	  regs_set = (rtx *) alloca (max_parallel * sizeof (rtx));
  	  n_regs_set = 0;
  
--- 418,423 ----
  	  register rtx link;
  
! 	  /* Make regs_set an empty set.  */
! 
  	  n_regs_set = 0;
  
***************
*** 416,420 ****
  	  if (code == INSN || code == CALL_INSN || code == JUMP_INSN)
  	    {
! 	      /* Mark any registers clobbered INSN as live,
  		 so they conflict with the inputs.  */
  
--- 424,428 ----
  	  if (code == INSN || code == CALL_INSN || code == JUMP_INSN)
  	    {
! 	      /* Mark any registers clobbered by INSN as live,
  		 so they conflict with the inputs.  */
  
***************
*** 428,432 ****
  
  	      /* Mark any registers set in INSN as live,
! 		 and mark them as conflicting with all other live regs.  */
  
  	      note_stores (PATTERN (insn), mark_reg_store);
--- 436,442 ----
  
  	      /* Mark any registers set in INSN as live,
! 		 and mark them as conflicting with all other live regs.
! 		 Clobbers are processed again, so they conflict with
! 		 the registers that are set.  */
  
  	      note_stores (PATTERN (insn), mark_reg_store);
***************
*** 775,787 ****
  
     REG might actually be something other than a register;
!    if so, we do nothing.  Also ignore CLOBBERs; they are
!    processed at a different time using mark_reg_clobber
!    and we don't want to do them twice.  */
  
  static void
! mark_reg_store (reg, setter)
!      rtx reg, setter;
  {
    register int regno;
  
    /* WORD is which word of a multi-register group is being stored.
--- 785,798 ----
  
     REG might actually be something other than a register;
!    if so, we do nothing.
  
+    CLOBBERs are processed here by calling mark_reg_clobber.  */ 
+ 
  static void
! mark_reg_store (orig_reg, setter)
!      rtx orig_reg, setter;
  {
    register int regno;
+   register rtx reg = orig_reg;
  
    /* WORD is which word of a multi-register group is being stored.
***************
*** 791,797 ****
    int word = 0;
  
-   if (GET_CODE (setter) != SET)
-     return;
- 
    if (GET_CODE (reg) == SUBREG)
      {
--- 802,805 ----
***************
*** 802,805 ****
--- 810,820 ----
    if (GET_CODE (reg) != REG)
      return;
+ 
+   if (GET_CODE (setter) != SET)
+     {
+       /* A clobber of a register should be processed here too.  */
+       mark_reg_clobber (orig_reg, setter);
+       return;
+     }
  
    regs_set[n_regs_set++] = reg;
diff -rc2N gcc-1.35/gnulib.c gcc-1.36/gnulib.c
*** gcc-1.35/gnulib.c	Sun Feb 12 07:07:37 1989
--- gcc-1.36/gnulib.c	Mon Aug 14 14:52:15 1989
***************
*** 23,40 ****
  #endif
  
- union double_di { double d; int i[2]; };
  union flt_or_int { int i; float f; };
  
- union longlong { int i[2]; unsigned int ui[2]; };
  
- 
- #ifdef WORDS_BIG_ENDIAN
- #define HIGH 0
- #define LOW 1
- #else
- #define HIGH 1
- #define LOW 0
- #endif
- 
  #ifdef L_eprintf
  #include <stdio.h>
--- 23,29 ----
***************
*** 139,176 ****
  }
  #endif
- 
- #ifdef L_cmpdi2
- SItype
- __cmpdi2 (a, b)
-      union longlong a, b;
- {
-   if (a.i[HIGH] < b.i[HIGH])
-     return 0;
-   else if (a.i[HIGH] > b.i[HIGH])
-     return 2;
-   if (a.ui[LOW] < b.ui[LOW])
-     return 0;
-   else if (a.ui[LOW] > b.ui[LOW])
-     return 2;
-   return 1;
- }
- #endif
- 
- #ifdef L_ucmpdi2
- SItype
- __ucmpdi2 (a, b)
-      union longlong a, b;
- {
-   if (a.ui[HIGH] < b.ui[HIGH])
-     return 0;
-   else if (a.ui[HIGH] > b.ui[HIGH])
-     return 2;
-   if (a.ui[LOW] < b.ui[LOW])
-     return 0;
-   else if (a.ui[LOW] > b.ui[LOW])
-     return 2;
-   return 1;
- }
- #endif
  \f


  #ifdef L_divdf3
--- 128,131 ----
***************
*** 241,256 ****
  #endif
  
- #ifdef L_fixunsdfdi
- double
- __fixunsdfdi (a)
-      double a;
- {
-   union double_di u;
-   u.i[LOW] = (unsigned int) a;
-   u.i[HIGH] = 0;
-   return u.d;
- }
- #endif
- 
  #ifdef L_fixdfsi
  SItype
--- 196,199 ----
***************
*** 262,277 ****
  #endif
  
- #ifdef L_fixdfdi
- double
- __fixdfdi (a)
-      double a;
- {
-   union double_di u;
-   u.i[LOW] = (int) a;
-   u.i[HIGH] = (int) a < 0 ? -1 : 0;
-   return u.d;
- }
- #endif
- 
  #ifdef L_floatsidf
  double
--- 205,208 ----
***************
*** 282,297 ****
  }
  #endif
- 
- #ifdef L_floatdidf
- double
- __floatdidf (u)
-      union double_di u;
- {
-   register double hi
-     = ((double) u.i[HIGH]) * (double) 0x10000 * (double) 0x10000;
-   register double low = (unsigned int) u.i[LOW];
-   return hi + low;
- }
- #endif
  \f


  #ifdef L_addsf3
--- 213,216 ----
***************
*** 467,471 ****
    for (i = 0; i < nelts; i++)
      {
!       ctor (p);
        p += size;
      }
--- 386,390 ----
    for (i = 0; i < nelts; i++)
      {
!       (*ctor) (p);
        p += size;
      }
***************
*** 530,534 ****
      {
        ptr -= size;
!       dtor (ptr, auto_delete);
      }
  
--- 449,453 ----
      {
        ptr -= size;
!       (*dtor) (ptr, auto_delete);
      }
  
***************
*** 538,540 ****
  
  #endif
- 
--- 457,458 ----
diff -rc2N gcc-1.35/gnulib2.c gcc-1.36/gnulib2.c
*** gcc-1.35/gnulib2.c	Sun Apr 23 13:07:47 1989
--- gcc-1.36/gnulib2.c	Sun Sep 17 18:08:10 1989
***************
*** 5,8 ****
--- 5,12 ----
  #include <stddef.h>
  
+ #ifndef SItype
+ #define SItype long int
+ #endif
+ 
  /* long long ints are pairs of long ints in the order determined by
     WORDS_BIG_ENDIAN.  */
***************
*** 14,17 ****
--- 18,34 ----
  #endif
  
+ /* We need this union to unpack/pack longlongs, since we don't have
+    any arithmetic yet.  Incoming long long parameters are stored
+    into the `ll' field, and the unpacked result is read from the struct
+    longlong.  */
+ 
+ typedef union
+ {
+   struct longlong s;
+   long long ll;
+   SItype i[2];
+   unsigned SItype ui[2];
+ } long_long;
+ 
  /* Internally, long long ints are strings of unsigned shorts in the
     order determined by BYTES_BIG_ENDIAN.  */
***************
*** 22,25 ****
--- 39,46 ----
  #ifdef BYTES_BIG_ENDIAN
  
+ /* Note that HIGH and LOW do not describe the order
+    of words in a long long.  They describe the order of words
+    in vectors ordered according to the byte order.  */
+ 
  #define HIGH 0
  #define LOW 1
***************
*** 48,57 ****
  /* These algorithms are all straight out of Knuth, vol. 2, sec. 4.3.1. */
  
- #define bdiv __div_internal
- 
  static int badd ();
  static int bsub ();
  static void bmul ();
- static void bdiv ();
  static int bneg ();
  static int bshift ();
--- 69,75 ----
***************
*** 58,78 ****
  
  #ifdef L_adddi3
! struct longlong 
  __adddi3 (u, v)
!      struct longlong u, v;
  {
    long a[2], b[2], c[2];
!   struct longlong w;
  
!   a[HIGH] = u.high;
!   a[LOW] = u.low;
!   b[HIGH] = v.high;
!   b[LOW] = v.low;
  
    badd (a, b, c, sizeof c);
  
!   w.high = c[HIGH];
!   w.low = c[LOW];
!   return w;
  }
  
--- 76,100 ----
  
  #ifdef L_adddi3
! long long 
  __adddi3 (u, v)
!      long long u, v;
  {
    long a[2], b[2], c[2];
!   long_long w;
!   long_long uu, vv;
  
!   uu.ll = u;
!   vv.ll = v;
! 
!   a[HIGH] = uu.s.high;
!   a[LOW] = uu.s.low;
!   b[HIGH] = vv.s.high;
!   b[LOW] = vv.s.low;
  
    badd (a, b, c, sizeof c);
  
!   w.s.high = c[HIGH];
!   w.s.low = c[LOW];
!   return w.ll;
  }
  
***************
*** 90,94 ****
    for (i = little_end (n); is_not_msd (i, n); i = next_msd (i))
      {
!       acc += a[i] + b[i];
        c[i] = acc & low16;
        acc = acc >> 16;
--- 112,117 ----
    for (i = little_end (n); is_not_msd (i, n); i = next_msd (i))
      {
!       /* Widen before adding to avoid loss of high bits.  */
!       acc += (unsigned long) a[i] + b[i];
        c[i] = acc & low16;
        acc = acc >> 16;
***************
*** 98,119 ****
  #endif
  
  #ifdef L_subdi3
! struct longlong 
  __subdi3 (u, v)
!      struct longlong u, v;
  {
    long a[2], b[2], c[2];
!   struct longlong w;
  
!   a[HIGH] = u.high;
!   a[LOW] = u.low;
!   b[HIGH] = v.high;
!   b[LOW] = v.low;
  
    bsub (a, b, c, sizeof c);
  
!   w.high = c[HIGH];
!   w.low = c[LOW];
!   return w;
  }
  
--- 121,349 ----
  #endif
  
+ #ifdef L_anddi3
+ long long 
+ __anddi3 (u, v)
+      long long u, v;
+ {
+   long_long w;
+   long_long uu, vv;
+ 
+   uu.ll = u;
+   vv.ll = v;
+ 
+   w.s.high = uu.s.high & vv.s.high;
+   w.s.low = uu.s.low & vv.s.low;
+ 
+   return w.ll;
+ }
+ #endif
+ 
+ #ifdef L_iordi3
+ long long 
+ __iordi3 (u, v)
+      long long u, v;
+ {
+   long_long w;
+   long_long uu, vv;
+ 
+   uu.ll = u;
+   vv.ll = v;
+ 
+   w.s.high = uu.s.high | vv.s.high;
+   w.s.low = uu.s.low | vv.s.low;
+ 
+   return w.ll;
+ }
+ #endif
+ 
+ #ifdef L_xordi3
+ long long 
+ __xordi3 (u, v)
+      long long u, v;
+ {
+   long_long w;
+   long_long uu, vv;
+ 
+   uu.ll = u;
+   vv.ll = v;
+ 
+   w.s.high = uu.s.high ^ vv.s.high;
+   w.s.low = uu.s.low ^ vv.s.low;
+ 
+   return w.ll;
+ }
+ #endif
+ 
+ #ifdef L_one_cmpldi2
+ long long
+ __one_cmpldi2 (u)
+      long long u;
+ {
+   long_long w;
+   long_long uu;
+ 
+   uu.ll = u;
+ 
+   w.s.high = ~uu.s.high;
+   w.s.low = ~uu.s.low;
+ 
+   return w.ll;
+ }
+ #endif
+ 
+ #ifdef L_lshldi3
+ long long
+ __lshldi3 (u, b)
+      long long u;
+      long int b;
+ {
+   long_long w;
+   unsigned long carries;
+   int bm;
+   long_long uu;
+ 
+   if (b == 0)
+     return u;
+ 
+   uu.ll = u;
+ 
+   bm = (sizeof (int) * BITS_PER_UNIT) - b;
+   if (bm <= 0)
+     {
+       w.s.low = 0;
+       w.s.high = (unsigned long)uu.s.low << -bm;
+     }
+   else
+     {
+       carries = (unsigned long)uu.s.low >> bm;
+       w.s.low = (unsigned long)uu.s.low << b;
+       w.s.high = ((unsigned long)uu.s.high << b) | carries;
+     }
+ 
+   return w.ll;
+ }
+ #endif
+ 
+ #ifdef L_lshrdi3
+ long long
+ __lshrdi3 (u, b)
+      long long u;
+      long int b;
+ {
+   long_long w;
+   unsigned long carries;
+   int bm;
+   long_long uu;
+ 
+   if (b == 0)
+     return u;
+ 
+   uu.ll = u;
+ 
+   bm = (sizeof (int) * BITS_PER_UNIT) - b;
+   if (bm <= 0)
+     {
+       w.s.high = 0;
+       w.s.low = (unsigned long)uu.s.high >> -bm;
+     }
+   else
+     {
+       carries = (unsigned long)uu.s.high << bm;
+       w.s.high = (unsigned long)uu.s.high >> b;
+       w.s.low = ((unsigned long)uu.s.low >> b) | carries;
+     }
+ 
+   return w.ll;
+ }
+ #endif
+ 
+ #ifdef L_ashldi3
+ long long
+ __ashldi3 (u, b)
+      long long u;
+      long int b;
+ {
+   long_long w;
+   unsigned long carries;
+   int bm;
+   long_long uu;
+ 
+   if (b == 0)
+     return u;
+ 
+   uu.ll = u;
+ 
+   bm = (sizeof (int) * BITS_PER_UNIT) - b;
+   if (bm <= 0)
+     {
+       w.s.low = 0;
+       w.s.high = (unsigned long)uu.s.low << -bm;
+     }
+   else
+     {
+       carries = (unsigned long)uu.s.low >> bm;
+       w.s.low = (unsigned long)uu.s.low << b;
+       w.s.high = ((unsigned long)uu.s.high << b) | carries;
+     }
+ 
+   return w.ll;
+ }
+ #endif
+ 
+ #ifdef L_ashrdi3
+ long long
+ __ashrdi3 (u, b)
+      long long u;
+      long int b;
+ {
+   long_long w;
+   unsigned long carries;
+   int bm;
+   long_long uu;
+ 
+   if (b == 0)
+     return u;
+ 
+   uu.ll = u;
+ 
+   bm = (sizeof (int) * BITS_PER_UNIT) - b;
+   if (bm <= 0)
+     {
+       w.s.high = uu.s.high >> 31; /* just to make w.s.high 1..1 or 0..0 */
+       w.s.low = uu.s.high >> -bm;
+     }
+   else
+     {
+       carries = (unsigned long)uu.s.high << bm;
+       w.s.high = uu.s.high >> b;
+       w.s.low = ((unsigned long)uu.s.low >> b) | carries;
+     }
+ 
+   return w.ll;
+ }
+ #endif
+ 
  #ifdef L_subdi3
! long long 
  __subdi3 (u, v)
!      long long u, v;
  {
    long a[2], b[2], c[2];
!   long_long w;
!   long_long uu, vv;
  
!   uu.ll = u;
!   vv.ll = v;
! 
!   a[HIGH] = uu.s.high;
!   a[LOW] = uu.s.low;
!   b[HIGH] = vv.s.high;
!   b[LOW] = vv.s.low;
  
    bsub (a, b, c, sizeof c);
  
!   w.s.high = c[HIGH];
!   w.s.low = c[LOW];
!   return w.ll;
  }
  
***************
*** 131,135 ****
    for (i = little_end (n); is_not_msd (i, n); i = next_msd (i))
      {
!       acc += a[i] - b[i];
        c[i] = acc & low16;
        acc = acc >> 16;
--- 361,366 ----
    for (i = little_end (n); is_not_msd (i, n); i = next_msd (i))
      {
!       /* Widen before subtracting to avoid loss of high bits.  */
!       acc += (long) a[i] - b[i];
        c[i] = acc & low16;
        acc = acc >> 16;
***************
*** 140,160 ****
  
  #ifdef L_muldi3
! struct longlong 
  __muldi3 (u, v)
!      struct longlong u, v;
  {
    long a[2], b[2], c[2][2];
!   struct longlong w;
  
!   a[HIGH] = u.high;
!   a[LOW] = u.low;
!   b[HIGH] = v.high;
!   b[LOW] = v.low;
  
    bmul (a, b, c, sizeof a, sizeof b);
  
!   w.high = c[LOW][HIGH];
!   w.low = c[LOW][LOW];
!   return w;
  }
  
--- 371,395 ----
  
  #ifdef L_muldi3
! long long 
  __muldi3 (u, v)
!      long long u, v;
  {
    long a[2], b[2], c[2][2];
!   long_long w;
!   long_long uu, vv;
  
!   uu.ll = u;
!   vv.ll = v;
! 
!   a[HIGH] = uu.s.high;
!   a[LOW] = uu.s.low;
!   b[HIGH] = vv.s.high;
!   b[LOW] = vv.s.low;
  
    bmul (a, b, c, sizeof a, sizeof b);
  
!   w.s.high = c[LOW][HIGH];
!   w.s.low = c[LOW][LOW];
!   return w.ll;
  }
  
***************
*** 174,185 ****
    for (j = little_end (n); is_not_msd (j, n); j = next_msd (j))
      {
        acc = 0;
        for (i = little_end (m); is_not_msd (i, m); i = next_msd (i))
  	{
! 	  acc += a[i] * b[j] + (c + next_lsd (j))[i];
! 	  (c + next_lsd (j))[i] = acc & low16;
  	  acc = acc >> 16;
  	}
!       c[j] = acc;
      }
  }
--- 409,422 ----
    for (j = little_end (n); is_not_msd (j, n); j = next_msd (j))
      {
+       unsigned short *c1 = c + j + little_end (2);
        acc = 0;
        for (i = little_end (m); is_not_msd (i, m); i = next_msd (i))
  	{
! 	  /* Widen before arithmetic to avoid loss of high bits.  */
! 	  acc += (unsigned long) a[i] * b[j] + c1[i];
! 	  c1[i] = acc & low16;
  	  acc = acc >> 16;
  	}
!       c1[i] = acc;
      }
  }
***************
*** 223,245 ****
  
  #ifdef L_udivdi3
! struct longlong 
  __udivdi3 (u, v)
!      struct longlong u, v;
  {
    unsigned long a[2][2], b[2], q[2], r[2];
!   struct longlong w;
  
    a[HIGH][HIGH] = 0;
    a[HIGH][LOW] = 0;
!   a[LOW][HIGH] = u.high;
!   a[LOW][LOW] = u.low;
!   b[HIGH] = v.high;
!   b[LOW] = v.low;
  
!   bdiv (a, b, q, r, sizeof a, sizeof b);
! 
!   w.high = q[HIGH];
!   w.low = q[LOW];
!   return w;
  }
  #endif
--- 460,486 ----
  
  #ifdef L_udivdi3
! long long 
  __udivdi3 (u, v)
!      long long u, v;
  {
    unsigned long a[2][2], b[2], q[2], r[2];
!   long_long w;
!   long_long uu, vv;
  
+   uu.ll = u;
+   vv.ll = v;
+ 
    a[HIGH][HIGH] = 0;
    a[HIGH][LOW] = 0;
!   a[LOW][HIGH] = uu.s.high;
!   a[LOW][LOW] = uu.s.low;
!   b[HIGH] = vv.s.high;
!   b[LOW] = vv.s.low;
  
!   __bdiv (a, b, q, r, sizeof a, sizeof b);
! 
!   w.s.high = q[HIGH];
!   w.s.low = q[LOW];
!   return w.ll;
  }
  #endif
***************
*** 246,268 ****
  
  #ifdef L_umoddi3
! struct longlong 
  __umoddi3 (u, v)
!      struct longlong u, v;
  {
    unsigned long a[2][2], b[2], q[2], r[2];
!   struct longlong w;
  
    a[HIGH][HIGH] = 0;
    a[HIGH][LOW] = 0;
!   a[LOW][HIGH] = u.high;
!   a[LOW][LOW] = u.low;
!   b[HIGH] = v.high;
!   b[LOW] = v.low;
  
!   bdiv (a, b, q, r, sizeof a, sizeof b);
! 
!   w.high = r[HIGH];
!   w.low = r[LOW];
!   return w;
  }
  #endif
--- 487,513 ----
  
  #ifdef L_umoddi3
! long long 
  __umoddi3 (u, v)
!      long long u, v;
  {
    unsigned long a[2][2], b[2], q[2], r[2];
!   long_long w;
!   long_long uu, vv;
! 
!   uu.ll = u;
!   vv.ll = v;
  
    a[HIGH][HIGH] = 0;
    a[HIGH][LOW] = 0;
!   a[LOW][HIGH] = uu.s.high;
!   a[LOW][LOW] = uu.s.low;
!   b[HIGH] = vv.s.high;
!   b[LOW] = vv.s.low;
  
!   __bdiv (a, b, q, r, sizeof a, sizeof b);
! 
!   w.s.high = r[HIGH];
!   w.s.low = r[LOW];
!   return w.ll;
  }
  #endif
***************
*** 269,287 ****
  
  #ifdef L_negdi2
! struct longlong 
  __negdi2 (u)
!      struct longlong u;
  {
    unsigned long a[2], b[2];
!   struct longlong w;
  
!   a[HIGH] = u.high;
!   a[LOW] = u.low;
  
    bneg (a, b, sizeof b);
  
!   w.high = b[HIGH];
!   w.low = b[LOW];
!   return w;
  }
  
--- 514,535 ----
  
  #ifdef L_negdi2
! long long 
  __negdi2 (u)
!      long long u;
  {
    unsigned long a[2], b[2];
!   long_long w;
!   long_long uu;
  
!   uu.ll = u;
  
+   a[HIGH] = uu.s.high;
+   a[LOW] = uu.s.low;
+ 
    bneg (a, b, sizeof b);
  
!   w.s.high = b[HIGH];
!   w.s.low = b[LOW];
!   return w.ll;
  }
  
***************
*** 317,323 ****
     n digits of a must be less than b, and m must be greater than n.  */
  
! #ifdef L_div_internal
  void 
! bdiv (a, b, q, r, m, n)
       unsigned short *a, *b, *q, *r;
       size_t m, n;
--- 565,574 ----
     n digits of a must be less than b, and m must be greater than n.  */
  
! /* The name of this used to be __div_internal,
!    but that is too long for SYSV.  */
! 
! #ifdef L_bdiv
  void 
! __bdiv (a, b, q, r, m, n)
       unsigned short *a, *b, *q, *r;
       size_t m, n;
***************
*** 327,333 ****
    unsigned short *u = (unsigned short *) alloca (m);
    unsigned short *v = (unsigned short *) alloca (n);
!   unsigned short *u1 = next_lsd (u);
!   unsigned short *u2 = next_lsd (u1);
!   unsigned short *vn;
    int d, qn;
    int i, j;
--- 578,583 ----
    unsigned short *u = (unsigned short *) alloca (m);
    unsigned short *v = (unsigned short *) alloca (n);
!   unsigned short *u0, *u1, *u2;
!   unsigned short *v0;
    int d, qn;
    int i, j;
***************
*** 337,342 ****
    qn = m - n;
  
!   /* Shift divisor and dividend left until the high bit of the divisor
!      is 1.  */
  
    while (b[big_end (n)] == 0)
--- 587,592 ----
    qn = m - n;
  
!   /* Remove leading zero digits from divisor, and the same number of
!      digits (which must be zero) from dividend.  */
  
    while (b[big_end (n)] == 0)
***************
*** 355,358 ****
--- 605,627 ----
      }
        
+   /* If divisor is a single digit, do short division.  */
+ 
+   if (n == 1)
+     {
+       acc = a[big_end (m)];
+       a += little_end (2);
+       for (j = big_end (qn); is_not_lsd (j, qn); j = next_lsd (j))
+ 	{
+ 	  acc = (acc << 16) | a[j];
+ 	  q[j] = acc / *b;
+ 	  acc = acc % *b;
+ 	}
+       *r = acc;
+       return;
+     }
+ 
+   /* No such luck, must do long division. Shift divisor and dividend
+      left until the high bit of the divisor is 1.  */
+ 
    for (d = 0; d < 16; d++)
      if (b[big_end (n)] & (1 << (16 - 1 - d)))
***************
*** 362,372 ****
    bshift (b, d, v, 0, n);
  
!   /* Get a pointer to the high divisor digit (so some of the upcoming code
!      fits on a line).  Provide the divisor with a trailing zero digit if
!      it is only one digit long.  */
  
!   vn = v + big_end (n);
!   if (n == 1)
!     *next_lsd (vn) = 0;
  
    /* Main loop: find a quotient digit, multiply it by the divisor,
--- 631,642 ----
    bshift (b, d, v, 0, n);
  
!   /* Get pointers to the high dividend and divisor digits.  */
  
!   u0 = u + big_end (m) - big_end (qn);
!   u1 = next_lsd (u0);
!   u2 = next_lsd (u1);
!   u += little_end (2);
! 
!   v0 = v + big_end (n);
  
    /* Main loop: find a quotient digit, multiply it by the divisor,
***************
*** 378,391 ****
  	 divisor digit.  */
  
!       if (u[j] == *vn)
  	{
  	  qhat = B - 1;
! 	  rhat = *vn + u1[j];
  	}
        else
  	{
! 	  unsigned long numerator = u[j] << 16 |  u1[j];
! 	  qhat = numerator / *vn;
! 	  rhat = numerator % *vn;
  	}
  
--- 648,661 ----
  	 divisor digit.  */
  
!       if (u0[j] == *v0)
  	{
  	  qhat = B - 1;
! 	  rhat = (unsigned long) *v0 + u1[j];
  	}
        else
  	{
! 	  unsigned long numerator = ((unsigned long) u0[j] << 16) | u1[j];
! 	  qhat = numerator / *v0;
! 	  rhat = numerator % *v0;
  	}
  
***************
*** 393,400 ****
  	 high 2 divisor digits.  */
  
!       while (rhat < B && qhat * *next_lsd (vn) > (rhat << 16 | u2[j]))
  	{
  	  qhat -= 1;
! 	  rhat += *vn;
  	}
  	    
--- 663,670 ----
  	 high 2 divisor digits.  */
  
!       while (rhat < B && qhat * *next_lsd (v0) > ((rhat << 16) | u2[j]))
  	{
  	  qhat -= 1;
! 	  rhat += *v0;
  	}
  	    
***************
*** 404,412 ****
        for (i = little_end (n); is_not_msd (i, n); i = next_msd (i))
  	{
! 	  acc += (u1 + j)[i] - v[i] * qhat;
! 	  (u1 + j)[i] = acc & low16;
  	  if (acc < B)
  	    acc = 0;
! 	  else acc = acc >> 16 | -B;
  	}
  
--- 674,683 ----
        for (i = little_end (n); is_not_msd (i, n); i = next_msd (i))
  	{
! 	  acc += (unsigned long) (u + j)[i] - v[i] * qhat;
! 	  (u + j)[i] = acc & low16;
  	  if (acc < B)
  	    acc = 0;
! 	  else
! 	    acc = (acc >> 16) | -B;
  	}
  
***************
*** 416,420 ****
  	 decrement the quotient by 1 and add the divisor back.  */
  
!       if ((signed long) (acc + u[j]) < 0)
  	{
  	  q[j] -= 1;
--- 687,691 ----
  	 decrement the quotient by 1 and add the divisor back.  */
  
!       if ((signed long) (acc + u0[j]) < 0)
  	{
  	  q[j] -= 1;
***************
*** 422,427 ****
  	  for (i = little_end (n); is_not_msd (i, n); i = next_msd (i))
  	    {
! 	      acc += (u1 + j)[i] + v[i];
! 	      (u1 + j)[i] = acc & low16;
  	      acc = acc >> 16;
  	    }
--- 693,698 ----
  	  for (i = little_end (n); is_not_msd (i, n); i = next_msd (i))
  	    {
! 	      acc += (unsigned long) (u + j)[i] + v[i];
! 	      (u + j)[i] = acc & low16;
  	      acc = acc >> 16;
  	    }
***************
*** 432,440 ****
       by the amount of the normalizing left shift at the top.  */
  
!   if (d == 0)
!     bshift (&u[j], d, r, 0, n);
!   else
!     r[big_end (n)] = bshift (&u[j], 16 - d, &r[next_lsd (big_end (n))],
! 			     u[little_end (m)] >> d, n - 1);
  }
  
--- 703,711 ----
       by the amount of the normalizing left shift at the top.  */
  
!   r[big_end (n)] = bshift (u + 1 + little_end (j - 1),
! 			   16 - d,
! 			   r + little_end (2),
! 			   u[little_end (m - 1)] >> d,
! 			   n - 1);
  }
  
***************
*** 460,464 ****
    for (i = little_end (n); is_not_msd (i, n); i = next_msd (i))
      {
!       acc |= u[i] << k;
        w[i] = acc & low16;
        acc = acc >> 16;
--- 731,735 ----
    for (i = little_end (n); is_not_msd (i, n); i = next_msd (i))
      {
!       acc |= (unsigned long) u[i] << k;
        w[i] = acc & low16;
        acc = acc >> 16;
***************
*** 467,469 ****
--- 738,847 ----
  }
  #endif
+ \f


+ #ifdef L_cmpdi2
+ SItype
+ __cmpdi2 (a, b)
+      long long a, b;
+ {
+   long_long au, bu;
+ 
+   au.ll = a, bu.ll = b;
+ 
+   if (au.s.high < bu.s.high)
+     return 0;
+   else if (au.s.high > bu.s.high)
+     return 2;
+   if ((unsigned) au.s.low < (unsigned) bu.s.low)
+     return 0;
+   else if ((unsigned) au.s.low > (unsigned) bu.s.low)
+     return 2;
+   return 1;
+ }
+ #endif
+ 
+ #ifdef L_ucmpdi2
+ SItype
+ __ucmpdi2 (a, b)
+      long long a, b;
+ {
+   long_long au, bu;
+ 
+   au.ll = a, bu.ll = b;
+ 
+   if ((unsigned) au.s.high < (unsigned) bu.s.high)
+     return 0;
+   else if ((unsigned) au.s.high > (unsigned) bu.s.high)
+     return 2;
+   if ((unsigned) au.s.low < (unsigned) bu.s.low)
+     return 0;
+   else if ((unsigned) au.s.low > (unsigned) bu.s.low)
+     return 2;
+   return 1;
+ }
+ #endif
+ \f


+ #ifdef L_fixunsdfdi
+ #define HIGH_WORD_COEFF (((long long) 1) << BITS_PER_WORD)
+ 
+ long long
+ __fixunsdfdi (a)
+      double a;
+ {
+   double b;
+   unsigned long long v;
+ 
+   if (a < 0)
+     return 0;
+ 
+   /* Compute high word of result, as a flonum.  */
+   b = (a / HIGH_WORD_COEFF);
+   /* Convert that to fixed (but not to long long!),
+      and shift it into the high word.  */
+   v = (unsigned long int) b;
+   v <<= BITS_PER_WORD;
+   /* Remove high part from the double, leaving the low part as flonum.  */
+   a -= (double)v;
+   /* Convert that to fixed (but not to long long!) and add it in.
+      Sometimes A comes out negative.  This is significant, since
+      A has more bits than a long int does.  */
+   if (a < 0)
+     v -= (unsigned long int) (- a);
+   else
+     v += (unsigned long int) a;
+   return v;
+ }
+ #endif
+ 
+ #ifdef L_fixdfdi
+ long long
+ __fixdfdi (a)
+      double a;
+ {
+   if (a < 0)
+     return - __fixunsdfdi (-a);
+   return __fixunsdfdi (a);
+ }
+ #endif
+ 
+ #ifdef L_floatdidf
+ #define HIGH_HALFWORD_COEFF (((long long) 1) << (BITS_PER_WORD / 2))
+ #define HIGH_WORD_COEFF (((long long) 1) << BITS_PER_WORD)
+ 
+ double
+ __floatdidf (u)
+      long long u;
+ {
+   double d;
+   int negate = 0;
+ 
+   if (d < 0)
+     u = -u, negate = 1;
+ 
+   d = (unsigned int) (u >> BITS_PER_WORD);
+   d *= HIGH_HALFWORD_COEFF;
+   d *= HIGH_HALFWORD_COEFF;
+   d += (unsigned int) (u & (HIGH_WORD_COEFF - 1));
  
+   return (negate ? -d : d);
+ }
+ #endif
diff -rc2N gcc-1.35/gvarargs.h gcc-1.36/gvarargs.h
*** gcc-1.35/gvarargs.h	Wed Dec 31 19:00:00 1969
--- gcc-1.36/gvarargs.h	Thu Sep 21 02:06:11 1989
***************
*** 0 ****
--- 1,64 ----
+ #ifndef __GNUC__
+ /* Use the system's macros with the system's compiler.  */
+ #include <varargs.h>
+ #else
+ #ifdef __spur__
+ #include "va-spur.h"
+ #else
+ #ifdef __mips__
+ #include "va-mips.h"
+ #else
+ #ifdef __i860__
+ #include "va-i860.h"
+ #else
+ #ifdef __pyr__
+ #include "va-pyr.h"
+ #else
+ 
+ #ifdef __NeXT__
+ 
+ /* On Next, erase any vestiges of stdarg.h.  */
+ 
+ #undef va_alist
+ #undef va_dcl
+ #undef va_list
+ #undef va_start
+ #undef va_end
+ #undef __va_rounded_size
+ #undef va_arg
+ 
+ /* Record that varargs.h is defined; this turns off stdarg.h.  */
+ 
+ #ifndef _VARARGS_H
+ #define _VARARGS_H
+ #endif
+ #endif  /* __NeXT__ */
+ 
+ /* These macros implement traditional (non-ANSI) varargs
+    for GNU C.  */
+ 
+ #define va_alist  __builtin_va_alist
+ #define va_dcl    int __builtin_va_alist;
+ #define va_list   char *
+ 
+ #ifdef __sparc__
+ #define va_start(AP) 						\
+  (__builtin_saveregs (),					\
+   AP = ((void *) &__builtin_va_alist))
+ #else
+ #define va_start(AP)  AP=(char *) &__builtin_va_alist
+ #endif
+ #define va_end(AP)
+ 
+ #define __va_rounded_size(TYPE)  \
+   (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
+ 
+ #define va_arg(AP, TYPE)						\
+  (AP += __va_rounded_size (TYPE),					\
+   *((TYPE *) (AP - __va_rounded_size (TYPE))))
+ 
+ #endif /* not pyr */
+ #endif /* not i860 */
+ #endif /* not mips */
+ #endif /* not spur */
+ #endif /* __GNUC__ */
diff -rc2N gcc-1.35/hard-params.c gcc-1.36/hard-params.c
*** gcc-1.35/hard-params.c	Wed Dec 31 19:00:00 1969
--- gcc-1.36/hard-params.c	Tue Jun 20 19:14:16 1989
***************
*** 0 ****
--- 1,1716 ----
+ /* Everything you wanted to know about your machine and C compiler,
+    but didn't know who to ask.
+    Author: Steven Pemberton, CWI, Amsterdam; steven@cwi.nl
+    Bugfixes and upgrades gratefully received.
+ 
+    Name changed to `hard-params' by Richard Stallman, April 89.
+    xmalloc function defined, Richard Stallman, June 89.
+ 
+    Copyright (c) 1988, 1989 Steven Pemberton, CWI, Amsterdam.
+    All rights reserved.
+ 
+    COMPILING
+    With luck and a following wind, just the following will work:
+ 	cc hard-params.c -o hard-params
+ 
+    If your compiler doesn't support:		add flag:
+ 	signed char (eg pcc)			-DNO_SC
+ 	unsigned char				-DNO_UC
+ 	unsigned short and long			-DNO_UI
+ 	signal(), or setjmp/longjmp()		-DNO_SIG
+ 
+    Try it first with no flags, and see if you get any errors - you might be
+    surprised. (Most non-ANSI compilers need -DNO_SC, though.)
+    Some compilers need a -f flag for floating point.
+ 
+    Don't use any optimisation flags: the program may not work if you do.
+    Though "while (a+1.0-a-1.0 == 0.0)" may look like "while(1)" to an
+    optimiser, to a floating-point unit there's a world of difference.
+ 
+    Some compilers offer various flags for different floating point
+    modes; it's worth trying all possible combinations of these.
+ 
+    Add -DID=\"name\" if you want the machine/flags identified in the output.
+ 
+    SYSTEM DEPENDENCIES
+    You may possibly need to add some calls to signal() for other sorts of
+    exception on your machine than SIGFPE, and SIGOVER.  See lines beginning
+    #ifdef SIGxxx in main() (and communicate the differences to me!).
+ 
+    If your C preprocessor doesn't have the predefined __FILE__ macro, and
+    you want to call this file anything other than hard-params.c, change the
+    #define command for __FILE__ accordingly.  If it doesn't accept macro
+    names at all in #include lines, order a new C compiler. While you're
+    waiting for it to arrive, change the last #include in this file (the
+    last but one line) accordingly.
+ 
+    OUTPUT
+    Run without argument to get the information as English text.  If run
+    with argument -l (e.g. hard-params -l), output is a series of #define's for
+    the ANSI standard limits.h include file, excluding MB_MAX_CHAR.  If run
+    with argument -f, output is a series of #define's for the ANSI standard
+    float.h include file.  Flag -v gives verbose output: output includes the
+    English text above as C comments.  The program exit(0)'s if everything
+    went ok, otherwise it exits with a positive number, telling how many
+    problems there were.
+ 
+    VERIFYING THE COMPILER
+    If, having produced the float.h and limits.h header files, you want to
+    verify that the compiler reads them back correctly (there are a lot of
+    boundary cases, of course, like minimum and maximum numbers), you can
+    recompile hard-params.c with -DVERIFY set (plus the other flags that you used
+    when compiling the version that produced the header files).  This then
+    recompiles the program so that it #includes "limits.h" and "float.h",
+    and checks that the constants it finds there are the same as the
+    constants it produces. Run the resulting program with hard-params -fl.  As of
+    this writing, of 21 compiler/flags combinations only 1 compiler has
+    passed without error! (The honour goes to 'pcc' on an IBM RT.)
+ 
+    You can also use this option if your compiler already has both files,
+    and you want to confirm that this program produces the right results.
+ 
+    TROUBLE SHOOTING.
+    This program is now quite trustworthy, and suspicious and wrong output
+    may well be caused by bugs in the compiler, not in the program (however
+    of course, this is not guaranteed, and no responsibility can be
+    accepted, etc.)
+ 
+    The program only works if overflows are ignored by the C system or
+    are catchable with signal().
+ 
+    If the program fails to run to completion (often with the error message
+    "Unexpected signal at point x"), this often turns out to be a bug in the
+    C compiler's run-time system. Check what was about to be printed, and
+    try to narrow the problem down.
+ 
+    Another possible problem is that you have compiled the program to produce
+    loss-of-precision arithmetic traps. The program cannot cope with these,
+    and you should re-compile without them. (They should never be the default).
+ 
+    Make sure you compiled with optimisation turned off.
+ 
+    Output preceded by *** WARNING: identifies behaviour of the C system
+    deemed incorrect by the program. Likely problems are that printf or
+    scanf don't cope properly with certain boundary numbers.  For each float
+    and double that is printed, the printed value is checked that it is
+    correct by using sscanf to read it back.  Care is taken that numbers are
+    printed with enough digits to uniquely identify them, and therefore that
+    they can be read back identically. If the number read back is different,
+    the program prints a warning message. If the two numbers in the warning
+    look identical, then printf is more than likely rounding the last
+    digit(s) incorrectly.  To put you at ease that the two really are
+    different, the bit patterns of the two numbers are also printed.  The
+    difference is very likely in the last bit.  Many scanf's read the
+    minimum double back as 0.0, and similarly cause overflow when reading
+    the maximum double.  The program quite ruthlessly declares all these
+    behaviours faulty.
+ 
+    The warning that "a cast didn't work" refers to cases like this:
+ 
+       float f;
+       #define C 1.234567890123456789
+       f= C;
+       if (f != (float) C) printf ("Wrong!");
+ 
+    A faulty compiler will widen f to double and ignore the cast to float,
+    and because there is more accuracy in a double than a float, fail to
+    recognise that they are the same. In the actual case in point, f and C
+    are passed as parameters to a function that discovers they are not equal,
+    so it's just possible that the error was in the parameter passing,
+    not in the cast (see function Validate()).
+    For ANSI C, which has float constants, the error message is "constant has
+    wrong precision".
+ 
+    REPORTING PROBLEMS
+    If the program doesn't work for you for any reason that can't be
+    narrowed down to a problem in the C compiler, or it has to be changed in
+    order to get it to compile, or it produces suspicious output (like a very
+    low maximum float, for instance), please mail the problem and an example
+    of the incorrect output to steven@cwi.nl or mcvax!steven.uucp, so that
+    improvements can be worked into future versions; mcvax/cwi.nl is the
+    European backbone, and is connected to uunet and other fine hosts.
+ 
+    This version of the program is the first to try to catch and diagnose
+    bugs in the compiler/run-time system. I would be especially pleased to
+    have reports of failures so that I can improve this service.
+ 
+    I apologise unreservedly for the contorted use of the preprocessor...
+ 
+    THE SMALL PRINT
+    You may copy and distribute verbatim copies of this source file.
+ 
+    You may modify this source file, and copy and distribute such
+    modified versions, provided that you leave the copyright notice
+    at the top of the file and also cause the modified file to carry
+    prominent notices stating that you changed the files and the date
+    of any change; and cause the whole of any work that you distribute
+    or publish, that in whole or in part contains or is a derivative of
+    this program or any part thereof, to be licensed at no charge to
+    all third parties on terms identical to those here.
+ 
+    If you do have a fix to any problem, please send it to me, so that
+    other people can have the benefits.
+ 
+    While every effort has been taken to make this program as reliable as
+    possible, no responsibility can be taken for the correctness of the
+    output, or suitability for any particular use.
+ 
+    ACKNOWLEDGEMENTS
+    Many people have given time and ideas to making this program what it is.
+    To all of them thanks, and apologies for not mentioning them by name.
+ */
+ 
+ #ifndef __FILE__
+ #define __FILE__ "hard-params.c"
+ #endif
+ 
+ #ifndef PASS
+ #define PASS 1
+ #define PASS1 1
+ #define VERSION "4.1"
+ 
+ /* Procedure just marks the functions that don't return a result */
+ #ifdef Procedure
+ #undef Procedure
+ #endif
+ #define Procedure
+ 
+ #define Vprintf if (V) printf
+ 
+ /* stdc is used in tests like if (stdc) */
+ #ifdef __STDC__
+ #define stdc 1
+ #else
+ #define stdc 0
+ #endif
+ 
+ /* volatile is used to reduce the chance of optimisation,
+    and to prevent variables being put in registers (when setjmp/longjmp
+    wouldn't work as we want)  */
+ #ifndef __STDC__
+ #define volatile static
+ #endif
+ 
+ #include <stdio.h>
+ 
+ #ifdef VERIFY
+ #include "limits.h"
+ #include "float.h"
+ #endif
+ 
+ #ifdef NO_SIG  /* There's no signal(), or setjmp/longjmp() */
+ 
+ 	/* Dummy routines instead */
+ 	int lab=1;
+ 	int setjmp(lab) int lab; { return(0); }
+ 	signal(i, p) int i, (*p)(); {}
+ 
+ #else
+ 
+ #include <signal.h>
+ #include <setjmp.h>
+ 
+ 	jmp_buf lab;
+ 	overflow(sig) int sig; { /* what to do on overflow/underflow */
+ 		signal(sig, overflow);
+ 		longjmp(lab, 1);
+ 	}
+ 
+ #endif /*NO_SIG*/
+ 
+ #define Unexpected(place) if (setjmp(lab)!=0) croak(place)
+ 
+ int V= 0,	/* verbose */
+     L= 0,	/* produce limits.h */
+     F= 0,	/* produce float.h  */
+     bugs=0;	/* The number of (possible) bugs in the output */
+ 
+ char co[4], oc[4]; /* Comment starter and ender symbols */
+ 
+ int bits_per_byte; /* the number of bits per unit returned by sizeof() */
+ 
+ #ifdef TEST
+ /* Set the fp modes on a SUN with 68881 chip, to check that different
+    rounding modes etc. get properly detected.
+    Compile with additional flag -DTEST, and run with additional parameter
+    +hex-number, to set the 68881 mode register to hex-number
+ */
+ 
+ /* Bits 0x30 = rounding mode: */
+ #define ROUND_BITS	0x30
+ #define TO_NEAREST	0x00
+ #define TO_ZERO		0x10
+ #define TO_MINUS_INF	0x20
+ #define TO_PLUS_INF	0x30 /* The SUN FP user's guide seems to be wrong here */
+ 
+ /* Bits 0xc0 = extended rounding: */
+ #define EXT_BITS	0xc0
+ #define ROUND_EXTENDED	0x00
+ #define ROUND_SINGLE 	0x40
+ #define ROUND_DOUBLE	0x80
+ 
+ /* Enabled traps: */
+ #define EXE_INEX1  0x100
+ #define EXE_INEX2  0x200
+ #define EXE_DZ	   0x400
+ #define EXE_UNFL   0x800
+ #define EXE_OVFL  0x1000
+ #define EXE_OPERR 0x2000
+ #define EXE_SNAN  0x4000
+ #define EXE_BSUN  0x8000
+ 
+ printmode(new) unsigned new; {
+ 	fpmode_(&new);
+ 	printf("New fp mode:\n");
+ 	printf("  Round toward ");
+ 	switch (new & ROUND_BITS) {
+ 	      case TO_NEAREST:   printf("nearest"); break;
+ 	      case TO_ZERO:      printf("zero"); break;
+ 	      case TO_MINUS_INF: printf("minus infinity"); break;
+ 	      case TO_PLUS_INF:  printf("plus infinity"); break;
+ 	      default: printf("???"); break;
+ 	}
+ 
+ 	printf("\n  Extended rounding precision: ");
+ 
+ 	switch (new & EXT_BITS) {
+ 	      case ROUND_EXTENDED: printf("extended"); break;
+ 	      case ROUND_SINGLE:   printf("single"); break;
+ 	      case ROUND_DOUBLE:   printf("double"); break;
+ 	      default: printf("???"); break;
+ 	}
+ 
+ 	printf("\n  Enabled exceptions:");
+ 	if (new & (unsigned) EXE_INEX1) printf(" inex1");
+ 	if (new & (unsigned) EXE_INEX2) printf(" inex2");
+ 	if (new & (unsigned) EXE_DZ)    printf(" dz"); 
+ 	if (new & (unsigned) EXE_UNFL)  printf(" unfl"); 
+ 	if (new & (unsigned) EXE_OVFL)  printf(" ovfl"); 
+ 	if (new & (unsigned) EXE_OPERR) printf(" operr"); 
+ 	if (new & (unsigned) EXE_SNAN)  printf(" snan"); 
+ 	if (new & (unsigned) EXE_BSUN)  printf(" bsun"); 
+ 	printf("\n");
+ }
+ 
+ int setmode(s) char *s; {
+ 	unsigned mode=0, dig;
+ 	char c;
+ 
+ 	while (*s) {
+ 		c= *s++;
+ 		if  (c>='0' && c<='9') dig= c-'0';
+ 		else if (c>='a' && c<='f') dig= c-'a'+10;
+ 		else if (c>='A' && c<='F') dig= c-'A'+10;
+ 		else return 1;
+ 		mode= mode<<4 | dig;
+ 	}
+ 	printmode(mode);
+ 	return 0;
+ }
+ #else
+ int setmode(s) char *s; {
+ 	fprintf(stderr, "Can't set mode: not compiled with TEST\n");
+ 	return(1);
+ }
+ #endif
+ 
+ croak(place) int place; {
+ 	printf("*** Unexpected signal at point %d\n", place);
+ 	exit(bugs+1); /* An exit isn't essential here, but avoids loops */
+ }
+ 
+ /* This is here in case alloca.c is used.  That wants to call this.  */
+ 
+ char *
+ xmalloc(size) unsigned size; {
+ 	char *malloc();
+ 	char *value = malloc(size);
+ 	if (value == 0) {
+ 		fprintf(stderr, "Virtual memory exceeded\n");
+ 		exit(bugs+1);
+ 	}
+ 	return value;
+ }
+ 
+ main(argc, argv) int argc; char *argv[]; {
+ 	int dprec, fprec, lprec, basic(), fprop(), dprop(), efprop(), edprop();
+ 	char *malloc();
+ 	unsigned int size;
+ 	long total;
+ 	int i; char *s; int bad;
+ 
+ #ifdef SIGFPE
+ 	signal(SIGFPE, overflow);
+ #endif
+ #ifdef SIGOVER
+ 	signal(SIGOVER, overflow);
+ #endif
+ /* Add more calls as necessary */
+ 
+ 	Unexpected(1);
+ 
+ 	bad=0;
+ 	for (i=1; i < argc; i++) {
+ 		s= argv[i];
+ 		if (*s == '-') {
+ 			s++;
+ 			while (*s) {
+ 				switch (*(s++)) {
+ 				      case 'v': V=1; break;
+ 				      case 'l': L=1; break;
+ 				      case 'f': F=1; break;
+ 				      default: bad=1; break;
+ 				}
+ 			}
+ 		} else if (*s == '+') {
+ 			s++;
+ 			bad= setmode(s);
+ 		} else bad= 1;
+ 	}
+ 	if (bad) {
+ 		fprintf(stderr,
+ 			"Usage: %s [-vlf]\n  v=Verbose l=Limits.h f=Float.h\n",
+ 			argv[0]);
+ 		exit(1);
+ 	}
+ 	if (L || F) {
+ 		co[0]= '/'; oc[0]= ' ';
+ 		co[1]= '*'; oc[1]= '*';
+ 		co[2]= ' '; oc[2]= '/';
+ 		co[3]= '\0'; oc[3]= '\0';
+ 	} else {
+ 		co[0]= '\0'; oc[0]= '\0';
+ 		V=1;
+ 	}
+ 
+ 	if (L) printf("%slimits.h%s\n", co, oc);
+ 	if (F) printf("%sfloat.h%s\n", co, oc);
+ #ifdef ID
+ 	printf("%sProduced on %s by hard-params version %s, CWI, Amsterdam%s\n",
+ 	       co, ID, VERSION, oc);
+ #else
+ 	printf("%sProduced by hard-params version %s, CWI, Amsterdam%s\n",
+ 	       co, VERSION, oc);
+ #endif
+ 
+ #ifdef VERIFY
+ 	printf("%sVerification phase%s\n", co, oc);
+ #endif
+ 
+ #ifdef NO_SIG
+ 	Vprintf("%sCompiled without signal(): %s%s\n",
+ 		co,
+ 		"there's nothing that can be done if overflow occurs",
+ 		oc);
+ #endif
+ #ifdef NO_SC
+ 	Vprintf("%sCompiled without signed char%s\n", co, oc);
+ #endif
+ #ifdef NO_UC
+ 	Vprintf("%Compiled without unsigned char%s\n", co, oc);
+ #endif
+ #ifdef NO_UI
+ 	Vprintf("%Compiled without unsigned short or long%s\n", co, oc);
+ #endif
+ #ifdef __STDC__
+ 	Vprintf("%sCompiler claims to be ANSI C level %d%s\n",
+ 		co, __STDC__, oc);
+ #else
+ 	Vprintf("%sCompiler does not claim to be ANSI C%s\n", co, oc);
+ #endif
+ 	printf("\n");
+ 	bits_per_byte= basic();
+ 	Vprintf("\n");
+ 	if (F||V) {
+ 		fprec= fprop(bits_per_byte);
+ 		dprec= dprop(bits_per_byte);
+ 		lprec= ldprop(bits_per_byte);
+ 		efprop(fprec, dprec, lprec);
+ 		edprop(fprec, dprec, lprec);
+ 		eldprop(fprec, dprec, lprec);
+ 	}
+ 	if (V) {
+ 		/* An extra goody: the approximate amount of data-space */
+ 		/* Allocate store until no more available */
+ 		size=1<<((bits_per_byte*sizeof(int))-2);
+ 		total=0;
+ 		while (size!=0) {
+ 			while (malloc(size)!=(char *)NULL) total+=(size/2);
+ 			size/=2;
+ 		}
+ 
+ 		Vprintf("%sMemory mallocatable ~= %ld Kbytes%s\n",
+ 			co, (total+511)/512, oc);
+ 	}
+ 	exit(bugs);
+ }
+ 
+ Procedure eek_a_bug(problem) char *problem; {
+ 	printf("\n%s*** WARNING: %s%s\n", co, problem, oc);
+ 	bugs++;
+ }
+ 
+ Procedure i_define(sort, name, val, req) char *sort, *name; long val, req; {
+ 	if (val >= 0) {
+ 		printf("#define %s%s %ld\n", sort, name, val);
+ 	} else {
+ 		printf("#define %s%s (%ld)\n", sort, name, val);
+ 	}
+ 	if (val != req) {
+ 		printf("%s*** Verify failed for above #define!\n", co);
+ 		printf("       Compiler has %ld for value%s\n\n", req, oc);
+ 		bugs++;
+ 	}
+ 	Vprintf("\n");
+ }
+ 
+ #ifndef NO_UI
+ 
+ #ifdef __STDC__
+ #define U "U"
+ #else
+ #define U ""
+ #endif
+ 
+ Procedure u_define(sort, name, val, req) char *sort, *name; unsigned long val, req; {
+ 	printf("#define %s%s %lu%s\n", sort, name, val, U);
+ 	if (val != req) {
+ 		printf("%s*** Verify failed for above #define!\n", co);
+ 		printf("       Compiler has %lu for value%s\n\n", req, oc);
+ 		bugs++;
+ 	}
+ 	Vprintf("\n");
+ }
+ #endif
+ 
+ /* Long_double is the longest floating point type available: */
+ #ifdef __STDC__
+ #define Long_double long double
+ #else
+ #define Long_double double
+ #endif
+ 
+ char *f_rep();
+ 
+ Procedure f_define(sort, name, precision, val, mark)
+      char *sort, *name; int precision; Long_double val; char *mark; {
+ 	if (stdc) {
+ 		printf("#define %s%s %s%s\n",
+ 		       sort, name, f_rep(precision, val), mark);
+ 	} else if (*mark == 'F') {
+ 		/* non-ANSI C has no float constants, so cast the constant */
+ 		printf("#define %s%s ((float)%s)\n",
+ 		       sort, name, f_rep(precision, val));
+ 	} else {
+ 		printf("#define %s%s %s\n", sort, name, f_rep(precision, val));
+ 	}
+ 	Vprintf("\n");
+ }
+ 
+ int floor_log(base, x) int base; Long_double x; { /* return floor(log base(x)) */
+ 	int r=0;
+ 	while (x>=base) { r++; x/=base; }
+ 	return r;
+ }
+ 
+ int ceil_log(base, x) int base; Long_double x; {
+ 	int r=0;
+ 	while (x>1.0) { r++; x/=base; }
+ 	return r;
+ }
+ 
+ int exponent(x, fract, exp) Long_double x; double *fract; int *exp; {
+ 	/* Split x into a fraction and a power of ten;
+ 	   returns 0 if x is unusable, 1 otherwise.
+ 	   Only used for error messages about faulty output.
+ 	*/
+ 	int r=0, neg=0;
+ 	Long_double old;
+ 	*fract=0.0; *exp=0;
+ 	if (x<0.0) {
+ 		x= -x;
+ 		neg= 1;
+ 	}
+ 	if (x==0.0) return 1;
+ 	if (x>=10.0) {
+ 		while (x>=10.0) {
+ 			old=x; r++; x/=10.0;
+ 			if (old==x) return 0;
+ 		}
+ 	} else {
+ 		while (x<1.0) {
+ 			old=x; r--; x*=10.0;
+ 			if (old==x) return 0;
+ 		}
+ 	}
+ 	if (neg) *fract= -x;
+ 	else *fract=x;
+ 	*exp=r;
+ 	return 1;
+ }
+ 
+ #define fabs(x) (((x)<0.0)?(-x):(x))
+ 
+ char *f_rep(precision, val) int precision; Long_double val; {
+ 	static char buf[1024];
+ 	char *f1;
+ 	if (sizeof(double) == sizeof(Long_double)) {
+ 		/* Assume they're the same, and use non-stdc format */
+ 		/* This is for stdc compilers using non-stdc libraries */
+ 		f1= "%.*e";
+ 	} else {
+ 		/* It had better support Le then */
+ 		f1= "%.*Le";
+ 	}
+ 	sprintf(buf, f1, precision, val);
+ 	return buf;
+ }
+ 
+ Procedure bitpattern(p, size) char *p; int size; {
+ 	char c;
+ 	int i, j;
+ 
+ 	for (i=1; i<=size; i++) {
+ 		c= *p;
+ 		p++;
+ 		for (j=bits_per_byte-1; j>=0; j--)
+ 			printf("%c", (c>>j)&1 ? '1' : '0');
+ 		if (i!=size) printf(" ");
+ 	}
+ }
+ 
+ #define Order(x, px, mode)\
+    printf("%s    %s ", co, mode); for (i=0; i<sizeof(x); i++) px[i]= c[i]; \
+    for (i=1; i<=sizeof(x); i++) { putchar((char)((x>>(bits_per_byte*(sizeof(x)-i)))&mask)); }\
+    printf("%s\n", oc);
+ 
+ Procedure endian(bits_per_byte) int bits_per_byte; {
+ 	/*unsigned*/ short s=0;
+ 	/*unsigned*/ int j=0;
+ 	/*unsigned*/ long l=0;
+ 
+ 	char *ps= (char *) &s,
+ 	     *pj= (char *) &j,
+ 	     *pl= (char *) &l,
+ 	     *c= "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ 	unsigned int mask, i;
+ 
+ 	mask=0;
+ 	for (i=1; i<=bits_per_byte; i++) mask= (mask<<1)|1;
+ 
+ 	if (V) {
+ 		printf("%sCharacter order:%s\n", co, oc);
+ 		Order(s, ps, "short:");
+ 		Order(j, pj, "int:  ");
+ 		Order(l, pl, "long: ");
+ 	}
+ }
+ 
+ #ifdef VERIFY
+ #ifndef SCHAR_MAX
+ #define SCHAR_MAX char_max
+ #define SCHAR_MIN char_min
+ #endif
+ #ifndef UCHAR_MAX
+ #define UCHAR_MAX char_max
+ #endif
+ #else
+ #define CHAR_BIT char_bit
+ #define CHAR_MAX char_max
+ #define CHAR_MIN char_min
+ #define SCHAR_MAX char_max
+ #define SCHAR_MIN char_min
+ #define UCHAR_MAX char_max
+ #endif /* VERIFY */
+ 
+ int cprop() { /* Properties of character */
+ 	volatile char c, char_max, char_min;
+ 	volatile int bits_per_byte, is_signed;
+ 	long char_bit;
+ 
+ 	Unexpected(2);
+ 
+ 	/* Calculate number of bits per character *************************/
+ 	c=1; bits_per_byte=0;
+ 	do { c=c<<1; bits_per_byte++; } while(c!=0);
+ 	c= (char)(-1);
+ 	if (((int)c)<0) is_signed=1;
+ 	else is_signed=0;
+ 	Vprintf("%sChar = %d bits, %ssigned%s\n",
+ 		co, (int)sizeof(c)*bits_per_byte, (is_signed?"":"un"), oc);
+ 	char_bit=(long)(sizeof(c)*bits_per_byte);
+ 	if (L) i_define("CHAR", "_BIT", char_bit, (long) CHAR_BIT);
+ 
+ 	c=0; char_max=0;
+ 	c++;
+ 	if (setjmp(lab)==0) { /* Yields char_max */
+ 		while (c>char_max) {
+ 			char_max=c;
+ 			c++;
+ 		}
+ 	} else {
+ 		Vprintf("%sCharacter overflow generates a trap!%s\n", co, oc);
+ 	}
+ 	c=0; char_min=0;
+ 	c--;
+ 	if (setjmp(lab)==0) { /* Yields char_min */
+ 		while (c<char_min) {
+ 			char_min=c;
+ 			c--;
+ 		}
+ 	}
+ 	Unexpected(3);
+ 
+ 	if (L) {
+ 		i_define("CHAR", "_MAX", (long) char_max, (long) CHAR_MAX);
+ 		i_define("CHAR", "_MIN", (long) char_min, (long) CHAR_MIN);
+ 		if (is_signed) {
+ 			i_define("SCHAR", "_MAX", (long) char_max,
+ 				 (long) SCHAR_MAX);
+ 			i_define("SCHAR", "_MIN", (long) char_min,
+ 				 (long) SCHAR_MIN);
+ 		} else {
+ 			i_define("UCHAR", "_MAX", (long) char_max,
+ 				 (long) UCHAR_MAX);
+ 		}
+ 
+ 		if (is_signed) {
+ #ifndef NO_UC
+ 			volatile unsigned char c, char_max;
+ 			c=0; char_max=0;
+ 			c++;
+ 			if (setjmp(lab)==0) { /* Yields char_max */
+ 				while (c>char_max) {
+ 					char_max=c;
+ 					c++;
+ 				}
+ 			}
+ 			Unexpected(4);
+ 			i_define("UCHAR", "_MAX", (long) char_max,
+ 				 (long) UCHAR_MAX);
+ #endif
+ 		} else {
+ #ifndef NO_SC /* Define NO_SC if the next line gives a syntax error */
+ 			volatile signed char c, char_max, char_min;
+ 			c=0; char_max=0;
+ 			c++;
+ 			if (setjmp(lab)==0) { /* Yields char_max */
+ 				while (c>char_max) {
+ 					char_max=c;
+ 					c++;
+ 				}
+ 			}
+ 			c=0; char_min=0;
+ 			c--;
+ 			if (setjmp(lab)==0) { /* Yields char_min */
+ 				while (c<char_min) {
+ 					char_min=c;
+ 					c--;
+ 				}
+ 			}
+ 			Unexpected(5);
+ 			i_define("SCHAR", "_MIN", (long) char_min,
+ 				 (long) SCHAR_MIN);
+ 			i_define("SCHAR", "_MAX", (long) char_max,
+ 				 (long) SCHAR_MAX);
+ #endif /* NO_SC */
+ 		}
+ 	}
+ 	return bits_per_byte;
+ }
+ 
+ int basic() {
+ 	/* The properties of the basic types.
+ 	   Returns number of bits per sizeof unit */
+ 	volatile int bits_per_byte;
+ 
+ 	bits_per_byte= cprop();
+ 
+ 	/* Shorts, ints and longs *****************************************/
+ 	Vprintf("%sShort=%d int=%d long=%d float=%d double=%d bits %s\n",
+ 		co,
+ 		(int) sizeof(short)*bits_per_byte,
+ 		(int) sizeof(int)*bits_per_byte,
+ 		(int) sizeof(long)*bits_per_byte,
+ 		(int) sizeof(float)*bits_per_byte,
+ 		(int) sizeof(double)*bits_per_byte, oc);
+ 	if (stdc) {
+ 		Vprintf("%sLong double=%d bits%s\n",
+ 			co, (int) sizeof(Long_double)*bits_per_byte, oc);
+ 	}
+ 	Vprintf("%sChar pointers = %d bits%s%s\n",
+ 		co, (int)sizeof(char *)*bits_per_byte,
+ 		sizeof(char *)>sizeof(int)?" BEWARE! larger than int!":"",
+ 		oc);
+ 	Vprintf("%sInt pointers = %d bits%s%s\n",
+ 		co, (int)sizeof(int *)*bits_per_byte,
+ 		sizeof(int *)>sizeof(int)?" BEWARE! larger than int!":"",
+ 		oc);
+ 	sprop();
+ 	iprop();
+ 	lprop();
+ 	usprop();
+ 	uiprop();
+ 	ulprop();
+ 
+ 	Unexpected(6);
+ 
+ 	/* Alignment constants ********************************************/
+ 	Vprintf("%sAlignments used for char=%d short=%d int=%d long=%d%s\n",
+ 		co,
+ 		(int)sizeof(struct{char i1; char c1;})-(int)sizeof(char),
+ 		(int)sizeof(struct{short i2; char c2;})-(int)sizeof(short),
+ 		(int)sizeof(struct{int i3; char c3;})-(int)sizeof(int),
+ 		(int)sizeof(struct{long i4; char c4;})-(int)sizeof(long),
+ 		oc);
+ 
+ 	/* Ten little endians *********************************************/
+ 
+ 	endian(bits_per_byte);
+ 
+ 	/* Pointers *******************************************************/
+ 	if (V) {
+ 		if ("abcd"=="abcd")
+ 			printf("%sStrings are shared%s\n", co, oc);
+ 		else printf("%sStrings are not shared%s\n", co, oc);
+ 	}
+ 
+ 	return bits_per_byte;
+ }
+ 
+ #endif /* ifndef PASS */
+ 
+ /* As I said, I apologise for the contortions below. The functions are
+    expanded by the preprocessor twice or three times (for float and double,
+    and maybe for long double, and for short, int and long). That way,
+    I never make a change to one that I forget to make to the other.
+    You can look on it as C's fault for not supporting multi-line macro's.
+    This whole file is read 3 times by the preprocessor, with PASSn set for
+    n=1, 2 or 3, to decide which parts to reprocess.
+ */
+ 
+ /* #undef on an already undefined thing is (wrongly) flagged as an error
+    by some compilers, therefore the #ifdef that follows: 
+ */
+ #ifdef Number
+ #undef Number
+ #undef THING
+ #undef Thing
+ #undef thing
+ #undef FPROP
+ #undef Fname
+ #undef Store
+ #undef Sum
+ #undef Diff
+ #undef Mul
+ #undef Div
+ #undef Self
+ #undef F_check
+ #undef Validate
+ #undef EPROP
+ #undef MARK
+ 
+ #undef F_RADIX
+ #undef F_MANT_DIG
+ #undef F_DIG
+ #undef F_ROUNDS
+ #undef F_EPSILON
+ #undef F_MIN_EXP
+ #undef F_MIN
+ #undef F_MIN_10_EXP
+ #undef F_MAX_EXP
+ #undef F_MAX
+ #undef F_MAX_10_EXP
+ #endif
+ 
+ #ifdef Integer
+ #undef Integer
+ #undef INT
+ #undef IPROP
+ #undef Iname
+ #undef UPROP
+ #undef Uname
+ #undef OK_UI
+ 
+ #undef I_MAX
+ #undef I_MIN
+ #undef U_MAX
+ #endif
+ 
+ #ifdef PASS1
+ 
+ #define Number float
+ #define THING "FLOAT"
+ #define Thing "Float"
+ #define thing "float"
+ #define Fname "FLT"
+ #define FPROP fprop
+ #define Store fStore
+ #define Sum fSum
+ #define Diff fDiff
+ #define Mul fMul
+ #define Div fDiv
+ #define Self fSelf
+ #define F_check fCheck
+ #define Validate fValidate
+ #define MARK "F"
+ 
+ #define EPROP efprop
+ 
+ #define Integer short
+ #define INT "short"
+ #define IPROP sprop
+ #define Iname "SHRT"
+ #ifndef NO_UI
+ #define OK_UI 1
+ #endif
+ 
+ #define UPROP usprop
+ #define Uname "USHRT"
+ 
+ #ifdef VERIFY
+ #define I_MAX SHRT_MAX
+ #define I_MIN SHRT_MIN
+ #define U_MAX USHRT_MAX
+ 
+ #define F_RADIX FLT_RADIX
+ #define F_MANT_DIG FLT_MANT_DIG
+ #define F_DIG FLT_DIG
+ #define F_ROUNDS FLT_ROUNDS
+ #define F_EPSILON FLT_EPSILON
+ #define F_MIN_EXP FLT_MIN_EXP
+ #define F_MIN FLT_MIN
+ #define F_MIN_10_EXP FLT_MIN_10_EXP
+ #define F_MAX_EXP FLT_MAX_EXP
+ #define F_MAX FLT_MAX
+ #define F_MAX_10_EXP FLT_MAX_10_EXP
+ #endif /* VERIFY */
+ 
+ #endif /* PASS1 */
+ 
+ #ifdef PASS2
+ 
+ #define Number double
+ #define THING "DOUBLE"
+ #define Thing "Double"
+ #define thing "double"
+ #define Fname "DBL"
+ #define FPROP dprop
+ #define Store dStore
+ #define Sum dSum
+ #define Diff dDiff
+ #define Mul dMul
+ #define Div dDiv
+ #define Self dSelf
+ #define F_check dCheck
+ #define Validate dValidate
+ #define MARK ""
+ 
+ #define EPROP edprop
+ 
+ #define Integer int
+ #define INT "int"
+ #define IPROP iprop
+ #define Iname "INT"
+ #define OK_UI 1 /* Unsigned int is always possible */
+ 
+ #define UPROP uiprop
+ #define Uname "UINT"
+ 
+ #ifdef VERIFY
+ #define I_MAX INT_MAX
+ #define I_MIN INT_MIN
+ #define U_MAX UINT_MAX
+ 
+ #define F_MANT_DIG DBL_MANT_DIG
+ #define F_DIG DBL_DIG
+ #define F_EPSILON DBL_EPSILON
+ #define F_MIN_EXP DBL_MIN_EXP
+ #define F_MIN DBL_MIN
+ #define F_MIN_10_EXP DBL_MIN_10_EXP
+ #define F_MAX_EXP DBL_MAX_EXP
+ #define F_MAX DBL_MAX
+ #define F_MAX_10_EXP DBL_MAX_10_EXP
+ #endif /* VERIFY */
+ 
+ #endif /* PASS2 */
+ 
+ #ifdef PASS3
+ 
+ #ifdef __STDC__
+ #define Number long double
+ #endif
+ 
+ #define THING "LONG DOUBLE"
+ #define Thing "Long double"
+ #define thing "long double"
+ #define Fname "LDBL"
+ #define FPROP ldprop
+ #define Store ldStore
+ #define Sum ldSum
+ #define Diff ldDiff
+ #define Mul ldMul
+ #define Div ldDiv
+ #define Self ldSelf
+ #define F_check ldCheck
+ #define Validate ldValidate
+ #define MARK "L"
+ 
+ #define EPROP eldprop
+ 
+ #define Integer long
+ #define INT "long"
+ #define IPROP lprop
+ #define Iname "LONG"
+ #ifndef NO_UI
+ #define OK_UI 1
+ #endif
+ 
+ #define UPROP ulprop
+ #define Uname "ULONG"
+ 
+ #ifdef VERIFY
+ #define I_MAX LONG_MAX
+ #define I_MIN LONG_MIN
+ #define U_MAX ULONG_MAX
+ 
+ #define F_MANT_DIG LDBL_MANT_DIG
+ #define F_DIG LDBL_DIG
+ #define F_EPSILON LDBL_EPSILON
+ #define F_MIN_EXP LDBL_MIN_EXP
+ #define F_MIN LDBL_MIN
+ #define F_MIN_10_EXP LDBL_MIN_10_EXP
+ #define F_MAX_EXP LDBL_MAX_EXP
+ #define F_MAX LDBL_MAX
+ #define F_MAX_10_EXP LDBL_MAX_10_EXP
+ #endif /* VERIFY */
+ 
+ #endif /* PASS3 */
+ 
+ #ifndef VERIFY
+ #define I_MAX int_max
+ #define I_MIN int_min
+ #define U_MAX int_max
+ 
+ #define F_RADIX f_radix
+ #define F_MANT_DIG f_mant_dig
+ #define F_DIG f_dig
+ #define F_ROUNDS f_rounds
+ #define F_EPSILON f_epsilon
+ #define F_MIN_EXP f_min_exp
+ #define F_MIN f_min
+ #define F_MIN_10_EXP f_min_10_exp
+ #define F_MAX_EXP f_max_exp
+ #define F_MAX f_max
+ #define F_MAX_10_EXP f_max_10_exp
+ #endif
+ 
+ Procedure IPROP() { /* for short, int, and long */
+ 	volatile Integer newi, int_max, maxeri, int_min, minneri;
+ 	volatile int ibits, ipower, two=2;
+ 
+ 	/* Calculate max short/int/long ***********************************/
+ 	/* Calculate 2**n-1 until overflow - then use the previous value  */
+ 
+ 	newi=1; int_max=0;
+ 
+ 	if (setjmp(lab)==0) { /* Yields int_max */
+ 		for(ipower=0; newi>int_max; ipower++) {
+ 			int_max=newi;
+ 			newi=newi*two+1;
+ 		}
+ 		Vprintf("%sOverflow of a%s %s does not generate a trap%s\n",
+ 			co, INT[0]=='i'?"n":"", INT, oc);
+ 	} else {
+ 		Vprintf("%sOverflow of a%s %s generates a trap%s\n",
+ 			co, INT[0]=='i'?"n":"", INT, oc);
+ 	}
+ 	Unexpected(7);
+ 
+ 	/* Minimum value: assume either two's or one's complement *********/
+ 	int_min= -int_max;
+ 	if (setjmp(lab)==0) { /* Yields int_min */
+ 		if (int_min-1 < int_min) int_min--;
+ 	}
+ 	Unexpected(8);
+ 
+ 	/* Now for those daft Cybers: */
+ 
+ 	maxeri=0; newi=int_max;
+ 
+ 	if (setjmp(lab)==0) { /* Yields maxeri */
+ 		for(ibits=ipower; newi>maxeri; ibits++) {
+ 			maxeri=newi;
+ 			newi=newi+newi+1;
+ 		}
+ 	}
+ 	Unexpected(9);
+ 
+ 	minneri= -maxeri;
+ 	if (setjmp(lab)==0) { /* Yields minneri */
+ 		if (minneri-1 < minneri) minneri--;
+ 	}
+ 	Unexpected(10);
+ 
+ 	Vprintf("%sMaximum %s = %ld (= 2**%d-1)%s\n",
+ 		co, INT, (long)int_max, ipower, oc);
+ 	Vprintf("%sMinimum %s = %ld%s\n", co, INT, (long)int_min, oc);
+ 
+ 	if (L) i_define(Iname, "_MAX", (long) int_max, (long) I_MAX);
+ 	if (L) i_define(Iname, "_MIN", (long) int_min, (long) I_MIN);
+ 
+ 	if (maxeri>int_max) {
+ 		Vprintf("%sThere is a larger %s, %ld (= 2**%d-1), %s %s%s\n",
+ 			co, INT, (long)maxeri, ibits, 
+ 			"but only for addition, not multiplication",
+ 			"(I smell a Cyber!)",
+ 			oc);
+ 	}
+ 
+ 	if (minneri<int_min) {
+ 		Vprintf("%sThere is a smaller %s, %ld, %s %s%s\n",
+ 			co, INT, (long)minneri, 
+ 			"but only for addition, not multiplication",
+ 			"(I smell a Cyber!)",
+ 			oc);
+ 	}
+ }
+ 
+ Procedure UPROP () { /* unsigned short/int/long */
+ #ifdef OK_UI
+ 	volatile unsigned Integer int_max, newi, two;
+ 	newi=1; int_max=0; two=2;
+ 
+ 	if (setjmp(lab)==0) { /* Yields int_max */
+ 		while(newi>int_max) {
+ 			int_max=newi;
+ 			newi=newi*two+1;
+ 		}
+ 	}
+ 	Unexpected(11);
+ 	Vprintf("%sMaximum unsigned %s = %lu%s\n",
+ 		co, INT, (unsigned long) int_max, oc);
+ 	if (L) u_define(Uname, "_MAX", (unsigned long) int_max,
+ 			(unsigned long) U_MAX);
+ #endif
+ }
+ 
+ 
+ #ifdef Number
+ 
+ /* These routines are intended to defeat any attempt at optimisation
+    or use of extended precision, and to defeat faulty narrowing casts:
+ */
+ Procedure Store(a, b) Number a, *b; { *b=a; }
+ Number Sum(a, b) Number a, b; { Number r; Store(a+b, &r); return (r); }
+ Number Diff(a, b) Number a, b; { Number r; Store(a-b, &r); return (r); }
+ Number Mul(a, b) Number a, b; { Number r; Store(a*b, &r); return (r); }
+ Number Div(a, b) Number a, b; { Number r; Store(a/b, &r); return (r); }
+ Number Self(a) Number a; { Number r; Store(a, &r); return (r); }
+ 
+ Procedure F_check(precision, val1) int precision; Long_double val1; {
+ 	/* You don't think I'm going to go to all the trouble of writing
+ 	   a program that works out what all sorts of values are, only to
+ 	   have printf go and print the wrong values out, do you?
+ 	   No, you're right, so this function tries to see if printf
+ 	   has written the right value, by reading it back again.
+ 	   This introduces a new problem of course: suppose printf writes
+ 	   the correct value, and scanf reads it back wrong... oh well.
+ 	   But I'm adamant about this: the precision given is enough
+ 	   to uniquely identify the printed number, therefore I insist
+ 	   that sscanf read the number back identically. Harsh yes, but
+ 	   sometimes you've got to be cruel to be kind.
+ 	*/
+ 	Long_double new1;
+ 	Number val, new, diff;
+ 	double rem;
+ 	int e;
+ 	char *rep;
+ 	char *f2;
+ 
+ 	if (sizeof(double) == sizeof(Long_double)) {
+ 		/* Assume they're the same, and use non-stdc format */
+ 		/* This is for stdc compilers using non-stdc libraries */
+ 		f2= "%le";   /* Input */
+ 	} else {
+ 		/* It had better support Le then */
+ 		f2= "%Le";
+ 	}
+ 	val= val1;
+ 	rep= f_rep(precision, (Long_double) val);
+ 	if (setjmp(lab)==0) {
+ 		sscanf(rep, f2, &new1);
+ 	} else {
+ 		eek_a_bug("sscanf caused a trap");
+ 		printf("%s    scanning: %s format: %s%s\n\n", co, rep, f2, oc);
+ 		Unexpected(12);
+ 		return;
+ 	}
+ 
+ 	if (setjmp(lab)==0) { /* See if new is usable */
+ 		new= new1;
+ 		if (new != 0.0) {
+ 			diff= val/new - 1.0;
+ 			if (diff < 0.1) diff= 1.0;
+ 			/* That should be enough to generate a trap */
+ 		}
+ 	} else {
+ 		eek_a_bug("sscanf returned an unusable number");
+ 		printf("%s    scanning: %s with format: %s%s\n\n",
+ 		       co, rep, f2, oc);
+ 		Unexpected(13);
+ 		return;
+ 	}
+ 
+ 	Unexpected(14);
+ 	if (new != val) {
+ 		eek_a_bug("Possibly bad output from printf above");
+ 		if (!exponent(val, &rem, &e)) {
+ 			printf("%s    but value was an unusable number%s\n\n",
+ 			       co, oc);
+ 			return;
+ 		}
+ 		printf("%s    expected value around %.*fe%d, bit pattern:\n    ",
+ 		       co, precision, rem, e);
+ 		bitpattern((char *) &val, sizeof(val));
+ 		printf ("%s\n", oc);
+ 		printf("%s    sscanf gave           %s, bit pattern:\n    ",
+ 		       co, f_rep(precision, (Long_double) new));
+ 		bitpattern((char *) &new, sizeof(new));
+ 		printf ("%s\n", oc);
+ 		printf("%s    difference= %s%s\n\n", 
+ 		       co, f_rep(precision, (Long_double) (val-new)), oc);
+ 	}
+ }
+ 
+ Procedure Validate(prec, val, req, same) int prec, same; Long_double val, req; {
+ 	Unexpected(15);
+ 	if (!same) {
+ 		printf("%s*** Verify failed for above #define!\n", co);
+ 		if (setjmp(lab) == 0) { /* for the case that req == nan */
+ 			printf("       Compiler has %s for value%s\n", 
+ 			       f_rep(prec, req), oc);
+ 		} else {
+ 			printf("       Compiler has %s for value%s\n",
+ 			       "an unusable number", oc);
+ 		}
+ 		if (setjmp(lab) == 0) {
+ 			F_check(prec, (Long_double) req);
+ 		} /*else forget it*/
+ 		if (setjmp(lab) == 0) {		
+ 			if (req > 0.0 && val > 0.0) {
+ 				printf("%s    difference= %s%s\n",
+ 				       co, f_rep(prec, val-req), oc);
+ 			}
+ 		} /*else forget it*/
+ 		Unexpected(16);
+ 		printf("\n");
+ 		bugs++;
+ 	} else if (val != req) {
+ 		if (stdc) {
+ 			printf("%s*** Verify failed for above #define!\n", co);
+ 			printf("       Constant has the wrong precision%s\n",
+ 			       oc);
+ 			bugs++;
+ 		} else eek_a_bug("the cast didn't work");
+ 		printf("\n");
+ 	}
+ }
+ 
+ int FPROP(bits_per_byte) int bits_per_byte; {
+ 	/* Properties of floating types, using algorithms by Cody and Waite
+ 	   from MA Malcolm, as modified by WM Gentleman and SB Marovich.
+ 	   Further extended by S Pemberton.
+ 
+ 	   Returns the number of digits in the fraction.
+ 	*/
+ 
+ 	volatile int i, f_radix, iexp, irnd, mrnd, f_rounds, f_mant_dig,
+ 	    iz, k, inf, machep, f_max_exp, f_min_exp, mx, negeps,
+ 	    mantbits, digs, f_dig, trap,
+ 	    hidden, normal, f_min_10_exp, f_max_10_exp;
+ 	volatile Number a, b, base, basein, basem1, f_epsilon, epsneg,
+ 	       f_max, newxmax, f_min, xminner, y, y1, z, z1, z2;
+ 
+ 	Unexpected(17);
+ 
+ 	Vprintf("%sPROPERTIES OF %s:%s\n", co, THING, oc);
+ 
+ 	/* Base and size of mantissa **************************************/
+ 	/* First repeatedly double until adding 1 has no effect.	  */
+ 	/* For instance, if base is 10, with 3 significant digits	  */
+ 	/* it will try 1, 2, 4, 8, ... 512, 1024, and stop there,	  */
+ 	/* since 1024 is only representable as 1020.			  */
+ 	a=1.0;
+ 	if (setjmp(lab)==0) { /* inexact trap? */
+ 		do { a=Sum(a, a); }
+ 		while (Diff(Diff(Sum(a, 1.0), a), 1.0) == 0.0);
+ 	} else {
+ 		fprintf(stderr, "*** Program got loss-of-precision trap!\n");
+ 		/* And supporting those is just TOO much trouble! */
+ 		exit(bugs+1);
+ 	}
+ 	Unexpected(18);
+ 	/* Now double until you find a number that can be added to the	  */
+ 	/* above number. For 1020 this is 8 or 16, depending whether the  */
+ 	/* result is rounded or truncated.				  */
+ 	/* In either case the result is 1030. 1030-1020= the base, 10.	  */
+ 	b=1.0;
+ 	do { b=Sum(b, b); } while ((base=Diff(Sum(a, b), a)) == 0.0);
+ 	f_radix=base;
+ 	Vprintf("%sBase = %d%s\n", co, f_radix, oc);
+ 
+ 	/* Sanity check; if base<2, I can't guarantee the rest will work  */
+ 	if (f_radix < 2) {
+ 		eek_a_bug("Function return or parameter passing faulty? (This is a guess.)");
+ 		printf("\n");
+ 		return(0);
+ 	}
+ 
+ #ifdef PASS1 /* only for FLT */
+ 	if (F) i_define("FLT", "_RADIX", (long) f_radix, (long) F_RADIX);
+ #endif
+ 
+ 	/* Now the number of digits precision: */
+ 	f_mant_dig=0; b=1.0;
+ 	do { f_mant_dig++; b=Mul(b, base); }
+ 	while (Diff(Diff(Sum(b,1.0),b),1.0) == 0.0);
+ 	f_dig=floor_log(10, (Long_double)(b/base)) + (base==10?1:0);
+ 	Vprintf("%sSignificant base digits = %d %s %d %s%s\n",
+ 		co, f_mant_dig, "(= at least", f_dig, "decimal digits)", oc);
+ 	if (F) i_define(Fname, "_MANT_DIG", (long) f_mant_dig,
+ 			(long) F_MANT_DIG);
+ 	if (F) i_define(Fname, "_DIG", (long) f_dig, (long) F_DIG);
+ 	digs= ceil_log(10, (Long_double)b); /* the number of digits to printf */
+ 
+ 	/* Rounding *******************************************************/
+ 	basem1=Diff(base, 0.5);
+ 	if (Diff(Sum(a, basem1), a) != 0.0) {
+ 		if (f_radix == 2) basem1=0.375;
+ 		else basem1=1.0;
+ 		if (Diff(Sum(a, basem1), a) != 0.0) irnd=2; /* away from 0 */
+ 		else irnd=1; /* to nearest */
+ 	} else irnd=0; /* towards 0 */
+ 
+ 	basem1=Diff(base, 0.5);
+ 
+ 	if (Diff(Diff(-a, basem1), -a) != 0.0) {
+ 		if (f_radix == 2) basem1=0.375;
+ 		else basem1=1.0;
+ 		if (Diff(Diff(-a, basem1), -a) != 0.0) mrnd=2; /* away from 0*/
+ 		else mrnd=1; /* to nearest */
+ 	} else mrnd=0; /* towards 0 */
+ 
+ 	f_rounds=4; /* Unknown rounding */
+ 	if (irnd==0 && mrnd==0) f_rounds=0; /* zero = chops */
+ 	if (irnd==1 && mrnd==1) f_rounds=1; /* nearest */
+ 	if (irnd==2 && mrnd==0) f_rounds=2; /* +inf */
+ 	if (irnd==0 && mrnd==2) f_rounds=3; /* -inf */
+ 
+ 	if (f_rounds != 4) {
+ 		Vprintf("%sArithmetic rounds towards ", co);
+ 		switch (f_rounds) {
+ 		      case 0: Vprintf("zero (i.e. it chops)"); break;
+ 		      case 1: Vprintf("nearest"); break;
+ 		      case 2: Vprintf("+infinity"); break;
+ 		      case 3: Vprintf("-infinity"); break;
+ 		      default: Vprintf("???"); break;
+ 		}
+ 		Vprintf("%s\n", oc);
+ 	} else { /* Hmm, try to give some help here: */
+ 		Vprintf("%sArithmetic rounds oddly: %s\n", co, oc);
+ 		Vprintf("%s    Negative numbers %s%s\n",
+ 			co, mrnd==0 ? "towards zero" :
+ 			    mrnd==1 ? "to nearest" :
+ 				      "away from zero",
+ 			oc);
+ 		Vprintf("%s    Positive numbers %s%s\n",
+ 			co, irnd==0 ? "towards zero" :
+ 			    irnd==1 ? "to nearest" :
+ 				      "away from zero",
+ 			oc);
+ 	}
+ 	/* An extra goody */
+ 	if (f_radix == 2 && f_rounds == 1) {
+ 		if (Diff(Sum(a, 1.0), a) != 0.0) {
+ 			Vprintf("%s   Tie breaking rounds up%s\n", co, oc);
+ 		} else if (Diff(Sum(a, 3.0), a) == 4.0) {
+ 			Vprintf("%s   Tie breaking rounds to even%s\n", co, oc);
+ 		} else {
+ 			Vprintf("%s   Tie breaking rounds down%s\n", co, oc);
+ 		}
+ 	}
+ #ifdef PASS1 /* only for FLT */
+ 	if (F) i_define("FLT", "_ROUNDS", (long) f_rounds, (long) F_ROUNDS);
+ #endif
+ 
+ 	/* Various flavours of epsilon ************************************/
+ 	negeps=f_mant_dig+f_mant_dig;
+ 	basein=1.0/base;
+ 	a=1.0;
+ 	for(i=1; i<=negeps; i++) a*=basein;
+ 
+ 	b=a;
+ 	while (Diff(Diff(1.0, a), 1.0) == 0.0) {
+ 		a*=base;
+ 		negeps--;
+ 	}
+ 	negeps= -negeps;
+ 	Vprintf("%sSmallest x such that 1.0-base**x != 1.0 = %d%s\n",
+ 		co, negeps, oc);
+ 
+ 	epsneg=a;
+ 	if ((f_radix!=2) && irnd) {
+ 	/*	a=(a*(1.0+a))/(1.0+1.0); => */
+ 		a=Div(Mul(a, Sum(1.0, a)), Sum(1.0, 1.0));
+ 	/*	if ((1.0-a)-1.0 != 0.0) epsneg=a; => */
+ 		if (Diff(Diff(1.0, a), 1.0) != 0.0) epsneg=a;
+ 	}
+ 	Vprintf("%sSmall x such that 1.0-x != 1.0 = %s%s\n",
+ 		co, f_rep(digs, (Long_double) epsneg), oc);
+ 	/* it may not be the smallest */
+ 	if (V) F_check(digs, (Long_double) epsneg);
+ 	Unexpected(19);
+ 
+ 	machep= -f_mant_dig-f_mant_dig;
+ 	a=b;
+ 	while (Diff(Sum(1.0, a), 1.0) == 0.0) { a*=base; machep++; }
+ 	Vprintf("%sSmallest x such that 1.0+base**x != 1.0 = %d%s\n",
+ 		co, machep, oc);
+ 
+ 	f_epsilon=a;
+ 	if ((f_radix!=2) && irnd) {
+ 	/*	a=(a*(1.0+a))/(1.0+1.0); => */
+ 		a=Div(Mul(a, Sum(1.0, a)), Sum(1.0, 1.0));
+ 	/*	if ((1.0+a)-1.0 != 0.0) f_epsilon=a; => */
+ 		if (Diff(Sum(1.0, a), 1.0) != 0.0) f_epsilon=a;
+ 	}
+ 	Vprintf("%sSmallest x such that 1.0+x != 1.0 = %s%s\n",
+ 		co, f_rep(digs, (Long_double) f_epsilon), oc);
+ 	/* Possible loss of precision warnings here from non-stdc compilers: */
+ 	if (F) f_define(Fname, "_EPSILON", digs, (Long_double) f_epsilon, MARK);
+ 	if (V || F) F_check(digs, (Long_double) f_epsilon);
+ 	Unexpected(20);
+ 	if (F) Validate(digs, (Long_double) f_epsilon, (Long_double) F_EPSILON,
+ 			f_epsilon == Self(F_EPSILON));
+ 	Unexpected(21);
+ 
+ 	/* Extra chop info *************************************************/
+ 	if (f_rounds == 0) {
+ 		if (Diff(Mul(Sum(1.0,f_epsilon),1.0),1.0) !=  0.0) {
+ 			Vprintf("%sAlthough arithmetic chops, it uses guard digits%s\n", co, oc);
+ 		}
+ 	}
+ 
+ 	/* Size of and minimum normalised exponent ************************/
+ 	y=0; i=0; k=1; z=basein; z1=(1.0+f_epsilon)/base;
+ 
+ 	/* Coarse search for the largest power of two */
+ 	if (setjmp(lab)==0) { /* for underflow trap */ /* Yields i, k, y, y1 */
+ 		do {
+ 			y=z; y1=z1;
+ 			z=Mul(y,y); z1=Mul(z1, y);
+ 			a=Mul(z,1.0);
+ 			z2=Div(z1,y);
+ 			if (z2 != y1) break;
+ 			if ((Sum(a,a) == 0.0) || (fabs(z) >= y)) break;
+ 			i++;
+ 			k+=k;
+ 		} while(1);
+ 	} else {
+ 		Vprintf("%s%s underflow generates a trap%s\n", co, Thing, oc);
+ 	}
+ 	Unexpected(22);
+ 
+ 	if (f_radix != 10) {
+ 		iexp=i+1; /* for the sign */
+ 		mx=k+k;
+ 	} else {
+ 		iexp=2;
+ 		iz=f_radix;
+ 		while (k >= iz) { iz*=f_radix; iexp++; }
+ 		mx=iz+iz-1;
+ 	}
+ 
+ 	/* Fine tune starting with y and y1 */
+ 	if (setjmp(lab)==0) { /* for underflow trap */ /* Yields k, f_min */
+ 		do {
+ 			f_min=y; z1=y1;
+ 			y=Div(y,base); y1=Div(y1,base);
+ 			a=Mul(y,1.0);
+ 			z2=Mul(y1,base);
+ 			if (z2 != z1) break;
+ 			if ((Sum(a,a) == 0.0) || (fabs(y) >= f_min)) break;
+ 			k++;
+ 		} while (1);
+ 	}
+ 	Unexpected(23);
+ 
+ 	f_min_exp=(-k)+1;
+ 
+ 	if ((mx <= k+k-3) && (f_radix != 10)) { mx+=mx; iexp+=1; }
+ 	Vprintf("%sNumber of bits used for exponent = %d%s\n", co, iexp, oc);
+ 	Vprintf("%sMinimum normalised exponent = %d%s\n", co, f_min_exp, oc);
+ 	if (F) i_define(Fname, "_MIN_EXP", (long) f_min_exp, (long) F_MIN_EXP);
+ 
+ 	if (setjmp(lab)==0) {
+ 		Vprintf("%sMinimum normalised positive number = %s%s\n",
+ 			co, f_rep(digs, (Long_double) f_min), oc);
+ 	} else {
+ 		eek_a_bug("printf can't print the smallest normalised number");
+ 		printf("\n");
+ 	}
+ 	Unexpected(24);
+ 	/* Possible loss of precision warnings here from non-stdc compilers: */
+ 	if (setjmp(lab) == 0) {
+ 		if (F) f_define(Fname, "_MIN", digs, (Long_double) f_min, MARK);
+ 		if (V || F) F_check(digs, (Long_double) f_min);
+ 	} else {
+ 		eek_a_bug("xxx_MIN caused a trap");
+ 		printf("\n");
+ 	}
+ 
+ 	if (setjmp(lab) == 0) {
+ 		if (F) Validate(digs, (Long_double) f_min, (Long_double) F_MIN,
+ 				f_min == Self(F_MIN));
+ 	} else {
+ 		printf("%s*** Verify failed for above #define!\n    %s %s\n\n",
+ 		       co, "Compiler has an unusable number for value", oc);
+ 		bugs++;
+ 	}
+ 	Unexpected(25);
+ 
+ 	a=1.0; f_min_10_exp=0;
+ 	while (a > f_min*10.0) { a/=10.0; f_min_10_exp--; }
+ 	if (F) i_define(Fname, "_MIN_10_EXP", (long) f_min_10_exp,
+ 			(long) F_MIN_10_EXP);
+ 
+ 	/* Minimum exponent ************************************************/
+ 	if (setjmp(lab)==0) { /* for underflow trap */ /* Yields xminner */
+ 		do {
+ 			xminner=y;
+ 			y=Div(y,base);
+ 			a=Mul(y,1.0);
+ 			if ((Sum(a,a) == 0.0) || (fabs(y) >= xminner)) break;
+ 		} while (1);
+ 	}
+ 	Unexpected(26);
+ 
+ 	if (xminner != 0.0 && xminner != f_min) {
+ 		normal= 0;
+ 		Vprintf("%sThe smallest numbers are not kept normalised%s\n",
+ 			co, oc);
+ 		if (setjmp(lab)==0) {
+ 		    Vprintf("%sSmallest unnormalised positive number = %s%s\n",
+ 			    co, f_rep(digs, (Long_double) xminner), oc);
+ 		    if (V) F_check(digs, (Long_double) xminner);
+ 		} else {
+ 			eek_a_bug("printf can't print the smallest unnormalised number.");
+ 			printf("\n");
+ 		}
+ 		Unexpected(27);
+ 	} else {
+ 		normal= 1;
+ 		Vprintf("%sThe smallest numbers are normalised%s\n", co, oc);
+ 	}
+ 
+ 	/* Maximum exponent ************************************************/
+ 	f_max_exp=2; f_max=1.0; newxmax=base+1.0;
+ 	inf=0; trap=0;
+ 	while (f_max<newxmax) {
+ 		f_max=newxmax;
+ 		if (setjmp(lab) == 0) { /* Yields inf, f_max_exp */
+ 			newxmax=Mul(newxmax, base);
+ 		} else {
+ 			trap=1;
+ 			break;
+ 		}
+ 		if (Div(newxmax, base) != f_max) {
+ 			inf=1; /* ieee infinity */
+ 			break;
+ 		}
+ 		f_max_exp++;
+ 	}
+ 	Unexpected(28);
+ 	if (trap) {
+ 		Vprintf("%s%s overflow generates a trap%s\n", co, Thing, oc);
+ 	}
+ 
+ 	if (inf) Vprintf("%sThere is an 'infinite' value%s\n", co, oc);
+ 	Vprintf("%sMaximum exponent = %d%s\n", co, f_max_exp, oc);
+ 	if (F) i_define(Fname, "_MAX_EXP", (long) f_max_exp, (long) F_MAX_EXP);
+ 
+ 	/* Largest number ***************************************************/
+ 	f_max=Diff(1.0, epsneg);
+ 	if (Mul(f_max,1.0) != f_max) f_max=Diff(1.0, Mul(base,epsneg));
+ 	for (i=1; i<=f_max_exp; i++) f_max=Mul(f_max, base);
+ 
+ 	if (setjmp(lab)==0) {
+ 		Vprintf("%sMaximum number = %s%s\n",
+ 			co, f_rep(digs, (Long_double) f_max), oc);
+ 	} else {
+ 		eek_a_bug("printf can't print the largest double.");
+ 		printf("\n");
+ 	}
+ 	if (setjmp(lab)==0) {
+ 	/* Possible loss of precision warnings here from non-stdc compilers: */
+ 		if (F) f_define(Fname, "_MAX", digs, (Long_double) f_max, MARK);
+ 		if (V || F) F_check(digs, (Long_double) f_max);
+ 	} else {
+ 		eek_a_bug("xxx_MAX caused a trap");
+ 		printf("\n");
+ 	}
+ 	if (setjmp(lab)==0) {
+ 		if (F) Validate(digs, (Long_double) f_max, (Long_double) F_MAX,
+ 				f_max == Self(F_MAX));
+ 	} else {
+ 		printf("%s*** Verify failed for above #define!\n    %s %s\n\n",
+ 		       co, "Compiler has an unusable number for value", oc);
+ 		bugs++;
+ 	}
+ 	Unexpected(29);
+ 
+ 	a=1.0; f_max_10_exp=0;
+ 	while (a < f_max/10.0) { a*=10.0; f_max_10_exp++; }
+ 	if (F) i_define(Fname, "_MAX_10_EXP", (long) f_max_10_exp,
+ 			(long) F_MAX_10_EXP);
+ 
+ 	/* Hidden bit + sanity check ****************************************/
+ 	if (f_radix != 10) {
+ 		hidden=0;
+ 		mantbits=floor_log(2, (Long_double)f_radix)*f_mant_dig;
+ 		if (mantbits+iexp == (int)sizeof(Number)*bits_per_byte) {
+ 			hidden=1;
+ 			Vprintf("%sArithmetic uses a hidden bit%s\n", co, oc);
+ 		} else if (mantbits+iexp+1 == (int)sizeof(Number)*bits_per_byte) {
+ 			Vprintf("%sArithmetic doesn't use a hidden bit%s\n",
+ 				co, oc);
+ 		} else {
+ 			printf("\n%s%s\n    %s %s %s!%s\n\n",
+ 			       co,
+ 			       "*** Something fishy here!",
+ 			       "Exponent size + mantissa size doesn't match",
+ 			       "with the size of a", thing,
+ 			       oc);
+ 		}
+ 		if (hidden && f_radix == 2 && f_max_exp+f_min_exp==3) {
+ 			Vprintf("%sIt looks like %s length IEEE format%s\n",
+ 				co, f_mant_dig==24 ? "single" :
+ 				    f_mant_dig==53 ? "double" :
+ 				    f_mant_dig >53 ? "extended" :
+ 						"some", oc);
+ 			if (f_rounds != 1 || normal) {
+ 				Vprintf("%s   though ", co);
+ 				if (f_rounds != 1) {
+ 					Vprintf("the rounding is unusual");
+ 					if (normal) Vprintf(" and ");
+ 				}
+ 				if (normal) Vprintf("the normalisation is unusual");
+ 				Vprintf("%s\n", oc);
+ 			}
+ 		} else {
+ 			Vprintf("%sIt doesn't look like IEEE format%s\n",
+ 				co, oc);
+ 		}
+ 	}
+ 	printf("\n"); /* regardless of verbosity */
+ 	return f_mant_dig;
+ }
+ 
+ Procedure EPROP(fprec, dprec, lprec) int fprec, dprec, lprec; {
+ 	/* See if expressions are evaluated in extended precision.
+ 	   Some compilers optimise even if you don't want it,
+ 	   and then this function fails to produce the right result.
+ 	   We try to diagnose this if it happens.
+ 	*/
+ 	volatile int eprec;
+ 	volatile double a, b, base, old;
+ 	volatile Number d, oldd, dbase, one, zero;
+ 	volatile int bad=0;
+ 
+ 	/* Size of mantissa **************************************/
+ 	a=1.0;
+ 	if (setjmp(lab) == 0) { /* Yields nothing */
+ 		do { old=a; a=a+a; }
+ 		while ((((a+1.0)-a)-1.0) == 0.0 && a>old);
+ 	} else bad=1;
+ 	if (a <= old) bad=1;
+ 
+ 	if (!bad) {
+ 		b=1.0;
+ 		if (setjmp(lab) == 0) { /* Yields nothing */
+ 			do { old=b; b=b+b; }
+ 			while ((base=((a+b)-a)) == 0.0 && b>old);
+ 			if (b <= old) bad=1;
+ 		} else bad=1;
+ 	}
+ 
+ 	if (!bad) {
+ 		eprec=0; d=1.0; dbase=base; one=1.0; zero=0.0;
+ 		if (setjmp(lab) == 0) { /* Yields nothing */
+ 			do { eprec++; oldd=d; d=d*dbase; }
+ 			while ((((d+one)-d)-one) == zero && d>oldd);
+ 			if (d <= oldd) bad=1;
+ 		} else bad=1;
+ 	}
+ 
+ 	Unexpected(30);
+ 
+ 	if (bad) {
+ 	  Vprintf("%sCan't determine precision for %s expressions:\n%s%s\n", 
+ 		 co, thing, "   check that you compiled without optimisation!",
+ 		 oc);
+ 	} else if (eprec==dprec) {
+ 	  Vprintf("%s%s expressions are evaluated in double precision%s\n",
+ 		  co, Thing, oc);
+ 	} else if (eprec==fprec) {
+ 	  Vprintf("%s%s expressions are evaluated in float precision%s\n",
+ 		  co, Thing, oc);
+ 	} else if (eprec==lprec) {
+ 	  Vprintf("%s%s expressions are evaluated in long double precision%s\n",
+ 		  co, Thing, oc);
+ 	} else {
+ 		Vprintf("%s%s expressions are evaluated in a %s %s %d %s%s\n",
+ 			co, Thing, eprec>dprec ? "higher" : "lower",
+ 			"precision than double,\n   using",
+ 			eprec, "base digits",
+ 		        oc);
+ 	}
+ }
+ 
+ #else /* Number */
+ 
+ #ifdef FPROP
+ /* ARGSUSED */
+ int FPROP(bits_per_byte) int bits_per_byte; {
+ 	return 0;
+ }
+ #endif
+ #ifdef EPROP
+ /* ARGSUSED */
+ Procedure EPROP(fprec, dprec, lprec) int fprec, dprec, lprec; {}
+ #endif
+ 
+ #endif /* ifdef Number */
+ 
+ #ifdef PASS3
+ #undef PASS
+ #endif
+ 
+ #ifdef PASS2
+ #undef PASS2
+ #define PASS3 1
+ #endif
+ 
+ #ifdef PASS1
+ #undef PASS1
+ #define PASS2 1
+ #endif
+ 
+ /* If your C compiler doesn't accept the next #include,
+    replace __FILE__ with the file name - and get a new C compiler... */
+ 
+ #ifdef PASS
+ #include __FILE__
+ #endif
+ 
diff -rc2N gcc-1.35/input.h gcc-1.36/input.h
*** gcc-1.35/input.h	Wed Dec 31 19:00:00 1969
--- gcc-1.36/input.h	Sat Apr 29 14:03:53 1989
***************
*** 0 ****
--- 1,22 ----
+ /* Source file current line is coming from.  */
+ extern char *input_filename;
+ 
+ /* Top-level source file.  */
+ extern char *main_input_filename;
+ 
+ /* Line number in current source file.  */
+ extern int lineno;
+ 
+ struct file_stack
+   {
+     char *name;
+     struct file_stack *next;
+     int line;
+   };
+ 
+ /* Stack of currently pending input files.
+    The line member is not accurate for the innermost file on the stack.  */
+ extern struct file_stack *input_file_stack;
+ 
+ /* Incremented on each change to input_file_stack.  */
+ extern int input_file_stack_tick;
diff -rc2N gcc-1.35/integrate.c gcc-1.36/integrate.c
*** gcc-1.35/integrate.c	Mon Apr 24 00:07:49 1989
--- gcc-1.36/integrate.c	Sat Sep  9 04:00:18 1989
***************
*** 38,44 ****
--- 38,47 ----
  extern struct obstack *rtl_obstack, *saveable_obstack, *current_obstack;
  
+ extern rtx stack_slot_list;
+ 
  #define MIN(x,y) ((x < y) ? x : y)
  
  extern tree pushdecl ();
+ extern tree poplevel ();
  
  /* Default max number of insns a function can have and still be inline.
***************
*** 46,50 ****
  #ifndef INTEGRATE_THRESHOLD
  #define INTEGRATE_THRESHOLD(DECL) \
!   (8 * (8 + list_length (DECL_ARGUMENTS (DECL)) + 16*TREE_INLINE (DECL)))
  #endif
  \f


--- 49,53 ----
  #ifndef INTEGRATE_THRESHOLD
  #define INTEGRATE_THRESHOLD(DECL) \
!   (8 * (8 + list_length (DECL_ARGUMENTS (DECL))))
  #endif
  \f


***************
*** 92,95 ****
--- 95,101 ----
  static rtvec copy_asm_operands_vector;
  
+ /* Likewise, this is the copied constraints vector.  */
+ static rtvec copy_asm_constraints_vector;
+ 
  /* Return a copy of an rtx (as needed), substituting pseudo-register,
     labels, and frame-pointer offsets as necessary.  */
***************
*** 98,101 ****
--- 104,110 ----
  static rtx copy_address ();
  
+ /* Return the rtx corresponding to a given index in the stack arguments.  */
+ static rtx access_parm_map ();
+ 
  static void copy_parm_decls ();
  static void copy_decl_tree ();
***************
*** 130,141 ****
  
    /* If its not even close, don't even look.  */
!   if (get_max_uid () > 2 * max_insns)
      return "function too large to be inline";
  
!   /* If the structure value address comes in the stack,
!      we can't handle it.  */
! #if defined (STRUCT_VALUE) || defined (STRUCT_VALUE_INCOMING)
!   if (TYPE_MODE (TREE_TYPE (TREE_TYPE (fndecl))) == BLKmode
!       || RETURN_IN_MEMORY (TREE_TYPE (TREE_TYPE (fndecl))))
      return "inline functions not supported for this return value type";
  #endif
--- 139,151 ----
  
    /* If its not even close, don't even look.  */
!   if (!TREE_INLINE (fndecl) && get_max_uid () > 3 * max_insns)
      return "function too large to be inline";
  
!   /* We can't inline functions that return structures
!      the old-fashioned PCC way, copying into a static block.  */
! #ifdef PCC_STATIC_STRUCT_RETURN
!   if (flag_pcc_struct_return
!       && (TYPE_MODE (TREE_TYPE (TREE_TYPE (fndecl))) == BLKmode
! 	  || RETURN_IN_MEMORY (TREE_TYPE (TREE_TYPE (fndecl)))))
      return "inline functions not supported for this return value type";
  #endif
***************
*** 161,165 ****
      }
  
!   if (get_max_uid () > max_insns)
      {
        for (ninsns = 0, insn = get_first_nonparm_insn (); insn && ninsns < max_insns;
--- 171,175 ----
      }
  
!   if (!TREE_INLINE (fndecl) && get_max_uid () > max_insns)
      {
        for (ninsns = 0, insn = get_first_nonparm_insn (); insn && ninsns < max_insns;
***************
*** 283,287 ****
    head = gen_inline_header_rtx (NULL, NULL, min_labelno, max_labelno,
  				max_parm_reg, max_reg,
! 				current_function_args_size);
    max_uid = INSN_UID (head);
  
--- 293,297 ----
    head = gen_inline_header_rtx (NULL, NULL, min_labelno, max_labelno,
  				max_parm_reg, max_reg,
! 				current_function_args_size, stack_slot_list);
    max_uid = INSN_UID (head);
  
***************
*** 349,353 ****
  	{
  	case NOTE:
! 	  if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_END)
  	    continue;
  
--- 359,366 ----
  	{
  	case NOTE:
! 	  /* It is probably essential to discard these.  */
! 	  if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_END
! 	      /* No need to keep these.  */
! 	      || NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED)
  	    continue;
  
***************
*** 365,368 ****
--- 378,382 ----
  	  LOG_LINKS (copy) = NULL;
  	  REG_NOTES (copy) = copy_for_inline (REG_NOTES (insn));
+ 	  RTX_INTEGRATED_P (copy) = RTX_INTEGRATED_P (insn);
  	  break;
  
***************
*** 443,447 ****
  	  XINT (x, 2) = XINT (orig, 2);
  	  XVEC (x, 3) = copy_asm_operands_vector;
! 	  XVEC (x, 4) = XVEC (orig, 4);
  	  return x;
  	}
--- 457,463 ----
  	  XINT (x, 2) = XINT (orig, 2);
  	  XVEC (x, 3) = copy_asm_operands_vector;
! 	  XVEC (x, 4) = copy_asm_constraints_vector;
! 	  XSTR (x, 5) = XSTR (orig, 5);
! 	  XINT (x, 6) = XINT (orig, 6);
  	  return x;
  	}
***************
*** 453,456 ****
--- 469,476 ----
        if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
  	return x;
+ #if 0 /* This is turned off because it is possible for
+ 	 unshare_all_rtl to copy the address, into memory that won't be saved.
+ 	 Although the MEM can safely be shared, and won't be copied there,
+ 	 the address itself cannot be shared, and may need to be copied.  */
        if (GET_CODE (XEXP (x, 0)) == PLUS
  	  && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
***************
*** 458,461 ****
--- 478,486 ----
  	      || REGNO (XEXP (XEXP (x, 0), 0)) == ARG_POINTER_REGNUM)
  	  && CONSTANT_ADDRESS_P (XEXP (XEXP (x, 0), 1)))
+ #if 0
+ 	/* This statement was accidentally deleted in the remote past.
+ 	   Reinsert it for 1.37.  Don't take the risk now.  */
+ 	return x;
+ #endif
  	if (GET_CODE (XEXP (x, 0)) == REG
  	    && (REGNO (XEXP (x, 0)) == FRAME_POINTER_REGNUM
***************
*** 463,466 ****
--- 488,492 ----
  	    && CONSTANT_ADDRESS_P (XEXP (x, 1)))
  	return x;
+ #endif /* 0 */
        break;
  
***************
*** 536,539 ****
--- 562,566 ----
        orig_asm_operands_vector = XVEC (orig, 3);
        copy_asm_operands_vector = XVEC (x, 3);
+       copy_asm_constraints_vector = XVEC (x, 4);
      }
  
***************
*** 581,586 ****
    nargs = list_length (DECL_ARGUMENTS (fndecl));
  
-   first_parm_offset = FIRST_PARM_OFFSET (fndecl);
- 
    /* We expect PARMS to have the right length; don't crash if not.  */
    if (list_length (parms) != nargs)
--- 608,611 ----
***************
*** 604,607 ****
--- 629,637 ----
      }
  
+   /* Make a binding contour to keep inline cleanups called at
+      outer function-scope level from looking like they are shadowing
+      parameter declarations.  */
+   pushlevel (0);
+ 
    /* Make a fresh binding contour that we can easily remove.  */
    pushlevel (0);
***************
*** 620,625 ****
         i++)
      {
!       tree arg = TREE_VALUE (actual); /* this has already been converted */
        enum machine_mode tmode = TYPE_MODE (DECL_ARG_TYPE (formal));
        enum machine_mode imode = TYPE_MODE (TREE_TYPE (formal));
        rtx copy;
--- 650,658 ----
         i++)
      {
!       /* Actual parameter, already converted to DECL_ARG_TYPE (formal).  */
!       tree arg = TREE_VALUE (actual);
!       /* Mode of the value supplied.  */
        enum machine_mode tmode = TYPE_MODE (DECL_ARG_TYPE (formal));
+       /* Mode of the variable used within the function.  */
        enum machine_mode imode = TYPE_MODE (TREE_TYPE (formal));
        rtx copy;
***************
*** 627,633 ****
        emit_note (DECL_SOURCE_FILE (formal), DECL_SOURCE_LINE (formal));
  
        if (TREE_ADDRESSABLE (formal))
  	{
! 	  int size = int_size_in_bytes (TREE_TYPE (formal));
  	  copy = assign_stack_local (tmode, size);
  	  if (!memory_address_p (DECL_MODE (formal), XEXP (copy, 0)))
--- 660,668 ----
        emit_note (DECL_SOURCE_FILE (formal), DECL_SOURCE_LINE (formal));
  
+       /* Make a place to hold the argument value, still in mode TMODE,
+ 	 and put it in COPY.  */
        if (TREE_ADDRESSABLE (formal))
  	{
! 	  int size = int_size_in_bytes (DECL_ARG_TYPE (formal));
  	  copy = assign_stack_local (tmode, size);
  	  if (!memory_address_p (DECL_MODE (formal), XEXP (copy, 0)))
***************
*** 659,663 ****
  	 Convert it to the nominal mode (i.e. truncate it).  */
        if (tmode != imode)
! 	copy = convert_to_mode (imode, copy);
        arg_vec[i] = copy;
      }
--- 694,698 ----
  	 Convert it to the nominal mode (i.e. truncate it).  */
        if (tmode != imode)
! 	copy = convert_to_mode (imode, copy, 0);
        arg_vec[i] = copy;
      }
***************
*** 674,686 ****
    if (structure_value_addr)
      {
!       if (GET_CODE (struct_value_rtx) == MEM)
! 	{
! 	  this_struct_value_rtx = force_reg (Pmode, structure_value_addr);
! 	}
        else
! 	{
! 	  this_struct_value_rtx = struct_value_rtx;
! 	  emit_move_insn (this_struct_value_rtx, structure_value_addr);
! 	}
      }
  
--- 709,717 ----
    if (structure_value_addr)
      {
!       if (GET_CODE (structure_value_addr) == REG
! 	  && (struct_value_rtx == 0 || GET_CODE (struct_value_rtx) == MEM))
! 	this_struct_value_rtx = structure_value_addr;
        else
!  	this_struct_value_rtx = copy_to_mode_reg (Pmode, structure_value_addr);
      }
  
***************
*** 692,704 ****
    bzero (reg_map, max_regno * sizeof (rtx));
  
    if (DECL_ARGUMENTS (fndecl))
      {
        tree decl = DECL_ARGUMENTS (fndecl);
-       int offset = FUNCTION_ARGS_SIZE (header);
- 
-       parm_map =
- 	(rtx *)alloca ((offset / UNITS_PER_WORD) * sizeof (rtx));
-       bzero (parm_map, (offset / UNITS_PER_WORD) * sizeof (rtx));
-       parm_map -= first_parm_offset / UNITS_PER_WORD;
  
        for (formal = decl, i = 0; formal; formal = TREE_CHAIN (formal), i++)
--- 723,739 ----
    bzero (reg_map, max_regno * sizeof (rtx));
  
+   parm_map = (rtx *)alloca ((FUNCTION_ARGS_SIZE (header)
+ 			     / UNITS_PER_WORD) * sizeof (rtx));
+   bzero (parm_map, ((FUNCTION_ARGS_SIZE (header)
+ 		     / UNITS_PER_WORD)
+ 		    * sizeof (rtx)));
+ 
+   /* Note that expand_expr (called above) can clobber first_parm_offset.  */
+   first_parm_offset = FIRST_PARM_OFFSET (fndecl);
+   parm_map -= first_parm_offset / UNITS_PER_WORD;
+ 
    if (DECL_ARGUMENTS (fndecl))
      {
        tree decl = DECL_ARGUMENTS (fndecl);
  
        for (formal = decl, i = 0; formal; formal = TREE_CHAIN (formal), i++)
***************
*** 728,735 ****
  			       && GET_CODE (XEXP (frtx, 0)) == CONST_INT)
  			offset = XEXP (frtx, 0);
  		    }
  		  if (offset)
  		    parm_map[INTVAL (offset) / UNITS_PER_WORD] = arg_vec[i];
! 		  else abort ();
  		}
  	      else if (GET_CODE (frtx) != REG)
--- 763,783 ----
  			       && GET_CODE (XEXP (frtx, 0)) == CONST_INT)
  			offset = XEXP (frtx, 0);
+ #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
+ 		      /* If there is a separate arg pointer
+ 			 and REG_PARM_STACK_SPACE is defined,
+ 			 parms passed in regs can be copied
+ 			 to slots reached via the arg pointer.  */
+ 		      if (XEXP (frtx, 0) == arg_pointer_rtx
+ 			  && GET_CODE (XEXP (frtx, 1)) == CONST_INT)
+ 			offset = XEXP (frtx, 1);
+ 		      else if (XEXP (frtx, 1) == arg_pointer_rtx
+ 			       && GET_CODE (XEXP (frtx, 0)) == CONST_INT)
+ 			offset = XEXP (frtx, 0);
+ #endif
  		    }
  		  if (offset)
  		    parm_map[INTVAL (offset) / UNITS_PER_WORD] = arg_vec[i];
! 		  else if (TREE_TYPE (formal) != error_mark_node)
! 		    abort ();
  		}
  	      else if (GET_CODE (frtx) != REG)
***************
*** 741,762 ****
  	    reg_map[REGNO (DECL_RTL (formal))] = arg_vec[i];
  	}
- 
-       /* Make certain that we can accept struct_value_{incoming_rtx,rtx},
- 	 and map it.  If it is a hard register, it is mapped automagically.  */
-       if (this_struct_value_rtx == 0
- 	  || GET_CODE (struct_value_incoming_rtx) == REG)
- 	;
-       else if (GET_CODE (struct_value_incoming_rtx) == MEM
- 	       && XEXP (XEXP (struct_value_incoming_rtx, 0), 0) == frame_pointer_rtx
- 	       && GET_CODE (XEXP (XEXP (struct_value_incoming_rtx, 0), 1)) == CONST_INT)
- 	parm_map[INTVAL (XEXP (XEXP (struct_value_incoming_rtx, 0), 1)) / UNITS_PER_WORD]
- 	  = this_struct_value_rtx;
-       else
- 	abort ();
      }
    else
!     {
!       parm_map = NULL;
!     }
  
    label_map = (rtx *)alloca ((max_labelno - min_labelno) * sizeof (rtx));
--- 789,826 ----
  	    reg_map[REGNO (DECL_RTL (formal))] = arg_vec[i];
  	}
      }
+ 
+ #if 0  /* This was turned off when it was written,
+ 	  because expand_call was changed not to need it.  */
+   /* Handle the case where our caller offers a register target
+      but the called function wants to return the value in memory.  */
+   if (this_struct_value_rtx == 0
+       && aggregate_value_p (DECL_RESULT (fndecl)))
+     {
+       enum machine_mode mode1 = GET_MODE (DECL_RTL (DECL_RESULT (fndecl)));
+       this_struct_value_rtx
+ 	= assign_stack_local (mode1, GET_MODE_SIZE (mode1));
+       target = 0;
+     }
+ #endif
+ 
+   /* Make certain that we can accept struct_value_{incoming_rtx,rtx},
+      and map it.  */
+   if (this_struct_value_rtx == 0)
+     ;
+   else if (GET_CODE (struct_value_incoming_rtx) == REG)
+     reg_map[REGNO (XEXP (DECL_RTL (DECL_RESULT (fndecl)), 0))]
+       = this_struct_value_rtx;
+   else if (GET_CODE (struct_value_incoming_rtx) == MEM
+ 	   && XEXP (XEXP (struct_value_incoming_rtx, 0), 0) == frame_pointer_rtx
+ 	   && GET_CODE (XEXP (XEXP (struct_value_incoming_rtx, 0), 1)) == CONST_INT)
+     reg_map[REGNO (XEXP (DECL_RTL (DECL_RESULT (fndecl)), 0))]
+       = this_struct_value_rtx;
+ #if 0
+     parm_map[INTVAL (XEXP (XEXP (struct_value_incoming_rtx, 0), 1)) / UNITS_PER_WORD]
+       = this_struct_value_rtx;
+ #endif
    else
!     abort ();
  
    label_map = (rtx *)alloca ((max_labelno - min_labelno) * sizeof (rtx));
***************
*** 774,778 ****
    /* Set up a target to translate the inline function's value-register.  */
  
!   if (structure_value_addr != 0 || TYPE_MODE (type) == VOIDmode)
      inline_target = 0;
    else
--- 838,842 ----
    /* Set up a target to translate the inline function's value-register.  */
  
!   if (this_struct_value_rtx != 0 || TYPE_MODE (type) == VOIDmode)
      inline_target = 0;
    else
***************
*** 801,809 ****
      }
  
!   /* We are about to make space in this function's stack frame
!      for a copy of the stack frame of the inline function.
!      First, create an RTX that points to that stack frame
!      with the same offset usually used for the frame pointer.
!      This will be substituted for all frame-pointer references.  */
  
    fp_delta = get_frame_size ();
--- 865,875 ----
      }
  
!   /* Make space in current function's stack frame
!      for the stack frame of the inline function.
!      Adjust all frame-pointer references by the difference
!      between the offset to this space
!      and the offset to the equivalent space in the inline
!      function's frame.
!      This difference equals the size of preexisting locals.  */
  
    fp_delta = get_frame_size ();
***************
*** 811,815 ****
    fp_delta = - fp_delta;
  #endif
-   fp_delta -= STARTING_FRAME_OFFSET;
  
    inline_fp_rtx
--- 877,880 ----
***************
*** 884,887 ****
--- 949,958 ----
  	      && REG_FUNCTION_VALUE_P (XEXP (pattern, 0)))
  	    break;
+ 	  /* Ignore setting a function value that we don't want to use.  */
+ 	  if (inline_target == 0
+ 	      && GET_CODE (pattern) == SET
+ 	      && GET_CODE (SET_DEST (pattern)) == REG
+ 	      && REG_FUNCTION_VALUE_P (SET_DEST (pattern)))
+ 	    break;
  
  	  /* Try to do some quick constant folding here.
***************
*** 898,903 ****
--- 969,983 ----
  	  else
  	    {
+ 	      rtx note = find_reg_note (insn, REG_EQUIV, 0);
+ 
  	      copy = emit_insn (copy_rtx_and_substitute (pattern));
  	      RTX_INTEGRATED_P (copy) = 1;
+ 
+ 	      /* If we are copying an insn that loads a constant,
+ 		 record the constantness.  */
+ 	      if (note)
+ 		REG_NOTES (copy)
+ 		  = gen_rtx (EXPR_LIST, REG_EQUIV, XEXP (note, 0),
+ 			     REG_NOTES (copy));
  	    }
  	  break;
***************
*** 969,973 ****
  
  	case NOTE:
! 	  if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END)
  	    copy = emit_note (NOTE_SOURCE_FILE (insn), NOTE_LINE_NUMBER (insn));
  	  else
--- 1049,1054 ----
  
  	case NOTE:
! 	  if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END
! 	      && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_BEG)
  	    copy = emit_note (NOTE_SOURCE_FILE (insn), NOTE_LINE_NUMBER (insn));
  	  else
***************
*** 994,997 ****
--- 1075,1079 ----
    expand_end_bindings (getdecls (), 1, 1);
    poplevel (1, 1, 0);
+   poplevel (0, 0, 0);
  
    reg_map = NULL;
***************
*** 1005,1009 ****
        if (target)
  	return target;
!       return gen_rtx (MEM, BLKmode,
  		      memory_address (BLKmode, structure_value_addr));
      }
--- 1087,1091 ----
        if (target)
  	return target;
!       return gen_rtx (MEM, TYPE_MODE (type),
  		      memory_address (BLKmode, structure_value_addr));
      }
***************
*** 1043,1047 ****
       int level;
  {
!   tree t;
  
    pushlevel (0);
--- 1125,1129 ----
       int level;
  {
!   tree t, node;
  
    pushlevel (0);
***************
*** 1075,1082 ****
      }
  
!   for (t = STMT_BODY (let); t; t = TREE_CHAIN (t))
      copy_decl_tree (t, level + 1);
  
!   poplevel (level > 0, 0, 0);
  }
  \f


--- 1157,1166 ----
      }
  
!   for (t = STMT_SUBBLOCKS (let); t; t = TREE_CHAIN (t))
      copy_decl_tree (t, level + 1);
  
!   node = poplevel (level > 0, 0, 0);
!   if (node)
!     TREE_USED (node) = TREE_USED (let);
  }
  \f


***************
*** 1114,1117 ****
--- 1198,1205 ----
        if (regno < FIRST_PSEUDO_REGISTER)
  	{
+ 	  /* Some hard registers are also mapped,
+ 	     but others are not translated.  */
+ 	  if (reg_map[regno] != 0)
+ 	    return reg_map[regno];
  	  if (REG_FUNCTION_VALUE_P (orig))
  	    {
***************
*** 1135,1138 ****
--- 1223,1235 ----
        return reg_map[regno];
  
+     case SUBREG:
+       copy = copy_rtx_and_substitute (SUBREG_REG (orig));
+       /* SUBREG is ordinary, but don't make nested SUBREGs.  */
+       if (GET_CODE (copy) == SUBREG)
+ 	return gen_rtx (SUBREG, GET_MODE (orig), SUBREG_REG (copy),
+ 			SUBREG_WORD (orig) + SUBREG_WORD (copy));
+       return gen_rtx (SUBREG, GET_MODE (orig), copy,
+ 		      SUBREG_WORD (orig));
+ 
      case CODE_LABEL:
        return label_map[CODE_LABEL_NUMBER (orig)];
***************
*** 1162,1166 ****
  	  XINT (copy, 2) = XINT (orig, 2);
  	  XVEC (copy, 3) = copy_asm_operands_vector;
! 	  XVEC (copy, 4) = XVEC (orig, 4);
  	  return copy;
  	}
--- 1259,1265 ----
  	  XINT (copy, 2) = XINT (orig, 2);
  	  XVEC (copy, 3) = copy_asm_operands_vector;
! 	  XVEC (copy, 4) = copy_asm_constraints_vector;
! 	  XSTR (copy, 5) = XSTR (orig, 5);
! 	  XINT (copy, 6) = XINT (orig, 6);
  	  return copy;
  	}
***************
*** 1196,1204 ****
  		  || XEXP (orig, 1) == arg_pointer_rtx)))
  	{
  	  if (XEXP (orig, 0) == frame_pointer_rtx
  	      || XEXP (orig, 0) == arg_pointer_rtx)
! 	    copy = XEXP (orig, 1);
  	  else
! 	    copy = XEXP (orig, 0);
  
  	  if (GET_CODE (copy) == CONST_INT)
--- 1295,1304 ----
  		  || XEXP (orig, 1) == arg_pointer_rtx)))
  	{
+ 	  rtx reg;
  	  if (XEXP (orig, 0) == frame_pointer_rtx
  	      || XEXP (orig, 0) == arg_pointer_rtx)
! 	    reg = XEXP (orig, 0), copy = XEXP (orig, 1);
  	  else
! 	    reg = XEXP (orig, 1), copy = XEXP (orig, 0);
  
  	  if (GET_CODE (copy) == CONST_INT)
***************
*** 1206,1212 ****
  	      int c = INTVAL (copy);
  
! 	      if (c > 0)
  		{
! 		  copy = parm_map[c / UNITS_PER_WORD];
  		  return XEXP (copy, 0);
  		}
--- 1306,1317 ----
  	      int c = INTVAL (copy);
  
! 	      if (reg == arg_pointer_rtx && c >= first_parm_offset)
  		{
! 		  copy = access_parm_map (c, VOIDmode);
! 		  if (GET_CODE (copy) != MEM)
! 		    /* Should not happen, because a parm we need to address
! 		       should not be living in a register.
! 		       (expand_inline_function copied it to a stack slot.)  */
! 		    abort ();
  		  return XEXP (copy, 0);
  		}
***************
*** 1303,1369 ****
  
  		  if (reg == arg_pointer_rtx && c >= first_parm_offset)
! 		    {
! 		      int index = c / UNITS_PER_WORD;
! 		      int offset = c % UNITS_PER_WORD;
! 
! 		      /* If we are referring to the middle of a multiword parm,
! 			 find the beginning of that parm.
! 			 OFFSET gets the offset of the reference from
! 			 the beginning of the parm.  */
! 
! 		      while (parm_map[index] == 0)
! 			{
! 			  index--;
! 			  if (index < first_parm_offset / UNITS_PER_WORD)
! 			    /* If this abort happens, it means we need
! 			       to handle "decrementing" INDEX back far
! 			       enough to start looking among the reg parms
! 			       instead of the stack parms.  What a mess!  */
! 			    abort ();
! 			  offset += UNITS_PER_WORD;
! 			}
! 
! 		      copy = parm_map[index];
! 
! #ifdef BYTES_BIG_ENDIAN
! 		      /* Subtract from OFFSET the offset of where
! 			 the actual parm value would start.  */
! 		      if (GET_MODE_SIZE (GET_MODE (copy)) < UNITS_PER_WORD)
! 			offset
! 			  -= (UNITS_PER_WORD
! 			      - GET_MODE_SIZE (GET_MODE (copy)));
! #endif
! 
! 		      /* If the MEM is only some of the bytes in the parm,
! 			 effectively perform a SUBREG of the actual parm.  */
! 		      if ((GET_MODE (copy) != mode
! 			   && GET_MODE (copy) != VOIDmode))
! 			{
! 			  if (GET_CODE (copy) == MEM)
! 			    return change_address (copy, mode,
! 						   plus_constant (XEXP (copy, 0),
! 								  offset));
! 			  if (GET_CODE (copy) == REG)
! 			    {
! 			      /* Crash if the portion of the arg wanted
! 				 is not the least significant.
! 				 Functions with refs to other parts of a
! 				 parameter should not be inline--
! 				 see function_cannot_inline_p. */
! #ifdef BYTES_BIG_ENDIAN
! 			      if (offset + GET_MODE_SIZE (mode)
! 				  != GET_MODE_SIZE (GET_MODE (copy)))
! 				abort ();
! #else
! 			      if (offset != 0)
! 				abort ();
! #endif
! 			      return gen_rtx (SUBREG, mode, copy, 0);
! 			    }
  
- 			  abort ();
- 			}
- 		      return copy;
- 		    }
  		  temp = gen_rtx (PLUS, Pmode,
  				  frame_pointer_rtx,
--- 1408,1413 ----
  
  		  if (reg == arg_pointer_rtx && c >= first_parm_offset)
! 		    return access_parm_map (c, mode);
  
  		  temp = gen_rtx (PLUS, Pmode,
  				  frame_pointer_rtx,
***************
*** 1477,1482 ****
--- 1521,1619 ----
        orig_asm_operands_vector = XVEC (orig, 3);
        copy_asm_operands_vector = XVEC (copy, 3);
+       copy_asm_constraints_vector = XVEC (copy, 4);
+     }
+ 
+   return copy;
+ }
+ \f


+ /* Get the value corresponding to an address relative to the arg pointer
+    at index RELADDRESS.  MODE is the machine mode of the reference.
+    MODE is used only when the value is a REG.
+    Pass VOIDmode for MODE when the mode is not known;
+    in such cases, you should make sure the value is a MEM.  */
+ 
+ static rtx
+ access_parm_map (reladdress, mode)
+      int reladdress;
+      enum machine_mode mode;
+ {
+   /* Index in parm_map.  */
+   int index = reladdress / UNITS_PER_WORD;
+   /* Offset of the data being referenced
+      from the beginning of the value for that parm.  */
+   int offset = reladdress % UNITS_PER_WORD;
+   rtx copy;
+ 
+   /* If we are referring to the middle of a multiword parm,
+      find the beginning of that parm.
+      OFFSET gets the offset of the reference from
+      the beginning of the parm.  */
+ 
+   while (parm_map[index] == 0)
+     {
+       index--;
+       if (index < first_parm_offset / UNITS_PER_WORD)
+ 	/* If this abort happens, it means we need
+ 	   to handle "decrementing" INDEX back far
+ 	   enough to start looking among the reg parms
+ 	   instead of the stack parms.  What a mess!  */
+ 	abort ();
+       offset += UNITS_PER_WORD;
      }
  
+   copy = parm_map[index];
+ 
+ #ifdef BYTES_BIG_ENDIAN
+   /* Subtract from OFFSET the offset of where
+      the actual parm value would start.  */
+   if (GET_MODE_SIZE (GET_MODE (copy)) < UNITS_PER_WORD)
+     offset
+       -= (UNITS_PER_WORD
+ 	  - GET_MODE_SIZE (GET_MODE (copy)));
+ #endif
+ 
+   /* For memory ref, adjust it by the desired offset.  */
+   if (GET_CODE (copy) == MEM)
+     {
+       if (offset != 0)
+ 	return change_address (copy, mode,
+ 			       plus_constant (XEXP (copy, 0),
+ 					      offset));
+       return copy;
+     }
+ 
+   if (GET_CODE (copy) != REG && GET_CODE (copy) != SUBREG
+       && ! CONSTANT_P (copy))
+     abort ();
+   if (mode == VOIDmode)
+     abort ();
+ 
+   /* A REG cannot be offset by bytes, so use a subreg
+      (which is possible only in certain cases).  */
+   if (GET_MODE (copy) != mode
+       && GET_MODE (copy) != VOIDmode)
+     {
+       int word;
+       /* Crash if the portion of the arg wanted
+ 	 is not the least significant.
+ 	 Functions with refs to other parts of a
+ 	 parameter should not be inline--
+ 	 see function_cannot_inline_p. */
+ #ifdef BYTES_BIG_ENDIAN
+       if (offset + GET_MODE_SIZE (mode)
+ 	  != GET_MODE_SIZE (GET_MODE (copy)))
+ 	abort ();
+ #else
+       if (offset != 0)
+ 	abort ();
+ #endif
+       word = 0;
+       if (GET_CODE (copy) == SUBREG)
+ 	word = SUBREG_WORD (copy), copy = SUBREG_REG (copy);
+       if (CONSTANT_P (copy))
+ 	copy = force_reg (GET_MODE (copy), copy);
+       return gen_rtx (SUBREG, mode, copy, word);
+     }
+ 
    return copy;
  }
***************
*** 1814,1817 ****
--- 1951,1955 ----
    rtx head = DECL_SAVED_INSNS (fndecl);
    rtx last;
+   extern rtx stack_slot_list;
  
    temporary_allocation ();
***************
*** 1819,1825 ****
    current_function_decl = fndecl;
  
!   /* This call is only used to initialize global variables.
!      The rtl code it emits will be discarded below.  */
!   expand_function_start (fndecl);
  
    /* Set stack frame size.  */
--- 1957,1962 ----
    current_function_decl = fndecl;
  
!   /* This call is only used to initialize global variables.  */
!   init_function_start (fndecl);
  
    /* Set stack frame size.  */
***************
*** 1827,1830 ****
--- 1964,1969 ----
  
    restore_reg_data (FIRST_PARM_INSN (head));
+ 
+   stack_slot_list = XEXP (head, 9);
  
    expand_function_end (DECL_SOURCE_FILE (fndecl), DECL_SOURCE_LINE (fndecl));
diff -rc2N gcc-1.35/jump.c gcc-1.36/jump.c
*** gcc-1.35/jump.c	Wed Mar 29 14:39:28 1989
--- gcc-1.36/jump.c	Thu Sep  7 00:39:18 1989
***************
*** 226,268 ****
      }
  
- #if 0
- #ifdef EXIT_IGNORE_STACK
-   /* If the last insn just adjusts the stack,
-      we can delete it on certain machines,
-      provided we have a frame pointer.  */
- 
-   if (frame_pointer_needed && EXIT_IGNORE_STACK)
-     {
-       insn = last_insn;
-       while (insn)
- 	{
- 	  rtx prev;
- 	  /* Back up to a real insn.  */
- 	  if (GET_CODE (insn) != INSN && GET_CODE (insn) != JUMP_INSN
- 	      && GET_CODE (insn) != CALL_INSN)
- 	    insn = prev_real_insn (insn);
- 	  if (insn == 0)
- 	    break;
- 	  prev = PREV_INSN (insn);
- 	  /* If this insn is a stack adjust, delete it.  */
- 	  if (GET_CODE (insn) == INSN
- 	      && GET_CODE (PATTERN (insn)) == SET
- 	      && GET_CODE (SET_DEST (PATTERN (insn))) == REG
- 	      && REGNO (SET_DEST (PATTERN (insn))) == STACK_POINTER_REGNUM)
- 	    {
- 	      delete_insn (insn);
- 	      if (insn == last_insn)
- 		last_insn = prev;
- 	    }
- 	  else
- 	    /* If we find an insn that isn't a stack adjust, stop deleting.  */
- 	    break;
- 	  /* Back up to insn before the deleted one and try to delete more.  */
- 	  insn = prev;
- 	}
-     }
- #endif
- #endif
- 
    if (noop_moves)
      for (insn = f; insn; )
--- 226,229 ----
***************
*** 364,367 ****
--- 325,349 ----
  	    }
  
+ 	  /* Don't allow dropping through into a dispatch table.
+ 	     That means the dispatch insn itself was deleted,
+ 	     so delete the table too.  */
+ 
+ 	  if (GET_CODE (insn) == JUMP_INSN)
+ 	    {
+ 	      /* Note: the corresponding job for ADDR_VEC is done
+ 		 in delete_insn.  */
+ 
+ 	      /* A vector of offsets is unused if its label
+ 		 is used only once (i.e., from the vector).  */
+ 	      if (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
+ 		  && LABEL_NUSES (XEXP (XEXP (PATTERN (insn), 0), 0)) == 1)
+ 		{
+ 		  /* So delete both label and vector.  */
+ 		  delete_insn (PREV_INSN (insn));
+ 		  delete_insn (insn);
+ 		  changed = 1;
+ 		}
+ 	    }
+ 
  	  if (GET_CODE (insn) == JUMP_INSN && JUMP_LABEL (insn))
  	    {
***************
*** 369,394 ****
  	      rtx temp;
  
- 	      /* Delete insns that adjust stack pointer before a return,
- 		 if this is the last jump-optimization before final
- 		 and we need to have a frame pointer.  */
- #if 0   /* These are now deleted by flow.c as dead stores.  */
- #ifdef EXIT_IGNORE_STACK
- 	      if (noop_moves && frame_pointer_needed && EXIT_IGNORE_STACK
- 		  && NEXT_INSN (JUMP_LABEL (insn)) == 0)
- 		{
- 		  rtx prev = prev_real_insn (insn);
- 		  if (prev != 0
- 		      && GET_CODE (prev) == INSN
- 		      && GET_CODE (PATTERN (prev)) == SET
- 		      && GET_CODE (SET_DEST (PATTERN (prev))) == REG
- 		      && REGNO (SET_DEST (PATTERN (prev))) == STACK_POINTER_REGNUM)
- 		    {
- 		      delete_insn (prev);
- 		      changed = 1;
- 		    }
- 		}
- #endif
- #endif
- 
  	      /* Detect jump to following insn.  */
  	      if (reallabelprev == insn && condjump_p (insn))
--- 351,354 ----
***************
*** 748,752 ****
       or make a new one if there is none.  */
    label = PREV_INSN (newlpos);
!   if (GET_CODE (label) != CODE_LABEL)
      {
        label = gen_label_rtx ();
--- 708,715 ----
       or make a new one if there is none.  */
    label = PREV_INSN (newlpos);
!   while (label && GET_CODE (label) == NOTE)
!     label = PREV_INSN (label);
! 
!   if (label == 0 || GET_CODE (label) != CODE_LABEL)
      {
        label = gen_label_rtx ();
***************
*** 795,799 ****
       Using reverse_condition is invalid for IEEE floating point with nans.  */
    prev = prev_real_insn (insn);
!   if (! (GET_CODE (prev) == INSN
  	 && GET_CODE (PATTERN (prev)) == SET
  	 && SET_DEST (PATTERN (prev)) == cc0_rtx
--- 758,763 ----
       Using reverse_condition is invalid for IEEE floating point with nans.  */
    prev = prev_real_insn (insn);
!   if (! (prev != 0
! 	 && GET_CODE (prev) == INSN
  	 && GET_CODE (PATTERN (prev)) == SET
  	 && SET_DEST (PATTERN (prev)) == cc0_rtx
***************
*** 1188,1198 ****
    register rtx prev = PREV_INSN (insn);
  
    if (INSN_DELETED_P (insn))
!     {
!       /* This insn is already deleted => return first following nondeleted.  */
!       while (next && INSN_DELETED_P (next))
! 	next = NEXT_INSN (next);
!       return next;
!     }
  
    /* Mark this insn as deleted.  */
--- 1152,1161 ----
    register rtx prev = PREV_INSN (insn);
  
+   while (next && INSN_DELETED_P (next))
+     next = NEXT_INSN (next);
+ 
+   /* This insn is already deleted => return first following nondeleted.  */
    if (INSN_DELETED_P (insn))
!     return next;
  
    /* Mark this insn as deleted.  */
***************
*** 1218,1221 ****
--- 1181,1187 ----
        if (next)
  	PREV_INSN (next)= prev;
+ 
+       if (NEXT_INSN (prev) == 0)
+ 	set_last_insn (prev);
      }
  
***************
*** 1241,1244 ****
--- 1207,1220 ----
    while (prev && (INSN_DELETED_P (prev) || GET_CODE (prev) == NOTE))
      prev = PREV_INSN (prev);
+ 
+   /* If INSN was a label and a dispatch table follows it,
+      delete the dispatch table.  The tablejump must have gone already.
+      It isn't useful to fall through into a table.  */
+ 
+   if (GET_CODE (insn) == CODE_LABEL
+       && NEXT_INSN (insn) != 0
+       && GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
+       && GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_VEC)
+     next = delete_insn (NEXT_INSN (insn));
  
    /* If INSN was a label, delete insns following it if now unreachable.  */
diff -rc2N gcc-1.35/limits.h gcc-1.36/limits.h
*** gcc-1.35/limits.h	Sat Dec  5 18:25:46 1987
--- gcc-1.36/limits.h	Thu Jun  8 15:00:01 1989
***************
*** 37,41 ****
  /* Minimum and maximum values a `signed long int' can hold.
     (Same as `int').  */
! #define LONG_MIN -2147483648
  #define LONG_MAX 2147483647
  
--- 37,41 ----
  /* Minimum and maximum values a `signed long int' can hold.
     (Same as `int').  */
! #define LONG_MIN (-LONG_MAX-1)
  #define LONG_MAX 2147483647
  
diff -rc2N gcc-1.35/local-alloc.c gcc-1.36/local-alloc.c
*** gcc-1.35/local-alloc.c	Sun Mar 12 12:00:52 1989
--- gcc-1.36/local-alloc.c	Thu Aug 24 15:47:39 1989
***************
*** 331,335 ****
    while (1)
      {
!       insn_count++;
        if (insn == basic_block_head[b])
  	break;
--- 331,336 ----
    while (1)
      {
!       if (GET_CODE (insn) != NOTE)
! 	insn_count++;
        if (insn == basic_block_head[b])
  	break;
***************
*** 340,344 ****
    regs_live_at = (HARD_REG_SET *) alloca ((insn_count + 1)
  					  * sizeof (HARD_REG_SET));
!   bzero (regs_live_at, insn_count * sizeof (HARD_REG_SET));
  
    /* Initialize table of hardware registers currently live.  */
--- 341,345 ----
    regs_live_at = (HARD_REG_SET *) alloca ((insn_count + 1)
  					  * sizeof (HARD_REG_SET));
!   bzero (regs_live_at, (insn_count + 1) * sizeof (HARD_REG_SET));
  
    /* Initialize table of hardware registers currently live.  */
***************
*** 358,363 ****
      {
        register rtx body = PATTERN (insn);
-       insn_number++;
  
        if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
  	  || GET_CODE (insn) == CALL_INSN)
--- 359,366 ----
      {
        register rtx body = PATTERN (insn);
  
+       if (GET_CODE (insn) != NOTE)
+ 	insn_number++;
+ 
        if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
  	  || GET_CODE (insn) == CALL_INSN)
***************
*** 472,476 ****
  		       /* Don't inhibit allocation of a "constant" register
  			  that we have already tied to something else!  */
! 		       && combined_regno < 0)
  		{
  		  i = REGNO (SET_DEST (body));
--- 475,481 ----
  		       /* Don't inhibit allocation of a "constant" register
  			  that we have already tied to something else!  */
! 		       && combined_regno < 0
! 		       /* Don't mess with things live during setjmp.  */
! 		       && reg_live_length[REGNO (SET_DEST (body))] >= 0)
  		{
  		  i = REGNO (SET_DEST (body));
***************
*** 630,635 ****
    register int tem = (qty_phys_sugg[*q2] >= 0) - (qty_phys_sugg[*q1] >= 0);
    if (tem != 0) return tem;
!   return -((qty_n_refs[*q1] + qty_death[*q1] - qty_birth[*q1]) * qty_size[*q2]
! 	   - (qty_n_refs[*q2] + qty_death[*q2] - qty_birth[*q2]) * qty_size[*q1]);
  }
  \f


--- 635,644 ----
    register int tem = (qty_phys_sugg[*q2] >= 0) - (qty_phys_sugg[*q1] >= 0);
    if (tem != 0) return tem;
!   tem = -((qty_n_refs[*q1] + qty_death[*q1] - qty_birth[*q1]) * qty_size[*q2]
! 	  - (qty_n_refs[*q2] + qty_death[*q2] - qty_birth[*q2]) * qty_size[*q1]);
!   if (tem != 0) return tem;
!   /* If qtys are equally good, sort by qty number,
!      so that the results of qsort leave nothing to chance.  */
!   return *q1 - *q2;
  }
  \f


diff -rc2N gcc-1.35/loop.c gcc-1.36/loop.c
*** gcc-1.35/loop.c	Mon Apr 10 17:03:27 1989
--- gcc-1.36/loop.c	Sun Sep 10 00:48:44 1989
***************
*** 1,4 ****
  /* Move constant computations out of loops.
!    Copyright (C) 1987, 1988 Free Software Foundation, Inc.
  
  This file is part of GNU CC.
--- 1,4 ----
  /* Move constant computations out of loops.
!    Copyright (C) 1987, 1988, 1989 Free Software Foundation, Inc.
  
  This file is part of GNU CC.
***************
*** 43,46 ****
--- 43,47 ----
  #include "insn-config.h"
  #include "regs.h"
+ #include "hard-reg-set.h"
  #include "recog.h"
  #include "flags.h"
***************
*** 172,177 ****
    unsigned int force : 1;	/* 1 means MUST move this insn */
    unsigned int global : 1;	/* 1 means reg is live outside this loop */
    unsigned int done : 1;	/* 1 inhibits further processing of this */
!   unsigned int partial : 1;	/* 1 moving this doesn't make it invariant */
    enum machine_mode savemode;   /* Nonzero means it is a mode for a low part
  				   that we should avoid changing when clearing
--- 173,183 ----
    unsigned int force : 1;	/* 1 means MUST move this insn */
    unsigned int global : 1;	/* 1 means reg is live outside this loop */
+ 		/* If PARTIAL is 1, GLOBAL means something different:
+ 		   that the reg is live outside the range from where it is set
+ 		   to the following label.  */
    unsigned int done : 1;	/* 1 inhibits further processing of this */
!   /* 1 in PARTIAL means this reg is used for zero-extending.
!      In particular, moving it does not make it invariant.  */
!   unsigned int partial : 1;
    enum machine_mode savemode;   /* Nonzero means it is a mode for a low part
  				   that we should avoid changing when clearing
***************
*** 184,187 ****
--- 190,198 ----
  static FILE *loop_dump_stream;
  
+ /* Forward declarations.  */
+ 
+ struct induction;
+ struct iv_class;
+ 
  static rtx verify_loop ();
  static int invariant_p ();
***************
*** 188,191 ****
--- 199,203 ----
  static int consec_sets_invariant_p ();
  static int can_jump_into_range_p ();
+ static int labels_in_range_p ();
  static void count_loop_regs_set ();
  static void note_addr_stored ();
***************
*** 195,200 ****
  static rtx replace_regs ();
  static void replace_call_address ();
  static void move_movables ();
- static int may_trap_p ();
  static void strength_reduce ();
  static void find_mem_givs ();
--- 207,216 ----
  static rtx replace_regs ();
  static void replace_call_address ();
+ static rtx skip_consec_insns ();
+ static void ignore_some_movables ();
+ static void force_movables ();
+ static void combine_movables ();
+ static int rtx_equal_for_loop_p ();
  static void move_movables ();
  static void strength_reduce ();
  static void find_mem_givs ();
***************
*** 240,244 ****
  
    /* First find the last real insn, and count the number of insns,
!      and assign insns their suids.  */
  
    for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
--- 256,260 ----
  
    /* First find the last real insn, and count the number of insns,
!      and assign insns their luids.  */
  
    for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
***************
*** 252,256 ****
    /* Compute the mapping from uids to luids.
       LUIDs are numbers assigned to insns, like uids,
!      except that luids increase monotonically through the code.  */
  
    for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
--- 268,274 ----
    /* Compute the mapping from uids to luids.
       LUIDs are numbers assigned to insns, like uids,
!      except that luids increase monotonically through the code.
!      Don't assign luids to line-number NOTEs, so that the distance in luids
!      between two insns is not affected by -g.  */
  
    for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
***************
*** 257,261 ****
      {
        last_insn = insn;
!       INSN_LUID (insn) = ++i;
      }
  
--- 275,284 ----
      {
        last_insn = insn;
!       if (GET_CODE (insn) != NOTE
! 	  || NOTE_LINE_NUMBER (insn) < 0)
! 	INSN_LUID (insn) = ++i;
!       else
! 	/* Give a line number note the same luid as preceding insn.  */
! 	INSN_LUID (insn) = i;
      }
  
***************
*** 545,553 ****
  		last_movable->next = m;
  	      last_movable = m;
! 	      /* Skip the consecutive insns, if there are any.  */
! 	      for (count = m->consec - 1; count >= 0; count--)
  		{
! 		  do p = NEXT_INSN (p);
! 		  while (GET_CODE (p) == NOTE);
  		}
  	    }
--- 568,579 ----
  		last_movable->next = m;
  	      last_movable = m;
! 	      if (m->consec > 0)
  		{
! 		  /* Skip this insn, not checking REG_LIBCALL notes.  */
! 		  p = NEXT_INSN (p);
! 		  /* Skip the consecutive insns, if there are any.  */
! 		  p = skip_consec_insns (p, m->consec);
! 		  /* Back up, so the main loop will advance to the right place.  */
! 		  p = PREV_INSN (p);
  		}
  	    }
***************
*** 586,592 ****
  		  /* If the insn may not be executed on some cycles,
  		     we can't clear the whole reg; clear just high part.
  		     Consider this:
  		     while (1)
! 		       while (1) {
  		         if (foo ()) x = *s;
  			 use (x);
--- 612,619 ----
  		  /* If the insn may not be executed on some cycles,
  		     we can't clear the whole reg; clear just high part.
+ 		     Not even if the reg is used only within this loop.
  		     Consider this:
  		     while (1)
! 		       while (s != t) {
  		         if (foo ()) x = *s;
  			 use (x);
***************
*** 593,598 ****
  		       }
  		     Clearing x before the inner loop could clobber a value
! 		     being saved from the last time around the outer loop.  */
! 		  if (maybe_never)
  		    m->savemode = GET_MODE (SET_SRC (PATTERN (NEXT_INSN (p))));
  		  else
--- 620,632 ----
  		       }
  		     Clearing x before the inner loop could clobber a value
! 		     being saved from the last time around the outer loop.
! 		     However, if the reg is not used outside this loop
! 		     and all uses of the register are in the same
! 		     basic block as the store, there is no problem.  */
! 		  m->global = (uid_luid[regno_last_uid[regno]] > INSN_LUID (end)
! 			       || uid_luid[regno_first_uid[regno]] < INSN_LUID (p)
! 			       || (labels_in_range_p
! 				   (p, uid_luid[regno_first_uid[regno]])));
! 		  if (maybe_never && m->global)
  		    m->savemode = GET_MODE (SET_SRC (PATTERN (NEXT_INSN (p))));
  		  else
***************
*** 600,608 ****
  		  m->regno = regno;
  		  m->cond = 0;
- 		  /* Say "global" so this register is not combined
- 		     with any other.  In fact, it is sometimes possible
- 		     to combine two of these registers, but the criteria
- 		     are special and have not been programmed in.  */
- 		  m->global = 1;
  		  m->match = 0;
  		  m->lifetime = (uid_luid[regno_last_uid[regno]]
--- 634,637 ----
***************
*** 616,636 ****
  		    last_movable->next = m;
  		  last_movable = m;
- 		  /* Skip the consecutive insns, if there are any.  */
- 		  for (count = m->consec - 1; count >= 0; count--)
- 		    {
- 		      /* If first insn of libcall sequence, skip to end.  */
- 		      /* Do this at start of loop, since p is guaranteed to 
- 			 be an insn here.  */
- 		      if (temp = find_reg_note (p, REG_LIBCALL, 0))
- 			{
- 			  p = XEXP (temp, 0);
- 			  /* Count the libcall as ten insns in terms of
- 			     importance of moving it.  */
- 			  m->savings += 10;
- 			}
- 		      
- 		      do p = NEXT_INSN (p);
- 		      while (GET_CODE (p) == NOTE);
- 		    }
  		}
  	    }
--- 645,648 ----
***************
*** 645,652 ****
  	 only move out sets of trivial variables
  	 (those not used after the loop).  */
!       else if (GET_CODE (p) == CODE_LABEL || GET_CODE (p) == JUMP_INSN)
  	maybe_never = 1;
      }
  
    /* For each movable insn, see if the reg that it loads
       leads when it dies right into another conditionally movable insn.
--- 657,672 ----
  	 only move out sets of trivial variables
  	 (those not used after the loop).  */
!       else if ((GET_CODE (p) == CODE_LABEL || GET_CODE (p) == JUMP_INSN)
! 	       /* If we enter the loop in the middle, and scan around
! 		  to the beginning, don't set maybe_never for that.  */
!                && ! (NEXT_INSN (p) == end && GET_CODE (p) == JUMP_INSN
!                      && simplejump_p (p)))
  	maybe_never = 1;
      }
  
+   /* If one movable subsumes another, ignore that other.  */
+ 
+   ignore_some_movables (movables);
+ 
    /* For each movable insn, see if the reg that it loads
       leads when it dies right into another conditionally movable insn.
***************
*** 654,686 ****
       since the second can be moved only if the first is.  */
  
!   {
!     register struct movable *m, *m1;
!     for (m1 = movables; m1; m1 = m1->next)
!       /* Omit this if moving just the (SET (REG) 0) of a zero-extend.  */
!       if (!m1->partial)
! 	{
! 	  int regno = m1->regno;
! 	  for (m = m1->next; m; m = m->next)
! 	    /* ??? Could this be a bug?  What if CSE caused the
! 	       register of M1 to be used after this insn?
! 	       Since CSE does not update regno_last_uid,
! 	       this insn M->insn might not be where it dies.
! 	       But very likely this doesn't matter; what matters is
! 	       that M's reg is computed from M1's reg.  */
! 	    if (INSN_UID (m->insn) == regno_last_uid[regno])
! 	      break;
! 	  if (m != 0 && m->set_src == SET_DEST (PATTERN (m1->insn)))
! 	    m = 0;
! 
! 	  /* Increase the priority of the moving the first insn
! 	     since it permits the second to be moved as well.  */
! 	  if (m != 0)
! 	    {
! 	      m->forces = m1;
! 	      m1->lifetime += m->lifetime;
! 	      m1->savings += m1->savings;
! 	    }
! 	}
!   }
  
    /* See if there are multiple movable insns that load the same value.
--- 674,678 ----
       since the second can be moved only if the first is.  */
  
!   force_movables (movables);
  
    /* See if there are multiple movable insns that load the same value.
***************
*** 689,737 ****
       all together as the priority of the first.  */
  
!   {
!     register struct movable *m;
!     char *matched_regs = (char *) alloca (nregs);
! 
!     /* Regs that are set more than once are not allowed to match
!        or be matched.  I'm no longer sure why not.  */
!     /* Perhaps testing m->consec_sets would be more appropriate here?  */
! 
!     for (m = movables; m; m = m->next)
!       if (m->match == 0 && n_times_used[m->regno] == 1)
! 	{
! 	  register struct movable *m1;
! 	  int regno = m->regno;
! 
! 	  bzero (matched_regs, nregs);
! 	  matched_regs[regno] = 1;
! 
! 	  for (m1 = m->next; m1; m1 = m1->next)
! 	    if (m1->match == 0 && n_times_used[m1->regno] == 1
! 		/* A reg used outside the loop mustn't be eliminated.  */
! 		&& !m1->global
! 		&& (matched_regs[m1->regno]
! 		    ||
! 		    (
! 		     /* Can't combine regs with different modes
! 			even if loaded from the same constant.  */
! 		     (GET_MODE (SET_DEST (PATTERN (m->insn)))
! 		      == GET_MODE (SET_DEST (PATTERN (m1->insn))))
! 		     /* See if the source of M1 says it matches M.  */
! 		     && ((GET_CODE (m1->set_src) == REG
! 			  && matched_regs[REGNO (m1->set_src)])
! 			 || rtx_equal_p (m->set_src, m1->set_src)
! 			 || (REG_NOTES (m->insn) && REG_NOTES (m1->insn)
! 			     && REG_NOTE_KIND (REG_NOTES (m->insn)) == REG_EQUIV
! 			     && REG_NOTE_KIND (REG_NOTES (m1->insn)) == REG_EQUIV
! 			     && rtx_equal_p (XEXP (REG_NOTES (m->insn), 0),
! 					     XEXP (REG_NOTES (m1->insn), 0)))))))
! 	      {
! 		m->lifetime += m1->lifetime;
! 		m->savings += m1->savings;
! 		m1->match = m;
! 		matched_regs[m1->regno] = 1;
! 	      }
! 	}
!   }
  	
    /* Now consider each movable insn to decide whether it is worth moving.
--- 681,685 ----
       all together as the priority of the first.  */
  
!   combine_movables (movables, nregs);
  	
    /* Now consider each movable insn to decide whether it is worth moving.
***************
*** 752,755 ****
--- 700,1030 ----
  }
  \f


+ /* Skip COUNT insns from INSN, counting library calls as 1 insn.  */
+ 
+ static rtx
+ skip_consec_insns (insn, count)
+      rtx insn;
+      int count;
+ {
+   for (; count > 0; count--)
+     {
+       if (GET_CODE (insn) == NOTE)
+ 	insn = NEXT_INSN (insn);
+       else if (GET_CODE (insn) == BARRIER || GET_CODE (insn) == CODE_LABEL)
+ 	abort ();
+       else
+ 	{
+ 	  rtx i1, temp;
+ 
+ 	  /* If first insn of gnulib call sequence, skip to end.  */
+ 	  /* Do this at start of loop, since INSN is guaranteed to 
+ 	     be an insn here.  */
+ 	  if (temp = find_reg_note (insn, REG_LIBCALL, 0))
+ 	    insn = XEXP (temp, 0);
+ 
+ 	  do insn = NEXT_INSN (insn);
+ 	  while (GET_CODE (insn) == NOTE);
+ 	}
+     }
+ 
+   return insn;
+ }
+ 
+ /* Ignore any movable whose insn falls within a libcall
+    which is part of another movable.
+    We make use of the fact that the movable for the libcall value
+    was made later and so appears later on the chain.  */
+ 
+ static void
+ ignore_some_movables (movables)
+      struct movable *movables;
+ {
+   register struct movable *m, *m1;
+ 
+   for (m = movables; m; m = m->next)
+     {
+       /* Is this a movable for the value of a libcall?  */
+       rtx note = find_reg_note (m->insn, REG_RETVAL, 0);
+       if (note)
+ 	{
+ 	  /* Find the beginning of that libcall.  */
+ 	  rtx first_insn = XEXP (note, 0);
+ 	  /* Check for earlier movables inside that range,
+ 	     and mark them invalid.  */
+ 	  for (m1 = movables; m1 != m; m1 = m1->next)
+ 	    if (INSN_LUID (m1->insn) >= INSN_LUID (first_insn)
+ 		&& INSN_LUID (m1->insn) < INSN_LUID (m->insn))
+ 	      m1->done = 1;
+ 	}
+     }
+ }	  
+ 
+ /* For each movable insn, see if the reg that it loads
+    leads when it dies right into another conditionally movable insn.
+    If so, record that the second insn "forces" the first one,
+    since the second can be moved only if the first is.  */
+ 
+ static void
+ force_movables (movables)
+      struct movable *movables;
+ {
+   register struct movable *m, *m1;
+   for (m1 = movables; m1; m1 = m1->next)
+     /* Omit this if moving just the (SET (REG) 0) of a zero-extend.  */
+     if (!m1->partial && !m1->done)
+       {
+ 	int regno = m1->regno;
+ 	for (m = m1->next; m; m = m->next)
+ 	  /* ??? Could this be a bug?  What if CSE caused the
+ 	     register of M1 to be used after this insn?
+ 	     Since CSE does not update regno_last_uid,
+ 	     this insn M->insn might not be where it dies.
+ 	     But very likely this doesn't matter; what matters is
+ 	     that M's reg is computed from M1's reg.  */
+ 	  if (INSN_UID (m->insn) == regno_last_uid[regno]
+ 	      && !m->done)
+ 	    break;
+ 	if (m != 0 && m->set_src == SET_DEST (PATTERN (m1->insn)))
+ 	  m = 0;
+ 
+ 	/* Increase the priority of the moving the first insn
+ 	   since it permits the second to be moved as well.  */
+ 	if (m != 0)
+ 	  {
+ 	    m->forces = m1;
+ 	    m1->lifetime += m->lifetime;
+ 	    m1->savings += m1->savings;
+ 	  }
+       }
+ }
+ \f


+ /* Find invariant expressions that are equal and can be combined into
+    one register.  */
+ 
+ static void
+ combine_movables (movables, nregs)
+      struct movable *movables;
+      int nregs;
+ {
+   register struct movable *m;
+   char *matched_regs = (char *) alloca (nregs);
+   enum machine_mode mode;
+ 
+   /* Regs that are set more than once are not allowed to match
+      or be matched.  I'm no longer sure why not.  */
+   /* Perhaps testing m->consec_sets would be more appropriate here?  */
+ 
+   for (m = movables; m; m = m->next)
+     if (m->match == 0 && n_times_used[m->regno] == 1 && !m->partial)
+       {
+ 	register struct movable *m1;
+ 	int regno = m->regno;
+ 
+ 	bzero (matched_regs, nregs);
+ 	matched_regs[regno] = 1;
+ 
+ 	for (m1 = m->next; m1; m1 = m1->next)
+ 	  if (m1->match == 0 && n_times_used[m1->regno] == 1
+ 	      /* A reg used outside the loop mustn't be eliminated.  */
+ 	      && !m1->global
+ 	      /* A reg used for zero-extending mustn't be eliminated.  */
+ 	      && !m1->partial
+ 	      && (matched_regs[m1->regno]
+ 		  ||
+ 		  (
+ 		   /* Can't combine regs with different modes
+ 		      even if loaded from the same constant.  */
+ 		   (GET_MODE (SET_DEST (PATTERN (m->insn)))
+ 		    == GET_MODE (SET_DEST (PATTERN (m1->insn))))
+ 		   /* See if the source of M1 says it matches M.  */
+ 		   && ((GET_CODE (m1->set_src) == REG
+ 			&& matched_regs[REGNO (m1->set_src)])
+ 		       || rtx_equal_for_loop_p (m->set_src, m1->set_src,
+ 						movables)
+ 		       || (REG_NOTES (m->insn) && REG_NOTES (m1->insn)
+ 			   && REG_NOTE_KIND (REG_NOTES (m->insn)) == REG_EQUIV
+ 			   && REG_NOTE_KIND (REG_NOTES (m1->insn)) == REG_EQUIV
+ 			   && rtx_equal_p (XEXP (REG_NOTES (m->insn), 0),
+ 					   XEXP (REG_NOTES (m1->insn), 0)))))))
+ 	    {
+ 	      m->lifetime += m1->lifetime;
+ 	      m->savings += m1->savings;
+ 	      m1->match = m;
+ 	      matched_regs[m1->regno] = 1;
+ 	    }
+       }
+ 
+   /* Now combine the regs used for zero-extension.
+      This can be done for those not marked `global'
+      provided their lives don't overlap.  */
+ 
+   for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
+        mode = (enum machine_mode) ((int) mode + 1))
+     if (GET_MODE_CLASS (mode) == MODE_INT)
+       {
+ 	register struct movable *m0 = 0;
+ 
+ 	/* Combine all the registers for extension from mode MODE.
+ 	   Don't combine any that are used outside this loop.  */
+ 	for (m = movables; m; m = m->next)
+ 	  if (m->partial && ! m->global
+ 	      && mode == GET_MODE (SET_SRC (PATTERN (NEXT_INSN (m->insn)))))
+ 	    {
+ 	      register struct movable *m1;
+ 	      int first = uid_luid[regno_first_uid[m->regno]];
+ 	      int last = uid_luid[regno_last_uid[m->regno]];
+ 
+ 	      if (m0 == 0)
+ 		{
+ 		  /* First one: don't check for overlap, just record it.  */
+ 		  m0 = m;
+ 		  continue;
+ 		}
+ 
+ 	      /* Make sure they extend to the same mode.
+ 		 (Almost always true.)  */
+ 	      if (GET_MODE (SET_DEST (PATTERN (m->insn)))
+ 		  != GET_MODE (SET_DEST (PATTERN (m0->insn))))
+ 		continue;
+ 
+ 	      /* We already have one: check for overlap with those
+ 		 already combined together.  */
+ 	      for (m1 = movables; m1 != m; m1 = m1->next)
+ 		if (m1 == m0 || (m1->partial && m1->match == m0))
+ 		  if (! (uid_luid[regno_first_uid[m1->regno]] > last
+ 			 || uid_luid[regno_last_uid[m1->regno]] < first))
+ 		    goto overlap;
+ 
+ 	      /* No overlap: we can combine this with the others.  */
+ 	      m0->lifetime += m->lifetime;
+ 	      m0->savings += m->savings;
+ 	      m->match = m0;
+ 
+ 	    overlap: ;
+ 	    }
+       }
+ }
+ \f


+ /* Return 1 if regs X and Y will become the same if moved.  */
+ 
+ static int
+ regs_match_p (x, y, movables)
+      rtx x, y;
+      struct movable *movables;
+ {
+   int xn = REGNO (x);
+   int yn = REGNO (y);
+   struct movable *mx, *my;
+ 
+   for (mx = movables; mx; mx = mx->next)
+     if (mx->regno == xn)
+       break;
+ 
+   for (my = movables; my; my = my->next)
+     if (my->regno == yn)
+       break;
+ 
+   return (mx && my
+ 	  && ((mx->match == my->match && mx->match != 0)
+ 	      || mx->match == my
+ 	      || mx == my->match));
+ }
+ 
+ /* Return 1 if X and Y are identical-looking rtx's.
+    This is the Lisp function EQUAL for rtx arguments.  */
+ 
+ static int
+ rtx_equal_for_loop_p (x, y, movables)
+      rtx x, y;
+      struct movable *movables;
+ {
+   register int i;
+   register int j;
+   register enum rtx_code code;
+   register char *fmt;
+ 
+   if (x == y)
+     return 1;
+   if (x == 0 || y == 0)
+     return 0;
+ 
+   code = GET_CODE (x);
+   /* Rtx's of different codes cannot be equal.  */
+   if (code != GET_CODE (y))
+     return 0;
+ 
+   /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.
+      (REG:SI x) and (REG:HI x) are NOT equivalent.  */
+ 
+   if (GET_MODE (x) != GET_MODE (y))
+     return 0;
+ 
+   /* These three types of rtx's can be compared nonrecursively.  */
+   /* Until the end of reload,
+      don't consider the a reference to the return register of the current
+      function the same as the return from a called function.  This eases
+      the job of function integration.  Once the distinction no longer
+      matters, the insn will be deleted.  */
+   if (code == REG)
+     return ((REGNO (x) == REGNO (y)
+ 	     && REG_FUNCTION_VALUE_P (x) == REG_FUNCTION_VALUE_P (y))
+ 	    || regs_match_p (x, y, movables));
+ 
+   if (code == LABEL_REF)
+     return XEXP (x, 0) == XEXP (y, 0);
+   if (code == SYMBOL_REF)
+     return XSTR (x, 0) == XSTR (y, 0);
+ 
+   /* Compare the elements.  If any pair of corresponding elements
+      fail to match, return 0 for the whole things.  */
+ 
+   fmt = GET_RTX_FORMAT (code);
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     {
+       switch (fmt[i])
+ 	{
+ 	case 'i':
+ 	  if (XINT (x, i) != XINT (y, i))
+ 	    return 0;
+ 	  break;
+ 
+ 	case 'E':
+ 	  /* Two vectors must have the same length.  */
+ 	  if (XVECLEN (x, i) != XVECLEN (y, i))
+ 	    return 0;
+ 
+ 	  /* And the corresponding elements must match.  */
+ 	  for (j = 0; j < XVECLEN (x, i); j++)
+ 	    if (rtx_equal_for_loop_p (XVECEXP (x, i, j), XVECEXP (y, i, j), movables) == 0)
+ 	      return 0;
+ 	  break;
+ 
+ 	case 'e':
+ 	  if (rtx_equal_for_loop_p (XEXP (x, i), XEXP (y, i), movables) == 0)
+ 	    return 0;
+ 	  break;
+ 
+ 	case 's':
+ 	  if (strcmp (XSTR (x, i), XSTR (y, i)))
+ 	    return 0;
+ 	  break;
+ 
+ 	case 'u':
+ 	  /* These are just backpointers, so they don't matter.  */
+ 	  break;
+ 
+ 	case '0':
+ 	  break;
+ 
+ 	  /* It is believed that rtx's at this level will never
+ 	     contain anything but integers and other rtx's,
+ 	     except for within LABEL_REFs and SYMBOL_REFs.  */
+ 	default:
+ 	  abort ();
+ 	}
+     }
+   return 1;
+ }
+ \f


  /* Scan MOVABLES, and move the insns that deserve to be moved.
     If two matching movables are combined, replace one reg with the
***************
*** 878,882 ****
  		     insns except the last before the loop.  The last insn is
  		     handled in the normal manner.  */
! 		  if (temp = find_reg_note (p, REG_RETVAL, 0))
  		    {
  		      rtx fn_address = 0;
--- 1153,1158 ----
  		     insns except the last before the loop.  The last insn is
  		     handled in the normal manner.  */
! 		  if (temp = find_reg_note (p, REG_RETVAL
! 					    , 0))
  		    {
  		      rtx fn_address = 0;
***************
*** 943,947 ****
  
  		  if (loop_dump_stream)
! 		    fprintf (loop_dump_stream, "moved to %d", INSN_UID (i1));
  
  		  /* Mark the moved, invariant reg as being equivalent to
--- 1219,1223 ----
  
  		  if (loop_dump_stream)
! 		    fprintf (loop_dump_stream, " moved to %d", INSN_UID (i1));
  
  		  /* Mark the moved, invariant reg as being equivalent to
***************
*** 1218,1221 ****
--- 1494,1546 ----
  }
  \f


+ /* Return the number of memory refs to addresses that vary
+    in the rtx X.  */
+ 
+ static int
+ count_nonfixed_reads (x)
+      rtx x;
+ {
+   register enum rtx_code code;
+   register int i;
+   register char *fmt;
+   int value;
+ 
+   if (x == 0)
+     return 0;
+ 
+   code = GET_CODE (x);
+   switch (code)
+     {
+     case PC:
+     case CC0:
+     case CONST_INT:
+     case CONST_DOUBLE:
+     case CONST:
+     case SYMBOL_REF:
+     case LABEL_REF:
+     case REG:
+       return 0;
+ 
+     case MEM:
+       return rtx_varies_p (XEXP (x, 0)) + count_nonfixed_reads (XEXP (x, 0));
+     }
+ 
+   value = 0;
+   fmt = GET_RTX_FORMAT (code);
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     {
+       if (fmt[i] == 'e')
+ 	value += count_nonfixed_reads (XEXP (x, i));
+       if (fmt[i] == 'E')
+ 	{
+ 	  register int j;
+ 	  for (j = 0; j < XVECLEN (x, i); j++)
+ 	    value += count_nonfixed_reads (XVECEXP (x, i, j));
+ 	}
+     }
+   return value;
+ }
+ 
+ \f


  #if 0
  /* P is an instruction that sets a register to the result of a ZERO_EXTEND.
***************
*** 1407,1410 ****
--- 1732,1753 ----
  }
  
+ /* Return nonzero if there is a label in the range from
+    insn INSN to the insn whose luid is END.  */
+ 
+ static int
+ labels_in_range_p (insn, end)
+      rtx insn;
+      int end;
+ {
+   while (insn && INSN_LUID (insn) <= end)
+     {
+       if (GET_CODE (insn) == CODE_LABEL)
+ 	return 0;
+       insn = NEXT_INSN (insn);
+     }
+ 
+   return 0;
+ }
+ 
  /* Record that a memory reference X is being set.  */
  
***************
*** 1628,1632 ****
    int count = n_sets - 1;
    int old = n_times_set[regno];
!   int tem = 0;
  
    /* If N_SETS hit the limit, we can't rely on its value.  */
--- 1971,1976 ----
    int count = n_sets - 1;
    int old = n_times_set[regno];
!   int value = 0;
!   int this;
  
    /* If N_SETS hit the limit, we can't rely on its value.  */
***************
*** 1646,1655 ****
  	p = XEXP (temp, 0);
  
        if (code == INSN && GET_CODE (PATTERN (p)) == SET
  	  && GET_CODE (SET_DEST (PATTERN (p))) == REG
! 	  && REGNO (SET_DEST (PATTERN (p))) == regno
! 	  && ((tem |= invariant_p (SET_SRC (PATTERN (p))))
! 	      || ((temp = find_reg_note (p, REG_EQUAL, 0))
! 		  && (tem |= invariant_p (XEXP (temp, 0))))))
  	count--;
        else if (code != NOTE)
--- 1990,2009 ----
  	p = XEXP (temp, 0);
  
+       this = 0;
        if (code == INSN && GET_CODE (PATTERN (p)) == SET
  	  && GET_CODE (SET_DEST (PATTERN (p))) == REG
! 	  && REGNO (SET_DEST (PATTERN (p))) == regno)
! 	{
! 	  this = invariant_p (SET_SRC (PATTERN (p)));
! 	  if (this != 0)
! 	    value |= this;
! 	  else if (temp = find_reg_note (p, REG_EQUAL, 0))
! 	    {
! 	      this = invariant_p (XEXP (temp, 0));
! 	      if (this != 0)
! 		value |= this;
! 	    }
! 	}
!       if (this != 0)
  	count--;
        else if (code != NOTE)
***************
*** 1662,1666 ****
    n_times_set[regno] = old;
    /* If invariant_p ever returned 2, we return 2.  */
!   return 1 + (tem & 2);
  }
  
--- 2016,2020 ----
    n_times_set[regno] = old;
    /* If invariant_p ever returned 2, we return 2.  */
!   return 1 + (value & 2);
  }
  
***************
*** 1842,1908 ****
      return reg_used_between_p (reg, scan_start, insn);
  }
- 
- /* Return nonzero if evaluating rtx X might cause a trap.  */
- 
- static int
- may_trap_p (x)
-      rtx x;
- {
-   int i;
-   enum rtx_code code;
-   char *fmt;
- 
-   if (x == 0)
-     return 0;
-   code = GET_CODE (x);
-   switch (code)
-     {
-       /* Handle these cases fast.  */
-     case CONST_INT:
-     case CONST_DOUBLE:
-     case SYMBOL_REF:
-     case LABEL_REF:
-     case CONST:
-     case PC:
-     case CC0:
-     case REG:
-       return 0;
- 
-       /* Memory ref can trap unless it's a static var or a stack slot.  */
-     case MEM:
-       return rtx_varies_p (XEXP (x, 0));
- 
-       /* Division by a non-constant might trap.  */
-     case DIV:
-     case MOD:
-     case UDIV:
-     case UMOD:
-       if (! CONSTANT_P (XEXP (x, 1))
- 	  && GET_CODE (XEXP (x, 1)) != CONST_DOUBLE)
- 	return 1;
-     default:
-       /* Any floating arithmetic may trap.  */
-       if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
- 	return 1;
-     }
- 
-   fmt = GET_RTX_FORMAT (code);
-   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-     {
-       if (fmt[i] == 'e')
- 	{
- 	  if (may_trap_p (XEXP (x, i)))
- 	    return 1;
- 	}
-       else if (fmt[i] == 'E')
- 	{
- 	  register int j;
- 	  for (j = 0; j < XVECLEN (x, i); j++)
- 	    if (may_trap_p (XVECEXP (x, i, j)))
- 	      return 1;
- 	}
-     }
-   return 0;
- }
  \f


  /* A "basic induction variable" or biv is a pseudo reg that is set
--- 2196,2199 ----
***************
*** 2094,2097 ****
--- 2385,2389 ----
    /* Map of pseudo-register replacements.  */
    rtx *reg_map;
+   int call_seen;
  
    induct_var = (enum iv_mode *) alloca (nregs * sizeof (induct_var[0]));
***************
*** 2113,2117 ****
  	{
  	  dest_regno = REGNO (SET_DEST (PATTERN (p)));
! 	  if (induct_var[dest_regno] != NOT_BASIC_INDUCT)
  	    {
  	      if (basic_induction_var (SET_SRC (PATTERN (p)), dest_regno,
--- 2405,2410 ----
  	{
  	  dest_regno = REGNO (SET_DEST (PATTERN (p)));
! 	  if (induct_var[dest_regno] != NOT_BASIC_INDUCT
! 	      && dest_regno >= FIRST_PSEUDO_REGISTER)
  	    {
  	      if (basic_induction_var (SET_SRC (PATTERN (p)), dest_regno,
***************
*** 2249,2252 ****
--- 2542,2546 ----
       or when all bivs have been seen.  */
  
+   call_seen = 0;
    p = loop_start;
    while (biv_found)
***************
*** 2256,2259 ****
--- 2550,2556 ----
  	break;
  
+       if (GET_CODE (p) == CALL_INSN)
+ 	call_seen = 1;
+ 
        if (GET_CODE (p) == INSN
  	  && GET_CODE (PATTERN (p)) == SET
***************
*** 2267,2270 ****
--- 2564,2569 ----
  	      /* This is the first modification found for this reg.  */
  
+ 	      rtx src = SET_SRC (PATTERN (p));
+ 
  	      /* Record the intializing INSN */
  
***************
*** 2276,2284 ****
  
  	      /* Save value if it is a constant or register.  */
! 	      if (CONSTANT_P (SET_SRC (PATTERN (p)))
! 		  || GET_CODE (SET_SRC (PATTERN (p))) == REG)
  		{
! 		  class_struct[dest_regno]->initial_value
! 		    = SET_SRC (PATTERN (p));
  		  
  		  if (loop_dump_stream)
--- 2575,2588 ----
  
  	      /* Save value if it is a constant or register.  */
! 	      if (CONSTANT_P (src)
! 		  || (GET_CODE (src) == REG
! 		      /* Don't try to use a value in a hard reg
! 			 across a call which clobbers it.  */
! 		      && ! (REGNO (src) < FIRST_PSEUDO_REGISTER
! 			    && call_used_regs[REGNO (src)]
! 			    && call_seen)
! 		      && ! reg_set_between_p (src, p, loop_start)))
  		{
! 		  class_struct[dest_regno]->initial_value = src;
  		  
  		  if (loop_dump_stream)
***************
*** 2286,2295 ****
  		  if (loop_dump_stream)
  		    {
! 		      if (GET_CODE (SET_SRC (PATTERN (p))) == CONST_INT)
! 			fprintf (loop_dump_stream, "%d\n", 
! 				 INTVAL (SET_SRC (PATTERN (p))));
  		      else
  			{
! 			  print_rtl (loop_dump_stream, SET_SRC (PATTERN (p)));
  			  fprintf (loop_dump_stream, "\n");
  			}
--- 2590,2598 ----
  		  if (loop_dump_stream)
  		    {
! 		      if (GET_CODE (src) == CONST_INT)
! 			fprintf (loop_dump_stream, "%d\n", INTVAL (src));
  		      else
  			{
! 			  print_rtl (loop_dump_stream, src);
  			  fprintf (loop_dump_stream, "\n");
  			}
***************
*** 2349,2352 ****
--- 2652,2657 ----
  
  	  dest_regno = REGNO (SET_DEST (PATTERN (p)));
+ 	  if (dest_regno < FIRST_PSEUDO_REGISTER)
+ 	    continue;
  
  	  if (/* Normal giv.  */
***************
*** 2458,2462 ****
  	   && ! bl->nonneg)
  	  || (final_value = final_biv_value (bl, loop_end)))
! 	check_eliminate_biv (bl, loop_start, end, 0);
        else
  	{
--- 2763,2767 ----
  	   && ! bl->nonneg)
  	  || (final_value = final_biv_value (bl, loop_end)))
! 	check_eliminate_biv (bl, loop_start, end);
        else
  	{
***************
*** 3004,3008 ****
  	   ((uid_luid[regno_last_uid[forces->dest_regno]]
  	     - uid_luid[regno_first_uid[forces->dest_regno]])
! 	    == (INSN_UID (insn) - INSN_UID (forces->insn))))
  	  && !reg_used_between_p (SET_DEST (PATTERN (forces->insn)),
  				  forces->insn, insn))
--- 3309,3313 ----
  	   ((uid_luid[regno_last_uid[forces->dest_regno]]
  	     - uid_luid[regno_first_uid[forces->dest_regno]])
! 	    == (INSN_LUID (insn) - INSN_LUID (forces->insn))))
  	  && !reg_used_between_p (SET_DEST (PATTERN (forces->insn)),
  				  forces->insn, insn))
***************
*** 3020,3024 ****
  	   ((uid_luid[regno_last_uid[forces2->dest_regno]]
  	     - uid_luid[regno_first_uid[forces2->dest_regno]])
! 	    == (INSN_UID (insn) - INSN_UID (forces2->insn))))
  	  && !reg_used_between_p (SET_DEST (PATTERN (forces2->insn)),
  				  forces2->insn, insn))
--- 3325,3329 ----
  	   ((uid_luid[regno_last_uid[forces2->dest_regno]]
  	     - uid_luid[regno_first_uid[forces2->dest_regno]])
! 	    == (INSN_LUID (insn) - INSN_LUID (forces2->insn))))
  	  && !reg_used_between_p (SET_DEST (PATTERN (forces2->insn)),
  				  forces2->insn, insn))
***************
*** 3052,3060 ****
      }
    else
!     {
!       /* Fatal error, biv missing for this giv?  */
!       fflush (loop_dump_stream);
!       abort ();
!     }
  
    if (type == DEST_ADDR)
--- 3357,3362 ----
      }
    else
!     /* Fatal error, biv missing for this giv?  */
!     abort ();
  
    if (type == DEST_ADDR)
***************
*** 3350,3354 ****
        else if (tem = general_induction_var (XEXP (x, 1), src_regno,
  					    add_val, mult_val,
! 					    forces, forces2))
  	{
  	  /* Set subexp true so that this can be handled a little
--- 3652,3657 ----
        else if (tem = general_induction_var (XEXP (x, 1), src_regno,
  					    add_val, mult_val,
! 					    forces, forces2)
! 	       && code != MINUS)
  	{
  	  /* Set subexp true so that this can be handled a little
***************
*** 3359,3362 ****
--- 3662,3667 ----
  	  g->mult_val = *mult_val;
  	  g->add_val = *add_val;
+ 	  /* Fake out the test below.  */
+ 	  g->replaceable = 1;
  	  /* Count this multiply as a shift, since that's what it
  	     really will do.  */
***************
*** 3381,3385 ****
  	}
        else if (GET_CODE (XEXP (x, 1)) == REG
! 	       && induct_var[REGNO (XEXP (x, 1))] == GENERAL_INDUCT)
  	{
  	  g = induct_struct[REGNO (XEXP (x, 1))];
--- 3686,3691 ----
  	}
        else if (GET_CODE (XEXP (x, 1)) == REG
! 	       && induct_var[REGNO (XEXP (x, 1))] == GENERAL_INDUCT
! 	       && code != MINUS)
  	{
  	  g = induct_struct[REGNO (XEXP (x, 1))];
***************
*** 3453,3456 ****
--- 3759,3768 ----
    else
      return 0;
+     
+   /* Until we can do the correct thing, suppress use of nonreplaceable givs
+      as sources for other givs.  */
+   if ((g && ! g->replaceable)
+       || (v && ! v->replaceable))
+     return 0;
  
    /* Now we know looks like a giv; extract the coefficients.
***************
*** 3887,3891 ****
    int benefit = first_benefit;
    enum rtx_code code;
!   rtx forces, forces2;
    rtx temp;
    int tem;
--- 4199,4203 ----
    int benefit = first_benefit;
    enum rtx_code code;
!   struct induction forces, forces2;
    rtx temp;
    int tem;
***************
*** 3973,3990 ****
  
  /* Emit code to initialize an induction variable created by strength
!    reduction.  */
! 
! /* This is necessarily long and messy because cse has already been done,
!    so we have to be careful to generate near optimal code for the sequence
!    reg = b * m;
!    reg += a
!  */
! 
! /* Do we need to add code to deal with constants other than CONST_INT's,
!    or will later passes recognize that the assembler can do the arithmetic?
!    March 16, 1989 -- self@bayes.arc.nasa.gov */
  
  static void
! emit_iv_init_code (b, m, a, reg, loop_start)
       rtx b;          /* initial value of basic induction variable */
       rtx m;          /* multiplicative constant */
--- 4285,4294 ----
  
  /* Emit code to initialize an induction variable created by strength
!    reduction.
!    More precisely, emit code before INSERT_BEFORE
!    to set REG = B * M + A.  */
  
  static void
! emit_iv_init_code (b, m, a, reg, insert_before)
       rtx b;          /* initial value of basic induction variable */
       rtx m;          /* multiplicative constant */
***************
*** 3991,4095 ****
       rtx a;          /* additive constant */
       rtx reg;        /* destination register */
!      rtx loop_start;
  {
!   /* Indicates which of B/M/A are constants.  */
!   int status = 0;
!   int const_val;
!   rtx tmp;
! 
!   if (GET_CODE (b) == CONST_INT)
!     status |= 0x1;
!   if (GET_CODE (m) == CONST_INT)
!     status |= 0x2;
!   if (GET_CODE (a) == CONST_INT)
!     status |= 0x4;
! 
!   switch (status)
!     {
!     case 0:  /* nothing constant */
!     case 4:  /* A constant */
!       emit_insn_before (gen_iv_mult (GET_MODE (reg), b, m, reg), loop_start);
!       /* Don't emit add unless it is necessary.  */
!       if (a != const0_rtx)
! 	emit_insn_before (gen_rtx (SET, VOIDmode, reg,
! 				   gen_rtx (PLUS, GET_MODE (reg), reg, a)),
! 			  loop_start);
!       break;
! 
!     case 1:  /* B constant */
!       /* Equivalent to state 2, just need to switch values of B and M
! 	 and fall through.  */
!     case 5:  /* B, a constant */
!       /* Equivalent to state 6, just need to switch values of B and M
! 	 and fall through.  */
!       tmp = b;
!       b = m;
!       m = tmp;
  
!     case 2:  /* M constant */
!     case 6:  /* M, A constant */
!       const_val = INTVAL (m);
!       if (const_val == 0)
! 	/* REG = A */
! 	emit_insn_before (gen_rtx (SET, VOIDmode, reg, a),
! 			  loop_start);
!       else if (const_val == 1)
! 	{
! 	  /* REG = A + B */
! 	  if (a != const0_rtx)
! 	    emit_insn_before (gen_rtx (SET, VOIDmode, reg,
! 				       gen_rtx (PLUS, GET_MODE (reg), b, a)),
! 			      loop_start);
! 	  else
! 	    emit_insn_before (gen_rtx (SET, VOIDmode, reg, b), loop_start);
! 	}
!       else if (const_val == -1)
! 	{
! 	  /* REG = A - B */
! 	  if (a != const0_rtx)
! 	    emit_insn_before (gen_rtx (SET, VOIDmode, reg,
! 				       gen_rtx (MINUS, GET_MODE (reg), a, b)),
! 			      loop_start);
! 	  else
! 	    emit_insn_before (gen_rtx (SET, VOIDmode, reg,
! 				       gen_rtx (NEG, GET_MODE (reg), b)),
! 			      loop_start);
! 	}
!       else
! 	{
! 	  /* Must generate a `multiply' instruction.  */
! 	  emit_insn_before (gen_iv_mult (GET_MODE (reg), b, m, reg),
! 			    loop_start);
  
! 	  if (a != const0_rtx)
! 	    emit_insn_before (gen_rtx (SET, VOIDmode, reg,
! 				       gen_rtx (PLUS, GET_MODE (reg), reg, a)),
! 			      loop_start);
! 	}
!       break;
! 
!     case 3:  /* B, M constant */
!       const_val = INTVAL (b) * INTVAL (m);
!       if (const_val == 0)
! 	emit_insn_before (gen_rtx (SET, VOIDmode, reg, a),
! 			  loop_start);
!       else
! 	emit_insn_before (gen_rtx (SET, VOIDmode, reg,
! 				   gen_rtx (PLUS, GET_MODE (reg), a,
! 					    gen_rtx (CONST_INT, VOIDmode,
! 						     const_val))),
! 			loop_start);
!       break;
  
!     case 7:  /* all are constant */
!       emit_insn_before (gen_rtx (SET, VOIDmode, reg,
! 			  gen_rtx (CONST_INT, VOIDmode,
! 				   INTVAL (b) * INTVAL (m) + INTVAL (a))),
! 		 loop_start);
!       break;
  
!     default:
!       abort ();
!     }
  }
  \f


--- 4295,4329 ----
       rtx a;          /* additive constant */
       rtx reg;        /* destination register */
!      rtx insert_before;
  {
!   rtx seq;
!   rtx result;
  
!   /* Prevent unexpected sharing of these rtx.  */
!   a = copy_rtx (a);
!   b = copy_rtx (b);
! 
!   start_sequence ();
!   result = expand_mult_add (b, m, a, GET_MODE (reg), 0);
!   if (reg != result)
!     emit_move_insn (reg, result);
!   seq = gen_sequence ();
!   end_sequence ();
  
!   emit_insn_before (seq, insert_before);
! }
  
! /* Emit code to increment the induction variable inside the loop.
!    Try to emit optimal code for the expression
!    REG = REG + BIV_ADD * GIV_MULT.  */
  
! static void
! emit_iv_inc (biv_add, giv_mult, reg, insn)
!      rtx biv_add;                   /* increment value for biv */
!      rtx giv_mult;                  /* multiply value of giv */
!      rtx reg;                       /* create insn to set this reg */
!      rtx insn;                      /* where to insert the new insn */
! {
!   emit_iv_init_code (biv_add, giv_mult, reg, reg, insn);
  }
  \f


***************
*** 4153,4236 ****
  
  \f


- /* Emit code to increment the induction variable inside the loop.
-    Try to emit optimal code for the expression
-    REG = REG + BIV_ADD * GIV_MULT.  */
- 
- static void
- emit_iv_inc (biv_add, giv_mult, reg, insn)
-      rtx biv_add;                   /* increment value for biv */
-      rtx giv_mult;                  /* multiply value of giv */
-      rtx reg;                       /* create insn to set this reg */
-      rtx insn;                      /* where to insert the new insn */
- {
-   /* Indicates which of MULT/ADD are constants.  */
-   int status = 0;
-   int const_val;
-   rtx tmp, tempreg;
-   enum machine_mode mode = GET_MODE (reg);
- 
-   if (GET_CODE (biv_add) == CONST_INT)
-     status |= 0x1;
-   if (GET_CODE (giv_mult) == CONST_INT)
-     status |= 0x2;
- 
-   switch (status)
-     {
-     case 1:
-       /* BIV_ADD value is constant */
-       /* Equivalent to state 2, just switch values of BIV_ADD and GIV_MULT
- 	 and fall through.  */
-       tmp = biv_add;
-       biv_add = giv_mult;
-       giv_mult = tmp;
- 
-     case 2:
-       /* GIV_MULT value is constant */
-       const_val = INTVAL (giv_mult);
-       if (const_val == 0)
- 	/* No code necessary.  This should be VERY rare.  */
- 	break;
-       else if (const_val == 1)
- 	{
- 	  emit_insn_before (gen_rtx (SET, VOIDmode, reg,
- 				     gen_rtx (PLUS, mode, reg, biv_add)),
- 			    insn);
- 	  break;
- 	}
-       else if (const_val == -1)
- 	{
- 	  emit_insn_before (gen_rtx (SET, VOIDmode, reg,
- 				     gen_rtx (MINUS, mode, reg, biv_add)),
- 			    insn);
- 	  break;
- 	}
- 
-     case 0:
-       /* Variable times variable,
- 	 or variable times constant (not 0, -1 or 1):
- 	 emit a real multiply.  */
-       tempreg = gen_reg_rtx (mode);
-       tmp = gen_iv_mult (mode, biv_add, giv_mult, tempreg);
-       emit_insn_before (tmp, insn);
-       emit_insn_before (gen_rtx (SET, VOIDmode, reg,
- 				 gen_rtx (PLUS, mode, reg, tempreg)),
- 			insn);
-       break;
- 
-     case 3:
-       /* Both BIV_ADD and GIV_MULT are constant */
-       emit_insn_before (gen_rtx (SET, VOIDmode, reg,
- 				 gen_rtx (PLUS, mode, reg,
- 					  gen_rtx (CONST_INT, VOIDmode,
- 						   INTVAL (biv_add)
- 						   * INTVAL (giv_mult)))),
- 			insn);
-       break;
- 
-     default:
-       abort ();
-     }
- }
- \f


  /* Check to see if loop can be terminated by a "decrement and branch until
     zero" instruction.  If so, add a REG_NONNEG note to the branch insn if so.
--- 4387,4390 ----
***************
*** 4317,4322 ****
  
        /* If biv set more than once, then give up.
! 	 We can't guarantee that it will be zero on the last iteration.  */
!       if (bl && bl->biv_count == 1)
  	{
  	  /* Look for the case where the basic induction variable is always
--- 4471,4480 ----
  
        /* If biv set more than once, then give up.
! 	 We can't guarantee that it will be zero on the last iteration.
! 	 Also give up if the biv is used between its update and the test
! 	 insn.  */
!       if (bl && bl->biv_count == 1
! 	  && ! reg_used_between_p (regno_reg_rtx[bl->regno], bl->biv->insn,
! 				   PREV_INSN (PREV_INSN (loop_end))))
  	{
  	  /* Look for the case where the basic induction variable is always
***************
*** 4361,4365 ****
  		}
  	    }
! 	  else
  	    {
  	      /* Try to change inc to dec, so can apply above optimization.  */
--- 4519,4523 ----
  		}
  	    }
! 	  else if (num_mem_sets <= 1)
  	    {
  	      /* Try to change inc to dec, so can apply above optimization.  */
***************
*** 4369,4378 ****
                         (obviously true if only one write)
  	         allow 2 insns for the compare/jump at the end of the loop.  */
  
  	      /* This code only acts for innermost loops.  Also it simplifies
  		 the memory address check by only reversing loops with
! 		 zero or one memory access.  */
  
! 	      if (num_mem_sets <= 1
  		  && !loop_has_call
  		  && (bl->giv_count + bl->biv_count + num_mem_sets
--- 4527,4545 ----
                         (obviously true if only one write)
  	         allow 2 insns for the compare/jump at the end of the loop.  */
+ 	      int num_nonfixed_reads = 0;
+ 	      rtx p;
+ 
+ 	      for (p = loop_start; p != loop_end; p = NEXT_INSN (p))
+ 		if (GET_CODE (p) == INSN || GET_CODE (p) == CALL_INSN
+ 		    || GET_CODE (p) == JUMP_INSN)
+ 		  num_nonfixed_reads += count_nonfixed_reads (PATTERN (p));
  
  	      /* This code only acts for innermost loops.  Also it simplifies
  		 the memory address check by only reversing loops with
! 		 zero or one memory access.
! 		 Two memory accesses could involve parts of the same array,
! 		 and that can't be reversed.  */
  
! 	      if (num_nonfixed_reads <= 1
  		  && !loop_has_call
  		  && (bl->giv_count + bl->biv_count + num_mem_sets
***************
*** 4380,4383 ****
--- 4547,4552 ----
  		{
  		  rtx src_two_before_end;
+ 		  int constant;
+ 		  int win;
  
  		  /* Loop can be reversed.  */
***************
*** 4401,4409 ****
  		    = SET_SRC (PATTERN (PREV_INSN (PREV_INSN (loop_end))));
  
! 		  if (bl->initial_value == const0_rtx
  		      && (branch_code == LT || branch_code == LE)
  		      && XEXP (XEXP (SET_SRC (PATTERN (PREV_INSN (loop_end))), 0), 1) == const0_rtx
! 		      && GET_CODE (XEXP (src_two_before_end, 1)) == CONST_INT
! 		      && (INTVAL (XEXP (src_two_before_end, 1)) % INTVAL (bl->biv->add_val)) == 0)
  		    {
  		      /* Register will always be nonnegative, with value
--- 4570,4586 ----
  		    = SET_SRC (PATTERN (PREV_INSN (PREV_INSN (loop_end))));
  
! 		  win = 1;
! 		  if (GET_CODE (src_two_before_end) == REG)
! 		    constant = 0;
! 		  else if (GET_CODE (src_two_before_end) == COMPARE
! 			   && GET_CODE (XEXP (src_two_before_end, 1)) == CONST_INT)
! 		    constant = INTVAL (XEXP (src_two_before_end, 1));
! 		  else
! 		    win = 0;
! 
! 		  if (win && bl->initial_value == const0_rtx
  		      && (branch_code == LT || branch_code == LE)
  		      && XEXP (XEXP (SET_SRC (PATTERN (PREV_INSN (loop_end))), 0), 1) == const0_rtx
! 		      && (constant % INTVAL (bl->biv->add_val)) == 0)
  		    {
  		      /* Register will always be nonnegative, with value
***************
*** 4419,4435 ****
  		      if (branch_code == LT)
  			{
! 			  final_value = XEXP (src_two_before_end, 1);
  			  start_value
  			    = gen_rtx (CONST_INT, VOIDmode,
! 				       (INTVAL (XEXP (src_two_before_end, 1))
! 					- INTVAL (bl->biv->add_val)));
  			}
  		      else /* branch_code == LE */
  			{
! 			  start_value = XEXP (src_two_before_end, 1);
  			  final_value
  			    = gen_rtx (CONST_INT, VOIDmode,
! 				       (INTVAL (XEXP (src_two_before_end, 1))
! 					+ INTVAL (bl->biv->add_val)));
  			}
  
--- 4596,4612 ----
  		      if (branch_code == LT)
  			{
! 			  final_value
! 			    = gen_rtx (CONST_INT, VOIDmode, constant);
  			  start_value
  			    = gen_rtx (CONST_INT, VOIDmode,
! 				       (constant - INTVAL (bl->biv->add_val)));
  			}
  		      else /* branch_code == LE */
  			{
! 			  start_value
! 			    = gen_rtx (CONST_INT, VOIDmode, constant);
  			  final_value
  			    = gen_rtx (CONST_INT, VOIDmode,
! 				       (constant + INTVAL (bl->biv->add_val)));
  			}
  
***************
*** 4451,4457 ****
  		      delete_insn (NEXT_INSN (bl->biv->insn));
  
! 		      /* Set LABEL_NUSES to two so that delete_insn will
  			 not delete the label.  */
! 		      LABEL_NUSES (XEXP (jump_label, 0)) = 2;
  
  		      if (regno_last_uid[bl->regno] != INSN_UID (PREV_INSN (loop_end)))
--- 4628,4634 ----
  		      delete_insn (NEXT_INSN (bl->biv->insn));
  
! 		      /* Inc LABEL_NUSES so that delete_insn will
  			 not delete the label.  */
! 		      LABEL_NUSES (XEXP (jump_label, 0)) ++;
  
  		      if (regno_last_uid[bl->regno] != INSN_UID (PREV_INSN (loop_end)))
***************
*** 4461,4465 ****
  
  		      /* Delete compare/branch at end of loop.  */
! 		      delete_insn (PREV_INSN (loop_end));
  		      delete_insn (PREV_INSN (loop_end));
  
--- 4638,4642 ----
  
  		      /* Delete compare/branch at end of loop.  */
! 		      delete_insn (PREV_INSN (loop_end));
  		      delete_insn (PREV_INSN (loop_end));
  
***************
*** 4475,4478 ****
--- 4652,4658 ----
  					  loop_end);
  
+ 		      JUMP_LABEL (PREV_INSN (loop_end)) = XEXP (jump_label, 0);
+ 		      /* Increment of LABEL_NUSES done above. */
+ 
  		      /* Register is now always nonnegative,
  			 so add REG_NONNEG note to the branch.  */
***************
*** 4698,4703 ****
  		for (tv = class_struct[REGNO (arg)]->giv; tv; tv = tv->family)
  		  if ((tv->new_reg != 0)
- 		      && rtx_equal_p (tv->mult_val, v->mult_val)
  		      && rtx_equal_p (tv->mult_val, v->mult_val)
  		      && ! tv->ignore
  		      && tv->mode == mode)
--- 4878,4883 ----
  		for (tv = class_struct[REGNO (arg)]->giv; tv; tv = tv->family)
  		  if ((tv->new_reg != 0)
  		      && rtx_equal_p (tv->mult_val, v->mult_val)
+ 		      && rtx_equal_p (tv->mult_val, v->mult_val)
  		      && ! tv->ignore
  		      && tv->mode == mode)
***************
*** 4766,4770 ****
  	  /* Replace biv with the giv's reduced register.  */
  	  SET_SRC (PATTERN (insn)) = gen_rtx (COMPARE, GET_MODE (v->new_reg),
! 					      v->new_reg, v->add_val);
  
  #if 0
--- 4946,4951 ----
  	  /* Replace biv with the giv's reduced register.  */
  	  SET_SRC (PATTERN (insn)) = gen_rtx (COMPARE, GET_MODE (v->new_reg),
! 					      v->new_reg,
! 					      copy_rtx (v->add_val));
  
  #if 0
***************
*** 4772,4776 ****
  	  /* calculate the appropriate constant to compare against */
  	  emit_insn_before (gen_rtx (SET, VOIDmode, compare_value,
! 				     v->add_val),
  			    loop_start);
  #endif
--- 4953,4957 ----
  	  /* calculate the appropriate constant to compare against */
  	  emit_insn_before (gen_rtx (SET, VOIDmode, compare_value,
! 				     copy_rtx (v->add_val)),
  			    loop_start);
  #endif
***************
*** 4808,4817 ****
  	  if (v)
  	    {
  	      /* Replace biv with the giv's reduced reg.  */
  	      XEXP (src, 1-arg_operand) = v->new_reg;
  	      /* Calculate the appropriate constant to compare against.  */
! 	      XEXP (src, arg_operand) = gen_rtx (CONST_INT, VOIDmode,
! 					 (INTVAL (arg) * INTVAL (v->mult_val)
! 					         + INTVAL (v->add_val)));
  	      return;
  	    }
--- 4989,5009 ----
  	  if (v)
  	    {
+ 	      rtx newval;
  	      /* Replace biv with the giv's reduced reg.  */
  	      XEXP (src, 1-arg_operand) = v->new_reg;
  	      /* Calculate the appropriate constant to compare against.  */
! 	      newval = gen_rtx (CONST_INT, VOIDmode,
! 				(INTVAL (arg) * INTVAL (v->mult_val)
! 				 + INTVAL (v->add_val)));
! 	      XEXP (src, arg_operand) = newval;
! 	      /* If that constant is no good in a compare,
! 		 put it in a register.  */
! 	      if (recog (PATTERN (insn), insn) < 0)
! 		{
! 		  rtx temp = gen_reg_rtx (mode);
! 		  emit_iv_init_code (arg, v->mult_val, v->add_val,
! 				     temp, loop_start);
! 		  XEXP (src, arg_operand) = temp;
! 		}
  	      return;
  	    }
***************
*** 4833,4841 ****
  
  	      /* At start of loop, compute value to compare against.  */
! 	      emit_insn_before (gen_rtx (SET, VOIDmode, compare_value,
! 				  gen_rtx (PLUS, mode, v->add_val,
! 				     gen_rtx (CONST_INT, VOIDmode,
! 					INTVAL (arg) * INTVAL (v->mult_val)))),
! 				loop_start);
  	      XEXP (src, arg_operand) = compare_value;
  	      return;
--- 5025,5031 ----
  
  	      /* At start of loop, compute value to compare against.  */
! 	      emit_iv_init_code (arg, v->mult_val, v->add_val,
! 				 compare_value, loop_start);
! 	      /* Use it in this insn.  */
  	      XEXP (src, arg_operand) = compare_value;
  	      return;
***************
*** 4862,4874 ****
  		  XEXP (src, 1-arg_operand) = v->new_reg;
  
! 		  /* Calculate the appropriate constant to compare against.  */
! 		  emit_insn_before (gen_iv_mult (mode, arg, v->mult_val,
! 						 compare_value),
! 				    loop_start);
! 		  emit_insn_before (gen_rtx (SET, VOIDmode, compare_value,
! 					     gen_rtx (PLUS, mode,
! 						      compare_value,
! 						      v->add_val)),
! 				    loop_start);
  		  XEXP (src, arg_operand) = compare_value;
  		  return;
--- 5052,5058 ----
  		  XEXP (src, 1-arg_operand) = v->new_reg;
  
! 		  /* At start of loop, compute value to compare against.  */
! 		  emit_iv_init_code (arg, v->mult_val, v->add_val,
! 				     compare_value, loop_start);
  		  XEXP (src, arg_operand) = compare_value;
  		  return;
diff -rc2N gcc-1.35/machmode.def gcc-1.36/machmode.def
*** gcc-1.35/machmode.def	Sun Apr  2 13:01:50 1989
--- gcc-1.36/machmode.def	Fri Jun  9 16:27:49 1989
***************
*** 47,57 ****
     MODE_RANDOM - anything else
  
!    Fourth argument is the size of the object, in bytes.
     It is zero when the size is meaningless or not determined.
  
!    Fifth arg is size of subunits of the object, in bytes.
     It is same as the fourth argument except for complexes and EPmode,
!    since they are really made of two equal size subunits.  */
  
  /* The compiler assumes that a mode may be widened to another
     HIGHER NUMBERED mode if both those modes AND ALL MODES IN BETWEEN
--- 47,65 ----
     MODE_RANDOM - anything else
  
!    Fourth argument is the relative size of the object.
     It is zero when the size is meaningless or not determined.
+    On most machines, this is also the actual size in bytes.
+    However, the general rule is that the size of SImode in bytes
+    is UNITS_PER_WORD and the other sizes are proportional to that.
+    (If UNITS_PER_WORD is less than 4, some modes would be less than
+    one byte.  Their sizes are rounded up to 1.)
  
!    Fifth arg is the relative size of subunits of the object.
     It is same as the fourth argument except for complexes and EPmode,
!    since they are really made of two equal size subunits.
  
+    Sixth arg is next wider natural mode of the same class,
+    for widening multiply and narrowing divide.  0 if there is none.  */
+ 
  /* The compiler assumes that a mode may be widened to another
     HIGHER NUMBERED mode if both those modes AND ALL MODES IN BETWEEN
***************
*** 61,104 ****
  /* VOIDmode is used when no mode needs to be specified,
     as for example on CONST_INT RTL expressions.  */
! DEF_MACHMODE (VOIDmode, "VOID", MODE_RANDOM, 0, 0)
  
! DEF_MACHMODE (QImode, "QI", MODE_INT, 1, 1)		/* int types */
! DEF_MACHMODE (HImode, "HI", MODE_INT, 2, 2)
  /* Pointers on some machines use this type to distinguish them from ints.
     Useful if a pointer is 4 bytes but has some bits that are not significant,
     so it is really not quite as wide as an integer.  */
! DEF_MACHMODE (PSImode, "PSI", MODE_INT, 4, 4)
! DEF_MACHMODE (SImode, "SI", MODE_INT, 4, 4)
! DEF_MACHMODE (PDImode, "PDI", MODE_INT, 8, 8)
! DEF_MACHMODE (DImode, "DI", MODE_INT, 8, 8)
! DEF_MACHMODE (TImode, "TI", MODE_INT, 16, 16)
! DEF_MACHMODE (QFmode, "QF", MODE_FLOAT, 1, 1)
! DEF_MACHMODE (HFmode, "HF", MODE_FLOAT, 2, 2)		/* floating types */
! DEF_MACHMODE (SFmode, "SF", MODE_FLOAT, 4, 4)
! DEF_MACHMODE (DFmode, "DF", MODE_FLOAT, 8, 8)
! DEF_MACHMODE (XFmode, "XF", MODE_FLOAT, 12, 12)	/* IEEE extended float */
! DEF_MACHMODE (TFmode, "TF", MODE_FLOAT, 16, 16)
! DEF_MACHMODE (CQImode, "CQI", MODE_COMPLEX_INT, 2, 1)
! DEF_MACHMODE (CHImode, "CHI", MODE_COMPLEX_INT, 4, 2)	/* complex ints */
! DEF_MACHMODE (CSImode, "CSI", MODE_COMPLEX_INT, 8, 4)
! DEF_MACHMODE (CDImode, "CDI", MODE_COMPLEX_INT, 16, 8)
! DEF_MACHMODE (CTImode, "CTI", MODE_COMPLEX_INT, 32, 16)
! DEF_MACHMODE (CQFmode, "CQF", MODE_COMPLEX_FLOAT, 2, 1)
! DEF_MACHMODE (CHFmode, "CHF", MODE_COMPLEX_FLOAT, 4, 2)	/* complex floats */
! DEF_MACHMODE (CSFmode, "CSF", MODE_COMPLEX_FLOAT, 8, 4)
! DEF_MACHMODE (CDFmode, "CDF", MODE_COMPLEX_FLOAT, 16, 8)
! DEF_MACHMODE (CXFmode, "CXF", MODE_COMPLEX_FLOAT, 24, 12)
! DEF_MACHMODE (CTFmode, "CTF", MODE_COMPLEX_FLOAT, 32, 16)
  
  /* BImode is used only in FIELD_DECL nodes for bit fields
     whose size and alignment are not such as to fit any other mode.  */
! DEF_MACHMODE (BImode, "BI", MODE_INT, 0, 0)	/* signed bit field */
  
  /* BLKmode is used for structures, arrays, etc.
     that fit no more specific mode.  */
! DEF_MACHMODE (BLKmode, "BLK", MODE_RANDOM, 0, 0)
  
  /* Function-variable that includes a static chain.  */
! DEF_MACHMODE (EPmode, "EP", MODE_RANDOM, 8, 4)
  
  /* The symbol Pmode stands for one of the above machine modes (usually SImode).
--- 69,112 ----
  /* VOIDmode is used when no mode needs to be specified,
     as for example on CONST_INT RTL expressions.  */
! DEF_MACHMODE (VOIDmode, "VOID", MODE_RANDOM, 0, 0, 0)
  
! DEF_MACHMODE (QImode, "QI", MODE_INT, 1, 1, HImode)		/* int types */
! DEF_MACHMODE (HImode, "HI", MODE_INT, 2, 2, SImode)
  /* Pointers on some machines use this type to distinguish them from ints.
     Useful if a pointer is 4 bytes but has some bits that are not significant,
     so it is really not quite as wide as an integer.  */
! DEF_MACHMODE (PSImode, "PSI", MODE_INT, 4, 4, 0)
! DEF_MACHMODE (SImode, "SI", MODE_INT, 4, 4, DImode)
! DEF_MACHMODE (PDImode, "PDI", MODE_INT, 8, 8, 0)
! DEF_MACHMODE (DImode, "DI", MODE_INT, 8, 8, TImode)
! DEF_MACHMODE (TImode, "TI", MODE_INT, 16, 16, 0)
! DEF_MACHMODE (QFmode, "QF", MODE_FLOAT, 1, 1, 0)
! DEF_MACHMODE (HFmode, "HF", MODE_FLOAT, 2, 2, 0)	/* floating types */
! DEF_MACHMODE (SFmode, "SF", MODE_FLOAT, 4, 4, 0)
! DEF_MACHMODE (DFmode, "DF", MODE_FLOAT, 8, 8, 0)
! DEF_MACHMODE (XFmode, "XF", MODE_FLOAT, 12, 12, 0)  /* IEEE extended float */
! DEF_MACHMODE (TFmode, "TF", MODE_FLOAT, 16, 16, 0)
! DEF_MACHMODE (CQImode, "CQI", MODE_COMPLEX_INT, 2, 1, 0)
! DEF_MACHMODE (CHImode, "CHI", MODE_COMPLEX_INT, 4, 2, 0)  /* complex ints */
! DEF_MACHMODE (CSImode, "CSI", MODE_COMPLEX_INT, 8, 4, 0)
! DEF_MACHMODE (CDImode, "CDI", MODE_COMPLEX_INT, 16, 8, 0)
! DEF_MACHMODE (CTImode, "CTI", MODE_COMPLEX_INT, 32, 16, 0)
! DEF_MACHMODE (CQFmode, "CQF", MODE_COMPLEX_FLOAT, 2, 1, 0)
! DEF_MACHMODE (CHFmode, "CHF", MODE_COMPLEX_FLOAT, 4, 2, 0) /* complex floats */
! DEF_MACHMODE (CSFmode, "CSF", MODE_COMPLEX_FLOAT, 8, 4, 0)
! DEF_MACHMODE (CDFmode, "CDF", MODE_COMPLEX_FLOAT, 16, 8, 0)
! DEF_MACHMODE (CXFmode, "CXF", MODE_COMPLEX_FLOAT, 24, 12, 0)
! DEF_MACHMODE (CTFmode, "CTF", MODE_COMPLEX_FLOAT, 32, 16, 0)
  
  /* BImode is used only in FIELD_DECL nodes for bit fields
     whose size and alignment are not such as to fit any other mode.  */
! DEF_MACHMODE (BImode, "BI", MODE_INT, 0, 0, 0)	/* signed bit field */
  
  /* BLKmode is used for structures, arrays, etc.
     that fit no more specific mode.  */
! DEF_MACHMODE (BLKmode, "BLK", MODE_RANDOM, 0, 0, 0)
  
  /* Function-variable that includes a static chain.  */
! DEF_MACHMODE (EPmode, "EP", MODE_RANDOM, 8, 4, 0)
  
  /* The symbol Pmode stands for one of the above machine modes (usually SImode).
diff -rc2N gcc-1.35/make-cc1.com gcc-1.36/make-cc1.com
*** gcc-1.35/make-cc1.com	Mon Mar 13 19:54:12 1989
--- gcc-1.36/make-cc1.com	Tue Jul 11 19:16:55 1989
***************
*** 7,33 ****
  $!    and to make definitions for bzero, bcopy and bcmp.)
  $!
  $ if "''p1'" .eqs. "LINK" then goto Link
! $ gcc/debug/cc1_options="-mpcc-alignment" rtl.c
! $ gcc/debug/cc1_options="-mpcc-alignment" obstack.c
  $!	Generate insn-flags.h
! $ gcc/debug/cc1_options="-mpcc-alignment" genflags.c
! $ link/nomap genflags,rtl,obstack,gnu_cc:[000000]gcclib/lib,sys$share:vaxcrtl/lib
! $ genflags:=$sys$disk:[]genflags
  $ assign/user insn-flags.h sys$output:
! $ genflags md
  $!	Generate insn-codes.h
! $ gcc/debug/cc1_options="-mpcc-alignment" gencodes.c
! $ link/nomap gencodes,rtl,obstack,gnu_cc:[000000]gcclib/lib,sys$share:vaxcrtl/lib
! $ gencodes:=$sys$disk:[]gencodes
  $ assign/user insn-codes.h sys$output:
! $ gencodes md
  $!	Generate insn-config.h
! $ gcc/debug/cc1_options="-mpcc-alignment" genconfig.c
! $ link/nomap genconfig,rtl,obstack,gnu_cc:[000000]gcclib/lib,sys$share:vaxcrtl/lib
! $ genconfig:=$sys$disk:[]genconfig
  $ assign/user insn-config.h sys$output:
! $ genconfig md
  $!
! $ gcc/debug/cc1_options="-mpcc-alignment" toplev.c
  $!
  $ t1:='f$search("C-PARSE_TAB.C")'
--- 7,51 ----
  $!    and to make definitions for bzero, bcopy and bcmp.)
  $!
+ $ set verify
+ $!
+ $!	C compiler
+ $!
+ $ CC	:=	gcc
+ $!
+ $!	Compiler options
+ $!
+ $ CFLAGS =	"/debug/cc1_options=""-mpcc-alignment""/inc=([],[.config])"
+ $!
+ $!	Link options
+ $!
+ $ LDFLAGS :=	/nomap
+ $!
+ $!	Link libraries
+ $!
+ $ LIBS :=	gnu_cc:[000000]gcclib/libr,sys$share:vaxcrtl/libr
+ $!
  $ if "''p1'" .eqs. "LINK" then goto Link
! $!
! $!	Recompile
! $!
! $ 'CC 'CFLAGS rtl.c
! $ 'CC 'CFLAGS obstack.c
  $!	Generate insn-flags.h
! $ 'CC 'CFLAGS genflags.c
! $ link 'LDFLAGS' genflags,rtl,obstack, 'LIBS'
  $ assign/user insn-flags.h sys$output:
! $ mcr sys$disk:[]genflags md
  $!	Generate insn-codes.h
! $ 'CC 'CFLAGS gencodes.c
! $ link 'LDFLAGS' gencodes,rtl,obstack, 'LIBS'
  $ assign/user insn-codes.h sys$output:
! $ mcr sys$disk:[]gencodes md
  $!	Generate insn-config.h
! $ 'CC 'CFLAGS genconfig.c
! $ link 'LDFLAGS' genconfig,rtl,obstack, 'LIBS'
  $ assign/user insn-config.h sys$output:
! $ mcr sys$disk:[]genconfig md
  $!
! $ 'CC 'CFLAGS toplev.c
  $!
  $ t1:='f$search("C-PARSE_TAB.C")'
***************
*** 42,117 ****
  $ 20$:
  $!
! $ gcc/debug/cc1_options="-mpcc-alignment" c-parse_tab.c
! $ gcc/debug/cc1_options="-mpcc-alignment" tree.c
! $ gcc/debug/cc1_options="-mpcc-alignment" print-tree.c
! $ gcc/debug/cc1_options="-mpcc-alignment" c-decl.c
! $ gcc/debug/cc1_options="-mpcc-alignment" c-typeck.c
! $ gcc/debug/cc1_options="-mpcc-alignment" c-convert.c
! $ gcc/debug/cc1_options="-mpcc-alignment" stor-layout.c
! $ gcc/debug/cc1_options="-mpcc-alignment" fold-const.c
! $ gcc/debug/cc1_options="-mpcc-alignment" varasm.c
! $ gcc/debug/cc1_options="-mpcc-alignment" expr.c
! $ gcc/debug/cc1_options="-mpcc-alignment" stmt.c
! $ gcc/debug/cc1_options="-mpcc-alignment" expmed.c
! $ gcc/debug/cc1_options="-mpcc-alignment" explow.c
! $ gcc/debug/cc1_options="-mpcc-alignment" optabs.c
! $ gcc/debug/cc1_options="-mpcc-alignment" symout.c
! $ gcc/debug/cc1_options="-mpcc-alignment" dbxout.c
! $ gcc/debug/cc1_options="-mpcc-alignment" emit-rtl.c
  $!	Generate insn-emit.c
! $ gcc/debug/cc1_options="-mpcc-alignment" genemit.c
! $ link/nomap genemit,rtl,obstack,gnu_cc:[000000]gcclib/lib,sys$share:vaxcrtl/lib
! $ genemit:=$sys$disk:[]genemit
  $ assign/user insn-emit.c sys$output:
! $ genemit md
  $!
! $ gcc/debug/cc1_options="-mpcc-alignment" insn-emit.c
! $ gcc/debug/cc1_options="-mpcc-alignment" jump.c
! $ gcc/debug/cc1_options="-mpcc-alignment" cse.c
! $ gcc/debug/cc1_options="-mpcc-alignment" loop.c
! $ gcc/debug/cc1_options="-mpcc-alignment" flow.c
! $ gcc/debug/cc1_options="-mpcc-alignment" stupid.c
! $ gcc/debug/cc1_options="-mpcc-alignment" combine.c
! $ gcc/debug/cc1_options="-mpcc-alignment" regclass.c
! $ gcc/debug/cc1_options="-mpcc-alignment" local-alloc.c
! $ gcc/debug/cc1_options="-mpcc-alignment" global-alloc.c
! $ gcc/debug/cc1_options="-mpcc-alignment" reload.c
! $ gcc/debug/cc1_options="-mpcc-alignment" reload1.c
  $!	Generate insn-peep.c
! $ gcc/debug/cc1_options="-mpcc-alignment" genpeep.c
! $ link/nomap genpeep,rtl,obstack,gnu_cc:[000000]gcclib/lib,sys$share:vaxcrtl/lib
! $ genpeep:=$sys$disk:[]genpeep
  $ assign/user insn-peep.c sys$output:
! $ genpeep md
  $!
! $ gcc/debug/cc1_options="-mpcc-alignment" insn-peep.c
! $ gcc/debug/cc1_options="-mpcc-alignment" final.c
! $ gcc/debug/cc1_options="-mpcc-alignment" recog.c
  $!	Generate insn-recog.c
! $ gcc/debug/cc1_options="-mpcc-alignment" genrecog.c
! $ link/nomap genrecog,rtl,obstack,gnu_cc:[000000]gcclib/lib,sys$share:vaxcrtl/lib
! $ genrecog:=$sys$disk:[]genrecog
  $ assign/user insn-recog.c sys$output:
! $ genrecog md
  $!
! $ gcc/debug/cc1_options="-mpcc-alignment" insn-recog.c
  $!	Generate insn-extract.c
! $ gcc/debug/cc1_options="-mpcc-alignment" genextract.c
! $ link/nomap genextract,rtl,obstack,gnu_cc:[000000]gcclib/lib,sys$share:vaxcrtl/lib
! $ genextract:=$sys$disk:[]genextract
  $ assign/user insn-extract.c sys$output:
! $ genextract md
  $!
! $ gcc/debug/cc1_options="-mpcc-alignment" insn-extract.c
  $!	Generate insn-output.c
! $ gcc/debug/cc1_options="-mpcc-alignment" genoutput.c
! $ link/nomap genoutput,rtl,obstack,gnu_cc:[000000]gcclib/lib,sys$share:vaxcrtl/lib
! $ genoutput:=$sys$disk:[]genoutput
  $ assign/user insn-output.c sys$output:
! $ genoutput md
  $!
! $ gcc/debug/cc1_options="-mpcc-alignment" insn-output.c
! $ gcc/debug/cc1_options="-mpcc-alignment" integrate.c
! $ gcc/debug/cc1_options="-mpcc-alignment" caller-save.c
  $!
  $!
--- 60,131 ----
  $ 20$:
  $!
! $ 'CC 'CFLAGS c-parse_tab.c /define="__inline=inline"
! $ 'CC 'CFLAGS tree.c
! $ 'CC 'CFLAGS print-tree.c
! $ 'CC 'CFLAGS c-decl.c
! $ 'CC 'CFLAGS c-typeck.c
! $ 'CC 'CFLAGS c-convert.c
! $ 'CC 'CFLAGS stor-layout.c
! $ 'CC 'CFLAGS fold-const.c
! $ 'CC 'CFLAGS varasm.c
! $ 'CC 'CFLAGS expr.c
! $ 'CC 'CFLAGS stmt.c
! $ 'CC 'CFLAGS expmed.c
! $ 'CC 'CFLAGS explow.c
! $ 'CC 'CFLAGS optabs.c
! $ 'CC 'CFLAGS symout.c
! $ 'CC 'CFLAGS dbxout.c
! $ 'CC 'CFLAGS rtlanal.c
! $ 'CC 'CFLAGS emit-rtl.c
  $!	Generate insn-emit.c
! $ 'CC 'CFLAGS genemit.c
! $ link 'LDFLAGS' genemit,rtl,obstack, 'LIBS'
  $ assign/user insn-emit.c sys$output:
! $ mcr sys$disk:[]genemit md
  $!
! $ 'CC 'CFLAGS insn-emit.c
! $ 'CC 'CFLAGS jump.c
! $ 'CC 'CFLAGS cse.c
! $ 'CC 'CFLAGS loop.c
! $ 'CC 'CFLAGS flow.c
! $ 'CC 'CFLAGS stupid.c
! $ 'CC 'CFLAGS combine.c
! $ 'CC 'CFLAGS regclass.c
! $ 'CC 'CFLAGS local-alloc.c
! $ 'CC 'CFLAGS global-alloc.c
! $ 'CC 'CFLAGS reload.c
! $ 'CC 'CFLAGS reload1.c
  $!	Generate insn-peep.c
! $ 'CC 'CFLAGS genpeep.c
! $ link 'LDFLAGS' genpeep,rtl,obstack, 'LIBS'
  $ assign/user insn-peep.c sys$output:
! $ mcr sys$disk:[]genpeep md
  $!
! $ 'CC 'CFLAGS insn-peep.c
! $ 'CC 'CFLAGS final.c
! $ 'CC 'CFLAGS recog.c
  $!	Generate insn-recog.c
! $ 'CC 'CFLAGS genrecog.c
! $ link 'LDFLAGS' genrecog,rtl,obstack, 'LIBS'
  $ assign/user insn-recog.c sys$output:
! $ mcr sys$disk:[]genrecog md
  $!
! $ 'CC 'CFLAGS insn-recog.c
  $!	Generate insn-extract.c
! $ 'CC 'CFLAGS genextract.c
! $ link 'LDFLAGS' genextract,rtl,obstack, 'LIBS'
  $ assign/user insn-extract.c sys$output:
! $ mcr sys$disk:[]genextract md
  $!
! $ 'CC 'CFLAGS insn-extract.c
  $!	Generate insn-output.c
! $ 'CC 'CFLAGS genoutput.c
! $ link 'LDFLAGS' genoutput,rtl,obstack, 'LIBS'
  $ assign/user insn-output.c sys$output:
! $ mcr sys$disk:[]genoutput md
  $!
! $ 'CC 'CFLAGS insn-output.c
! $ 'CC 'CFLAGS integrate.c
! $ 'CC 'CFLAGS caller-save.c
  $!
  $!
***************
*** 119,123 ****
  $!
  $ Link:
! $ link/nomap/exe=gcc-cc1 sys$input:/opt
  !
  !	"CC1" Linker options file
--- 133,137 ----
  $!
  $ Link:
! $ link 'LDFLAGS' /exe=gcc-cc1 sys$input:/opt,'LIBS'
  !
  !	"CC1" Linker options file
***************
*** 124,132 ****
  !
  toplev,c-parse_tab,tree,print-tree,c-decl,c-typeck,c-convert,stor-layout,fold-const,-
! varasm,rtl,expr,stmt,expmed,explow,optabs,symout,dbxout,emit-rtl,insn-emit,-
  jump,cse,loop,flow,stupid,combine,regclass,local-alloc,global-alloc,reload,-
  reload1,insn-peep,final,recog,insn-recog,insn-extract,insn-output,obstack,-
! integrate,caller-save,-
! gnu_cc:[000000]gcclib/lib,sys$share:vaxcrtl/lib
  $!
  $!	Done
--- 138,145 ----
  !
  toplev,c-parse_tab,tree,print-tree,c-decl,c-typeck,c-convert,stor-layout,fold-const,-
! varasm,rtl,rtlanal,expr,stmt,expmed,explow,optabs,symout,dbxout,emit-rtl,insn-emit,-
  jump,cse,loop,flow,stupid,combine,regclass,local-alloc,global-alloc,reload,-
  reload1,insn-peep,final,recog,insn-recog,insn-extract,insn-output,obstack,-
! integrate,caller-save
  $!
  $!	Done
diff -rc2N gcc-1.35/make-cccp.com gcc-1.36/make-cccp.com
*** gcc-1.35/make-cccp.com	Sun Jan 22 04:59:57 1989
--- gcc-1.36/make-cccp.com	Tue Jul 11 19:16:58 1989
***************
*** 2,7 ****
  $!	Build the GNU "C" pre-processor on VMS
  $!
  $ if "''p1'" .eqs. "LINK" then goto Link
! $ gcc/debug cccp.c
  $ t1:='f$search("CEXP.C")'
  $ if "''t1'" .eqs. "" then goto 10$
--- 2,24 ----
  $!	Build the GNU "C" pre-processor on VMS
  $!
+ $
+ $!
+ $!	C compiler
+ $!
+ $ CC	:=	gcc
+ $!
+ $!	Compiler options
+ $!
+ $ CFLAGS =	"/debug/inc=([],[.config])"
+ $!
+ $!	Link options
+ $!
+ $ LDFLAGS :=	/nomap
+ $!
+ $!	Link libraries
+ $!
+ $ LIBS :=	gnu_cc:[000000]gcclib/libr,sys$share:vaxcrtl/libr
  $ if "''p1'" .eqs. "LINK" then goto Link
! $ 'CC 'CFLAGS cccp.c
  $ t1:='f$search("CEXP.C")'
  $ if "''t1'" .eqs. "" then goto 10$
***************
*** 16,27 ****
  $ 20$:
  $!
! $ gcc/debug cexp.c
! $ gcc/debug version.c
  $ Link:
! $ link/exe=gcc-cpp/nomap sys$input:/opt
! !
! !	Linker options file for linking the GNU "C" pre-processor
! !
! cccp,cexp,version,gnu_cc:[000000]gcclib/lib,sys$share:vaxcrtl/lib
  $!
  $!	Done
--- 33,40 ----
  $ 20$:
  $!
! $ 'CC 'CFLAGS cexp.c
! $ 'CC 'CFLAGS version.c
  $ Link:
! $ link 'LDFLAGS /exe=gcc-cpp cccp,cexp,version,'LIBS'
  $!
  $!	Done
diff -rc2N gcc-1.35/math-68881.h gcc-1.36/math-68881.h
*** gcc-1.35/math-68881.h	Wed Dec 31 19:00:00 1969
--- gcc-1.36/math-68881.h	Sat May 20 15:19:13 1989
***************
*** 0 ****
--- 1,462 ----
+ /******************************************************************\
+ *								   *
+ *  <math-68881.h>		last modified: 18 May 1989.	   *
+ *								   *
+ *  Copyright (C) 1989 by Matthew Self.				   *
+ *  You may freely distribute verbatim copies of this software	   *
+ *  provided that this copyright notice is retained in all copies.  *
+ *  You may distribute modifications to this software under the     *
+ *  conditions above if you also clearly note such modifications    *
+ *  with their author and date.			   	     	   *
+ *								   *
+ *  Note:  errno is not set to EDOM when domain errors occur for    *
+ *  most of these functions.  Rather, it is assumed that the	   *
+ *  68881's OPERR exception will be enabled and handled		   *
+ *  appropriately by the	operating system.  Similarly, overflow	   *
+ *  and underflow do not set errno to ERANGE.			   *
+ *								   *
+ *  Send bugs to Matthew Self (self@bayes.arc.nasa.gov).		   *
+ *								   *
+ \******************************************************************/
+ 
+ #include <errno.h>
+ 
+ #ifndef HUGE_VAL
+ #define HUGE_VAL							\
+ ({									\
+   double huge_val;							\
+ 									\
+   __asm ("fmove%.d #0x7ff0000000000000,%0"	/* Infinity */		\
+ 	 : "=f" (huge_val)						\
+ 	 : /* no inputs */);						\
+   huge_val;								\
+ })
+ #endif
+ 
+ __inline static const double sin (double x)
+ {
+   double value;
+ 
+   __asm ("fsin%.x %1,%0"
+ 	 : "=f" (value)
+ 	 : "f" (x));
+   return value;
+ }
+ 
+ __inline static const double cos (double x)
+ {
+   double value;
+ 
+   __asm ("fcos%.x %1,%0"
+ 	 : "=f" (value)
+ 	 : "f" (x));
+   return value;
+ }
+ 
+ __inline static const double tan (double x)
+ {
+   double value;
+ 
+   __asm ("ftan%.x %1,%0"
+ 	 : "=f" (value)
+ 	 : "f" (x));
+   return value;
+ }
+ 
+ __inline static const double asin (double x)
+ {
+   double value;
+ 
+   __asm ("fasin%.x %1,%0"
+ 	 : "=f" (value)
+ 	 : "f" (x));
+   return value;
+ }
+ 
+ __inline static const double acos (double x)
+ {
+   double value;
+ 
+   __asm ("facos%.x %1,%0"
+ 	 : "=f" (value)
+ 	 : "f" (x));
+   return value;
+ }
+ 
+ __inline static const double atan (double x)
+ {
+   double value;
+ 
+   __asm ("fatan%.x %1,%0"
+ 	 : "=f" (value)
+ 	 : "f" (x));
+   return value;
+ }
+ 
+ __inline static const double atan2 (double y, double x)
+ {
+   double pi, pi_over_2;
+ 
+   __asm ("fmovecr%.x %#0,%0"		/* extended precision pi */
+ 	 : "=f" (pi)
+ 	 : /* no inputs */ );
+   __asm ("fscale%.b %#-1,%0"		/* no loss of accuracy */
+ 	 : "=f" (pi_over_2)
+ 	 : "0" (pi));
+   if (x > 0)
+     {
+       if (y > 0)
+ 	{
+ 	  if (x > y)
+ 	    return atan (y / x);
+ 	  else
+ 	    return pi_over_2 - atan (x / y);
+ 	}
+       else
+ 	{
+ 	  if (x > -y)
+ 	    return atan (y / x);
+ 	  else
+ 	    return - pi_over_2 - atan (x / y);
+ 	}
+     }
+   else
+     {
+       if (y > 0)
+ 	{
+ 	  if (-x > y)
+ 	    return pi + atan (y / x);
+ 	  else
+ 	    return pi_over_2 - atan (x / y);
+ 	}
+       else
+ 	{
+ 	  if (-x > -y)
+ 	    return - pi + atan (y / x);
+ 	  else if (y < 0)
+ 	    return - pi_over_2 - atan (x / y);
+ 	  else
+ 	    {
+ 	      double value;
+ 
+ 	      errno = EDOM;
+ 	      __asm ("fmove%.d %#0rnan,%0" 	/* quiet NaN */
+ 		     : "=f" (value)
+ 		     : /* no inputs */);
+ 	      return value;
+ 	    }
+ 	}
+     }
+ }
+ 
+ __inline static const double sinh (double x)
+ {
+   double value;
+ 
+   __asm ("fsinh%.x %1,%0"
+ 	 : "=f" (value)
+ 	 : "f" (x));
+   return value;
+ }
+ 
+ __inline static const double cosh (double x)
+ {
+   double value;
+ 
+   __asm ("fcosh%.x %1,%0"
+ 	 : "=f" (value)
+ 	 : "f" (x));
+   return value;
+ }
+ 
+ __inline static const double tanh (double x)
+ {
+   double value;
+ 
+   __asm ("ftanh%.x %1,%0"
+ 	 : "=f" (value)
+ 	 : "f" (x));
+   return value;
+ }
+ 
+ __inline static const double atanh (double x)
+ {
+   double value;
+ 
+   __asm ("fatanh%.x %1,%0"
+ 	 : "=f" (value)
+ 	 : "f" (x));
+   return value;
+ }
+ 
+ __inline static const double exp (double x)
+ {
+   double value;
+ 
+   __asm ("fetox%.x %1,%0"
+ 	 : "=f" (value)
+ 	 : "f" (x));
+   return value;
+ }
+ 
+ __inline static const double expm1 (double x)
+ {
+   double value;
+ 
+   __asm ("fetoxm1%.x %1,%0"
+ 	 : "=f" (value)
+ 	 : "f" (x));
+   return value;
+ }
+ 
+ __inline static const double log (double x)
+ {
+   double value;
+ 
+   __asm ("flogn%.x %1,%0"
+ 	 : "=f" (value)
+ 	 : "f" (x));
+   return value;
+ }
+ 
+ __inline static const double log1p (double x)
+ {
+   double value;
+ 
+   __asm ("flognp1%.x %1,%0"
+ 	 : "=f" (value)
+ 	 : "f" (x));
+   return value;
+ }
+ 
+ __inline static const double log10 (double x)
+ {
+   double value;
+ 
+   __asm ("flog10%.x %1,%0"
+ 	 : "=f" (value)
+ 	 : "f" (x));
+   return value;
+ }
+ 
+ __inline static const double sqrt (double x)
+ {
+   double value;
+ 
+   __asm ("fsqrt%.x %1,%0"
+ 	 : "=f" (value)
+ 	 : "f" (x));
+   return value;
+ }
+ 
+ __inline static const double pow (const double x, const double y)
+ {
+   if (x > 0)
+     return exp (y * log (x));
+   else if (x == 0)
+     {
+       if (y > 0)
+ 	return 0.0;
+       else
+ 	{
+ 	  double value;
+ 
+ 	  errno = EDOM;
+ 	  __asm ("fmove%.d %#0rnan,%0"		/* quiet NaN */
+ 		 : "=f" (value)
+ 		 : /* no inputs */);
+ 	  return value;
+ 	}
+     }
+   else
+     {
+       double temp;
+ 
+       __asm ("fintrz%.x %1,%0"
+ 	     : "=f" (temp)			/* integer-valued float */
+ 	     : "f" (y));
+       if (y == temp)
+         {
+ 	  int i = (int) y;
+ 	  
+ 	  if (i & 1 == 0)			/* even */
+ 	    return exp (y * log (x));
+ 	  else
+ 	    return - exp (y * log (x));
+         }
+       else
+         {
+ 	  double value;
+ 
+ 	  errno = EDOM;
+ 	  __asm ("fmove%.d %#0rnan,%0"		/* quiet NaN */
+ 		 : "=f" (value)
+ 		 : /* no inputs */);
+ 	  return value;
+         }
+     }
+ }
+ 
+ __inline static const double fabs (double x)
+ {
+   double value;
+ 
+   __asm ("fabs%.x %1,%0"
+ 	 : "=f" (value)
+ 	 : "f" (x));
+   return value;
+ }
+ 
+ __inline static const double ceil (double x)
+ {
+   int rounding_mode, round_up;
+   double value;
+ 
+   __asm volatile ("fmove%.l fpcr,%0"
+ 		  : "=dm" (rounding_mode)
+ 		  : /* no inputs */ );
+   round_up = rounding_mode | 0x30;
+   __asm volatile ("fmove%.l %0,fpcr"
+ 		  : /* no outputs */
+ 		  : "dmi" (round_up));
+   __asm volatile ("fint%.x %1,%0"
+ 		  : "=f" (value)
+ 		  : "f" (x));
+   __asm volatile ("fmove%.l %0,fpcr"
+ 		  : /* no outputs */
+ 		  : "dmi" (rounding_mode));
+   return value;
+ }
+ 
+ __inline static const double floor (double x)
+ {
+   int rounding_mode, round_down;
+   double value;
+ 
+   __asm volatile ("fmove%.l fpcr,%0"
+ 		  : "=dm" (rounding_mode)
+ 		  : /* no inputs */ );
+   round_down = (rounding_mode & ~0x10)
+ 		| 0x20;
+   __asm volatile ("fmove%.l %0,fpcr"
+ 		  : /* no outputs */
+ 		  : "dmi" (round_down));
+   __asm volatile ("fint%.x %1,%0"
+ 		  : "=f" (value)
+ 		  : "f" (x));
+   __asm volatile ("fmove%.l %0,fpcr"
+ 		  : /* no outputs */
+ 		  : "dmi" (rounding_mode));
+   return value;
+ }
+ 
+ __inline static const double rint (double x)
+ {
+   int rounding_mode, round_nearest;
+   double value;
+ 
+   __asm volatile ("fmove%.l fpcr,%0"
+ 		  : "=dm" (rounding_mode)
+ 		  : /* no inputs */ );
+   round_nearest = rounding_mode & ~0x30;
+   __asm volatile ("fmove%.l %0,fpcr"
+ 		  : /* no outputs */
+ 		  : "dmi" (round_nearest));
+   __asm volatile ("fint%.x %1,%0"
+ 		  : "=f" (value)
+ 		  : "f" (x));
+   __asm volatile ("fmove%.l %0,fpcr"
+ 		  : /* no outputs */
+ 		  : "dmi" (rounding_mode));
+   return value;
+ }
+ 
+ __inline static const double fmod (double x, double y)
+ {
+   double value;
+ 
+   __asm ("fmod%.x %2,%0"
+ 	 : "=f" (value)
+ 	 : "0" (x),
+ 	   "f" (y));
+   return value;
+ }
+ 
+ __inline static const double drem (double x, double y)
+ {
+   double value;
+ 
+   __asm ("frem%.x %2,%0"
+ 	 : "=f" (value)
+ 	 : "0" (x),
+ 	   "f" (y));
+   return value;
+ }
+ 
+ __inline static const double scalb (double x, int n)
+ {
+   double value;
+ 
+   __asm ("fscale%.l %2,%0"
+ 	 : "=f" (value)
+ 	 : "0" (x),
+ 	   "dmi" (n));
+   return value;
+ }
+ 
+ __inline static double logb (double x)
+ {
+   double exponent;
+ 
+   __asm ("fgetexp%.x %1,%0"
+ 	 : "=f" (exponent)
+ 	 : "f" (x));
+   return exponent;
+ }
+ 
+ __inline static const double ldexp (double x, int n)
+ {
+   double value;
+ 
+   __asm ("fscale%.l %2,%0"
+ 	 : "=f" (value)
+ 	 : "0" (x),
+ 	   "dmi" (n));
+   return value;
+ }
+ 
+ __inline static double frexp (double x, int *exp)
+ {
+   double float_exponent;
+   int int_exponent;
+   double mantissa;
+ 
+   __asm ("fgetexp%.x %1,%0"
+ 	 : "=f" (float_exponent) 	/* integer-valued float */
+ 	 : "f" (x));
+   int_exponent = (int) float_exponent;
+   __asm ("fgetman%.x %1,%0"
+ 	 : "=f" (mantissa)		/* 1.0 <= mantissa < 2.0 */
+ 	 : "f" (x));
+   if (mantissa != 0)
+     {
+       __asm ("fscale%.b %#-1,%0"
+ 	     : "=f" (mantissa)		/* mantissa /= 2.0 */
+ 	     : "0" (mantissa));
+       int_exponent += 1;
+     }
+   *exp = int_exponent;
+   return mantissa;
+ }
+ 
+ __inline static double modf (double x, double *ip)
+ {
+   double temp;
+ 
+   __asm ("fintrz%.x %1,%0"
+ 	 : "=f" (temp)			/* integer-valued float */
+ 	 : "f" (x));
+   *ip = temp;
+   return x - temp;
+ }
+ 
diff -rc2N gcc-1.35/move-if-change gcc-1.36/move-if-change
*** gcc-1.35/move-if-change	Sat Jun  6 00:45:04 1987
--- gcc-1.36/move-if-change	Sat Jun  3 22:30:46 1989
***************
*** 1,2 ****
--- 1,3 ----
+ #!/bin/sh
  if
  test -r $2
diff -rc2N gcc-1.35/obstack.c gcc-1.36/obstack.c
*** gcc-1.35/obstack.c	Tue Mar 28 14:42:59 1989
--- gcc-1.36/obstack.c	Sun Sep 24 08:14:55 1989
***************
*** 108,114 ****
    register int obj_size = h->next_free - h->object_base;
    register int i;
  
    /* Compute size for new chunk.  */
!   new_size = (obj_size + length) << 1;
    if (new_size < h->chunk_size)
      new_size = h->chunk_size;
--- 108,115 ----
    register int obj_size = h->next_free - h->object_base;
    register int i;
+   int already;
  
    /* Compute size for new chunk.  */
!   new_size = (obj_size + length) + (obj_size >> 3) + 100;
    if (new_size < h->chunk_size)
      new_size = h->chunk_size;
***************
*** 120,129 ****
  
    /* Move the existing object to the new chunk.
!      Word at a time is fast and is safe because these
!      structures are aligned at least that much.  */
!   for (i = (obj_size + sizeof (COPYING_UNIT) - 1) / sizeof (COPYING_UNIT) - 1;
!        i >= 0; i--)
!     ((COPYING_UNIT *)new_chunk->contents)[i]
!       = ((COPYING_UNIT *)h->object_base)[i];
  
    h->object_base = new_chunk->contents;
--- 121,142 ----
  
    /* Move the existing object to the new chunk.
!      Word at a time is fast and is safe if the object
!      is sufficiently aligned.  */
!   if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
!     {
!       for (i = obj_size / sizeof (COPYING_UNIT) - 1;
! 	   i >= 0; i--)
! 	((COPYING_UNIT *)new_chunk->contents)[i]
! 	  = ((COPYING_UNIT *)h->object_base)[i];
!       /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
! 	 but that can cross a page boundary on a machine
! 	 which does not do strict alignment for COPYING_UNITS.  */
!       already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
!     }
!   else
!     already = 0;
!   /* Copy remaining bytes one by one.  */
!   for (i = already; i < obj_size; i++)
!     new_chunk->contents[i] = h->object_base[i];
  
    h->object_base = new_chunk->contents;
***************
*** 185,188 ****
--- 198,213 ----
      abort ();
  }
+ 
+ /* Let same .o link with output of gcc and other compilers.  */
+ 
+ #ifdef __STDC__
+ void
+ _obstack_free (h, obj)
+      struct obstack *h;
+      POINTER obj;
+ {
+   obstack_free (h, obj);
+ }
+ #endif
  \f


  #if 0
diff -rc2N gcc-1.35/obstack.h gcc-1.36/obstack.h
*** gcc-1.35/obstack.h	Wed Feb 22 11:45:35 1989
--- gcc-1.36/obstack.h	Sun Sep 24 08:14:55 1989
***************
*** 47,51 ****
  
  One motivation for this package is the problem of growing char strings
! in symbol tables.  Unless you are "facist pig with a read-only mind"
  [Gosper's immortal quote from HAKMEM item 154, out of context] you
  would not like to put any arbitrary upper limit on the length of your
--- 47,51 ----
  
  One motivation for this package is the problem of growing char strings
! in symbol tables.  Unless you are "fascist pig with a read-only mind"
  [Gosper's immortal quote from HAKMEM item 154, out of context] you
  would not like to put any arbitrary upper limit on the length of your
***************
*** 66,70 ****
  
  The way we do this is to take a large chunk, allocating memory from
! low addresses.  When you want to build a aymbol in the chunk you just
  add chars above the current "high water mark" in the chunk.  When you
  have finished adding chars, because you got to the end of the symbol,
--- 66,70 ----
  
  The way we do this is to take a large chunk, allocating memory from
! low addresses.  When you want to build a symbol in the chunk you just
  add chars above the current "high water mark" in the chunk.  When you
  have finished adding chars, because you got to the end of the symbol,
***************
*** 83,88 ****
  When the chars burst over a chunk boundary, we allocate a larger
  chunk, and then copy the partly formed object from the end of the old
! chunk to the beggining of the new larger chunk.  We then carry on
! accreting characters to the end of the object as we normaly would.
  
  A special macro is provided to add a single char at a time to a
--- 83,88 ----
  When the chars burst over a chunk boundary, we allocate a larger
  chunk, and then copy the partly formed object from the end of the old
! chunk to the beginning of the new larger chunk.  We then carry on
! accreting characters to the end of the object as we normally would.
  
  A special macro is provided to add a single char at a time to a
***************
*** 162,165 ****
--- 162,167 ----
  
  void obstack_1grow (struct obstack *obstack, int data_char);
+ void obstack_ptr_grow (struct obstack *obstack, void *data);
+ void obstack_int_grow (struct obstack *obstack, int data);
  
  void * obstack_finish (struct obstack *obstack);
***************
*** 169,172 ****
--- 171,176 ----
  int obstack_room (struct obstack *obstack);
  void obstack_1grow_fast (struct obstack *obstack, int data_char);
+ void obstack_ptr_grow_fast (struct obstack *obstack, void *data);
+ void obstack_int_grow_fast (struct obstack *obstack, int data);
  void obstack_blank_fast (struct obstack *obstack, int size);
  
***************
*** 250,253 ****
--- 254,278 ----
     (void) 0; })
  
+ /* These assume that the obstack alignment is good enough for pointers or ints,
+    and that the data added so far to the current object
+    shares that much alignment.  */
+    
+ #define obstack_ptr_grow(OBSTACK,datum)					\
+ ({ struct obstack *__o = (OBSTACK);					\
+    ((__o->next_free + sizeof (void *) > __o->chunk_limit)		\
+     ? _obstack_newchunk (__o, sizeof (void *)) : 0),			\
+    *((void **)__o->next_free)++ = ((void *)datum);			\
+    (void) 0; })
+ 
+ #define obstack_int_grow(OBSTACK,datum)					\
+ ({ struct obstack *__o = (OBSTACK);					\
+    ((__o->next_free + sizeof (int) > __o->chunk_limit)			\
+     ? _obstack_newchunk (__o, sizeof (int)) : 0),			\
+    *((int *)__o->next_free)++ = ((int)datum);				\
+    (void) 0; })
+ 
+ #define obstack_ptr_grow_fast(h,aptr) (*((void **)(h)->next_free)++ = (void *)aptr)
+ #define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint)
+ 
  #define obstack_blank(OBSTACK,length)					\
  ({ struct obstack *__o = (OBSTACK);					\
***************
*** 324,327 ****
--- 349,365 ----
     ? _obstack_newchunk ((h), 1) : 0),					\
    *((h)->next_free)++ = (datum))
+ 
+ #define obstack_ptr_grow(h,datum)					\
+ ( (((h)->next_free + sizeof (char *) > (h)->chunk_limit)		\
+    ? _obstack_newchunk ((h), sizeof (char *)) : 0),			\
+   *((char **)(h)->next_free)++ = ((char *)datum))
+ 
+ #define obstack_int_grow(h,datum)					\
+ ( (((h)->next_free + sizeof (int) > (h)->chunk_limit)			\
+    ? _obstack_newchunk ((h), sizeof (int)) : 0),			\
+   *((int *)(h)->next_free)++ = ((int)datum))
+ 
+ #define obstack_ptr_grow_fast(h,aptr) (*((char **)(h)->next_free)++ = (char *)aptr)
+ #define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint)
  
  #define obstack_blank(h,length)						\
diff -rc2N gcc-1.35/optabs.c gcc-1.36/optabs.c
*** gcc-1.35/optabs.c	Tue Apr  4 19:47:48 1989
--- gcc-1.36/optabs.c	Tue Sep  5 16:22:31 1989
***************
*** 113,117 ****
    enum machine_mode wider_mode;
    register rtx temp;
!   rtx last = get_last_insn ();
  
    class = GET_MODE_CLASS (mode);
--- 113,117 ----
    enum machine_mode wider_mode;
    register rtx temp;
!   rtx last;
  
    class = GET_MODE_CLASS (mode);
***************
*** 135,138 ****
--- 135,141 ----
      }
  
+   /* Record where to delete back to if we backtrack.  */
+   last = get_last_insn ();
+ 
    /* If operation is commutative,
       try to make the first operand a register.
***************
*** 164,168 ****
    /* If we can do it with a three-operand insn, do so.  */
  
!   if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
      {
        int icode = (int) binoptab->handlers[(int) mode].insn_code;
--- 167,172 ----
    /* If we can do it with a three-operand insn, do so.  */
  
!   if (methods != OPTAB_MUST_WIDEN
!       && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
      {
        int icode = (int) binoptab->handlers[(int) mode].insn_code;
***************
*** 227,230 ****
--- 231,235 ----
  	funexp = copy_to_mode_reg (Pmode, funexp);
  #endif
+ 
        insn_before = get_last_insn ();
        if (insn_before == 0)
***************
*** 234,240 ****
  	 on getting a SYMBOL_REF.  But cse will make this SYMBOL_REF
  	 be replaced with the copy we made just above.  */
        emit_library_call (gen_rtx (SYMBOL_REF, Pmode,
  				  binoptab->handlers[(int) mode].lib_call),
! 			 mode, 2, op0, mode, op1, mode);
        target = hard_libcall_value (mode);
        temp = copy_to_reg (target);
--- 239,247 ----
  	 on getting a SYMBOL_REF.  But cse will make this SYMBOL_REF
  	 be replaced with the copy we made just above.  */
+       /* Pass 1 for NO_QUEUE so we don't lose any increments
+ 	 if the libcall is cse'd or moved.  */
        emit_library_call (gen_rtx (SYMBOL_REF, Pmode,
  				  binoptab->handlers[(int) mode].lib_call),
! 			 1, mode, 2, op0, mode, op1, mode);
        target = hard_libcall_value (mode);
        temp = copy_to_reg (target);
***************
*** 258,262 ****
    /* It can't be done in this mode.  Can we do it in a wider mode?  */
  
!   if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN))
      return 0;			/* Caller says, don't even try.  */
  
--- 265,270 ----
    /* It can't be done in this mode.  Can we do it in a wider mode?  */
  
!   if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
! 	 || methods == OPTAB_MUST_WIDEN))
      return 0;			/* Caller says, don't even try.  */
  
***************
*** 283,298 ****
  	    {
  	      rtx xop0 = op0, xop1 = op1;
  
  	      if (GET_MODE (xop0) != VOIDmode)
  		{
! 		  temp = gen_reg_rtx (wider_mode);
! 		  convert_move (temp, xop0, unsignedp);
! 		  xop0 = temp;
  		}
  	      if (GET_MODE (xop1) != VOIDmode)
  		{
! 		  temp = gen_reg_rtx (wider_mode);
! 		  convert_move (temp, xop1, unsignedp);
! 		  xop1 = temp;
  		}
  
--- 291,334 ----
  	    {
  	      rtx xop0 = op0, xop1 = op1;
+ 	      int no_extend = 0;
+ 
+ 	      /* For certain operations, we need not actually extend
+ 		 the narrow operands, as long as we will truncate
+ 		 the results to the same narrowness.  */
+ 
+ 	      if (binoptab == ior_optab || binoptab == and_optab
+ 		  || binoptab == xor_optab || binoptab == andcb_optab
+ 		  || binoptab == add_optab || binoptab == sub_optab
+ 		  || binoptab == smul_optab || binoptab == umul_optab
+ 		  || binoptab == ashl_optab || binoptab == lshl_optab)
+ 		no_extend = 1;
  
  	      if (GET_MODE (xop0) != VOIDmode)
  		{
! 		  if (no_extend)
! 		    {
! 		      temp = force_reg (GET_MODE (xop0), xop0);
! 		      xop0 = gen_rtx (SUBREG, wider_mode, temp, 0);
! 		    }
! 		  else
! 		    {
! 		      temp = gen_reg_rtx (wider_mode);
! 		      convert_move (temp, xop0, unsignedp);
! 		      xop0 = temp;
! 		    }
  		}
  	      if (GET_MODE (xop1) != VOIDmode)
  		{
! 		  if (no_extend)
! 		    {
! 		      temp = force_reg (GET_MODE (xop1), xop1);
! 		      xop1 = gen_rtx (SUBREG, wider_mode, temp, 0);
! 		    }
! 		  else
! 		    {
! 		      temp = gen_reg_rtx (wider_mode);
! 		      convert_move (temp, xop1, unsignedp);
! 		      xop1 = temp;
! 		    }
  		}
  
***************
*** 543,546 ****
--- 579,583 ----
  	funexp = copy_to_mode_reg (Pmode, funexp);
  #endif
+ 
        insn_before = get_last_insn ();
  
***************
*** 548,554 ****
  	 on getting a SYMBOL_REF.  But cse will make this SYMBOL_REF
  	 be replaced with the copy we made just above.  */
        emit_library_call (gen_rtx (SYMBOL_REF, Pmode,
  				  unoptab->handlers[(int) mode].lib_call),
! 			 mode, 1, op0, mode);
        target = hard_libcall_value (mode);
        temp = copy_to_reg (target);
--- 585,593 ----
  	 on getting a SYMBOL_REF.  But cse will make this SYMBOL_REF
  	 be replaced with the copy we made just above.  */
+       /* Pass 1 for NO_QUEUE so we don't lose any increments
+ 	 if the libcall is cse'd or moved.  */
        emit_library_call (gen_rtx (SYMBOL_REF, Pmode,
  				  unoptab->handlers[(int) mode].lib_call),
! 			 1, mode, 1, op0, mode);
        target = hard_libcall_value (mode);
        temp = copy_to_reg (target);
***************
*** 619,623 ****
    enum machine_mode mode0 = insn_operand_mode[icode][1];
    rtx insn;
!   rtx prev_insn = get_last_insn ();
  
    temp = target = protect_from_queue (target, 1);
--- 658,662 ----
    enum machine_mode mode0 = insn_operand_mode[icode][1];
    rtx insn;
!   rtx prev_insn;
  
    temp = target = protect_from_queue (target, 1);
***************
*** 637,640 ****
--- 676,680 ----
      temp = gen_reg_rtx (GET_MODE (temp));
  
+   prev_insn = get_last_insn ();
    insn = emit_insn (GEN_FCN (icode) (temp, op0));
  
***************
*** 718,722 ****
        if (HAVE_cmpstrqi
  	  && GET_CODE (size) == CONST_INT
! 	  && INTVAL (size) < (1 << BITS_PER_UNIT))
  	emit_insn (gen_cmpstrqi (x, y, size,
  				 gen_rtx (CONST_INT, VOIDmode, align)));
--- 758,762 ----
        if (HAVE_cmpstrqi
  	  && GET_CODE (size) == CONST_INT
! 	  && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
  	emit_insn (gen_cmpstrqi (x, y, size,
  				 gen_rtx (CONST_INT, VOIDmode, align)));
***************
*** 726,730 ****
        if (HAVE_cmpstrhi
  	  && GET_CODE (size) == CONST_INT
! 	  && INTVAL (size) < (1 << BITS_PER_UNIT))
  	emit_insn (gen_cmpstrhi (x, y, size,
  				 gen_rtx (CONST_INT, VOIDmode, align)));
--- 766,770 ----
        if (HAVE_cmpstrhi
  	  && GET_CODE (size) == CONST_INT
! 	  && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
  	emit_insn (gen_cmpstrhi (x, y, size,
  				 gen_rtx (CONST_INT, VOIDmode, align)));
***************
*** 739,747 ****
  	{
  #ifdef TARGET_MEM_FUNCTIONS
! 	  emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "memcmp"),
! 			     SImode, 3, x, Pmode, y, Pmode, size, Pmode);
  #else
! 	  emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "bcmp"),
! 			     SImode, 3, x, Pmode, y, Pmode, size, Pmode);
  #endif
  	  emit_cmp_insn (hard_libcall_value (SImode), const0_rtx, 0, 0, 0);
--- 779,791 ----
  	{
  #ifdef TARGET_MEM_FUNCTIONS
! 	  emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "memcmp"), 0, 
! 			     SImode, 3,
! 			     XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
! 			     size, Pmode);
  #else
! 	  emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "bcmp"), 0,
! 			     SImode, 3,
! 			     XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
! 			     size, Pmode);
  #endif
  	  emit_cmp_insn (hard_libcall_value (SImode), const0_rtx, 0, 0, 0);
***************
*** 752,756 ****
    /* Handle some compares against zero.  */
  
!   if ((y == const0_rtx || y == fconst0_rtx || y == dconst0_rtx)
        && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
      {
--- 796,800 ----
    /* Handle some compares against zero.  */
  
!   if (y == CONST0_RTX (mode)
        && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
      {
***************
*** 807,811 ****
  	      x = convert_to_mode (wider_mode, x, unsignedp);
  	      y = convert_to_mode (wider_mode, y, unsignedp);
! 	      emit_cmp_insn (x, y, 0, unsignedp);
  	      return;
  	    }
--- 851,855 ----
  	      x = convert_to_mode (wider_mode, x, unsignedp);
  	      y = convert_to_mode (wider_mode, y, unsignedp);
! 	      emit_cmp_insn (x, y, 0, unsignedp, align);
  	      return;
  	    }
***************
*** 823,827 ****
  	string = ucmp_optab->handlers[(int) mode].lib_call;
  
!       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, string),
  			 SImode, 2, x, mode, y, mode);
  
--- 867,871 ----
  	string = ucmp_optab->handlers[(int) mode].lib_call;
  
!       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, string), 0,
  			 SImode, 2, x, mode, y, mode);
  
***************
*** 851,855 ****
  	      x = convert_to_mode (wider_mode, x, unsignedp);
  	      y = convert_to_mode (wider_mode, y, unsignedp);
! 	      emit_cmp_insn (x, y, 0, unsignedp);
  	    }
  	}
--- 895,899 ----
  	      x = convert_to_mode (wider_mode, x, unsignedp);
  	      y = convert_to_mode (wider_mode, y, unsignedp);
! 	      emit_cmp_insn (x, y, 0, unsignedp, align);
  	    }
  	}
***************
*** 1143,1147 ****
      }
    else if (GET_MODE (to) == SFmode
! 	   && ((icode = can_float_p (GET_MODE (from), DFmode))
  	       != CODE_FOR_nothing))
      {
--- 1187,1191 ----
      }
    else if (GET_MODE (to) == SFmode
! 	   && ((icode = can_float_p (DFmode, GET_MODE (from)))
  	       != CODE_FOR_nothing))
      {
***************
*** 1186,1190 ****
  				  (GET_MODE (from) == SImode ? "__floatsidf"
  				   : "__floatdidf")),
! 			 DFmode, 1, from, GET_MODE (from));
        to = copy_to_reg (hard_libcall_value (DFmode));
      }
--- 1230,1234 ----
  				  (GET_MODE (from) == SImode ? "__floatsidf"
  				   : "__floatdidf")),
! 			 0, DFmode, 1, from, GET_MODE (from));
        to = copy_to_reg (hard_libcall_value (DFmode));
      }
***************
*** 1258,1261 ****
--- 1302,1346 ----
  	}
  
+ #if 0  /* Turned off.  It fails because the positive numbers
+ 	  that become temporarily negative are rounded up instead of down.  */
+ 
+       /* If no insns for unsigned conversion,
+ 	 we can go via a signed number.
+ 	 But make sure we won't overflow in the compiler.  */
+       if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_INT
+ 	  /* Make sure we won't lose significant bits doing this.  */
+ 	  && GET_MODE_BITSIZE (GET_MODE (from)) > GET_MODE_BITSIZE (GET_MODE (to)))
+ 	{
+ 	  icode = can_fix_p (GET_MODE (to), GET_MODE (from),
+ 			     0, &must_trunc);
+ 
+ 	  if (icode != CODE_FOR_nothing)
+ 	    {
+ 	      REAL_VALUE_TYPE offset;
+ 	      rtx temp, temp1;
+ 	      int bitsize = GET_MODE_BITSIZE (GET_MODE (to));
+ 
+ 	      if (must_trunc)
+ 		from = ftruncify (from);
+ 
+ 	      /* Subtract 2**(N-1), convert to signed number,
+ 		 then add 2**(N-1).  */
+ 	      offset = REAL_VALUE_LDEXP (1.0, bitsize - 1);
+ 	      temp = expand_binop (GET_MODE (from), sub_optab, from,
+ 				   immed_real_const_1 (offset, GET_MODE (from)),
+ 				   0, 0, OPTAB_LIB_WIDEN);
+ 
+ 	      temp1 = gen_reg_rtx (GET_MODE (to));
+ 	      emit_unop_insn (icode, temp1, temp, FIX);
+ 	      temp = expand_binop (GET_MODE (to), add_optab, temp1,
+ 				   gen_rtx (CONST_INT, VOIDmode,
+ 					    1 << (bitsize - 1)),
+ 				   to, 1, OPTAB_LIB_WIDEN);
+ 	      if (temp != to)
+ 		emit_move_insn (to, temp);
+ 	      return;
+ 	    }
+ 	}
+ #endif
        icode = can_fix_p (DImode, GET_MODE (from), unsignedp, &must_trunc);
  
***************
*** 1292,1296 ****
  				  unsignedp ? "__fixunsdfsi"
  				  : "__fixdfsi"),
! 			 SImode, 1, from, DFmode);
        target = hard_libcall_value (SImode);
      }
--- 1377,1381 ----
  				  unsignedp ? "__fixunsdfsi"
  				  : "__fixdfsi"),
! 			 0, SImode, 1, from, DFmode);
        target = hard_libcall_value (SImode);
      }
***************
*** 1300,1304 ****
  				  unsignedp ? "__fixunsdfdi"
  				  : "__fixdfdi"),
! 			 DImode, 1, from, DFmode);
        target = hard_libcall_value (DImode);
      }
--- 1385,1389 ----
  				  unsignedp ? "__fixunsdfdi"
  				  : "__fixdfdi"),
! 			 0, DImode, 1, from, DFmode);
        target = hard_libcall_value (DImode);
      }
***************
*** 1965,1968 ****
--- 2050,2057 ----
      mov_optab->handlers[(int) DImode].insn_code = CODE_FOR_movdi;
  #endif
+ #ifdef HAVE_movti
+   if (HAVE_movti)
+     mov_optab->handlers[(int) TImode].insn_code = CODE_FOR_movti;
+ #endif
  #ifdef HAVE_movsf
    if (HAVE_movsf)
***************
*** 1972,1975 ****
--- 2061,2068 ----
    if (HAVE_movdf)
      mov_optab->handlers[(int) DFmode].insn_code = CODE_FOR_movdf;
+ #endif
+ #ifdef HAVE_movtf
+   if (HAVE_movtf)
+     mov_optab->handlers[(int) TFmode].insn_code = CODE_FOR_movtf;
  #endif
  
diff -rc2N gcc-1.35/output.h gcc-1.36/output.h
*** gcc-1.35/output.h	Wed Feb 22 11:56:03 1989
--- gcc-1.36/output.h	Mon Jul 17 16:22:12 1989
***************
*** 29,34 ****
  int nonimmediate_operand ();
  
! int offsetable_address_p ();
! rtx adj_offsetable_operand ();
  
  /* Output a string of assembler code.
--- 29,34 ----
  int nonimmediate_operand ();
  
! int offsettable_address_p ();
! rtx adj_offsettable_operand ();
  
  /* Output a string of assembler code.
***************
*** 39,40 ****
--- 39,95 ----
     of the constraints was actually satisfied.  */
  int which_alternative;
+ 
+ /* When outputting delayed branch sequences, this rtx holds the
+    sequence being output.  It is null when no delayed branch
+    sequence is being output, so it can be used as a test in the
+    insn output code.
+ 
+    This variable is defined  in final.c.  */
+ rtx final_sequence;
+ 
+ /* Nonzero if function being compiled pops its args on return.
+    May affect compilation of return insn or of function epilogue.  */
+ 
+ int current_function_pops_args;
+ 
+ /* Nonzero if function being compiled needs to be given an address
+    where the value should be stored.  */
+ 
+ int current_function_returns_struct;
+ 
+ /* Nonzero if function being compiled needs to
+    return the address of where it has put a structure value.  */
+ 
+ int current_function_returns_pcc_struct;
+ 
+ /* Nonzero if function being compiled needs to be passed a static chain.  */
+ 
+ int current_function_needs_context;
+ 
+ /* Nonzero if function being compiled can call setjmp.  */
+ 
+ int current_function_calls_setjmp;
+ 
+ /* Nonzero if function being compiled can call alloca,
+    either as a subroutine or builtin.  */
+ 
+ int current_function_calls_alloca;
+ 
+ /* Nonzero if the current function returns a pointer type */
+ 
+ int current_function_returns_pointer;
+ 
+ /* If function's args have a fixed size, this is that size, in bytes.
+    Otherwise, it is -1.
+    May affect compilation of return insn or of function epilogue.  */
+ 
+ int current_function_args_size;
+ 
+ /* # bytes the prologue should push and pretend that the caller pushed them.
+    The prologue must do this, but only if parms can be passed in registers.  */
+ 
+ int current_function_pretend_args_size;
+ 
+ /* Name of function now being compiled.  */
+ 
+ char *current_function_name;
diff -rc2N gcc-1.35/print-self.c gcc-1.36/print-self.c
*** gcc-1.35/print-self.c	Wed Dec 31 19:00:00 1969
--- gcc-1.36/print-self.c	Wed Sep  6 14:39:53 1989
***************
*** 0 ****
--- 1,1 ----
+ main(){char*p="main(){char*p=%c%s%c;(void)printf(p,34,p,34,10);}%c";(void)printf(p,34,p,34,10);}
No newline at end of file gcc-1.36/print-self1.c
diff -rc2N gcc-1.35/print-self1.c gcc-1.36/print-self1.c
*** gcc-1.35/print-self1.c	Wed Dec 31 19:00:00 1969
--- gcc-1.36/print-self1.c	Wed Sep  6 14:39:27 1989
***************
*** 0 ****
--- 1,1 ----
+ main(a){a="main(a){a=%c%s%c;printf(a,34,a,34);}";printf(a,34,a,34);}
diff -rc2N gcc-1.35/print-tree.c gcc-1.36/print-tree.c
*** gcc-1.35/print-tree.c	Mon Apr 24 15:28:27 1989
--- gcc-1.36/print-tree.c	Thu Sep 21 18:43:39 1989
***************
*** 388,391 ****
--- 388,401 ----
  
      case 't':
+       if (TYPE_NAME (node) != NULL)
+ 	{
+ 	  if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
+ 	    fprintf (outfile, " type name = %s;",
+ 		     IDENTIFIER_POINTER (TYPE_NAME (node)));
+ 	  else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
+ 		   && DECL_NAME (TYPE_NAME (node)) != NULL)
+ 	    fprintf (outfile, " type name = %s;",
+ 		     IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node))));
+ 	}
        prtypemodeinfo (node);
        prtypeinfo (node);
***************
*** 476,480 ****
  	    {
  	      skip (indent);
! 	      print_rtl (outfile, TREE_OPERAND (node, i));
  	      fprintf (outfile, "\n");
  	    }
--- 486,493 ----
  	    {
  	      skip (indent);
! 	      if (TREE_OPERAND (node, i))
! 		print_rtl (outfile, TREE_OPERAND (node, i));
! 	      else
! 		fprintf (outfile, "(nil)");
  	      fprintf (outfile, "\n");
  	    }
***************
*** 512,515 ****
--- 525,529 ----
  	  part ("bind_size", STMT_BIND_SIZE (node));
  	  part ("body", STMT_BODY (node));
+ 	  part ("subblocks", STMT_SUBBLOCKS (node));
  	  break;
  
***************
*** 541,544 ****
--- 555,559 ----
  	  walk (STMT_BIND_SIZE (node), node, indent);
  	  walk (STMT_BODY (node), node, indent);
+ 	  walk (STMT_SUBBLOCKS (node), node, indent);
  	  break;
  
***************
*** 575,580 ****
  	  {
  	    int i;
- 	    fprintf (outfile, " = 0x");
  	    char *p = (char *) &TREE_REAL_CST (node);
  	    for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
  	      fprintf (outfile, "%02x", *p++);
--- 590,595 ----
  	  {
  	    int i;
  	    char *p = (char *) &TREE_REAL_CST (node);
+ 	    fprintf (outfile, " = 0x");
  	    for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
  	      fprintf (outfile, "%02x", *p++);
diff -rc2N gcc-1.35/real.h gcc-1.36/real.h
*** gcc-1.35/real.h	Wed Feb 22 11:55:58 1989
--- gcc-1.36/real.h	Sat Sep 16 01:47:42 1989
***************
*** 18,21 ****
--- 18,24 ----
  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  
+ #ifndef REAL_H_INCLUDED
+ #define REAL_H_INCLUDED
+ 
  /* If we are not cross-compiling, use a `double' to represent the
     floating-point value.  Otherwise, use some other type
***************
*** 70,76 ****
  /* For a CONST_DOUBLE:
     The usual two ints that hold the value.
!    For a DImode, that is all there are.
     For a float, the number of ints varies,
!    so use &CONST_DOUBLE_LOW(r) as the address of an array of them.  */
  #define CONST_DOUBLE_LOW(r) XINT (r, 2)
  #define CONST_DOUBLE_HIGH(r) XINT (r, 3)
--- 73,81 ----
  /* For a CONST_DOUBLE:
     The usual two ints that hold the value.
!    For a DImode, that is all there are;
!     and CONST_DOUBLE_LOW is the low-order word and ..._HIGH the high-order.
     For a float, the number of ints varies,
!     and CONST_DOUBLE_LOW is the one that should come first *in memory*.
!     So use &CONST_DOUBLE_LOW(r) as the address of an array of ints.  */
  #define CONST_DOUBLE_LOW(r) XINT (r, 2)
  #define CONST_DOUBLE_HIGH(r) XINT (r, 3)
***************
*** 82,83 ****
--- 87,94 ----
     or cc0_rtx if it is not on the chain.  */
  #define CONST_DOUBLE_MEM(r) XEXP (r, 0)
+ 
+ /* Function to return a real value (not a tree node)
+    from a given integer constant.  */
+ REAL_VALUE_TYPE real_value_from_int_cst ();
+ 
+ #endif /* Not REAL_H_INCLUDED */
diff -rc2N gcc-1.35/recog.c gcc-1.36/recog.c
*** gcc-1.35/recog.c	Mon Apr 10 17:46:51 1989
--- gcc-1.36/recog.c	Sun Aug  6 00:12:48 1989
***************
*** 231,234 ****
--- 231,236 ----
        if (! volatile_ok && MEM_VOLATILE_P (op))
  	return 0;
+       /* Use the mem's mode, since it will be reloaded thus.  */
+       mode = GET_MODE (op);
        GO_IF_LEGITIMATE_ADDRESS (mode, y, win);
      }
***************
*** 400,403 ****
--- 402,406 ----
       enum machine_mode mode;
  {
+   rtx inner;
    int mode_altering_drug = 0;
  
***************
*** 407,419 ****
      return GET_CODE (op) == MEM && general_operand (op, mode);
  
!   while (GET_CODE (op) == SUBREG)
!     {
!       op = SUBREG_REG (op);
!       mode_altering_drug = 1;
!     }
  
!   return (GET_CODE (op) == MEM && general_operand (op, mode)
! 	  && ! (mode_altering_drug
! 		&& mode_dependent_address_p (XEXP (op, 0))));
  }
  
--- 410,421 ----
      return GET_CODE (op) == MEM && general_operand (op, mode);
  
!   if (mode != VOIDmode && GET_MODE (op) != mode)
!     return 0;
! 
!   inner = op;
!   while (GET_CODE (inner) == SUBREG)
!     inner = SUBREG_REG (inner);
  
!   return (GET_CODE (inner) == MEM && general_operand (op, mode));
  }
  
***************
*** 713,721 ****
  
  int
! offsetable_memref_p (op)
       rtx op;
  {
    return ((GET_CODE (op) == MEM)
! 	  && offsetable_address_p (1, GET_MODE (op), XEXP (op, 0)));
  }
  
--- 715,723 ----
  
  int
! offsettable_memref_p (op)
       rtx op;
  {
    return ((GET_CODE (op) == MEM)
! 	  && offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)));
  }
  
***************
*** 731,735 ****
  
  int
! offsetable_address_p (strictp, mode, y)
       int strictp;
       enum machine_mode mode;
--- 733,737 ----
  
  int
! offsettable_address_p (strictp, mode, y)
       int strictp;
       enum machine_mode mode;
***************
*** 813,817 ****
  
  /* Given an operand OP that is a valid memory reference
!    which satisfies offsetable_memref_p,
     return a new memory reference whose address has been adjusted by OFFSET.
     OFFSET should be positive and less than the size of the object referenced.
--- 815,819 ----
  
  /* Given an operand OP that is a valid memory reference
!    which satisfies offsettable_memref_p,
     return a new memory reference whose address has been adjusted by OFFSET.
     OFFSET should be positive and less than the size of the object referenced.
***************
*** 819,823 ****
  
  rtx
! adj_offsetable_operand (op, offset)
       rtx op;
       int offset;
--- 821,825 ----
  
  rtx
! adj_offsettable_operand (op, offset)
       rtx op;
       int offset;
***************
*** 1032,1036 ****
  
  	      case 'o':
! 		if (offsetable_memref_p (op))
  		  win = 1;
  		break;
--- 1034,1038 ----
  
  	      case 'o':
! 		if (offsettable_memref_p (op))
  		  win = 1;
  		break;
diff -rc2N gcc-1.35/reload.c gcc-1.36/reload.c
*** gcc-1.35/reload.c	Tue Apr 25 17:07:00 1989
--- gcc-1.36/reload.c	Wed Sep  6 16:19:57 1989
***************
*** 1,4 ****
  /* Search an insn for pseudo regs that must be in hard regs and are not.
!    Copyright (C) 1987, 1988 Free Software Foundation, Inc.
  
  This file is part of GNU CC.
--- 1,4 ----
  /* Search an insn for pseudo regs that must be in hard regs and are not.
!    Copyright (C) 1987, 1988, 1989 Free Software Foundation, Inc.
  
  This file is part of GNU CC.
***************
*** 64,69 ****
  2 happens only when REPLACE is 1, which is only when
  actually doing the reloads, not when just counting them.
- */
  
  #define REG_OK_STRICT
  
--- 64,83 ----
  2 happens only when REPLACE is 1, which is only when
  actually doing the reloads, not when just counting them.
  
+ 
+ Using a reload register for several reloads in one insn:
+ 
+ When an insn has reloads, it is considered as having three parts:
+ the input reloads, the insn itself after reloading, and the output reloads.
+ Reloads of values used in memory addresses are often needed for only one part.
+ 
+ When this is so, reload_when_needed records which part needs the reload.
+ Two reloads for different parts of the insn can share the same reload
+ register.
+ 
+ When a reload is used for addresses in multiple parts, or when it is
+ an ordinary operand, it is classified as RELOAD_OTHER, and cannot share
+ a register with any other reload.  */
+ 
  #define REG_OK_STRICT
  
***************
*** 108,126 ****
  			   reload_inmode or reload_outmode.
     reload_nocombine	  char, nonzero if this reload shouldn't be
! 			   combined with another reload.  */
  
  int n_reloads;
  
! rtx reload_in[FIRST_PSEUDO_REGISTER];
! rtx reload_out[FIRST_PSEUDO_REGISTER];
! enum reg_class reload_reg_class[FIRST_PSEUDO_REGISTER];
! enum machine_mode reload_inmode[FIRST_PSEUDO_REGISTER];
! enum machine_mode reload_outmode[FIRST_PSEUDO_REGISTER];
! char reload_strict_low[FIRST_PSEUDO_REGISTER];
! rtx reload_reg_rtx[FIRST_PSEUDO_REGISTER];
! char reload_optional[FIRST_PSEUDO_REGISTER];
! int reload_inc[FIRST_PSEUDO_REGISTER];
! rtx reload_in_reg[FIRST_PSEUDO_REGISTER];
! char reload_nocombine[FIRST_PSEUDO_REGISTER];
  
  /* All the "earlyclobber" operands of the current insn
--- 122,152 ----
  			   reload_inmode or reload_outmode.
     reload_nocombine	  char, nonzero if this reload shouldn't be
! 			   combined with another reload.
!    reload_needed_for      rtx, operand this reload is needed for address of.
! 			   0 means it isn't needed for addressing.
!    reload_needed_for_multiple
! 			  int, 1 if this reload needed for more than one thing.
!    reload_when_needed     enum, classifies reload as needed either for
! 			   addressing an input reload, addressing an output,
! 			   for addressing a non-reloaded mem ref,
! 			   or for unspecified purposes (i.e., more than one
! 			   of the above).  */
  
  int n_reloads;
  
! rtx reload_in[MAX_RELOADS];
! rtx reload_out[MAX_RELOADS];
! enum reg_class reload_reg_class[MAX_RELOADS];
! enum machine_mode reload_inmode[MAX_RELOADS];
! enum machine_mode reload_outmode[MAX_RELOADS];
! char reload_strict_low[MAX_RELOADS];
! rtx reload_reg_rtx[MAX_RELOADS];
! char reload_optional[MAX_RELOADS];
! int reload_inc[MAX_RELOADS];
! rtx reload_in_reg[MAX_RELOADS];
! char reload_nocombine[MAX_RELOADS];
! int reload_needed_for_multiple[MAX_RELOADS];
! rtx reload_needed_for[MAX_RELOADS];
! enum reload_when_needed reload_when_needed[MAX_RELOADS];
  
  /* All the "earlyclobber" operands of the current insn
***************
*** 224,228 ****
  static int
  push_reload (in, out, inloc, outloc, class,
! 	     inmode, outmode, strict_low, optional)
       register rtx in, out;
       rtx *inloc, *outloc;
--- 250,254 ----
  static int
  push_reload (in, out, inloc, outloc, class,
! 	     inmode, outmode, strict_low, optional, needed_for)
       register rtx in, out;
       rtx *inloc, *outloc;
***************
*** 231,234 ****
--- 257,261 ----
       int strict_low;
       int optional;
+      rtx needed_for;
  {
    register int i;
***************
*** 373,376 ****
--- 400,405 ----
        reload_nocombine[i] = 0;
        reload_in_reg[i] = *inloc;
+       reload_needed_for[i] = needed_for;
+       reload_needed_for_multiple[i] = 0;
  
        n_reloads++;
***************
*** 392,395 ****
--- 421,426 ----
  	reload_out[i] = out;
        reload_optional[i] &= optional;
+       if (reload_needed_for[i] != needed_for)
+ 	reload_needed_for_multiple[i] = 1;
      }
  
***************
*** 533,536 ****
--- 564,569 ----
    for (i = 0; i < n_reloads; i++)
      if (reload_in[i] && ! reload_optional[i] && ! reload_nocombine[i]
+ 	/* Life span of this reload must not extend past main insn.  */
+ 	&& reload_when_needed[i] != RELOAD_FOR_OUTPUT_RELOAD_ADDRESS
  	&& reload_inmode[i] == reload_outmode[output_reload]
  	&& reload_inc[i] == 0
***************
*** 547,550 ****
--- 580,586 ----
  	/* Mark the old output reload as inoperative.  */
  	reload_out[output_reload] = 0;
+ 	/* The combined reload is needed for the entire insn.  */
+ 	reload_needed_for_multiple[i] = 1;
+ 	reload_when_needed[i] = RELOAD_OTHER;
  
  	/* Transfer all replacements from the old reload to the combined.  */
***************
*** 613,616 ****
--- 649,657 ----
  	regno = reg_renumber[regno];
        if (regno < FIRST_PSEUDO_REGISTER
+ 	  /* A fixed reg that can overlap other regs better not be used
+ 	     for reloading in any way.  */
+ #ifdef OVERLAPPING_REGNO_P
+ 	  && ! (fixed_regs[regno] && OVERLAPPING_REGNO_P (regno))
+ #endif
  	  && ! refers_to_regno_p (regno, regno + HARD_REGNO_NREGS (regno, GET_MODE (out)),
  				  PATTERN (this_insn), outloc)
***************
*** 847,850 ****
--- 888,1047 ----
  }
  \f


+ struct decomposition
+ {
+   int reg_flag;
+   int safe;
+   rtx base;
+   int start;
+   int end;
+ };
+ 
+ /* Describe the range of registers or memory referenced by X.
+    If X is a register, set REG_FLAG and put the first register 
+    number into START and the last plus one into END.
+    If X is a memory reference, put a base address into BASE 
+    and a range of integer offsets into START and END.
+    If X is pushing on the stack, we can assume it causes no trouble, 
+    so we set the SAFE field.  */
+ 
+ static struct decomposition
+ decompose (x)
+      rtx x;
+ {
+   struct decomposition val;
+   int all_const = 0;
+ 
+   val.reg_flag = 0;
+   val.safe = 0;
+   if (GET_CODE (x) == MEM)
+     {
+       rtx base, offset = 0;
+       rtx addr = XEXP (x, 0);
+ 
+       if (GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == PRE_INC
+ 	  || GET_CODE (addr) == POST_DEC || GET_CODE (addr) == POST_INC)
+ 	{
+ 	  val.base = XEXP (addr, 0);
+ 	  val.start = - GET_MODE_SIZE (GET_MODE (x));
+ 	  val.end = GET_MODE_SIZE (GET_MODE (x));
+ 	  val.safe = REGNO (val.base) == STACK_POINTER_REGNUM;
+ 	  return val;
+ 	}
+ 
+       if (GET_CODE (addr) == CONST)
+ 	{
+ 	  addr = XEXP (addr, 0);
+ 	  all_const = 1;
+ 	}
+       if (GET_CODE (addr) == PLUS)
+ 	{
+ 	  if (CONSTANT_P (XEXP (addr, 0)))
+ 	    {
+ 	      base = XEXP (addr, 1);
+ 	      offset = XEXP (addr, 0);
+ 	    }
+ 	  else if (CONSTANT_P (XEXP (addr, 1)))
+ 	    {
+ 	      base = XEXP (addr, 0);
+ 	      offset = XEXP (addr, 1);
+ 	    }
+ 	}
+ 
+       if (offset == 0)
+ 	{
+ 	  base = addr;
+ 	  offset = const0_rtx;
+ 	} 
+       if (GET_CODE (offset) == CONST)
+ 	offset = XEXP (offset, 0);
+       if (GET_CODE (offset) == PLUS)
+ 	{
+ 	  if (GET_CODE (XEXP (offset, 0)) == CONST_INT)
+ 	    {
+ 	      base = gen_rtx (PLUS, GET_MODE (base), base, XEXP (offset, 1));
+ 	      offset = XEXP (offset, 0);
+ 	    }
+ 	  else if (GET_CODE (XEXP (offset, 1)) == CONST_INT)
+ 	    {
+ 	      base = gen_rtx (PLUS, GET_MODE (base), base, XEXP (offset, 0));
+ 	      offset = XEXP (offset, 1);
+ 	    }
+ 	  else
+ 	    {
+ 	      base = gen_rtx (PLUS, GET_MODE (base), base, offset);
+ 	      offset = const0_rtx;
+ 	    }
+ 	}
+       else if (GET_CODE (offset) != CONST_INT)
+ 	{
+ 	  base = gen_rtx (PLUS, GET_MODE (base), base, offset);
+ 	  offset = const0_rtx;
+ 	}
+ 
+       if (all_const && GET_CODE (base) == PLUS)
+ 	base = gen_rtx (CONST, GET_MODE (base), base);
+ 
+       if (GET_CODE (offset) != CONST_INT)
+ 	abort ();
+ 
+       val.start = INTVAL (offset);
+       val.end = val.start + GET_MODE_SIZE (GET_MODE (x));
+       val.base = base;
+       return val;
+     }
+   else
+     {
+       val.start = true_regnum (x); 
+       val.end = val.start + HARD_REGNO_NREGS (val.start, GET_MODE (x));
+       val.reg_flag = 1;
+     }
+   return val;
+ }
+ 
+ /* Return 1 if altering Y will not modify the value of X.
+    Y is also described by YDATA, which should be decompose (Y).  */
+ 
+ static int
+ immune_p (x, y, ydata)
+      rtx x, y;
+      struct decomposition ydata;
+ {
+   struct decomposition xdata;
+ 
+   if (ydata.reg_flag)
+     return !refers_to_regno_p (ydata.start, ydata.end, x, 0);
+   if (ydata.safe)
+     return 1;
+ 
+   if (GET_CODE (y) != MEM)
+     abort ();
+   /* If Y is memory and X is not, Y can't affect X.  */
+   if (GET_CODE (x) != MEM)
+     return 1;
+ 
+   xdata =  decompose (x);
+ 
+   if (! rtx_equal_p (xdata.base, ydata.base))
+     {
+       /* If bases are distinct symbolic constants, there is no overlap.  */
+       if (CONSTANT_P (xdata.base) && CONSTANT_P (ydata.base))
+ 	return 1;
+       /* Constants and stack slots never overlap.  */
+       if (CONSTANT_P (xdata.base)
+ 	  && (ydata.base == frame_pointer_rtx
+ 	      || ydata.base == stack_pointer_rtx))
+ 	return 1;
+       if (CONSTANT_P (ydata.base)
+ 	  && (xdata.base == frame_pointer_rtx
+ 	      || xdata.base == stack_pointer_rtx))
+ 	return 1;
+       /* If either base is variable, we don't know anything.  */
+       return 0;
+     }
+ 
+ 
+   return (xdata.start >= ydata.end || ydata.start >= xdata.end);
+ }
+ \f


  /* Main entry point of this file: search the body of INSN
     for values that need reloading and record them with push_reload.
***************
*** 1063,1067 ****
  	{
  	  find_reloads_address (VOIDmode, 0,
! 				recog_operand[i], recog_operand_loc[i]);
  	  substed_operand[i] = recog_operand[i] = *recog_operand_loc[i];
  	}
--- 1260,1265 ----
  	{
  	  find_reloads_address (VOIDmode, 0,
! 				recog_operand[i], recog_operand_loc[i],
! 				recog_operand[i]);
  	  substed_operand[i] = recog_operand[i] = *recog_operand_loc[i];
  	}
***************
*** 1071,1075 ****
  				    recog_operand_loc[i],
  				    XEXP (recog_operand[i], 0),
! 				    &XEXP (recog_operand[i], 0)))
  	    address_reloaded[i] = 1;
  	  substed_operand[i] = recog_operand[i] = *recog_operand_loc[i];
--- 1269,1274 ----
  				    recog_operand_loc[i],
  				    XEXP (recog_operand[i], 0),
! 				    &XEXP (recog_operand[i], 0),
! 				    recog_operand[i]))
  	    address_reloaded[i] = 1;
  	  substed_operand[i] = recog_operand[i] = *recog_operand_loc[i];
***************
*** 1100,1104 ****
  				    recog_operand_loc[i],
  				    XEXP (recog_operand[i], 0),
! 				    &XEXP (recog_operand[i], 0));
  	      substed_operand[i] = recog_operand[i] = *recog_operand_loc[i];
  	    }
--- 1299,1304 ----
  				    recog_operand_loc[i],
  				    XEXP (recog_operand[i], 0),
! 				    &XEXP (recog_operand[i], 0),
! 				    recog_operand[i]);
  	      substed_operand[i] = recog_operand[i] = *recog_operand_loc[i];
  	    }
***************
*** 1316,1323 ****
  		  break;
  		if ((GET_CODE (operand) == MEM
! 		     && offsetable_memref_p (operand))
! 		    /* Certain mem addresses will become offsetable
  		       after they themselves are reloaded.  This is important;
! 		       we don't want our own handling of unoffsetables
  		       to override the handling of reg_equiv_address.  */
  		    || (GET_CODE (operand) == MEM
--- 1516,1523 ----
  		  break;
  		if ((GET_CODE (operand) == MEM
! 		     && offsettable_memref_p (operand))
! 		    /* Certain mem addresses will become offsettable
  		       after they themselves are reloaded.  This is important;
! 		       we don't want our own handling of unoffsettables
  		       to override the handling of reg_equiv_address.  */
  		    || (GET_CODE (operand) == MEM
***************
*** 1339,1343 ****
  		/* Output operand that is stored before the need for the
  		   input operands (and their index registers) is over.  */
! 		if (GET_CODE (operand) == REG)
  		  earlyclobber = 1, this_earlyclobber = 1;
  		break;
--- 1539,1544 ----
  		/* Output operand that is stored before the need for the
  		   input operands (and their index registers) is over.  */
! 		if (GET_CODE (operand) == REG
! 		    || GET_CODE (operand) == MEM)
  		  earlyclobber = 1, this_earlyclobber = 1;
  		break;
***************
*** 1438,1446 ****
  	    && this_alternative_win[i])
  	  {
! 	    int regno = true_regnum (recog_operand[i]); 
! 	    int endregno
! 	      = regno + HARD_REGNO_NREGS (regno, GET_MODE (recog_operand[i]));
  	    int j;
  
  	    for (j = 0; j < noperands; j++)
  	      /* Is this an input operand or a memory ref?  */
--- 1639,1647 ----
  	    && this_alternative_win[i])
  	  {
! 	    struct decomposition early_data; 
  	    int j;
  
+ 	    early_data = decompose (recog_operand[i]);
+ 
  	    for (j = 0; j < noperands; j++)
  	      /* Is this an input operand or a memory ref?  */
***************
*** 1447,1453 ****
  	      if ((GET_CODE (recog_operand[j]) == MEM
  		   || modified[j] != RELOAD_WRITE)
! 		  /* Does it refer to the earlyclobber operand?  */
! 		  && refers_to_regno_p (regno, endregno,
! 					recog_operand[j], 0))
  		{
  		  /* If the output is in a single-reg class,
--- 1648,1658 ----
  	      if ((GET_CODE (recog_operand[j]) == MEM
  		   || modified[j] != RELOAD_WRITE)
! 		  && j != i
! 		  /* Don't count an input operand that is constrained to match
! 		     the early clobber operand.  */
! 		  && ! (this_alternative_matches[j] == i
! 			&& rtx_equal_p (recog_operand[i], recog_operand[j]))
! 		  /* Is it altered by storing the earlyclobber operand?  */
! 		  && !immune_p (recog_operand[j], recog_operand[i], early_data))
  		{
  		  /* If the output is in a single-reg class,
***************
*** 1469,1472 ****
--- 1674,1684 ----
  		losers++;
  		this_alternative_win[i] = 0;
+ 		for (j = 0; j < noperands; j++)
+ 		  if (this_alternative_matches[j] == i
+ 		      && this_alternative_win[j])
+ 		    {
+ 		      this_alternative_win[j] = 0;
+ 		      losers++;
+ 		    }
  	      }
  	  }
***************
*** 1640,1645 ****
  	if (goal_alternative_matches[i] >= 0)
  	  ;
! 	/* Handle an operand with a nonoffsetable address
! 	   appearing where an offsetable address will do
  	   by reloading the address into a base register.  */
  	else if (goal_alternative_matched[i] == -1
--- 1852,1857 ----
  	if (goal_alternative_matches[i] >= 0)
  	  ;
! 	/* Handle an operand with a nonoffsettable address
! 	   appearing where an offsettable address will do
  	   by reloading the address into a base register.  */
  	else if (goal_alternative_matched[i] == -1
***************
*** 1651,1655 ****
  			     &XEXP (recog_operand[i], 0), 0,
  			     BASE_REG_CLASS, GET_MODE (XEXP (recog_operand[i], 0)),
! 			     0, 0, 0);
  	    reload_inc[operand_reloadnum[i]]
  	      = GET_MODE_SIZE (GET_MODE (recog_operand[i]));
--- 1863,1867 ----
  			     &XEXP (recog_operand[i], 0), 0,
  			     BASE_REG_CLASS, GET_MODE (XEXP (recog_operand[i], 0)),
! 			     0, 0, 0, 0);
  	    reload_inc[operand_reloadnum[i]]
  	      = GET_MODE_SIZE (GET_MODE (recog_operand[i]));
***************
*** 1665,1669 ****
  			 (insn_code_number < 0 ? 0
  			  : insn_operand_strict_low[insn_code_number][i]),
! 			 0);
  	/* In a matching pair of operands, one must be input only
  	   and the other must be output only.
--- 1877,1881 ----
  			 (insn_code_number < 0 ? 0
  			  : insn_operand_strict_low[insn_code_number][i]),
! 			 0, 0);
  	/* In a matching pair of operands, one must be input only
  	   and the other must be output only.
***************
*** 1680,1684 ****
  			     operand_mode[i],
  			     operand_mode[goal_alternative_matched[i]],
! 			     VOIDmode, 0);
  	    operand_reloadnum[goal_alternative_matched[i]] = output_reloadnum;
  	  }
--- 1892,1896 ----
  			     operand_mode[i],
  			     operand_mode[goal_alternative_matched[i]],
! 			     VOIDmode, 0, 0);
  	    operand_reloadnum[goal_alternative_matched[i]] = output_reloadnum;
  	  }
***************
*** 1694,1698 ****
  			     operand_mode[goal_alternative_matched[i]],
  			     operand_mode[i],
! 			     VOIDmode, 0);
  	    operand_reloadnum[i] = output_reloadnum;
  	  }
--- 1906,1910 ----
  			     operand_mode[goal_alternative_matched[i]],
  			     operand_mode[i],
! 			     VOIDmode, 0, 0);
  	    operand_reloadnum[i] = output_reloadnum;
  	  }
***************
*** 1737,1741 ****
  			   (insn_code_number < 0 ? 0
  			    : insn_operand_strict_low[insn_code_number][i]),
! 			   1);
  	/* Make an optional reload for an explicit mem ref.  */
  	else if (GET_CODE (operand) == MEM
--- 1949,1953 ----
  			   (insn_code_number < 0 ? 0
  			    : insn_operand_strict_low[insn_code_number][i]),
! 			   1, 0);
  	/* Make an optional reload for an explicit mem ref.  */
  	else if (GET_CODE (operand) == MEM
***************
*** 1754,1765 ****
  			   (insn_code_number < 0 ? 0
  			    : insn_operand_strict_low[insn_code_number][i]),
! 			   1);
        }
  
-   /* Perhaps an output reload can be combined with another
-      to reduce needs by one.  */
-   if (!goal_earlyclobber)
-     combine_reloads ();
- 
    /* Record the values of the earlyclobber operands for the caller.  */
    if (goal_earlyclobber)
--- 1966,1972 ----
  			   (insn_code_number < 0 ? 0
  			    : insn_operand_strict_low[insn_code_number][i]),
! 			   1, 0);
        }
  
    /* Record the values of the earlyclobber operands for the caller.  */
    if (goal_earlyclobber)
***************
*** 1810,1813 ****
--- 2017,2021 ----
    int noperands;
    int insn_code_number;
+   int goal_earlyclobber = 0; /* Always 0, to make combine_reloads happen.  */
    register int i;
    rtx body = PATTERN (insn);
***************
*** 1873,1877 ****
  	if (insn_operand_address_p[insn_code_number][i])
  	  find_reloads_address (VOIDmode, 0,
! 				recog_operand[i], recog_operand_loc[i]);
        if (code == MEM)
  	find_reloads_address (GET_MODE (recog_operand[i]),
--- 2081,2086 ----
  	if (insn_operand_address_p[insn_code_number][i])
  	  find_reloads_address (VOIDmode, 0,
! 				recog_operand[i], recog_operand_loc[i],
! 				recog_operand[i]);
        if (code == MEM)
  	find_reloads_address (GET_MODE (recog_operand[i]),
***************
*** 1878,1882 ****
  			      recog_operand_loc[i],
  			      XEXP (recog_operand[i], 0),
! 			      &XEXP (recog_operand[i], 0));
        if (code == SUBREG)
  	recog_operand[i] = *recog_operand_loc[i]
--- 2087,2092 ----
  			      recog_operand_loc[i],
  			      XEXP (recog_operand[i], 0),
! 			      &XEXP (recog_operand[i], 0),
! 			      recog_operand[i]);
        if (code == SUBREG)
  	recog_operand[i] = *recog_operand_loc[i]
***************
*** 1897,1900 ****
--- 2107,2163 ----
      }
  #endif /* no REGISTER_CONSTRAINTS */
+ 
+   /* Determine which part of the insn each reload is needed for,
+      based on which operand the reload is needed for.
+      Reloads of entire operands are classified as RELOAD_OTHER.
+      So are reloads for which a unique purpose is not known.  */
+ 
+   for (i = 0; i < n_reloads; i++)
+     {
+       reload_when_needed[i] = RELOAD_OTHER;
+ 
+       if (reload_needed_for[i] != 0 && ! reload_needed_for_multiple[i])
+ 	{
+ 	  int j;
+ 	  int output_address = 0;
+ 	  int input_address = 0;
+ 	  int operand_address = 0;
+ 
+ 	  /* This reload is needed only for the address of something.
+ 	     Determine whether it is needed for addressing an operand
+ 	     being reloaded for input, whether it is needed for an
+ 	     operand being reloaded for output, and whether it is needed
+ 	     for addressing an operand that won't really be reloaded.  */
+ 
+ 	  for (j = 0; j < n_reloads; j++)
+ 	    if (reload_needed_for[i] == reload_in[j]
+ 		|| reload_needed_for[i] == reload_out[j])
+ 	      {
+ 		if (reload_optional[j])
+ 		  operand_address = 1;
+ 		else
+ 		  {
+ 		    if (reload_needed_for[i] == reload_in[j])
+ 		      input_address = 1;
+ 		    if (reload_needed_for[i] == reload_out[j])
+ 		      output_address = 1;
+ 		  }
+ 	      }
+ 
+ 	  /* If it is needed for only one of those, record which one.  */
+ 
+ 	  if (input_address && ! output_address && ! operand_address)
+ 	    reload_when_needed[i] = RELOAD_FOR_INPUT_RELOAD_ADDRESS;
+ 	  if (output_address && ! input_address && ! operand_address)
+ 	    reload_when_needed[i] = RELOAD_FOR_OUTPUT_RELOAD_ADDRESS;
+ 	  if (operand_address && ! input_address && ! output_address)
+ 	    reload_when_needed[i] = RELOAD_FOR_OPERAND_ADDRESS;
+ 	}
+     }
+ 
+   /* Perhaps an output reload can be combined with another
+      to reduce needs by one.  */
+   if (!goal_earlyclobber)
+     combine_reloads ();
  }
  
***************
*** 1944,1950 ****
        if (reg_equiv_constant[regno] != 0)
  	x = reg_equiv_constant[regno];
! /*  This creates (subreg (mem...)) where it isn't wanted.  */
! /*      else if (reg_equiv_mem[regno] != 0)
! 	x = reg_equiv_mem[regno];  */
        else if (reg_equiv_address[regno] != 0)
  	{
--- 2207,2216 ----
        if (reg_equiv_constant[regno] != 0)
  	x = reg_equiv_constant[regno];
! #if 0
! /*  This creates (subreg (mem...)) which would cause an unnecessary
!     reload of the mem.  */
!       else if (reg_equiv_mem[regno] != 0)
! 	x = reg_equiv_mem[regno];
! #endif
        else if (reg_equiv_address[regno] != 0)
  	{
***************
*** 1953,1957 ****
  	  find_reloads_address (GET_MODE (x), 0,
  				XEXP (x, 0),
! 				&XEXP (x, 0));
  	}
        return x;
--- 2219,2223 ----
  	  find_reloads_address (GET_MODE (x), 0,
  				XEXP (x, 0),
! 				&XEXP (x, 0), x);
  	}
        return x;
***************
*** 1960,1964 ****
      {
        rtx tem = x;
!       find_reloads_address (GET_MODE (x), &tem, XEXP (x, 0), &XEXP (x, 0));
        return tem;
      }
--- 2226,2230 ----
      {
        rtx tem = x;
!       find_reloads_address (GET_MODE (x), &tem, XEXP (x, 0), &XEXP (x, 0), x);
        return tem;
      }
***************
*** 1984,1987 ****
--- 2250,2272 ----
  	     push_reload will strip the subreg later.  */
  	}
+       /* If the subreg contains a reg that will be converted to a mem,
+ 	 convert the subreg to a narrower memref now.
+ 	 Otherwise, we would get (subreg (mem ...) ...),
+ 	 which would force reload of the mem.  */
+       else if (regno >= FIRST_PSEUDO_REGISTER && reg_equiv_address[regno] != 0)
+ 	{
+ 	  int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
+ 	  rtx addr;
+ #ifdef BYTES_BIG_ENDIAN
+ 	  offset += (GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))
+ 		     - GET_MODE_SIZE (GET_MODE (x)));
+ #endif
+ 	  addr = plus_constant (reg_equiv_address[regno], offset);
+ 	  x = gen_rtx (MEM, GET_MODE (x), addr);
+ 	  find_reloads_address (GET_MODE (x), 0,
+ 				XEXP (x, 0),
+ 				&XEXP (x, 0), x);
+ 	}
+ 
      }
  
***************
*** 2011,2019 ****
  /* Record all reloads needed for handling memory address AD
     which appears in *LOC in a memory reference to mode MODE
!    which itself is stored in location  *MEMREFLOC.
!    (MEMREFLOC may be zero, meaning don't ever bother to copy the memref.)
     Note that we take shortcuts assuming that no multi-reg machine mode
     occurs as part of an address.
  
     Value is nonzero if this address is reloaded or replaced as a whole.
     This is interesting to the caller if the address is an autoincrement.  */
--- 2296,2305 ----
  /* Record all reloads needed for handling memory address AD
     which appears in *LOC in a memory reference to mode MODE
!    which itself is found in location  *MEMREFLOC.
     Note that we take shortcuts assuming that no multi-reg machine mode
     occurs as part of an address.
  
+    OPERAND is the operand of the insn within which this address appears.
+ 
     Value is nonzero if this address is reloaded or replaced as a whole.
     This is interesting to the caller if the address is an autoincrement.  */
***************
*** 2020,2024 ****
  
  static int
! find_reloads_address (mode, memrefloc, ad, loc)
       enum machine_mode mode;
       rtx *memrefloc;
--- 2306,2310 ----
  
  static int
! find_reloads_address (mode, memrefloc, ad, loc, operand)
       enum machine_mode mode;
       rtx *memrefloc;
***************
*** 2025,2028 ****
--- 2311,2315 ----
       rtx ad;
       rtx *loc;
+      rtx operand;
  {
    register int regno;
***************
*** 2057,2063 ****
  	  push_reload (XEXP (tem, 0), 0, &XEXP (tem, 0), 0,
  		       BASE_REG_CLASS,
! 		       GET_MODE (XEXP (tem, 0)), 0, VOIDmode, 0);
  	  push_reload (tem, 0, loc, 0, BASE_REG_CLASS,
! 		       GET_MODE (ad), 0, VOIDmode, 0);
  	  return 1;
  	}
--- 2344,2352 ----
  	  push_reload (XEXP (tem, 0), 0, &XEXP (tem, 0), 0,
  		       BASE_REG_CLASS,
! 		       GET_MODE (XEXP (tem, 0)), 0, VOIDmode, 0,
! 		       operand);
  	  push_reload (tem, 0, loc, 0, BASE_REG_CLASS,
! 		       GET_MODE (ad), 0, VOIDmode, 0,
! 		       operand);
  	  return 1;
  	}
***************
*** 2067,2071 ****
  	{
  	  push_reload (ad, 0, loc, 0, BASE_REG_CLASS,
! 		       GET_MODE (ad), 0, VOIDmode, 0);
  	  return 1;
  	}
--- 2356,2360 ----
  	{
  	  push_reload (ad, 0, loc, 0, BASE_REG_CLASS,
! 		       GET_MODE (ad), 0, VOIDmode, 0, operand);
  	  return 1;
  	}
***************
*** 2113,2121 ****
        if (memrefloc)
  	{
  	  *memrefloc = copy_rtx (*memrefloc);
  	  loc = &XEXP (*memrefloc, 0);
  	}
!       push_reload (ad, 0, loc, 0, BASE_REG_CLASS,
! 		   GET_MODE (ad), 0, VOIDmode, 0);
        return 1;
      }
--- 2402,2428 ----
        if (memrefloc)
  	{
+ 	  rtx oldref = *memrefloc;
  	  *memrefloc = copy_rtx (*memrefloc);
  	  loc = &XEXP (*memrefloc, 0);
+ 	  if (operand == oldref)
+ 	    operand = *memrefloc;
+ 	}
+       if (double_reg_address_ok)
+ 	{
+ 	  /* Unshare the sum as well.  */
+ 	  *loc = ad = copy_rtx (ad);
+ 	  /* Reload the displacement into an index reg.
+ 	     We assume the frame pointer or arg pointer is a base reg.  */
+ 	  push_reload (XEXP (ad, 1), 0, &XEXP (ad, 1), 0, INDEX_REG_CLASS, 
+ 		       GET_MODE (ad), VOIDmode, 0, 0, operand);
  	}
!       else
! 	{
! 	  /* If the sum of two regs is not necessarily valid,
! 	     reload the sum into a base reg.
! 	     That will at least work.  */
! 	  push_reload (ad, 0, loc, 0, BASE_REG_CLASS,
! 		       GET_MODE (ad), VOIDmode, 0, 0, operand);
! 	}
        return 1;
      }
***************
*** 2150,2158 ****
        push_reload (ad, 0, loc, 0,
  		   BASE_REG_CLASS,
! 		   Pmode, 0, VOIDmode, 0);
        return 1;
      }
  
!   return find_reloads_address_1 (ad, 0, loc);
  }
  \f


--- 2457,2465 ----
        push_reload (ad, 0, loc, 0,
  		   BASE_REG_CLASS,
! 		   Pmode, 0, VOIDmode, 0, operand);
        return 1;
      }
  
!   return find_reloads_address_1 (ad, 0, loc, operand);
  }
  \f


***************
*** 2280,2283 ****
--- 2587,2592 ----
     = 0 means we are considering them as base regs.
  
+    OPERAND is the operand of the insn within which this address appears.
+ 
     We return nonzero if X, as a whole, is reloaded or replaced.  */
  
***************
*** 2289,2296 ****
  
  static int
! find_reloads_address_1 (x, context, loc)
       rtx x;
       int context;
       rtx *loc;
  {
    register RTX_CODE code = GET_CODE (x);
--- 2598,2606 ----
  
  static int
! find_reloads_address_1 (x, context, loc, operand)
       rtx x;
       int context;
       rtx *loc;
+      rtx operand;
  {
    register RTX_CODE code = GET_CODE (x);
***************
*** 2304,2314 ****
        if (code0 == MULT || code0 == SIGN_EXTEND || code1 == MEM)
  	{
! 	  find_reloads_address_1 (op0, 1, &XEXP (x, 0));
! 	  find_reloads_address_1 (op1, 0, &XEXP (x, 1));
  	}
        else if (code1 == MULT || code1 == SIGN_EXTEND || code0 == MEM)
  	{
! 	  find_reloads_address_1 (op0, 0, &XEXP (x, 0));
! 	  find_reloads_address_1 (op1, 1, &XEXP (x, 1));
  	}
        else if (code0 == CONST_INT || code0 == CONST
--- 2614,2624 ----
        if (code0 == MULT || code0 == SIGN_EXTEND || code1 == MEM)
  	{
! 	  find_reloads_address_1 (op0, 1, &XEXP (x, 0), operand);
! 	  find_reloads_address_1 (op1, 0, &XEXP (x, 1), operand);
  	}
        else if (code1 == MULT || code1 == SIGN_EXTEND || code0 == MEM)
  	{
! 	  find_reloads_address_1 (op0, 0, &XEXP (x, 0), operand);
! 	  find_reloads_address_1 (op1, 1, &XEXP (x, 1), operand);
  	}
        else if (code0 == CONST_INT || code0 == CONST
***************
*** 2315,2319 ****
  	       || code0 == SYMBOL_REF || code0 == LABEL_REF)
  	{
! 	  find_reloads_address_1 (op1, 0, &XEXP (x, 1));
  	}
        else if (code1 == CONST_INT || code1 == CONST
--- 2625,2629 ----
  	       || code0 == SYMBOL_REF || code0 == LABEL_REF)
  	{
! 	  find_reloads_address_1 (op1, 0, &XEXP (x, 1), operand);
  	}
        else if (code1 == CONST_INT || code1 == CONST
***************
*** 2320,2324 ****
  	       || code1 == SYMBOL_REF || code1 == LABEL_REF)
  	{
! 	  find_reloads_address_1 (op0, 0, &XEXP (x, 0));
  	}
        else if (code0 == REG && code1 == REG)
--- 2630,2634 ----
  	       || code1 == SYMBOL_REF || code1 == LABEL_REF)
  	{
! 	  find_reloads_address_1 (op0, 0, &XEXP (x, 0), operand);
  	}
        else if (code0 == REG && code1 == REG)
***************
*** 2331,2345 ****
  	    return 0;
  	  else if (REG_OK_FOR_BASE_P (op1))
! 	    find_reloads_address_1 (op0, 1, &XEXP (x, 0));
  	  else if (REG_OK_FOR_BASE_P (op0))
! 	    find_reloads_address_1 (op1, 1, &XEXP (x, 1));
  	  else if (REG_OK_FOR_INDEX_P (op1))
! 	    find_reloads_address_1 (op0, 0, &XEXP (x, 0));
  	  else if (REG_OK_FOR_INDEX_P (op0))
! 	    find_reloads_address_1 (op1, 0, &XEXP (x, 1));
  	  else
  	    {
! 	      find_reloads_address_1 (op0, 1, &XEXP (x, 0));
! 	      find_reloads_address_1 (op1, 0, &XEXP (x, 1));
  	    }
  	}
--- 2641,2655 ----
  	    return 0;
  	  else if (REG_OK_FOR_BASE_P (op1))
! 	    find_reloads_address_1 (op0, 1, &XEXP (x, 0), operand);
  	  else if (REG_OK_FOR_BASE_P (op0))
! 	    find_reloads_address_1 (op1, 1, &XEXP (x, 1), operand);
  	  else if (REG_OK_FOR_INDEX_P (op1))
! 	    find_reloads_address_1 (op0, 0, &XEXP (x, 0), operand);
  	  else if (REG_OK_FOR_INDEX_P (op0))
! 	    find_reloads_address_1 (op1, 0, &XEXP (x, 1), operand);
  	  else
  	    {
! 	      find_reloads_address_1 (op0, 1, &XEXP (x, 0), operand);
! 	      find_reloads_address_1 (op1, 0, &XEXP (x, 1), operand);
  	    }
  	}
***************
*** 2346,2356 ****
        else if (code0 == REG)
  	{
! 	  find_reloads_address_1 (op0, 1, &XEXP (x, 0));
! 	  find_reloads_address_1 (op1, 0, &XEXP (x, 1));
  	}
        else if (code1 == REG)
  	{
! 	  find_reloads_address_1 (op1, 1, &XEXP (x, 1));
! 	  find_reloads_address_1 (op0, 0, &XEXP (x, 0));
  	}
      }
--- 2656,2666 ----
        else if (code0 == REG)
  	{
! 	  find_reloads_address_1 (op0, 1, &XEXP (x, 0), operand);
! 	  find_reloads_address_1 (op1, 0, &XEXP (x, 1), operand);
  	}
        else if (code1 == REG)
  	{
! 	  find_reloads_address_1 (op1, 1, &XEXP (x, 1), operand);
! 	  find_reloads_address_1 (op0, 0, &XEXP (x, 0), operand);
  	}
      }
***************
*** 2376,2380 ****
  	      push_reload (XEXP (tem, 0), 0, &XEXP (tem, 0), 0,
  			   BASE_REG_CLASS,
! 			   GET_MODE (XEXP (tem, 0)), 0, VOIDmode, 0);
  	      /* Put this inside a new increment-expression.  */
  	      x = gen_rtx (GET_CODE (x), GET_MODE (x), tem);
--- 2686,2691 ----
  	      push_reload (XEXP (tem, 0), 0, &XEXP (tem, 0), 0,
  			   BASE_REG_CLASS,
! 			   GET_MODE (XEXP (tem, 0)), 0, VOIDmode, 0,
! 			   operand);
  	      /* Put this inside a new increment-expression.  */
  	      x = gen_rtx (GET_CODE (x), GET_MODE (x), tem);
***************
*** 2404,2408 ****
  		= push_reload (x, 0, loc, 0,
  			       context ? INDEX_REG_CLASS : BASE_REG_CLASS,
! 			       GET_MODE (x), GET_MODE (x), VOIDmode, 0);
  	      reload_inc[reloadnum]
  		= find_inc_amount (PATTERN (this_insn), XEXP (x, 0));
--- 2715,2719 ----
  		= push_reload (x, 0, loc, 0,
  			       context ? INDEX_REG_CLASS : BASE_REG_CLASS,
! 			       GET_MODE (x), GET_MODE (x), VOIDmode, 0, operand);
  	      reload_inc[reloadnum]
  		= find_inc_amount (PATTERN (this_insn), XEXP (x, 0));
***************
*** 2429,2433 ****
  	  push_reload (reg_equiv_constant[regno], 0, loc, 0,
  		       context ? INDEX_REG_CLASS : BASE_REG_CLASS,
! 		       GET_MODE (x), 0, VOIDmode, 0);
  	  return 1;
  	}
--- 2740,2744 ----
  	  push_reload (reg_equiv_constant[regno], 0, loc, 0,
  		       context ? INDEX_REG_CLASS : BASE_REG_CLASS,
! 		       GET_MODE (x), 0, VOIDmode, 0, operand);
  	  return 1;
  	}
***************
*** 2439,2443 ****
  	  push_reload (reg_equiv_mem[regno], 0, loc, 0,
  		       context ? INDEX_REG_CLASS : BASE_REG_CLASS,
! 		       GET_MODE (x), 0, VOIDmode, 0);
  	  return 1;
  	}
--- 2750,2754 ----
  	  push_reload (reg_equiv_mem[regno], 0, loc, 0,
  		       context ? INDEX_REG_CLASS : BASE_REG_CLASS,
! 		       GET_MODE (x), 0, VOIDmode, 0, operand);
  	  return 1;
  	}
***************
*** 2448,2452 ****
  	  push_reload (XEXP (x, 0), 0, &XEXP (x, 0), 0,
  		       BASE_REG_CLASS,
! 		       GET_MODE (XEXP (x, 0)), 0, VOIDmode, 0);
  	}
  
--- 2759,2763 ----
  	  push_reload (XEXP (x, 0), 0, &XEXP (x, 0), 0,
  		       BASE_REG_CLASS,
! 		       GET_MODE (XEXP (x, 0)), 0, VOIDmode, 0, operand);
  	}
  
***************
*** 2459,2463 ****
  	  push_reload (x, 0, loc, 0,
  		       context ? INDEX_REG_CLASS : BASE_REG_CLASS,
! 		       GET_MODE (x), 0, VOIDmode, 0);
  	  return 1;
  	}
--- 2770,2774 ----
  	  push_reload (x, 0, loc, 0,
  		       context ? INDEX_REG_CLASS : BASE_REG_CLASS,
! 		       GET_MODE (x), 0, VOIDmode, 0, operand);
  	  return 1;
  	}
***************
*** 2470,2474 ****
  	{
  	  if (fmt[i] == 'e')
! 	    find_reloads_address_1 (XEXP (x, i), context, &XEXP (x, i));
  	}
      }
--- 2781,2785 ----
  	{
  	  if (fmt[i] == 'e')
! 	    find_reloads_address_1 (XEXP (x, i), context, &XEXP (x, i), operand);
  	}
      }
diff -rc2N gcc-1.35/reload.h gcc-1.36/reload.h
*** gcc-1.35/reload.h	Wed Feb 22 12:28:49 1989
--- gcc-1.36/reload.h	Fri Aug 25 23:14:31 1989
***************
*** 21,37 ****
  /* See reload.c and reload1.c for comments on these variables.  */
  
! extern rtx reload_in[FIRST_PSEUDO_REGISTER];
! extern rtx reload_out[FIRST_PSEUDO_REGISTER];
! extern rtx reload_in_reg[FIRST_PSEUDO_REGISTER];
! extern enum reg_class reload_reg_class[FIRST_PSEUDO_REGISTER];
! extern enum machine_mode reload_inmode[FIRST_PSEUDO_REGISTER];
! extern enum machine_mode reload_outmode[FIRST_PSEUDO_REGISTER];
! extern char reload_strict_low[FIRST_PSEUDO_REGISTER];
! extern char reload_optional[FIRST_PSEUDO_REGISTER];
! extern int reload_inc[FIRST_PSEUDO_REGISTER];
  extern int n_reloads;
  
! extern rtx reload_reg_rtx[FIRST_PSEUDO_REGISTER];
  
  extern rtx *reg_equiv_constant;
  extern rtx *reg_equiv_address;
--- 21,52 ----
  /* See reload.c and reload1.c for comments on these variables.  */
  
! /* Maximum number of reloads we can need.  */
! #define MAX_RELOADS (2 * MAX_RECOG_OPERANDS * (MAX_REGS_PER_ADDRESS + 1))
! 
! extern rtx reload_in[MAX_RELOADS];
! extern rtx reload_out[MAX_RELOADS];
! extern rtx reload_in_reg[MAX_RELOADS];
! extern enum reg_class reload_reg_class[MAX_RELOADS];
! extern enum machine_mode reload_inmode[MAX_RELOADS];
! extern enum machine_mode reload_outmode[MAX_RELOADS];
! extern char reload_strict_low[MAX_RELOADS];
! extern char reload_optional[MAX_RELOADS];
! extern int reload_inc[MAX_RELOADS];
! extern int reload_needed_for_multiple[MAX_RELOADS];
! extern rtx reload_needed_for[MAX_RELOADS];
  extern int n_reloads;
  
! extern rtx reload_reg_rtx[MAX_RELOADS];
! 
! enum reload_when_needed
! {
!   RELOAD_FOR_INPUT_RELOAD_ADDRESS,
!   RELOAD_FOR_OUTPUT_RELOAD_ADDRESS,
!   RELOAD_FOR_OPERAND_ADDRESS,
!   RELOAD_OTHER
! };
  
+ extern enum reload_when_needed reload_when_needed[MAX_RELOADS];
+ 
  extern rtx *reg_equiv_constant;
  extern rtx *reg_equiv_address;
***************
*** 46,49 ****
--- 61,67 ----
     Used in find_equiv_reg.  */
  extern int reload_first_uid;
+ 
+ /* Nonzero if an address (plus (reg frame_pointer) (reg ...)) is valid.  */
+ extern char double_reg_address_ok;
  
  void init_reload ();
diff -rc2N gcc-1.35/reload1.c gcc-1.36/reload1.c
*** gcc-1.35/reload1.c	Thu Mar 23 09:03:42 1989
--- gcc-1.36/reload1.c	Sat Sep 16 20:16:41 1989
***************
*** 31,34 ****
--- 31,35 ----
  
  #define min(A,B) ((A) < (B) ? (A) : (B))
+ #define max(A,B) ((A) > (B) ? (A) : (B))
  
  /* This file contains the reload pass of the compiler, which is
***************
*** 150,154 ****
  /* For each register, 1 if it was counted against the need for
     non-groups.  0 means it can become part of a new group.
!    During choose_reload_targets, 1 here means don't use this reg
     as part of a group, even if it seems to be otherwise ok.  */
  static char counted_for_nongroups[FIRST_PSEUDO_REGISTER];
--- 151,155 ----
  /* For each register, 1 if it was counted against the need for
     non-groups.  0 means it can become part of a new group.
!    During choose_reload_regs, 1 here means don't use this reg
     as part of a group, even if it seems to be otherwise ok.  */
  static char counted_for_nongroups[FIRST_PSEUDO_REGISTER];
***************
*** 159,162 ****
--- 160,167 ----
  static char spill_indirect_ok;
  
+ /* Nonzero if an address (plus (reg frame_pointer) (reg ...)) is valid.  */
+ 
+ char double_reg_address_ok;
+ 
  /* Record the stack slot for each spilled hard register.  */
  
***************
*** 179,182 ****
--- 184,191 ----
  int caller_save_needed;
  
+ /* Set to 1 by alter_frame_pointer_addresses if it changes anything.  */
+ 
+ static int frame_pointer_address_altered;
+ 
  void mark_home_live ();
  static void reload_as_needed ();
***************
*** 186,190 ****
  static int new_spill_reg();
  static int spill_hard_reg ();
! static void choose_reload_targets ();
  static void delete_output_reload ();
  static void forget_old_reloads_1 ();
--- 195,200 ----
  static int new_spill_reg();
  static int spill_hard_reg ();
! static void choose_reload_regs ();
! static void emit_reload_insns ();
  static void delete_output_reload ();
  static void forget_old_reloads_1 ();
***************
*** 191,200 ****
  static void order_regs_for_reload ();
  static void eliminate_frame_pointer ();
! static void inc_for_reload ();
  static int constraint_accepts_reg_p ();
  static int count_occurrences ();
  
  extern void remove_death ();
! extern rtx adj_offsetable_operand ();
  \f


  /* Main entry point for the reload pass, and only entry point
--- 201,211 ----
  static void order_regs_for_reload ();
  static void eliminate_frame_pointer ();
! static rtx inc_for_reload ();
  static int constraint_accepts_reg_p ();
  static int count_occurrences ();
+ static rtx gen_input_reload ();
  
  extern void remove_death ();
! extern rtx adj_offsettable_operand ();
  \f


  /* Main entry point for the reload pass, and only entry point
***************
*** 234,238 ****
       Set spill_indirect_ok if so.  */
    register rtx tem
!     = gen_rtx (MEM, SImode,
  	       gen_rtx (PLUS, Pmode,
  			gen_rtx (REG, Pmode, FRAME_POINTER_REGNUM),
--- 245,249 ----
       Set spill_indirect_ok if so.  */
    register rtx tem
!     = gen_rtx (MEM, Pmode,
  	       gen_rtx (PLUS, Pmode,
  			gen_rtx (REG, Pmode, FRAME_POINTER_REGNUM),
***************
*** 241,244 ****
--- 252,263 ----
    spill_indirect_ok = memory_address_p (QImode, tem);
  
+   tem = gen_rtx (PLUS, Pmode, 
+ 		 gen_rtx (REG, Pmode, FRAME_POINTER_REGNUM),
+ 		 gen_rtx (REG, Pmode, FRAME_POINTER_REGNUM));
+   /* This way, we make sure that reg+reg is an offsettable address.  */
+   tem = plus_constant (tem, 4);
+ 
+   double_reg_address_ok = memory_address_p (QImode, tem);
+ 
    /* Enable find_equiv_reg to distinguish insns made by reload.  */
    reload_first_uid = get_max_uid ();
***************
*** 262,265 ****
--- 281,288 ----
      mark_home_live (i);
  
+   /* Make sure that the last insn in the chain
+      is not something that needs reloading.  */
+   emit_note (0, NOTE_INSN_DELETED);
+ 
    /* Find all the pseudo registers that didn't get hard regs
       but do have known equivalent constants or memory slots.
***************
*** 340,344 ****
        break;
  
!   if (i == max_regno && frame_pointer_needed)
      return;
  #endif
--- 363,367 ----
        break;
  
!   if (i == max_regno && frame_pointer_needed && ! caller_save_needed)
      return;
  #endif
***************
*** 357,360 ****
--- 380,386 ----
      }
  
+   if (caller_save_needed)
+     frame_pointer_needed = 1;
+ 
    if (frame_pointer_needed)
      {
***************
*** 428,431 ****
--- 454,459 ----
  	      || GET_CODE (insn) == CALL_INSN)
  	    {
+ 	      /* Initially, count RELOAD_OTHER reloads.
+ 		 Later, merge in the other kinds.  */
  	      int insn_needs[N_REG_CLASSES];
  	      int insn_groups[N_REG_CLASSES];
***************
*** 432,437 ****
  	      int insn_total_groups = 0;
  
  	      for (i = 0; i < N_REG_CLASSES; i++)
! 		insn_needs[i] = 0, insn_groups[i] = 0;
  
  #if 0  /* This wouldn't work nowadays, since optimize_bit_field
--- 460,485 ----
  	      int insn_total_groups = 0;
  
+ 	      /* Count RELOAD_FOR_INPUT_RELOAD_ADDRESS reloads.  */
+ 	      int insn_needs_for_inputs[N_REG_CLASSES];
+ 	      int insn_groups_for_inputs[N_REG_CLASSES];
+ 	      int insn_total_groups_for_inputs = 0;
+ 
+ 	      /* Count RELOAD_FOR_OUTPUT_RELOAD_ADDRESS reloads.  */
+ 	      int insn_needs_for_outputs[N_REG_CLASSES];
+ 	      int insn_groups_for_outputs[N_REG_CLASSES];
+ 	      int insn_total_groups_for_outputs = 0;
+ 
+ 	      /* Count RELOAD_FOR_OPERAND_ADDRESS reloads.  */
+ 	      int insn_needs_for_operands[N_REG_CLASSES];
+ 	      int insn_groups_for_operands[N_REG_CLASSES];
+ 	      int insn_total_groups_for_operands = 0;
+ 
  	      for (i = 0; i < N_REG_CLASSES; i++)
! 		{
! 		  insn_needs[i] = 0, insn_groups[i] = 0;
! 		  insn_needs_for_inputs[i] = 0, insn_groups_for_inputs[i] = 0;
! 		  insn_needs_for_outputs[i] = 0, insn_groups_for_outputs[i] = 0;
! 		  insn_needs_for_operands[i] = 0, insn_groups_for_operands[i] = 0;
! 		}
  
  #if 0  /* This wouldn't work nowadays, since optimize_bit_field
***************
*** 472,475 ****
--- 520,526 ----
  		  int size;
  		  enum machine_mode mode;
+ 		  int *this_groups;
+ 		  int *this_needs;
+ 		  int *this_total_groups;
  
  		  /* Don't count the dummy reloads, for which one of the
***************
*** 482,485 ****
--- 533,564 ----
  		    continue;
  
+ 		  /* Decide which time-of-use to count this reload for.  */
+ 		  switch (reload_when_needed[i])
+ 		    {
+ 		    case RELOAD_OTHER:
+ 		      this_needs = insn_needs;
+ 		      this_groups = insn_groups;
+ 		      this_total_groups = &insn_total_groups;
+ 		      break;
+ 
+ 		    case RELOAD_FOR_INPUT_RELOAD_ADDRESS:
+ 		      this_needs = insn_needs_for_inputs;
+ 		      this_groups = insn_groups_for_inputs;
+ 		      this_total_groups = &insn_total_groups_for_inputs;
+ 		      break;
+ 
+ 		    case RELOAD_FOR_OUTPUT_RELOAD_ADDRESS:
+ 		      this_needs = insn_needs_for_outputs;
+ 		      this_groups = insn_groups_for_outputs;
+ 		      this_total_groups = &insn_total_groups_for_outputs;
+ 		      break;
+ 
+ 		    case RELOAD_FOR_OPERAND_ADDRESS:
+ 		      this_needs = insn_needs_for_operands;
+ 		      this_groups = insn_groups_for_operands;
+ 		      this_total_groups = &insn_total_groups_for_operands;
+ 		      break;
+ 		    }
+ 
  		  mode = reload_inmode[i];
  		  if (GET_MODE_SIZE (reload_outmode[i]) > GET_MODE_SIZE (mode))
***************
*** 490,498 ****
  		      /* Count number of groups needed separately from
  			 number of individual regs needed.  */
! 		      insn_groups[(int) reload_reg_class[i]]++;
  		      p = reg_class_superclasses[(int) reload_reg_class[i]];
  		      while (*p != LIM_REG_CLASSES)
! 			insn_groups[(int) *p++]++;
! 		      insn_total_groups++;
  
  		      /* If a group of consecutive regs are needed,
--- 569,577 ----
  		      /* Count number of groups needed separately from
  			 number of individual regs needed.  */
! 		      this_groups[(int) reload_reg_class[i]]++;
  		      p = reg_class_superclasses[(int) reload_reg_class[i]];
  		      while (*p != LIM_REG_CLASSES)
! 			this_groups[(int) *p++]++;
! 		      (*this_total_groups)++;
  
  		      /* If a group of consecutive regs are needed,
***************
*** 514,521 ****
  		  else if (size == 1)
  		    {
! 		      insn_needs[(int) reload_reg_class[i]] += 1;
  		      p = reg_class_superclasses[(int) reload_reg_class[i]];
  		      while (*p != LIM_REG_CLASSES)
! 			insn_needs[(int) *p++] += 1;
  		    }
  		  else
--- 593,600 ----
  		  else if (size == 1)
  		    {
! 		      this_needs[(int) reload_reg_class[i]] += 1;
  		      p = reg_class_superclasses[(int) reload_reg_class[i]];
  		      while (*p != LIM_REG_CLASSES)
! 			this_needs[(int) *p++] += 1;
  		    }
  		  else
***************
*** 530,533 ****
--- 609,637 ----
  		}
  
+ 	      /* All reloads have been counted for this insn;
+ 		 now merge the various times of use.
+ 		 This sets insn_needs, etc., to the maximum total number
+ 		 of registers needed at any point in this insn.  */
+ 
+ 	      for (i = 0; i < N_REG_CLASSES; i++)
+ 		{
+ 		  int this_max;
+ 		  this_max = insn_needs_for_inputs[i];
+ 		  if (insn_needs_for_outputs[i] > this_max)
+ 		    this_max = insn_needs_for_outputs[i];
+ 		  if (insn_needs_for_operands[i] > this_max)
+ 		    this_max = insn_needs_for_operands[i];
+ 		  insn_needs[i] += this_max;
+ 		  this_max = insn_groups_for_inputs[i];
+ 		  if (insn_groups_for_outputs[i] > this_max)
+ 		    this_max = insn_groups_for_outputs[i];
+ 		  if (insn_groups_for_operands[i] > this_max)
+ 		    this_max = insn_groups_for_operands[i];
+ 		  insn_groups[i] += this_max;
+ 		}
+ 	      insn_total_groups += max (insn_total_groups_for_inputs,
+ 					max (insn_total_groups_for_outputs,
+ 					     insn_total_groups_for_operands));
+ 
  	      /* Remember for later shortcuts which insns had any reloads.  */
  
***************
*** 534,538 ****
  	      PUT_MODE (insn, n_reloads ? QImode : VOIDmode);
  
! 	      /* For each class, collect maximum need of any insn */
  
  	      for (i = 0; i < N_REG_CLASSES; i++)
--- 638,642 ----
  	      PUT_MODE (insn, n_reloads ? QImode : VOIDmode);
  
! 	      /* For each class, collect maximum need of any insn.  */
  
  	      for (i = 0; i < N_REG_CLASSES; i++)
***************
*** 804,811 ****
  
    if (caller_save_needed)
!     {
!       frame_pointer_needed = 1;
!       save_call_clobbered_regs ();
!     }
  
    /* Now we know for certain whether we have a frame pointer.
--- 908,912 ----
  
    if (caller_save_needed)
!     save_call_clobbered_regs ();
  
    /* Now we know for certain whether we have a frame pointer.
***************
*** 974,985 ****
  	{
  	case INSN:
  	  alter_frame_pointer_addresses (pattern, depth);
! #ifdef PUSH_ROUNDING
  	  /* Notice pushes and pops; update DEPTH.  */
  	  if (GET_CODE (pattern) == SET)
  	    {
  	      if (push_operand (SET_DEST (pattern),
  				GET_MODE (SET_DEST (pattern))))
  		depth += PUSH_ROUNDING (GET_MODE_SIZE (GET_MODE (SET_DEST (pattern))));
  	      if (GET_CODE (SET_DEST (pattern)) == REG
  		  && REGNO (SET_DEST (pattern)) == STACK_POINTER_REGNUM)
--- 1075,1092 ----
  	{
  	case INSN:
+ 	  frame_pointer_address_altered = 0;
  	  alter_frame_pointer_addresses (pattern, depth);
! 	  /* Rerecognize insn if changed.  */
! 	  if (frame_pointer_address_altered)
! 	    INSN_CODE (insn) = -1;
! 
  	  /* Notice pushes and pops; update DEPTH.  */
  	  if (GET_CODE (pattern) == SET)
  	    {
+ #ifdef PUSH_ROUNDING
  	      if (push_operand (SET_DEST (pattern),
  				GET_MODE (SET_DEST (pattern))))
  		depth += PUSH_ROUNDING (GET_MODE_SIZE (GET_MODE (SET_DEST (pattern))));
+ #endif
  	      if (GET_CODE (SET_DEST (pattern)) == REG
  		  && REGNO (SET_DEST (pattern)) == STACK_POINTER_REGNUM)
***************
*** 1002,1010 ****
  		}
  	    }
- #endif
  	  break;
  
  	case JUMP_INSN:
  	  alter_frame_pointer_addresses (pattern, depth);
  	  if (GET_CODE (pattern) == ADDR_VEC)
  	    for (i = 0; i < XVECLEN (pattern, 0); i++)
--- 1109,1121 ----
  		}
  	    }
  	  break;
  
  	case JUMP_INSN:
+ 	  frame_pointer_address_altered = 0;
  	  alter_frame_pointer_addresses (pattern, depth);
+ 	  /* Rerecognize insn if changed.  */
+ 	  if (frame_pointer_address_altered)
+ 	    INSN_CODE (insn) = -1;
+ 
  	  if (GET_CODE (pattern) == ADDR_VEC)
  	    for (i = 0; i < XVECLEN (pattern, 0); i++)
***************
*** 1027,1031 ****
--- 1138,1146 ----
  
  	case CALL_INSN:
+ 	  frame_pointer_address_altered = 0;
  	  alter_frame_pointer_addresses (pattern, depth);
+ 	  /* Rerecognize insn if changed.  */
+ 	  if (frame_pointer_address_altered)
+ 	    INSN_CODE (insn) = -1;
  	  break;
  	}
***************
*** 1064,1068 ****
--- 1179,1186 ----
        if (x == frame_pointer_rtx)
  	{
+ 	  rtx oldx = x;
  	  FIX_FRAME_POINTER_ADDRESS (x, depth);
+ 	  if (x != oldx)
+ 	    frame_pointer_address_altered = 1;
  	}
        return x;
***************
*** 1071,1086 ****
        {
  	rtx addr = XEXP (x, 0);
  	FIX_FRAME_POINTER_ADDRESS (addr, depth);
  	/* These MEMs are normally shared.  Make a changed copy;
  	   don't alter the shared MEM, since it needs to be altered
  	   differently each time it occurs (since DEPTH varies).  */
! 	return gen_rtx (MEM, GET_MODE (x), addr);
        }
  
      case PLUS:
!       /* Handle addresses being loaded or pushed, etc.,
! 	 rather than referenced.  */
!       FIX_FRAME_POINTER_ADDRESS (x, depth);
!       break;
      }
  
--- 1189,1216 ----
        {
  	rtx addr = XEXP (x, 0);
+ 	rtx mem;
+ 	rtx old_addr = addr;
  	FIX_FRAME_POINTER_ADDRESS (addr, depth);
+ 	if (addr != old_addr)
+ 	  frame_pointer_address_altered = 1;
  	/* These MEMs are normally shared.  Make a changed copy;
  	   don't alter the shared MEM, since it needs to be altered
  	   differently each time it occurs (since DEPTH varies).  */
! 	mem = gen_rtx (MEM, GET_MODE (x), addr);
! 	MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (x);
! 	return mem;
        }
  
      case PLUS:
!       {
! 	rtx oldx = x;
! 	/* Handle addresses being loaded or pushed, etc.,
! 	   rather than referenced.  */
! 	FIX_FRAME_POINTER_ADDRESS (x, depth);
! 	if (x != oldx)
! 	  frame_pointer_address_altered = 1;
! 	code = GET_CODE (x);
! 	break;
!       }
      }
  
***************
*** 1114,1117 ****
--- 1244,1252 ----
       int from_reg;
  {
+   /* When outputting an inline function, this can happen
+      for a reg that isn't actually used.  */
+   if (regno_reg_rtx[i] == 0)
+     return;
+ 
    /* If the reg got changed to a MEM at rtl-generation time,
       ignore it.  */
***************
*** 1256,1260 ****
       struct hard_reg_n_uses *p1, *p2;
  {
!   return p1->uses - p2->uses;
  }
  
--- 1391,1399 ----
       struct hard_reg_n_uses *p1, *p2;
  {
!   int tem = p1->uses - p2->uses;
!   if (tem != 0) return tem;
!   /* If regs are equally good, sort by regno,
!      so that the results of qsort leave nothing to chance.  */
!   return p1->regno - p2->regno;
  }
  
***************
*** 1297,1302 ****
    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
      if (fixed_regs[i] || regs_explicitly_used[i])
!       hard_reg_n_uses[i].uses = large;
!   hard_reg_n_uses[FRAME_POINTER_REGNUM].uses = large;
  
    qsort (hard_reg_n_uses, FIRST_PSEUDO_REGISTER,
--- 1436,1441 ----
    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
      if (fixed_regs[i] || regs_explicitly_used[i])
!       hard_reg_n_uses[i].uses += large;
!   hard_reg_n_uses[FRAME_POINTER_REGNUM].uses += large;
  
    qsort (hard_reg_n_uses, FIRST_PSEUDO_REGISTER,
***************
*** 1421,1425 ****
  		 load insns to reload them.  Maybe output store insns too.
  		 Record the choices of reload reg in reload_reg_rtx.  */
! 	      choose_reload_targets (insn);
  	      /* Substitute the chosen reload regs from reload_reg_rtx
  		 into the insn's body (or perhaps into the bodies of other
--- 1560,1569 ----
  		 load insns to reload them.  Maybe output store insns too.
  		 Record the choices of reload reg in reload_reg_rtx.  */
! 	      choose_reload_regs (insn);
! 
! 	      /* Generate the insns to reload operands into or out of
! 		 their reload regs.  */
! 	      emit_reload_insns (insn);
! 
  	      /* Substitute the chosen reload regs from reload_reg_rtx
  		 into the insn's body (or perhaps into the bodies of other
***************
*** 1557,1562 ****
    /* Consider reloads in order of increasing reg-class number.  */
    t = (int) reload_reg_class[r1] - (int) reload_reg_class[r2];
!   return t;
  }
  
  /* Assign hard reg targets for the pseudo-registers we must reload
--- 1701,1853 ----
    /* Consider reloads in order of increasing reg-class number.  */
    t = (int) reload_reg_class[r1] - (int) reload_reg_class[r2];
!   if (t != 0) return t;
!   /* If reloads are equally urgent, sort by reload number,
!      so that the results of qsort leave nothing to chance.  */
!   return r1 - r2;
! }
! \f


! /* The following tables are indexed by register number,
!    not by spill_regs index.  */
! 
! /* 1 if reg is in use as a reload reg for a RELOAD_OTHER reload.  */
! static char reload_reg_in_use[FIRST_PSEUDO_REGISTER];
! /* 1 if reg is in use for a RELOAD_FOR_INPUT_RELOAD_ADDRESS reload.  */
! static char reload_reg_in_use_for_inputs[FIRST_PSEUDO_REGISTER];
! /* 1 if reg is in use for a RELOAD_FOR_OUTPUT_RELOAD_ADDRESS reload.  */
! static char reload_reg_in_use_for_outputs[FIRST_PSEUDO_REGISTER];
! /* 1 if reg is in use for a RELOAD_FOR_OPERAND_ADDRESS reload.  */
! static char reload_reg_in_use_for_operands[FIRST_PSEUDO_REGISTER];
! 
! /* 1 if reg is in use as a reload reg for any sort of reload.  */
! static char reload_reg_in_use_at_all[FIRST_PSEUDO_REGISTER];
! 
! /* Mark reg REGNO as in use for a reload of the sort spec'd by WHEN_NEEDED.  */
! 
! static void
! mark_reload_reg_in_use (regno, when_needed)
!      int regno;
!      enum reload_when_needed when_needed;
! {
!   switch (when_needed)
!     {
!     case RELOAD_OTHER:
!       reload_reg_in_use[regno] = 1;
!       break;
! 
!     case RELOAD_FOR_INPUT_RELOAD_ADDRESS:
!       reload_reg_in_use_for_inputs[regno] = 1;
!       break;
! 
!     case RELOAD_FOR_OUTPUT_RELOAD_ADDRESS:
!       reload_reg_in_use_for_outputs[regno] = 1;
!       break;
! 
!     case RELOAD_FOR_OPERAND_ADDRESS:
!       reload_reg_in_use_for_operands[regno] = 1;
!       break;
!     }
!   reload_reg_in_use_at_all[regno] = 1;
! }
! 
! /* 1 if reg REGNO is free as a reload reg for a reload of the sort
!    specified by WHEN_NEEDED.  */
! 
! static int
! reload_reg_free_p (regno, when_needed)
!      int regno;
!      enum reload_when_needed when_needed;
! {
!   /* In use for a RELOAD_OTHER means it's not available for anything.  */
!   if (reload_reg_in_use[regno])
!     return 0;
!   switch (when_needed)
!     {
!     case RELOAD_OTHER:
!       /* In use for anything means not available for a RELOAD_OTHER.  */
!       return ! reload_reg_in_use_at_all[regno];
! 
!       /* The other three kinds of use can share a register.  */
!     case RELOAD_FOR_INPUT_RELOAD_ADDRESS:
!       return ! reload_reg_in_use_for_inputs[regno];
!     case RELOAD_FOR_OUTPUT_RELOAD_ADDRESS:
!       return ! reload_reg_in_use_for_outputs[regno];
!     case RELOAD_FOR_OPERAND_ADDRESS:
!       return ! reload_reg_in_use_for_operands[regno];
!     }
! }
! 
! /* Return 1 if the value in reload reg REGNO, as used by a reload
!    needed for the part of the insn specified by WHEN_NEEDED,
!    is not in use for a reload in any prior part of the insn.  */
! 
! static int
! reload_reg_free_before_p (regno, when_needed)
!      int regno;
!      enum reload_when_needed when_needed;
! {
!   switch (when_needed)
!     {
!     case RELOAD_OTHER:
!       /* Since a RELOAD_OTHER reload claims the reg for the entire insn,
! 	 its use starts from the beginning, so nothing can use it earlier.  */
!       return 1;
! 
!       /* If this use is for part of the insn,
! 	 check the reg is not in use for any prior part.  */
!     case RELOAD_FOR_OUTPUT_RELOAD_ADDRESS:
!       if (reload_reg_in_use_for_operands[regno])
! 	return 0;
!     case RELOAD_FOR_OPERAND_ADDRESS:
!       if (reload_reg_in_use_for_inputs[regno])
! 	return 0;
!     case RELOAD_FOR_INPUT_RELOAD_ADDRESS:
!       return 1;
!     }
! }
! 
! /* Return 1 if the value in reload reg REGNO, as used by a reload
!    needed for the part of the insn specified by WHEN_NEEDED,
!    is still available in REGNO at the end of the insn.  */
! 
! static int
! reload_reg_reaches_end_p (regno, when_needed)
!      int regno;
!      enum reload_when_needed when_needed;
! {
!   switch (when_needed)
!     {
!     case RELOAD_OTHER:
!       /* Since a RELOAD_OTHER reload claims the reg for the entire insn,
! 	 its value must reach the end.  */
!       return 1;
! 
!       /* If this use is for part of the insn,
! 	 its value reaches if no subsequent part uses the same register.  */
!     case RELOAD_FOR_INPUT_RELOAD_ADDRESS:
!       if (reload_reg_in_use_for_operands[regno])
! 	return 0;
!     case RELOAD_FOR_OPERAND_ADDRESS:
!       if (reload_reg_in_use_for_outputs[regno])
! 	return 0;
!     case RELOAD_FOR_OUTPUT_RELOAD_ADDRESS:
!       return 1;
!     }
  }
+ \f


+ /* Vector of reload-numbers showing the order in which the reloads should
+    be processed.  */
+ short reload_order[MAX_RELOADS];
+ 
+ /* Indexed by reload number, 1 if incoming value
+    inherited from previous insns.  */
+ char reload_inherited[MAX_RELOADS];
+ 
+ /* If non-zero, this is a place to get the value of the reload,
+    rather than using reload_in.  */
+ rtx reload_override_in[MAX_RELOADS];
+ 
+ /* For each reload, the index in spill_regs of the spill register used,
+    or -1 if we did not need one of the spill registers for this reload.  */
+ int reload_spill_index[MAX_RELOADS];
  
  /* Assign hard reg targets for the pseudo-registers we must reload
***************
*** 1568,1587 ****
  
  static void
! choose_reload_targets (insn)
       rtx insn;
  {
    register int j;
-   char reload_reg_in_use[FIRST_PSEUDO_REGISTER];
-   short reload_order[FIRST_PSEUDO_REGISTER];
-   char reload_inherited[FIRST_PSEUDO_REGISTER];
    int have_groups = 0;
! 
!   /* For each reload, the index in spill_regs of the spill register used,
!      or -1 if we did not need one of the spill registers for this reload.  */
!   int reload_spill_index[FIRST_PSEUDO_REGISTER];
  
!   bzero (reload_inherited, FIRST_PSEUDO_REGISTER);
    bzero (reload_reg_in_use, FIRST_PSEUDO_REGISTER);
  
    /* In order to be certain of getting the registers we need,
       we must sort the reloads into order of increasing register class.
--- 1859,1892 ----
  
  static void
! choose_reload_regs (insn)
       rtx insn;
  {
    register int j;
    int have_groups = 0;
!   /* Non-zero means we must reuse spill regs for multiple reloads in this insn
!      or we will not have enough spill regs.  */
!   int must_reuse = 0;
  
!   bzero (reload_inherited, MAX_RELOADS);
!   bzero (reload_override_in, MAX_RELOADS * sizeof (rtx));
    bzero (reload_reg_in_use, FIRST_PSEUDO_REGISTER);
+   bzero (reload_reg_in_use_at_all, FIRST_PSEUDO_REGISTER);
+   bzero (reload_reg_in_use_for_inputs, FIRST_PSEUDO_REGISTER);
+   bzero (reload_reg_in_use_for_outputs, FIRST_PSEUDO_REGISTER);
+   bzero (reload_reg_in_use_for_operands, FIRST_PSEUDO_REGISTER);
  
+   /* See if we have more mandatory reloads than spill regs.
+      If so, then we cannot risk optimizations that could prevent
+      reloads from sharing one spill register.  */
+ 
+   {
+     int tem = 0;
+     for (j = 0; j < n_reloads; j++)
+       if (! reload_optional[j] && reload_reg_rtx[j] == 0)
+ 	tem++;
+     if (tem > n_spills)
+       must_reuse = 1;
+   }
+ 
    /* In order to be certain of getting the registers we need,
       we must sort the reloads into order of increasing register class.
***************
*** 1612,1615 ****
--- 1917,1924 ----
        if (CLASS_MAX_NREGS (reload_reg_class[j], mode) > 1)
  	have_groups = 1;
+       /* If we have already decided to use a certain register,
+ 	 don't use it in another way.  */
+       if (reload_reg_rtx[j])
+ 	mark_reload_reg_in_use (REGNO (reload_reg_rtx[j]), reload_when_needed[j]);
      }
  
***************
*** 1636,1655 ****
  
        if (reload_reg_rtx[r] != 0)
! 	{
! #if 0
! 	  /* But do see if the chosen reload-reg already contains
! 	     a copy of the desired value.  */
! 	  if (reload_in[r] != 0)
! 	    {
! 	      register rtx equiv
! 		= find_equiv_reg (reload_in[r], insn, 0,
! 				  REGNO (reload_reg_rtx[r]), 0, 0,
! 				  reload_mode);
! 	      if (equiv != 0)
! 		reload_inherited[r] = 1;
! 	    }
! #endif
! 	  continue;
! 	}
  
        /* First see if this pseudo is already available as reloaded
--- 1945,1949 ----
  
        if (reload_reg_rtx[r] != 0)
! 	continue;
  
        /* First see if this pseudo is already available as reloaded
***************
*** 1681,1685 ****
  	if (regno >= 0
  	    && reg_last_reload_reg[regno] != 0
! 	    && ! have_groups)
  	  {
  	    i = spill_reg_order[REGNO (reg_last_reload_reg[regno])];
--- 1975,1981 ----
  	if (regno >= 0
  	    && reg_last_reload_reg[regno] != 0
! 	    && ! have_groups
! 	    /* See comment at next use of must_reuse.  */
! 	    && ! must_reuse)
  	  {
  	    i = spill_reg_order[REGNO (reg_last_reload_reg[regno])];
***************
*** 1686,1696 ****
  
  	    if (reg_reloaded_contents[i] == regno
  		&& TEST_HARD_REG_BIT (reg_class_contents[(int) reload_reg_class[r]],
  				      spill_regs[i])
! 		&& ! reload_reg_in_use[spill_regs[i]])
  	      {
! 		/* Mark the reload register as in use for this insn.  */
  		reload_reg_rtx[r] = reg_last_reload_reg[regno];
- 		reload_reg_in_use[spill_regs[i]] = 1;
  		reload_inherited[r] = 1;
  		reload_spill_index[r] = i;
--- 1982,1995 ----
  
  	    if (reg_reloaded_contents[i] == regno
+ 		&& HARD_REGNO_MODE_OK (regno, reload_mode)
  		&& TEST_HARD_REG_BIT (reg_class_contents[(int) reload_reg_class[r]],
  				      spill_regs[i])
! 		&& reload_reg_free_p (spill_regs[i], reload_when_needed[r])
! 		&& reload_reg_free_before_p (spill_regs[i],
! 					     reload_when_needed[r]))
  	      {
! 		/* Mark the register as in use for this part of the insn.  */
! 		mark_reload_reg_in_use (spill_regs[i], reload_when_needed[r]);
  		reload_reg_rtx[r] = reg_last_reload_reg[regno];
  		reload_inherited[r] = 1;
  		reload_spill_index[r] = i;
***************
*** 1707,1719 ****
  	      || GET_CODE (reload_in[r]) == REG
  	      || GET_CODE (reload_in[r]) == MEM)
! 	  && ! have_groups)
  	{
- 	  /* We don't allow any spill regs to be found by this call,
- 	     since they might be needed for reloads yet to be processed,
- 	     even if not now in reload_reg_rtx.  */
  	  register rtx equiv
  	    = find_equiv_reg (reload_in[r], insn, reload_reg_class[r],
! 			      -1, spill_reg_order, 0, reload_mode);
  
  	  /* We found a register that contains the value we need.
  	     If this register is the same as an `earlyclobber' operand
--- 2006,2042 ----
  	      || GET_CODE (reload_in[r]) == REG
  	      || GET_CODE (reload_in[r]) == MEM)
! 	  && ! have_groups
! 	  /* This optimization can prevent this reload from reusing
! 	     a spill reg used for another reload.  That could take away
! 	     a spill reg that another reload will need.  If we cannot
! 	     be sure there will still be enough spill regs,
! 	     don't do this optimization.  */
! 	  && ! must_reuse)
  	{
  	  register rtx equiv
  	    = find_equiv_reg (reload_in[r], insn, reload_reg_class[r],
! 			      -1, 0, 0, reload_mode);
! 	  int regno;
  
+ 	  if (equiv != 0)
+ 	    regno = REGNO (equiv);
+ 
+ 	  /* If we found a spill reg, reject it unless it is free
+ 	     and of the desired class.  */
+ 	  if (equiv != 0 && GET_CODE (equiv) == REG
+ 	      && spill_reg_order[regno] >= 0
+ 	      && reload_reg_free_before_p (regno, reload_when_needed[r]))
+ 	    {
+ 	      if (! TEST_HARD_REG_BIT (reg_class_contents[(int) reload_reg_class[r]],
+ 				       regno))
+ 		equiv = 0;
+ 	    }
+ 
+ 	  if (equiv != 0 && reload_reg_in_use_at_all[regno])
+ 	    equiv = 0;
+ 
+ 	  if (equiv != 0 && ! HARD_REGNO_MODE_OK (regno, reload_mode))
+ 	    equiv = 0;
+ 
  	  /* We found a register that contains the value we need.
  	     If this register is the same as an `earlyclobber' operand
***************
*** 1725,1729 ****
  	      if (reg_overlap_mentioned_p (equiv, reload_earlyclobbers[i]))
  		{
! 		  reload_in[r] = equiv;
  		  equiv = 0;
  		  break;
--- 2048,2052 ----
  	      if (reg_overlap_mentioned_p (equiv, reload_earlyclobbers[i]))
  		{
! 		  reload_override_in[r] = equiv;
  		  equiv = 0;
  		  break;
***************
*** 1744,1748 ****
  		  int nr = HARD_REGNO_NREGS (spill_regs[i], reload_mode);
  		  while (nr > 0)
! 		    reload_reg_in_use[REGNO (equiv) + --nr] = 1;
  		}
  	    }
--- 2067,2072 ----
  		  int nr = HARD_REGNO_NREGS (spill_regs[i], reload_mode);
  		  while (nr > 0)
! 		    mark_reload_reg_in_use (REGNO (equiv) + --nr,
! 					    reload_when_needed[r]);
  		}
  	    }
***************
*** 1774,1778 ****
  	    int regno = spill_regs[i];
  	    int class = (int) reload_reg_class[r];
! 	    if (reload_reg_in_use[regno] == 0
  		&& TEST_HARD_REG_BIT (reg_class_contents[class],
  				      regno)
--- 2098,2102 ----
  	    int regno = spill_regs[i];
  	    int class = (int) reload_reg_class[r];
! 	    if (reload_reg_in_use_at_all[regno] == 0
  		&& TEST_HARD_REG_BIT (reg_class_contents[class],
  				      regno)
***************
*** 1779,1783 ****
  		&& !(regno + 1 < FIRST_PSEUDO_REGISTER
  		     && spill_reg_order[regno + 1] >= 0
! 		     && reload_reg_in_use[regno + 1] == 0
  		     && TEST_HARD_REG_BIT (reg_class_contents[class],
  					   regno + 1))
--- 2103,2107 ----
  		&& !(regno + 1 < FIRST_PSEUDO_REGISTER
  		     && spill_reg_order[regno + 1] >= 0
! 		     && reload_reg_in_use_at_all[regno + 1] == 0
  		     && TEST_HARD_REG_BIT (reg_class_contents[class],
  					   regno + 1))
***************
*** 1784,1788 ****
  		&& !(regno > 0
  		     && spill_reg_order[regno - 1] >= 0
! 		     && reload_reg_in_use[regno - 1] == 0
  		     && TEST_HARD_REG_BIT (reg_class_contents[class],
  					   regno - 1)))
--- 2108,2112 ----
  		&& !(regno > 0
  		     && spill_reg_order[regno - 1] >= 0
! 		     && reload_reg_in_use_at_all[regno - 1] == 0
  		     && TEST_HARD_REG_BIT (reg_class_contents[class],
  					   regno - 1)))
***************
*** 1802,1806 ****
  	    int regno = spill_regs[i];
  	    int class = (int) reload_reg_class[r];
! 	    if (reload_reg_in_use[regno] == 0
  		&& TEST_HARD_REG_BIT (reg_class_contents[class],
  				      regno)
--- 2126,2130 ----
  	    int regno = spill_regs[i];
  	    int class = (int) reload_reg_class[r];
! 	    if (reload_reg_in_use_at_all[regno] == 0
  		&& TEST_HARD_REG_BIT (reg_class_contents[class],
  				      regno)
***************
*** 1807,1811 ****
  		&& (!(regno + 1 < FIRST_PSEUDO_REGISTER
  		      && spill_reg_order[regno + 1] >= 0
! 		      && reload_reg_in_use[regno + 1] == 0
  		      && TEST_HARD_REG_BIT (reg_class_contents[class],
  					    regno + 1))
--- 2131,2135 ----
  		&& (!(regno + 1 < FIRST_PSEUDO_REGISTER
  		      && spill_reg_order[regno + 1] >= 0
! 		      && reload_reg_in_use_at_all[regno + 1] == 0
  		      && TEST_HARD_REG_BIT (reg_class_contents[class],
  					    regno + 1))
***************
*** 1812,1816 ****
  		    || !(regno > 0
  			 && spill_reg_order[regno - 1] >= 0
! 			 && reload_reg_in_use[regno - 1] == 0
  			 && TEST_HARD_REG_BIT (reg_class_contents[class],
  					       regno - 1))))
--- 2136,2140 ----
  		    || !(regno > 0
  			 && spill_reg_order[regno - 1] >= 0
! 			 && reload_reg_in_use_at_all[regno - 1] == 0
  			 && TEST_HARD_REG_BIT (reg_class_contents[class],
  					       regno - 1))))
***************
*** 1824,1827 ****
--- 2148,2152 ----
        if (i == n_spills)
  	{
+ 	  int pass;
  	  /* If we put this reload ahead, thinking it is a group,
  	     then insist on finding a group.  Otherwise we can grab a
***************
*** 1840,1884 ****
  	    force_group = 0;
  
! 	  for (i = 0; i < n_spills; i++)
  	    {
! 	      int class = (int) reload_reg_class[r];
! 	      if (reload_reg_in_use[spill_regs[i]] == 0
! 		  && TEST_HARD_REG_BIT (reg_class_contents[class],
! 					spill_regs[i]))
  		{
! 		  int nr = HARD_REGNO_NREGS (spill_regs[i], reload_mode);
! 		  /* Avoid the problem where spilling a GENERAL_OR_FP_REG
! 		     (on 68000) got us two FP regs.  If NR is 1,
! 		     we would reject both of them.  */
! 		  if (force_group)
! 		    nr = CLASS_MAX_NREGS (reload_reg_class[r], reload_mode);
! 		  /* If we need only one reg, we have already won.  */
! 		  if (nr == 1)
  		    {
! 		      /* But reject a single reg if we demand a group.  */
  		      if (force_group)
! 			continue;
! 		      break;
! 		    }
! 		  /* Otherwise check that as many consecutive regs as we need
! 		     are available here.
! 		     Also, don't use for a group registers that are
! 		     needed for nongroups.  */
! 		  if (HARD_REGNO_MODE_OK (spill_regs[i], reload_mode)
! 		      && ! counted_for_nongroups[spill_regs[i]])
! 		    while (nr > 1)
! 		      {
! 			int regno = spill_regs[i] + nr - 1;
! 			if (!(TEST_HARD_REG_BIT (reg_class_contents[class],
! 						 regno)
! 			      && spill_reg_order[regno] >= 0
! 			      && reload_reg_in_use[regno] == 0
! 			      && ! counted_for_nongroups[regno]))
  			  break;
! 			nr--;
! 		      }
! 		  if (nr == 1)
! 		    break;
! 		}
  	    }
  	}
--- 2165,2217 ----
  	    force_group = 0;
  
! 	  for (pass = 0; pass < 2; pass++)
  	    {
! 	      for (i = 0; i < n_spills; i++)
  		{
! 		  int class = (int) reload_reg_class[r];
! 		  if (reload_reg_free_p (spill_regs[i], reload_when_needed[r])
! 		      && TEST_HARD_REG_BIT (reg_class_contents[class],
! 					    spill_regs[i])
! 		      /* Look first for regs to share, then for unshared.  */
! 		      && (pass || reload_reg_in_use_at_all[spill_regs[i]]))
  		    {
! 		      int nr = HARD_REGNO_NREGS (spill_regs[i], reload_mode);
! 		      /* Avoid the problem where spilling a GENERAL_OR_FP_REG
! 			 (on 68000) got us two FP regs.  If NR is 1,
! 			 we would reject both of them.  */
  		      if (force_group)
! 			nr = CLASS_MAX_NREGS (reload_reg_class[r], reload_mode);
! 		      /* If we need only one reg, we have already won.  */
! 		      if (nr == 1)
! 			{
! 			  /* But reject a single reg if we demand a group.  */
! 			  if (force_group)
! 			    continue;
  			  break;
! 			}
! 		      /* Otherwise check that as many consecutive regs as we need
! 			 are available here.
! 			 Also, don't use for a group registers that are
! 			 needed for nongroups.  */
! 		      if (HARD_REGNO_MODE_OK (spill_regs[i], reload_mode)
! 			  && ! counted_for_nongroups[spill_regs[i]])
! 			while (nr > 1)
! 			  {
! 			    int regno = spill_regs[i] + nr - 1;
! 			    if (!(TEST_HARD_REG_BIT (reg_class_contents[class],
! 						     regno)
! 				  && spill_reg_order[regno] >= 0
! 				  && reload_reg_free_p (regno, reload_when_needed[r])
! 				  && ! counted_for_nongroups[regno]))
! 			      break;
! 			    nr--;
! 			  }
! 		      if (nr == 1)
! 			break;
! 		    }
! 		}
! 	      /* If find something on pass 1, omit pass 2.  */
! 	      if (i < n_spills)
! 		break;
  	    }
  	}
***************
*** 1893,1897 ****
  	while (nr > 0)
  	  {
! 	    reload_reg_in_use[spill_regs[i] + --nr] = 1;
  	    reg_reloaded_contents[spill_reg_order[spill_regs[i] + nr]] = -1;
  	  }
--- 2226,2231 ----
  	while (nr > 0)
  	  {
! 	    mark_reload_reg_in_use (spill_regs[i] + --nr,
! 				    reload_when_needed[r]);
  	    reg_reloaded_contents[spill_reg_order[spill_regs[i] + nr]] = -1;
  	  }
***************
*** 1907,1911 ****
  
        /* Detect when the reload reg can't hold the reload mode.  */
!       if (! HARD_REGNO_MODE_OK (REGNO (reload_reg_rtx[r]), reload_mode))
  	{
  	  if (asm_noperands (PATTERN (insn)) < 0)
--- 2241,2251 ----
  
        /* Detect when the reload reg can't hold the reload mode.  */
!       if (! HARD_REGNO_MODE_OK (REGNO (reload_reg_rtx[r]), reload_mode)
! 	  || (reload_in[r] != 0
! 	      && ! HARD_REGNO_MODE_OK (REGNO (reload_reg_rtx[r]),
! 				       GET_MODE (reload_in[r])))
! 	  || (reload_out[r] != 0
! 	      && ! HARD_REGNO_MODE_OK (REGNO (reload_reg_rtx[r]),
! 				       GET_MODE (reload_out[r]))))
  	{
  	  if (asm_noperands (PATTERN (insn)) < 0)
***************
*** 1923,1926 ****
--- 2263,2295 ----
      }
  
+   /* If we thought we could inherit a reload, because it seemed that
+      nothing else wanted the same reload register earlier in the insn,
+      verify that assumption, now that all reloads have been assigned.  */
+ 
+   for (j = 0; j < n_reloads; j++)
+     {
+       register int r = reload_order[j];
+ 
+       if (reload_inherited[r] && reload_reg_rtx[r] != 0
+ 	  && ! reload_reg_free_before_p (REGNO (reload_reg_rtx[r]),
+ 					 reload_when_needed[r]))
+ 	reload_inherited[r] = 0;
+ 
+       /* If we found a better place to reload from,
+ 	 validate it in the same fashion, if it is a reload reg.  */
+       if (reload_override_in[r]
+ 	  && GET_CODE (reload_override_in[r]) == REG
+ 	  && spill_reg_order[REGNO (reload_override_in[r])] >= 0
+ 	  && ! reload_reg_free_before_p (REGNO (reload_override_in[r]),
+ 					 reload_when_needed[r]))
+ 	reload_override_in[r] = 0;
+     }
+ 
+   /* Now that reload_override_in is known valid,
+      actually override reload_in.  */
+   for (j = 0; j < n_reloads; j++)
+     if (reload_override_in[j])
+       reload_in[j] = reload_override_in[j];
+ 
    /* For all the spill regs newly reloaded in this instruction,
       record what they were reloaded from, so subsequent instructions
***************
*** 1945,1948 ****
--- 2314,2319 ----
  	      reg_has_output_reload[nregno] = 1;
  	      reg_is_output_reload[spill_regs[i]] = 1;
+ 	      if (reload_when_needed[r] != RELOAD_OTHER)
+ 		abort ();
  	    }
  	  /* Maybe the spill reg contains a copy of reload_in.  */
***************
*** 1956,1962 ****
  	      else
  		nregno = REGNO (reload_in_reg[r]);
  	      /* If there are two separate reloads (one in and one out)
! 		 for the same (hard or pseudo) reg, set reg_last_reload_reg
! 		 based on the output reload.  */
  	      if (!reg_has_output_reload[nregno])
  		{
--- 2327,2336 ----
  	      else
  		nregno = REGNO (reload_in_reg[r]);
+ 
  	      /* If there are two separate reloads (one in and one out)
! 		 for the same (hard or pseudo) reg,
! 		 leave reg_last_reload_reg set 
! 		 based on the output reload.
! 		 Otherwise, set it from this input reload.  */
  	      if (!reg_has_output_reload[nregno])
  		{
***************
*** 1963,1966 ****
--- 2337,2346 ----
  		  reg_last_reload_reg[nregno] = reload_reg_rtx[r];
  		  reg_reloaded_contents[i] = nregno;
+ 
+ 		  /* But don't do so if another input reload
+ 		     will clobber this one's value.  */
+ 		  if (! reload_reg_reaches_end_p (spill_regs[i],
+ 						  reload_when_needed[r]))
+ 		    reg_reloaded_contents[i] = -1;
  		}
  	    }
***************
*** 1987,1990 ****
--- 2367,2383 ----
  	}
      }
+ }
+ \f


+ /* Output insns to reload values in and out of the chosen reload regs.  */
+ 
+ static void
+ emit_reload_insns (insn)
+      rtx insn;
+ {
+   register int j;
+   rtx first_output_reload_insn = NEXT_INSN (insn);
+   rtx first_other_reload_insn = insn;
+   rtx first_operand_address_reload_insn = insn;
+   int special;
  
    /* Now output the instructions to copy the data into and out of the
***************
*** 2006,2009 ****
--- 2399,2404 ----
  	  rtx oldequiv = 0;
  	  enum machine_mode mode;
+ 	  rtx where;
+ 	  rtx this_reload_insn = 0;
  
  #if 0
***************
*** 2074,2077 ****
--- 2469,2482 ----
  				       -1, 0, 0, mode);
  
+ 	  /* If OLDEQUIV is a spill register, don't use it for this
+ 	     if any other reload needs it at an earlier stage of this insn
+ 	     or at this stage.  */	   
+ 	  if (oldequiv && GET_CODE (oldequiv) == REG
+ 	      && spill_reg_order[REGNO (oldequiv)] >= 0
+ 	      && (! reload_reg_free_p (REGNO (oldequiv), reload_when_needed[j])
+ 		  || ! reload_reg_free_before_p (REGNO (oldequiv),
+ 						 reload_when_needed[j])))
+ 	    oldequiv = 0;
+ 
  	  if (oldequiv == 0)
  	    oldequiv = old;
***************
*** 2088,2091 ****
--- 2493,2515 ----
  	    oldequiv = gen_rtx (SUBREG, mode, oldequiv, 0);
  
+ 	  /* Decide where to put reload insn for this reload.  */
+ 	  switch (reload_when_needed[j])
+ 	    {
+ 	    case RELOAD_OTHER:
+ 	      where = first_operand_address_reload_insn;
+ 	      break;
+ 	    case RELOAD_FOR_INPUT_RELOAD_ADDRESS:
+ 	      where = first_other_reload_insn;
+ 	      break;
+ 	    case RELOAD_FOR_OUTPUT_RELOAD_ADDRESS:
+ 	      where = first_output_reload_insn;
+ 	      break;
+ 	    case RELOAD_FOR_OPERAND_ADDRESS:
+ 	      where = insn;
+ 	    }
+ 
+ 	  special = 0;
+ 
+ 	  /* Auto-increment addresses must be reloaded in a special way.  */
  	  if (GET_CODE (oldequiv) == POST_INC
  	      || GET_CODE (oldequiv) == POST_DEC
***************
*** 2092,2096 ****
  	      || GET_CODE (oldequiv) == PRE_INC
  	      || GET_CODE (oldequiv) == PRE_DEC)
! 	    inc_for_reload (reloadreg, oldequiv, reload_inc[j], insn);
  
  	  /* If we are reloading a pseudo-register that was set by the previous
--- 2516,2526 ----
  	      || GET_CODE (oldequiv) == PRE_INC
  	      || GET_CODE (oldequiv) == PRE_DEC)
! 	    {
! 	      /* Prevent normal processing of this reload.  */
! 	      special = 1;
! 	      /* Output a special code sequence for this case.  */
! 	      this_reload_insn
! 		= inc_for_reload (reloadreg, oldequiv, reload_inc[j], where);
! 	    }
  
  	  /* If we are reloading a pseudo-register that was set by the previous
***************
*** 2100,2104 ****
  	  else if (optimize && GET_CODE (old) == REG
  		   && REGNO (old) >= FIRST_PSEUDO_REGISTER
! 		   && dead_or_set_p (insn, old))
  	    {
  	      rtx temp = PREV_INSN (insn);
--- 2530,2538 ----
  	  else if (optimize && GET_CODE (old) == REG
  		   && REGNO (old) >= FIRST_PSEUDO_REGISTER
! 		   && dead_or_set_p (insn, old)
! 		   /* This is unsafe if some other reload
! 		      uses the same reg first.  */
! 		   && (reload_when_needed[j] == RELOAD_OTHER
! 		       || reload_when_needed[j] == RELOAD_FOR_INPUT_RELOAD_ADDRESS))
  	    {
  	      rtx temp = PREV_INSN (insn);
***************
*** 2109,2112 ****
--- 2543,2548 ----
  		  && GET_CODE (PATTERN (temp)) == SET
  		  && SET_DEST (PATTERN (temp)) == old
+ 		  /* Make sure we can access insn_operand_constraint.  */
+ 		  && asm_noperands (PATTERN (temp)) < 0
  		  /* This is unsafe if prev insn rejects our reload reg.  */
  		  && constraint_accepts_reg_p (insn_operand_constraint[recog_memoized (temp)][0],
***************
*** 2128,2167 ****
  		      alter_reg (REGNO (old), -1);
  		    }
  		}
- 	      else
- 		/* We can't do that, so output an insn to load RELOADREG.  */
- 		emit_insn_before (gen_move_insn (reloadreg, oldequiv), insn);
  	    }
- 	  else
- 	    /* We can't do that, so output an insn to load RELOADREG.  */
- 	    emit_insn_before (gen_move_insn (reloadreg, oldequiv), insn);
  
! #ifdef PRESERVE_DEATH_INFO_REGNO_P
! 	  if (PRESERVE_DEATH_INFO_REGNO_P (REGNO (reloadreg)))
! 	    {
! #if 0
! 	      /* An input reload means the original reg is no longer
! 		 used, therefore no longer dies here.  */
! 	      /* Deleted because it interferes with deletion (below)
! 		 of the insn that stored the output reload.
! 		 Also, who cares about OLDEQUIV's death notes?  */
! 
! 	      if (GET_CODE (oldequiv) == REG
! 		  && regno_dead_p (REGNO (oldequiv), insn))
! 		remove_death (REGNO (oldequiv), insn);
! #endif
! 
! 	      /* Add a death note to this insn, for an input reload.  */
! 
! 	      if (! dead_or_set_p (insn, reloadreg))
! 		REG_NOTES (insn)
! 		  = gen_rtx (EXPR_LIST, REG_DEAD,
! 			     reloadreg, REG_NOTES (insn));
! 	    }
! #endif
  
! 	  /* reload_inc[j] was processed here.  */
  	}
  
  #ifdef PRESERVE_DEATH_INFO_REGNO_P
        /* For some registers it is important to keep the REG_DEATH
--- 2564,2630 ----
  		      alter_reg (REGNO (old), -1);
  		    }
+ 		  special = 1;
  		}
  	    }
  
! 	  /* We can't do that, so output an insn to load RELOADREG.
! 	     Keep them in the following order:
! 	     all reloads for input reload addresses,
! 	     all reloads for ordinary input operands,
! 	     all reloads for addresses of non-reloaded operands,
! 	     the insn being reloaded,
! 	     all reloads for addresses of output reloads,
! 	     the output reloads.  */
! 	  if (! special)
! 	    this_reload_insn = gen_input_reload (reloadreg, oldequiv, where);
! 
! 	  /* Update where to put other reload insns.  */
! 	  if (this_reload_insn)
! 	    switch (reload_when_needed[j])
! 	      {
! 	      case RELOAD_OTHER:
! 		if (first_other_reload_insn == first_operand_address_reload_insn)
! 		  first_other_reload_insn = this_reload_insn;
! 		break;
! 	      case RELOAD_FOR_OPERAND_ADDRESS:
! 		if (first_operand_address_reload_insn == insn)
! 		  first_operand_address_reload_insn = this_reload_insn;
! 		if (first_other_reload_insn == insn)
! 		  first_other_reload_insn = this_reload_insn;
! 	      }
  
! 	  /* reload_inc[j] was formerly processed here.  */
  	}
  
+       /* Add a note saying the input reload reg
+ 	 dies in this insn, if anyone cares.  */
+ #ifdef PRESERVE_DEATH_INFO_REGNO_P
+       if (old != 0
+ 	  && reload_reg_rtx[j] != old
+ 	  && reload_reg_rtx[j] != 0
+ 	  && reload_out[j] == 0
+ 	  && PRESERVE_DEATH_INFO_REGNO_P (REGNO (reload_reg_rtx[j])))
+ 	{
+ 	  register rtx reloadreg = reload_reg_rtx[j];
+ 
+ 	  /* The code below is incorrect except for RELOAD_OTHER.  */
+ 	  if (reload_when_needed[j] != RELOAD_OTHER)
+ 	    abort ();
+ 
+ 	  /* Add a death note to this insn, for an input reload.  */
+ 
+ 	  if (! dead_or_set_p (insn, reloadreg))
+ 	    REG_NOTES (insn)
+ 	      = gen_rtx (EXPR_LIST, REG_DEAD,
+ 			 reloadreg, REG_NOTES (insn));
+ 	}
+ #endif
+ 
+       /* ??? The following code is inadequate.
+ 	 It handles regs inherited via reg_last_reloaded_contents
+ 	 but not those inherited via find_equiv_reg.
+ 	 Note that we can't expect spill_reg_store to contain anything
+ 	 useful in the case of find_equiv_reg.  */
+ 
  #ifdef PRESERVE_DEATH_INFO_REGNO_P
        /* For some registers it is important to keep the REG_DEATH
***************
*** 2188,2191 ****
--- 2651,2657 ----
  
        if (optimize && reload_inherited[j] && reload_spill_index[j] >= 0
+ 	  /* This is unsafe if some other reload uses the same reg first.  */
+ 	  && (reload_when_needed[j] == RELOAD_OTHER
+ 	      || reload_when_needed[j] == RELOAD_FOR_INPUT_RELOAD_ADDRESS)
  	  && GET_CODE (reload_in[j]) == REG
  	  && REGNO (reload_in[j]) >= FIRST_PSEUDO_REGISTER
***************
*** 2203,2207 ****
        if (old != 0
  	  && reload_reg_rtx[j] != old
! 	  && reload_reg_rtx[j] != 0)
  	{
  	  register rtx reloadreg = reload_reg_rtx[j];
--- 2669,2678 ----
        if (old != 0
  	  && reload_reg_rtx[j] != old
! 	  && reload_reg_rtx[j] != 0
! 	  /* An output operand that dies right away
! 	     does need a reload reg, but need not
! 	     be copied from it.  */
! 	  && ! (GET_CODE (old) == REG
! 		&& find_reg_note (insn, REG_DEAD, old)))
  	{
  	  register rtx reloadreg = reload_reg_rtx[j];
***************
*** 2242,2246 ****
  	    old = gen_rtx (SUBREG, mode, old, 0);
  	  /* Output the reload insn.  */
! 	  store_insn = emit_insn_after (gen_move_insn (old, reloadreg), insn);
  	  /* If this output reload doesn't come from a spill reg,
  	     clear any memory of reloaded copies of the pseudo reg.
--- 2713,2719 ----
  	    old = gen_rtx (SUBREG, mode, old, 0);
  	  /* Output the reload insn.  */
! 	  store_insn = emit_insn_before (gen_move_insn (old, reloadreg),
! 					 first_output_reload_insn);
! 	  first_output_reload_insn = store_insn;
  	  /* If this output reload doesn't come from a spill reg,
  	     clear any memory of reloaded copies of the pseudo reg.
***************
*** 2248,2254 ****
  	     reg_has_output_reload will make this do nothing.  */
  	  note_stores (PATTERN (store_insn), forget_old_reloads_1);
! 	  /* If final will look at death notes for this reg,
! 	     put one on each output-reload insn.  */
  #ifdef PRESERVE_DEATH_INFO_REGNO_P
  	  if (PRESERVE_DEATH_INFO_REGNO_P (REGNO (reloadreg)))
  	    REG_NOTES (store_insn)
--- 2721,2728 ----
  	     reg_has_output_reload will make this do nothing.  */
  	  note_stores (PATTERN (store_insn), forget_old_reloads_1);
! 
  #ifdef PRESERVE_DEATH_INFO_REGNO_P
+ 	  /* If final will look at death notes for this reg,
+ 	     put one on the output-reload insn.  */
  	  if (PRESERVE_DEATH_INFO_REGNO_P (REGNO (reloadreg)))
  	    REG_NOTES (store_insn)
***************
*** 2256,2287 ****
  			   reloadreg, REG_NOTES (store_insn));
  
! 	  {
! 	    /* Move all death-notes from the insn being reloaded
! 	       to the output reload.
! 	       This may err on the side of caution.
! 	       If one insn gets >1 output reloads, this will move
! 	       the death notes to the first output reload insn generated,
! 	       which will be the last one in the insn stream.  */
! 
! 	    /* The note we will examine next.  */
! 	    rtx reg_notes = REG_NOTES (insn);
! 	    /* The place that pointed to this note.  */
! 	    rtx *prev_reg_note = &REG_NOTES (insn);
! 
! 	    while (reg_notes)
! 	      {
! 		rtx next_reg_notes = XEXP (reg_notes, 1);
! 		if (REG_NOTE_KIND (reg_notes) == REG_DEAD)
! 		  {
! 		    *prev_reg_note = next_reg_notes;
! 		    XEXP (reg_notes, 1) = REG_NOTES (store_insn);
! 		    REG_NOTES (store_insn) = reg_notes;
! 		  }
! 		else
! 		  prev_reg_note = &XEXP (reg_notes, 1);
  
! 		reg_notes = next_reg_notes;
! 	      }
! 	  }
  #endif
  	}
--- 2730,2759 ----
  			   reloadreg, REG_NOTES (store_insn));
  
! 	  /* Move all death-notes from the insn being reloaded
! 	     to the output reload, if they are for things used
! 	     as inputs in this output reload.  */
! 	  if (GET_CODE (old) != REG)
! 	    {
! 	      /* The note we will examine next.  */
! 	      rtx reg_notes = REG_NOTES (insn);
! 	      /* The place that pointed to this note.  */
! 	      rtx *prev_reg_note = &REG_NOTES (insn);
! 
! 	      while (reg_notes)
! 		{
! 		  rtx next_reg_notes = XEXP (reg_notes, 1);
! 		  if (REG_NOTE_KIND (reg_notes) == REG_DEAD
! 		      && reg_mentioned_p (XEXP (reg_notes, 0), old))
! 		    {
! 		      *prev_reg_note = next_reg_notes;
! 		      XEXP (reg_notes, 1) = REG_NOTES (store_insn);
! 		      REG_NOTES (store_insn) = reg_notes;
! 		    }
! 		  else
! 		    prev_reg_note = &XEXP (reg_notes, 1);
  
! 		  reg_notes = next_reg_notes;
! 		}
! 	    }
  #endif
  	}
***************
*** 2291,2294 ****
--- 2763,2829 ----
  	spill_reg_store[reload_spill_index[j]] = store_insn;
      }
+ 
+   /* Move death notes from INSN to output-operand-address reload insns.  */
+ #ifdef PRESERVE_DEATH_INFO_REGNO_P
+   {
+     rtx insn1;
+     /* Loop over those insns, last ones first.  */
+     for (insn1 = PREV_INSN (first_output_reload_insn); insn1 != insn;
+ 	 insn1 = PREV_INSN (insn1))
+       if (GET_CODE (insn1) == INSN && GET_CODE (PATTERN (insn1)) == SET)
+ 	{
+ 	  rtx source = SET_SRC (PATTERN (insn1));
+ 
+ 	  /* The note we will examine next.  */
+ 	  rtx reg_notes = REG_NOTES (insn);
+ 	  /* The place that pointed to this note.  */
+ 	  rtx *prev_reg_note = &REG_NOTES (insn);
+ 
+ 	  /* If the note is for something used in the source of this
+ 	     output address reload insn, move the note.  */
+ 	  while (reg_notes)
+ 	    {
+ 	      rtx next_reg_notes = XEXP (reg_notes, 1);
+ 	      if (REG_NOTE_KIND (reg_notes) == REG_DEAD
+ 		  && reg_mentioned_p (XEXP (reg_notes, 0), source))
+ 		{
+ 		  *prev_reg_note = next_reg_notes;
+ 		  XEXP (reg_notes, 1) = REG_NOTES (insn1);
+ 		  REG_NOTES (insn1) = reg_notes;
+ 		}
+ 	      else
+ 		prev_reg_note = &XEXP (reg_notes, 1);
+ 
+ 	      reg_notes = next_reg_notes;
+ 	    }
+ 	}
+   }
+ #endif
+ }
+ \f


+ /* Emit code before BEFORE_INSN to perform an input reload of IN to RELOADREG.
+    Handle case of reloading a PLUS expression (currently only happens for
+    stack slots with out-of-range offset).
+ 
+    Returns last insn emitted.  */
+ 
+ static rtx
+ gen_input_reload (reloadreg, in, before_insn)
+      rtx reloadreg;
+      rtx in;
+      rtx before_insn;
+ {
+ #if 0  /* Install this in version 1.37.  Avoid risk for now.  */
+   if (GET_CODE (in) == PLUS)
+     {
+       /* Don't use gen_move_insn to make what is actually an add insn.  */
+       emit_insn_before (gen_move_insn (reloadreg, XEXP (in, 0)), before_insn);
+       emit_insn_before (gen_add2_insn (reloadreg, XEXP (in, 1)), before_insn);
+     }
+   else
+ #endif
+     emit_insn_before (gen_move_insn (reloadreg, in), before_insn);
+ 
+   return PREV_INSN (before_insn);
  }
  \f


***************
*** 2390,2394 ****
  
  \f


! /* Output reload-insns around INSN to reload VALUE into RELOADREG. 
     VALUE is a autoincrement or autodecrement RTX whose operand
     is a register or memory location;
--- 2925,2929 ----
  
  \f


! /* Output reload-insns to reload VALUE into RELOADREG. 
     VALUE is a autoincrement or autodecrement RTX whose operand
     is a register or memory location;
***************
*** 2396,2402 ****
  
     INC_AMOUNT is the number to increment or decrement by (always positive).
!    This cannot be deduced from VALUE.  */
  
! static void
  inc_for_reload (reloadreg, value, inc_amount, insn)
       rtx reloadreg;
--- 2931,2941 ----
  
     INC_AMOUNT is the number to increment or decrement by (always positive).
!    This cannot be deduced from VALUE.
  
!    INSN is the insn before which the new insns should be emitted.
! 
!    The return value is the first of the insns emitted.  */
! 
! static rtx
  inc_for_reload (reloadreg, value, inc_amount, insn)
       rtx reloadreg;
***************
*** 2422,2430 ****
  	   || reg_renumber[REGNO (incloc)] >= 0))
  	{
! 	  emit_insn_before (gen_add2_insn (incloc,
! 					   gen_rtx (CONST_INT, VOIDmode,
! 						    inc_amount)),
! 			    insn);
  	  emit_insn_before (gen_move_insn (reloadreg, incloc), insn);
  	}
        else
--- 2961,2971 ----
  	   || reg_renumber[REGNO (incloc)] >= 0))
  	{
! 	  rtx first_new
! 	    = emit_insn_before (gen_add2_insn (incloc,
! 					       gen_rtx (CONST_INT, VOIDmode,
! 							inc_amount)),
! 				insn);
  	  emit_insn_before (gen_move_insn (reloadreg, incloc), insn);
+ 	  return first_new;
  	}
        else
***************
*** 2433,2437 ****
  	   copy it to the reload register, increment there, then save back.  */
  	{
! 	  emit_insn_before (gen_move_insn (reloadreg, incloc), insn);
  	  emit_insn_before (gen_add2_insn (reloadreg,
  					   gen_rtx (CONST_INT, VOIDmode,
--- 2974,2979 ----
  	   copy it to the reload register, increment there, then save back.  */
  	{
! 	  rtx first_new
! 	    = emit_insn_before (gen_move_insn (reloadreg, incloc), insn);
  	  emit_insn_before (gen_add2_insn (reloadreg,
  					   gen_rtx (CONST_INT, VOIDmode,
***************
*** 2439,2442 ****
--- 2981,2985 ----
  			    insn);
  	  emit_insn_before (gen_move_insn (incloc, reloadreg), insn);
+ 	  return first_new;
  	}
      }
***************
*** 2448,2452 ****
      {
        /* Copy the value, then increment it.  */
!       emit_insn_before (gen_move_insn (reloadreg, incloc), insn);
  
        /* If incrementing a register, assume we can
--- 2991,2996 ----
      {
        /* Copy the value, then increment it.  */
!       rtx first_new
! 	= emit_insn_before (gen_move_insn (reloadreg, incloc), insn);
  
        /* If incrementing a register, assume we can
***************
*** 2478,2483 ****
  			    insn);
  	}
      }
- 
  }
  \f


--- 3022,3027 ----
  			    insn);
  	}
+       return first_new;
      }
  }
  \f


diff -rc2N gcc-1.35/rtl.c gcc-1.36/rtl.c
*** gcc-1.35/rtl.c	Sat Apr  1 16:10:37 1989
--- gcc-1.36/rtl.c	Fri Sep 22 00:31:27 1989
***************
*** 1,3 ****
! /* Manage RTL for C-Compiler
     Copyright (C) 1987, 1988 Free Software Foundation, Inc.
  
--- 1,3 ----
! /* Allocate, read and print RTL for C-Compiler
     Copyright (C) 1987, 1988 Free Software Foundation, Inc.
  
***************
*** 19,27 ****
  
  
- /* This file contains the low level primitives for allocating,
-    printing and reading rtl expressions and vectors.
-    It also contains some functions for semantic analysis
-    on rtl expressions.  */
- 
  #include "config.h"
  #include <ctype.h>
--- 19,22 ----
***************
*** 66,70 ****
     This name does not include the letters "mode".  */
  
! #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT)  NAME,
  
  char *mode_name[] = {
--- 61,65 ----
     This name does not include the letters "mode".  */
  
! #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  NAME,
  
  char *mode_name[] = {
***************
*** 77,81 ****
     GET_MODE_CLASS uses this.  */
  
! #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT)  CLASS,
  
  enum mode_class mode_class[] = {
--- 72,76 ----
     GET_MODE_CLASS uses this.  */
  
! #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  CLASS,
  
  enum mode_class mode_class[] = {
***************
*** 88,92 ****
     GET_MODE_SIZE uses this.  */
  
! #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT)  SIZE,
  
  int mode_size[] = {
--- 83,88 ----
     GET_MODE_SIZE uses this.  */
  
! #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  \
!   (SIZE*UNITS_PER_WORD+3)/4,
  
  int mode_size[] = {
***************
*** 99,103 ****
     GET_MODE_UNIT_SIZE uses this.  */
  
! #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT)  UNIT,
  
  int mode_unit_size[] = {
--- 95,100 ----
     GET_MODE_UNIT_SIZE uses this.  */
  
! #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  \
!   (UNIT*UNITS_PER_WORD+3)/4,
  
  int mode_unit_size[] = {
***************
*** 107,110 ****
--- 104,120 ----
  #undef DEF_MACHMODE
  
+ /* Indexed by machine mode, gives next wider natural mode
+    (QI -> HI -> SI -> DI, etc.)  Widening multiply instructions
+    use this.  */
+ 
+ #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  \
+   (enum machine_mode) WIDER,
+ 
+ enum machine_mode mode_wider_mode[] = {
+ #include "machmode.def"		/* machine modes are documented here */
+ };
+ 
+ #undef DEF_MACHMODE
+ 
  /* Indexed by rtx code, gives a sequence of operand-types for
     rtx's of that code.  The sequence is a C string in which
***************
*** 230,234 ****
  	{
  	case 'e':
! 	  XEXP (copy, i) = copy_rtx (XEXP (orig, i));
  	  break;
  
--- 240,246 ----
  	{
  	case 'e':
! 	  XEXP (copy, i) = XEXP (orig, i);
! 	  if (XEXP (orig, i) != NULL)
! 	    XEXP (copy, i) = copy_rtx (XEXP (orig, i));
  	  break;
  
***************
*** 251,797 ****
  }
  \f


- /* Return 1 if the value of X is unstable
-    (would be different at a different point in the program).
-    The frame pointer, arg pointer, etc. are considered stable
-    (within one function) and so is anything marked `unchanging'.  */
- 
- int
- rtx_unstable_p (x)
-      rtx x;
- {
-   register RTX_CODE code = GET_CODE (x);
-   register int i;
-   register char *fmt;
- 
-   if (code == MEM)
-     return ! RTX_UNCHANGING_P (x);
- 
-   if (code == QUEUED)
-     return 1;
- 
-   if (code == CONST || code == CONST_INT)
-     return 0;
- 
-   if (code == REG)
-     return ! (REGNO (x) == FRAME_POINTER_REGNUM
- 	      || REGNO (x) == ARG_POINTER_REGNUM
- 	      || RTX_UNCHANGING_P (x));
- 
-   fmt = GET_RTX_FORMAT (code);
-   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-     if (fmt[i] == 'e')
-       if (rtx_unstable_p (XEXP (x, i)))
- 	return 1;
-   return 0;
- }
- 
- /* Return 1 if X has a value that can vary even between two
-    executions of the program.  0 means X can be compared reliably
-    against certain constants or near-constants.
-    The frame pointer and the arg pointer are considered constant.  */
- 
- int
- rtx_varies_p (x)
-      rtx x;
- {
-   register RTX_CODE code = GET_CODE (x);
-   register int i;
-   register char *fmt;
- 
-   if (code == MEM)
-     return 1;
- 
-   if (code == QUEUED)
-     return 1;
- 
-   if (code == CONST || code == CONST_INT)
-     return 0;
- 
-   if (code == REG)
-     return ! (REGNO (x) == FRAME_POINTER_REGNUM
- 	      || REGNO (x) == ARG_POINTER_REGNUM);
- 
-   fmt = GET_RTX_FORMAT (code);
-   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-     if (fmt[i] == 'e')
-       if (rtx_varies_p (XEXP (x, i)))
- 	return 1;
-   return 0;
- }
- 
- /* Return 1 if X refers to a memory location whose address 
-    cannot be compared reliably with constant addresses,
-    or if X refers to a BLKmode memory object.  */
- 
- int
- rtx_addr_varies_p (x)
-      rtx x;
- {
-   register enum rtx_code code;
-   register int i;
-   register char *fmt;
- 
-   if (x == 0)
-     return 0;
- 
-   code = GET_CODE (x);
-   if (code == MEM)
-     return GET_MODE (x) == BLKmode || rtx_varies_p (XEXP (x, 0));
- 
-   fmt = GET_RTX_FORMAT (code);
-   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-     if (fmt[i] == 'e')
-       if (rtx_addr_varies_p (XEXP (x, i)))
- 	return 1;
-   return 0;
- }
- \f


- /* Nonzero if register REG appears somewhere within IN.
-    Also works if REG is not a register; in this case it checks
-    for a subexpression of IN that is Lisp "equal" to REG.  */
- 
- int
- reg_mentioned_p (reg, in)
-      register rtx reg, in;
- {
-   register char *fmt;
-   register int i;
-   register enum rtx_code code;
- 
-   if (in == 0)
-     return 0;
- 
-   if (reg == in)
-     return 1;
- 
-   code = GET_CODE (in);
- 
-   switch (code)
-     {
-       /* Compare registers by number.  */
-     case REG:
-       return GET_CODE (reg) == REG && REGNO (in) == REGNO (reg);
- 
-       /* These codes have no constituent expressions
- 	 and are unique.  */
-     case CC0:
-     case PC:
-       return 0;
- 
-     case CONST_INT:
-       return GET_CODE (reg) == CONST_INT && INTVAL (in) == INTVAL (reg);
-     }
- 
-   if (GET_CODE (reg) == code && rtx_equal_p (reg, in))
-     return 1;
- 
-   fmt = GET_RTX_FORMAT (code);
- 
-   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-     {
-       if (fmt[i] == 'E')
- 	{
- 	  register int j;
- 	  for (j = XVECLEN (in, i) - 1; j >= 0; j--)
- 	    if (reg_mentioned_p (reg, XVECEXP (in, i, j)))
- 	      return 1;
- 	}
-       else if (fmt[i] == 'e'
- 	       && reg_mentioned_p (reg, XEXP (in, i)))
- 	return 1;
-     }
-   return 0;
- }
- 
- /* Nonzero if register REG is used in an insn between
-    FROM_INSN and TO_INSN (exclusive of those two).  */
- 
- int
- reg_used_between_p (reg, from_insn, to_insn)
-      rtx reg, from_insn, to_insn;
- {
-   register rtx insn;
-   register RTX_CODE code;
-   for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))
-     if (((code = GET_CODE (insn)) == INSN
- 	 || code == JUMP_INSN || code == CALL_INSN)
- 	&& reg_mentioned_p (reg, PATTERN (insn)))
-       return 1;
-   return 0;
- }
- \f


- /* Return nonzero if hard register in range [REGNO, ENDREGNO)
-    appears either explicitly or implicitly in X
-    other than being stored into.
- 
-    References contained within the substructure at LOC do not count.
-    LOC may be zero, meaning don't ignore anything.  */
- 
- int
- refers_to_regno_p (regno, endregno, x, loc)
-      int regno, endregno;
-      rtx x;
-      rtx *loc;
- {
-   register int i;
-   register RTX_CODE code;
-   register char *fmt;
- 
-  repeat:
-   code = GET_CODE (x);
-   if (code == REG)
-     {
-       i = REGNO (x);
-       return (endregno > i && regno < i + HARD_REGNO_NREGS (i, GET_MODE (x)));
-     }
- 
-   if (code == SET)
-     {
-       /* Note setting a SUBREG counts as referring to the REG it is in!  */
-       if (GET_CODE (SET_DEST (x)) != REG
- 	  && refers_to_regno_p (regno, endregno, SET_DEST (x), loc))
- 	return 1;
-       if (loc == &SET_SRC (x))
- 	return 0;
-       x = SET_SRC (x);
-       goto repeat;
-     }
- 
-   if (code == CLOBBER)
-     {
-       if (GET_CODE (SET_DEST (x)) != REG
- 	  && refers_to_regno_p (regno, endregno, SET_DEST (x), loc))
- 	return 1;
-       return 0;
-     }
- 
-   /* X does not match, so try its subexpressions.  */
- 
-   fmt = GET_RTX_FORMAT (code);
-   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-     {
-       if (fmt[i] == 'e' && loc != &XEXP (x, i))
- 	{
- 	  if (i == 0)
- 	    {
- 	      x = XEXP (x, 0);
- 	      goto repeat;
- 	    }
- 	  else
- 	    if (refers_to_regno_p (regno, endregno, XEXP (x, i), loc))
- 	      return 1;
- 	}
-       else if (fmt[i] == 'E')
- 	{
- 	  register int j;
- 	  for (j = XVECLEN (x, i) - 1; j >=0; j--)
- 	    if (loc != &XVECEXP (x, i, j)
- 		&& refers_to_regno_p (regno, endregno, XVECEXP (x, i, j), loc))
- 	      return 1;
- 	}
-     }
-   return 0;
- }
- 
- /* Nonzero if X contains any reg that overlaps hard register REG.  */
- 
- int
- reg_overlap_mentioned_p (reg, x)
-      rtx reg, x;
- {
-   int regno = REGNO (reg);
-   int endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (reg));
-   return refers_to_regno_p (regno, endregno, x, 0);
- }
- \f


- /* This is 1 until after reload pass.  */
- int rtx_equal_function_value_matters;
- 
- /* Return 1 if X and Y are identical-looking rtx's.
-    This is the Lisp function EQUAL for rtx arguments.  */
- 
- int
- rtx_equal_p (x, y)
-      rtx x, y;
- {
-   register int i;
-   register int j;
-   register enum rtx_code code;
-   register char *fmt;
- 
-   if (x == y)
-     return 1;
-   if (x == 0 || y == 0)
-     return 0;
- 
-   code = GET_CODE (x);
-   /* Rtx's of different codes cannot be equal.  */
-   if (code != GET_CODE (y))
-     return 0;
- 
-   /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.
-      (REG:SI x) and (REG:HI x) are NOT equivalent.  */
- 
-   if (GET_MODE (x) != GET_MODE (y))
-     return 0;
- 
-   /* These three types of rtx's can be compared nonrecursively.  */
-   /* Until the end of reload,
-      don't consider the a reference to the return register of the current
-      function the same as the return from a called function.  This eases
-      the job of function integration.  Once the distinction no longer
-      matters, the insn will be deleted.  */
-   if (code == REG)
-     return (REGNO (x) == REGNO (y)
- 	    && (! rtx_equal_function_value_matters
- 		|| REG_FUNCTION_VALUE_P (x) == REG_FUNCTION_VALUE_P (y)));
-   if (code == LABEL_REF)
-     return XEXP (x, 0) == XEXP (y, 0);
-   if (code == SYMBOL_REF)
-     return XSTR (x, 0) == XSTR (y, 0);
- 
-   /* Compare the elements.  If any pair of corresponding elements
-      fail to match, return 0 for the whole things.  */
- 
-   fmt = GET_RTX_FORMAT (code);
-   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-     {
-       switch (fmt[i])
- 	{
- 	case 'i':
- 	  if (XINT (x, i) != XINT (y, i))
- 	    return 0;
- 	  break;
- 
- 	case 'E':
- 	  for (j = 0; j < XVECLEN (x, i); j++)
- 	    if (rtx_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)) == 0)
- 	      return 0;
- 	  break;
- 
- 	case 'e':
- 	  if (rtx_equal_p (XEXP (x, i), XEXP (y, i)) == 0)
- 	    return 0;
- 	  break;
- 
- 	case 's':
- 	  if (strcmp (XSTR (x, i), XSTR (y, i)))
- 	    return 0;
- 	  break;
- 
- 	case 'u':
- 	  /* These are just backpointers, so they don't matter.  */
- 	  break;
- 
- 	case '0':
- 	  break;
- 
- 	  /* It is believed that rtx's at this level will never
- 	     contain anything but integers and other rtx's,
- 	     except for within LABEL_REFs and SYMBOL_REFs.  */
- 	default:
- 	  abort ();
- 	}
-     }
-   return 1;
- }
- \f


- /* Call FUN on each register or MEM that is stored into or clobbered by X.
-    (X would be the pattern of an insn).
-    FUN receives two arguments:
-      the REG, MEM, CC0 or PC being stored in or clobbered,
-      the SET or CLOBBER rtx that does the store.  */
-      
- void
- note_stores (x, fun)
-      register rtx x;
-      void (*fun) ();
- {
-   if ((GET_CODE (x) == SET || GET_CODE (x) == CLOBBER))
-     {
-       register rtx dest = SET_DEST (x);
-       while (GET_CODE (dest) == SUBREG
- 	     || GET_CODE (dest) == ZERO_EXTRACT
- 	     || GET_CODE (dest) == SIGN_EXTRACT
- 	     || GET_CODE (dest) == STRICT_LOW_PART)
- 	dest = XEXP (dest, 0);
-       (*fun) (dest, x);
-     }
-   else if (GET_CODE (x) == PARALLEL)
-     {
-       register int i;
-       for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
- 	{
- 	  register rtx y = XVECEXP (x, 0, i);
- 	  if (GET_CODE (y) == SET || GET_CODE (y) == CLOBBER)
- 	    {
- 	      register rtx dest = SET_DEST (y);
- 	      while (GET_CODE (dest) == SUBREG
- 		     || GET_CODE (dest) == ZERO_EXTRACT
- 		     || GET_CODE (dest) == SIGN_EXTRACT
- 		     || GET_CODE (dest) == STRICT_LOW_PART)
- 		dest = XEXP (dest, 0);
- 	      (*fun) (dest, XVECEXP (x, 0, i));
- 	    }
- 	}
-     }
- }
- \f


- /* Return nonzero if register REG's old contents don't survive after INSN.
-    This can be because REG dies in INSN or because INSN entirely sets REG.
- 
-    "Entirely set" means set directly and not through a SUBREG,
-    ZERO_EXTRACT or SIGN_EXTRACT, so no trace of the old contents remains.
- 
-    REG may be a hard or pseudo reg.  Renumbering is not taken into account,
-    but for this use that makes no difference, since regs don't overlap
-    during their lifetimes.  Therefore, this function may be used
-    at any time after deaths have been computed (in flow.c).  */
- 
- int
- dead_or_set_p (insn, reg)
-      rtx insn;
-      rtx reg;
- {
-   register rtx link;
-   register int regno = REGNO (reg);
- 
-   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
-     if ((REG_NOTE_KIND (link) == REG_DEAD
- 	 || REG_NOTE_KIND (link) == REG_INC)
- 	&& REGNO (XEXP (link, 0)) == regno)
-       return 1;
- 
-   if (GET_CODE (PATTERN (insn)) == SET)
-     return SET_DEST (PATTERN (insn)) == reg;
-   else if (GET_CODE (PATTERN (insn)) == PARALLEL)
-     {
-       register int i;
-       for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
- 	{
- 	  if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET
- 	      && SET_DEST (XVECEXP (PATTERN (insn), 0, i)) == reg)
- 	    return 1;
- 	}
-     }
-   return 0;
- }
- 
- /* Return the reg-note of kind KIND in insn INSN, if there is one.
-    If DATUM is nonzero, look for one whose datum is DATUM.  */
- 
- rtx
- find_reg_note (insn, kind, datum)
-      rtx insn;
-      enum reg_note kind;
-      rtx datum;
- {
-   register rtx link;
- 
-   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
-     if (REG_NOTE_KIND (link) == kind
- 	&& (datum == 0 || datum == XEXP (link, 0)))
-       return link;
-   return 0;
- }
- 
- /* Return the reg-note of kind KIND in insn INSN which applies to register
-    number REGNO, if any.  Return 0 if there is no such reg-note.  */
- 
- rtx
- find_regno_note (insn, kind, regno)
-      rtx insn;
-      enum reg_note kind;
-      int regno;
- {
-   register rtx link;
- 
-   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
-     if (REG_NOTE_KIND (link) == kind
- 	&& REGNO (XEXP (link, 0)) == regno)
-       return link;
-   return 0;
- }
- \f


- /* Nonzero if FROM precedes TO with no intervening labels.  */
- 
- int
- no_labels_between (from, to)
-      register rtx from, to;
- {
-   register rtx p = to;
- 
-   while (1)
-     {
-       p = PREV_INSN (p);
-       if (p == 0)
- 	return 0;
-       if (p == from)
- 	return 1;
-       if (GET_CODE (p) == CODE_LABEL)
- 	return 0;
-     }
- }
- \f


- /* Nonzero if X contains any volatile memory references
-    or volatile ASM_OPERANDS expressions.  */
- 
- int
- volatile_refs_p (x)
-      rtx x;
- {
-   register RTX_CODE code;
- 
-   code = GET_CODE (x);
-   switch (code)
-     {
-     case LABEL_REF:
-     case SYMBOL_REF:
-     case CONST_INT:
-     case CONST:
-     case CONST_DOUBLE:
-     case CC0:
-     case PC:
-     case REG:
-     case CLOBBER:
-     case ASM_INPUT:
-     case ADDR_VEC:
-     case ADDR_DIFF_VEC:
-       return 0;
- 
-     case CALL:
-       return 1;
- 
-     case MEM:
-     case ASM_OPERANDS:
-       if (MEM_VOLATILE_P (x))
- 	return 1;
-     }
- 
-   /* Recursively scan the operands of this expression.  */
- 
-   {
-     register char *fmt = GET_RTX_FORMAT (code);
-     register int i;
-     
-     for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-       {
- 	if (fmt[i] == 'e')
- 	  {
- 	    if (volatile_refs_p (XEXP (x, i)))
- 	      return 1;
- 	  }
- 	if (fmt[i] == 'E')
- 	  {
- 	    register int j;
- 	    for (j = 0; j < XVECLEN (x, i); j++)
- 	      if (volatile_refs_p (XVECEXP (x, i, j)))
- 		return 1;
- 	  }
-       }
-   }
-   return 0;
- }
- \f


  /* Printing rtl for debugging dumps.  */
  
--- 263,266 ----
***************
*** 998,1004 ****
    int c, i;
  
!   fprintf (stderr,
! 	   "Expected character %c. Read character %c. At file position: %ld\n",
! 	   expected_c, actual_c, ftell (infile));
    fprintf (stderr, "Following characters are:\n\t");
    for (i = 0; i < 200; i++)
--- 467,475 ----
    int c, i;
  
!   if (expected_c >= 0)
!     fprintf (stderr,
! 	     "Expected character %c.  Found character %c.",
! 	     expected_c, actual_c);
!   fprintf (stderr, "  At file position: %ld\n", ftell (infile));
    fprintf (stderr, "Following characters are:\n\t");
    for (i = 0; i < 200; i++)
***************
*** 1077,1081 ****
        c = getc (infile);
      }
!   *p = NULL;
  }
  \f


--- 548,558 ----
        c = getc (infile);
      }
!   if (p == str)
!     {
!       fprintf (stderr, "missing name or number");
!       dump_and_abort (-1, -1, infile);
!     }
! 
!   *p = 0;
  }
  \f


***************
*** 1320,1325 ****
    if (rtx_length[(int) CONST_DOUBLE] < i)
      {
!       char *s = (char *) permalloc (i + 1);
        rtx_length[(int) CONST_DOUBLE] = i;
        *s++ = 'e';
        *s++ = '0';
--- 797,803 ----
    if (rtx_length[(int) CONST_DOUBLE] < i)
      {
!       char *s = (char *) malloc (i + 1);
        rtx_length[(int) CONST_DOUBLE] = i;
+       rtx_format[(int) CONST_DOUBLE] = s;
        *s++ = 'e';
        *s++ = '0';
diff -rc2N gcc-1.35/rtl.h gcc-1.36/rtl.h
*** gcc-1.35/rtl.h	Sat Apr  1 16:11:47 1989
--- gcc-1.36/rtl.h	Tue Jun 20 19:34:57 1989
***************
*** 49,53 ****
  #ifndef HAVE_MACHINE_MODES
  
! #define DEF_MACHMODE(SYM, NAME, TYPE, SIZE, UNIT)  SYM,
  
  enum machine_mode {
--- 49,53 ----
  #ifndef HAVE_MACHINE_MODES
  
! #define DEF_MACHMODE(SYM, NAME, TYPE, SIZE, UNIT, WIDER)  SYM,
  
  enum machine_mode {
***************
*** 99,102 ****
--- 99,107 ----
     ((GET_MODE_BITSIZE (MODE) >= HOST_BITS_PER_INT)  \
      ? -1 : ((1 << GET_MODE_BITSIZE (MODE)) - 1))
+ 
+ /* Get the next wider natural mode (eg, QI -> HI -> SI -> DI -> TI).  */
+ 
+ extern enum machine_mode mode_wider_mode[];
+ #define GET_MODE_WIDER_MODE(MODE)	(mode_wider_mode[(int)(MODE)])
  \f


  /* Common union for an element of an rtx.  */
***************
*** 158,162 ****
  } *rtx;
  
! #define NULL_RTX (rtx) NULL
  
  /* Define macros to access the `code' field of the rtx.  */
--- 163,167 ----
  } *rtx;
  
! #define NULL_RTX (rtx) 0
  
  /* Define macros to access the `code' field of the rtx.  */
***************
*** 185,189 ****
  } *rtvec;
  
! #define NULL_RTVEC (rtvec) NULL
  
  #define GET_NUM_ELEM(RTVEC)		((RTVEC)->num_elem)
--- 190,194 ----
  } *rtvec;
  
! #define NULL_RTVEC (rtvec) 0
  
  #define GET_NUM_ELEM(RTVEC)		((RTVEC)->num_elem)
***************
*** 306,310 ****
--- 311,320 ----
     for kinds of notes that are not line numbers.  */
  
+ /* This note indicates the end of the real body of the function,
+    after moving the parms into their homes, etc.  */
  #define NOTE_INSN_FUNCTION_BEG 0
+ 
+ /* This note is used to get rid of an insn
+    when it isn't safe to patch the insn out of the chain.  */
  #define NOTE_INSN_DELETED -1
  #define NOTE_INSN_BLOCK_BEG -2
***************
*** 474,477 ****
--- 484,488 ----
  extern rtx emit_label ();
  extern rtx emit_barrier ();
+ extern rtx emit_barrier_after ();
  extern rtx emit_note ();
  extern rtx emit_line_note ();
***************
*** 483,487 ****
  extern rtx find_equiv_reg ();
  extern rtx delete_insn ();
! extern rtx adj_offsetable_operand ();
  
  /* Maximum number of parallel sets and clobbers in any insn in this fn.
--- 494,498 ----
  extern rtx find_equiv_reg ();
  extern rtx delete_insn ();
! extern rtx adj_offsettable_operand ();
  
  /* Maximum number of parallel sets and clobbers in any insn in this fn.
***************
*** 514,519 ****
   ((MODE == SFmode) ? fconst0_rtx			\
    : ((MODE == DFmode) ? dconst0_rtx			\
!   : ((GET_MODE_CLASS (MODE) == MODE_INT) ? const0_rtx	\
!   : (rtx) abort ())))
  
  /* All references to certain hard regs, except those created
--- 525,530 ----
   ((MODE == SFmode) ? fconst0_rtx			\
    : ((MODE == DFmode) ? dconst0_rtx			\
!      : ((GET_MODE_CLASS (MODE) == MODE_INT) ? const0_rtx	\
!         : (abort (), NULL_RTX))))
  
  /* All references to certain hard regs, except those created
diff -rc2N gcc-1.35/rtlanal.c gcc-1.36/rtlanal.c
*** gcc-1.35/rtlanal.c	Wed Dec 31 19:00:00 1969
--- gcc-1.36/rtlanal.c	Mon Jun 19 13:36:16 1989
***************
*** 0 ****
--- 1,679 ----
+ /* Analyze RTL for C-Compiler
+    Copyright (C) 1987, 1988 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+ 
+ 
+ #include "config.h"
+ #include "rtl.h"
+ 
+ extern void note_stores ();
+ static int reg_set_p ();
+ \f


+ /* Return 1 if the value of X is unstable
+    (would be different at a different point in the program).
+    The frame pointer, arg pointer, etc. are considered stable
+    (within one function) and so is anything marked `unchanging'.  */
+ 
+ int
+ rtx_unstable_p (x)
+      rtx x;
+ {
+   register RTX_CODE code = GET_CODE (x);
+   register int i;
+   register char *fmt;
+ 
+   if (code == MEM)
+     return ! RTX_UNCHANGING_P (x);
+ 
+   if (code == QUEUED)
+     return 1;
+ 
+   if (code == CONST || code == CONST_INT)
+     return 0;
+ 
+   if (code == REG)
+     return ! (REGNO (x) == FRAME_POINTER_REGNUM
+ 	      || REGNO (x) == ARG_POINTER_REGNUM
+ 	      || RTX_UNCHANGING_P (x));
+ 
+   fmt = GET_RTX_FORMAT (code);
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     if (fmt[i] == 'e')
+       if (rtx_unstable_p (XEXP (x, i)))
+ 	return 1;
+   return 0;
+ }
+ 
+ /* Return 1 if X has a value that can vary even between two
+    executions of the program.  0 means X can be compared reliably
+    against certain constants or near-constants.
+    The frame pointer and the arg pointer are considered constant.  */
+ 
+ int
+ rtx_varies_p (x)
+      rtx x;
+ {
+   register RTX_CODE code = GET_CODE (x);
+   register int i;
+   register char *fmt;
+ 
+   if (code == MEM)
+     return 1;
+ 
+   if (code == QUEUED)
+     return 1;
+ 
+   if (code == CONST || code == CONST_INT)
+     return 0;
+ 
+   if (code == REG)
+     return ! (REGNO (x) == FRAME_POINTER_REGNUM
+ 	      || REGNO (x) == ARG_POINTER_REGNUM);
+ 
+   fmt = GET_RTX_FORMAT (code);
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     if (fmt[i] == 'e')
+       if (rtx_varies_p (XEXP (x, i)))
+ 	return 1;
+   return 0;
+ }
+ 
+ /* Return 1 if X refers to a memory location whose address 
+    cannot be compared reliably with constant addresses,
+    or if X refers to a BLKmode memory object.  */
+ 
+ int
+ rtx_addr_varies_p (x)
+      rtx x;
+ {
+   register enum rtx_code code;
+   register int i;
+   register char *fmt;
+ 
+   if (x == 0)
+     return 0;
+ 
+   code = GET_CODE (x);
+   if (code == MEM)
+     return GET_MODE (x) == BLKmode || rtx_varies_p (XEXP (x, 0));
+ 
+   fmt = GET_RTX_FORMAT (code);
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     if (fmt[i] == 'e')
+       if (rtx_addr_varies_p (XEXP (x, i)))
+ 	return 1;
+   return 0;
+ }
+ \f


+ /* Nonzero if register REG appears somewhere within IN.
+    Also works if REG is not a register; in this case it checks
+    for a subexpression of IN that is Lisp "equal" to REG.  */
+ 
+ int
+ reg_mentioned_p (reg, in)
+      register rtx reg, in;
+ {
+   register char *fmt;
+   register int i;
+   register enum rtx_code code;
+ 
+   if (in == 0)
+     return 0;
+ 
+   if (reg == in)
+     return 1;
+ 
+   code = GET_CODE (in);
+ 
+   switch (code)
+     {
+       /* Compare registers by number.  */
+     case REG:
+       return GET_CODE (reg) == REG && REGNO (in) == REGNO (reg);
+ 
+       /* These codes have no constituent expressions
+ 	 and are unique.  */
+     case CC0:
+     case PC:
+       return 0;
+ 
+     case CONST_INT:
+       return GET_CODE (reg) == CONST_INT && INTVAL (in) == INTVAL (reg);
+     }
+ 
+   if (GET_CODE (reg) == code && rtx_equal_p (reg, in))
+     return 1;
+ 
+   fmt = GET_RTX_FORMAT (code);
+ 
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     {
+       if (fmt[i] == 'E')
+ 	{
+ 	  register int j;
+ 	  for (j = XVECLEN (in, i) - 1; j >= 0; j--)
+ 	    if (reg_mentioned_p (reg, XVECEXP (in, i, j)))
+ 	      return 1;
+ 	}
+       else if (fmt[i] == 'e'
+ 	       && reg_mentioned_p (reg, XEXP (in, i)))
+ 	return 1;
+     }
+   return 0;
+ }
+ 
+ /* Nonzero if register REG is used in an insn between
+    FROM_INSN and TO_INSN (exclusive of those two).  */
+ 
+ int
+ reg_used_between_p (reg, from_insn, to_insn)
+      rtx reg, from_insn, to_insn;
+ {
+   register rtx insn;
+   register RTX_CODE code;
+   for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))
+     if (((code = GET_CODE (insn)) == INSN
+ 	 || code == JUMP_INSN || code == CALL_INSN)
+ 	&& reg_mentioned_p (reg, PATTERN (insn)))
+       return 1;
+   return 0;
+ }
+ 
+ /* Nonzero if register REG is set or clobbered in an insn between
+    FROM_INSN and TO_INSN (exclusive of those two).
+    Does not notice increments, only SET and CLOBBER.  */
+ 
+ int
+ reg_set_between_p (reg, from_insn, to_insn)
+      rtx reg, from_insn, to_insn;
+ {
+   register rtx insn;
+   register RTX_CODE code;
+   for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))
+     if (((code = GET_CODE (insn)) == INSN
+ 	 || code == JUMP_INSN || code == CALL_INSN)
+ 	&& reg_set_p (reg, PATTERN (insn)))
+       return 1;
+   return 0;
+ }
+ 
+ /* Internals of reg_set_between_p.  */
+ 
+ static rtx reg_set_reg;
+ static int reg_set_flag;
+ 
+ static void
+ reg_set_p_1 (x)
+      rtx x;
+ {
+   if (reg_overlap_mentioned_p (reg_set_reg, x))
+     reg_set_flag = 1;
+ }
+ 
+ static int
+ reg_set_p (reg, insn)
+      rtx reg, insn;
+ {
+   reg_set_reg = reg;
+   reg_set_flag = 0;
+   note_stores (insn, reg_set_p_1);
+   return reg_set_flag;
+ }
+ \f


+ /* Return nonzero if hard register in range [REGNO, ENDREGNO)
+    appears either explicitly or implicitly in X
+    other than being stored into.
+ 
+    References contained within the substructure at LOC do not count.
+    LOC may be zero, meaning don't ignore anything.  */
+ 
+ int
+ refers_to_regno_p (regno, endregno, x, loc)
+      int regno, endregno;
+      rtx x;
+      rtx *loc;
+ {
+   register int i;
+   register RTX_CODE code;
+   register char *fmt;
+ 
+  repeat:
+   code = GET_CODE (x);
+   if (code == REG)
+     {
+       i = REGNO (x);
+       return (endregno > i && regno < i + HARD_REGNO_NREGS (i, GET_MODE (x)));
+     }
+ 
+   if (code == SET)
+     {
+       /* Note setting a SUBREG counts as referring to the REG it is in!  */
+       if (GET_CODE (SET_DEST (x)) != REG
+ 	  && refers_to_regno_p (regno, endregno, SET_DEST (x), loc))
+ 	return 1;
+       if (loc == &SET_SRC (x))
+ 	return 0;
+       x = SET_SRC (x);
+       goto repeat;
+     }
+ 
+   if (code == CLOBBER)
+     {
+       if (GET_CODE (SET_DEST (x)) != REG
+ 	  && refers_to_regno_p (regno, endregno, SET_DEST (x), loc))
+ 	return 1;
+       return 0;
+     }
+ 
+   /* X does not match, so try its subexpressions.  */
+ 
+   fmt = GET_RTX_FORMAT (code);
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     {
+       if (fmt[i] == 'e' && loc != &XEXP (x, i))
+ 	{
+ 	  if (i == 0)
+ 	    {
+ 	      x = XEXP (x, 0);
+ 	      goto repeat;
+ 	    }
+ 	  else
+ 	    if (refers_to_regno_p (regno, endregno, XEXP (x, i), loc))
+ 	      return 1;
+ 	}
+       else if (fmt[i] == 'E')
+ 	{
+ 	  register int j;
+ 	  for (j = XVECLEN (x, i) - 1; j >=0; j--)
+ 	    if (loc != &XVECEXP (x, i, j)
+ 		&& refers_to_regno_p (regno, endregno, XVECEXP (x, i, j), loc))
+ 	      return 1;
+ 	}
+     }
+   return 0;
+ }
+ 
+ /* Nonzero if X contains any reg that overlaps hard register REG.  */
+ 
+ int
+ reg_overlap_mentioned_p (reg, x)
+      rtx reg, x;
+ {
+   int regno = REGNO (reg);
+   int endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (reg));
+   return refers_to_regno_p (regno, endregno, x, 0);
+ }
+ \f


+ /* This is 1 until after reload pass.  */
+ int rtx_equal_function_value_matters;
+ 
+ /* Return 1 if X and Y are identical-looking rtx's.
+    This is the Lisp function EQUAL for rtx arguments.  */
+ 
+ int
+ rtx_equal_p (x, y)
+      rtx x, y;
+ {
+   register int i;
+   register int j;
+   register enum rtx_code code;
+   register char *fmt;
+ 
+   if (x == y)
+     return 1;
+   if (x == 0 || y == 0)
+     return 0;
+ 
+   code = GET_CODE (x);
+   /* Rtx's of different codes cannot be equal.  */
+   if (code != GET_CODE (y))
+     return 0;
+ 
+   /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.
+      (REG:SI x) and (REG:HI x) are NOT equivalent.  */
+ 
+   if (GET_MODE (x) != GET_MODE (y))
+     return 0;
+ 
+   /* These three types of rtx's can be compared nonrecursively.  */
+   /* Until the end of reload,
+      don't consider the a reference to the return register of the current
+      function the same as the return from a called function.  This eases
+      the job of function integration.  Once the distinction no longer
+      matters, the insn will be deleted.  */
+   if (code == REG)
+     return (REGNO (x) == REGNO (y)
+ 	    && (! rtx_equal_function_value_matters
+ 		|| REG_FUNCTION_VALUE_P (x) == REG_FUNCTION_VALUE_P (y)));
+   if (code == LABEL_REF)
+     return XEXP (x, 0) == XEXP (y, 0);
+   if (code == SYMBOL_REF)
+     return XSTR (x, 0) == XSTR (y, 0);
+ 
+   /* Compare the elements.  If any pair of corresponding elements
+      fail to match, return 0 for the whole things.  */
+ 
+   fmt = GET_RTX_FORMAT (code);
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     {
+       switch (fmt[i])
+ 	{
+ 	case 'i':
+ 	  if (XINT (x, i) != XINT (y, i))
+ 	    return 0;
+ 	  break;
+ 
+ 	case 'E':
+ 	  /* Two vectors must have the same length.  */
+ 	  if (XVECLEN (x, i) != XVECLEN (y, i))
+ 	    return 0;
+ 
+ 	  /* And the corresponding elements must match.  */
+ 	  for (j = 0; j < XVECLEN (x, i); j++)
+ 	    if (rtx_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)) == 0)
+ 	      return 0;
+ 	  break;
+ 
+ 	case 'e':
+ 	  if (rtx_equal_p (XEXP (x, i), XEXP (y, i)) == 0)
+ 	    return 0;
+ 	  break;
+ 
+ 	case 's':
+ 	  if (strcmp (XSTR (x, i), XSTR (y, i)))
+ 	    return 0;
+ 	  break;
+ 
+ 	case 'u':
+ 	  /* These are just backpointers, so they don't matter.  */
+ 	  break;
+ 
+ 	case '0':
+ 	  break;
+ 
+ 	  /* It is believed that rtx's at this level will never
+ 	     contain anything but integers and other rtx's,
+ 	     except for within LABEL_REFs and SYMBOL_REFs.  */
+ 	default:
+ 	  abort ();
+ 	}
+     }
+   return 1;
+ }
+ \f


+ /* Call FUN on each register or MEM that is stored into or clobbered by X.
+    (X would be the pattern of an insn).
+    FUN receives two arguments:
+      the REG, MEM, CC0 or PC being stored in or clobbered,
+      the SET or CLOBBER rtx that does the store.  */
+      
+ void
+ note_stores (x, fun)
+      register rtx x;
+      void (*fun) ();
+ {
+   if ((GET_CODE (x) == SET || GET_CODE (x) == CLOBBER))
+     {
+       register rtx dest = SET_DEST (x);
+       while (GET_CODE (dest) == SUBREG
+ 	     || GET_CODE (dest) == ZERO_EXTRACT
+ 	     || GET_CODE (dest) == SIGN_EXTRACT
+ 	     || GET_CODE (dest) == STRICT_LOW_PART)
+ 	dest = XEXP (dest, 0);
+       (*fun) (dest, x);
+     }
+   else if (GET_CODE (x) == PARALLEL)
+     {
+       register int i;
+       for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
+ 	{
+ 	  register rtx y = XVECEXP (x, 0, i);
+ 	  if (GET_CODE (y) == SET || GET_CODE (y) == CLOBBER)
+ 	    {
+ 	      register rtx dest = SET_DEST (y);
+ 	      while (GET_CODE (dest) == SUBREG
+ 		     || GET_CODE (dest) == ZERO_EXTRACT
+ 		     || GET_CODE (dest) == SIGN_EXTRACT
+ 		     || GET_CODE (dest) == STRICT_LOW_PART)
+ 		dest = XEXP (dest, 0);
+ 	      (*fun) (dest, XVECEXP (x, 0, i));
+ 	    }
+ 	}
+     }
+ }
+ \f


+ /* Return nonzero if register REG's old contents don't survive after INSN.
+    This can be because REG dies in INSN or because INSN entirely sets REG.
+ 
+    "Entirely set" means set directly and not through a SUBREG,
+    ZERO_EXTRACT or SIGN_EXTRACT, so no trace of the old contents remains.
+ 
+    REG may be a hard or pseudo reg.  Renumbering is not taken into account,
+    but for this use that makes no difference, since regs don't overlap
+    during their lifetimes.  Therefore, this function may be used
+    at any time after deaths have been computed (in flow.c).  */
+ 
+ int
+ dead_or_set_p (insn, reg)
+      rtx insn;
+      rtx reg;
+ {
+   register rtx link;
+   register int regno = REGNO (reg);
+ 
+   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
+     if ((REG_NOTE_KIND (link) == REG_DEAD
+ 	 || REG_NOTE_KIND (link) == REG_INC)
+ 	&& REGNO (XEXP (link, 0)) == regno)
+       return 1;
+ 
+   if (GET_CODE (PATTERN (insn)) == SET)
+     return SET_DEST (PATTERN (insn)) == reg;
+   else if (GET_CODE (PATTERN (insn)) == PARALLEL)
+     {
+       register int i;
+       for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
+ 	{
+ 	  if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET
+ 	      && SET_DEST (XVECEXP (PATTERN (insn), 0, i)) == reg)
+ 	    return 1;
+ 	}
+     }
+   return 0;
+ }
+ 
+ /* Return the reg-note of kind KIND in insn INSN, if there is one.
+    If DATUM is nonzero, look for one whose datum is DATUM.  */
+ 
+ rtx
+ find_reg_note (insn, kind, datum)
+      rtx insn;
+      enum reg_note kind;
+      rtx datum;
+ {
+   register rtx link;
+ 
+   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
+     if (REG_NOTE_KIND (link) == kind
+ 	&& (datum == 0 || datum == XEXP (link, 0)))
+       return link;
+   return 0;
+ }
+ 
+ /* Return the reg-note of kind KIND in insn INSN which applies to register
+    number REGNO, if any.  Return 0 if there is no such reg-note.  */
+ 
+ rtx
+ find_regno_note (insn, kind, regno)
+      rtx insn;
+      enum reg_note kind;
+      int regno;
+ {
+   register rtx link;
+ 
+   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
+     if (REG_NOTE_KIND (link) == kind
+ 	&& REGNO (XEXP (link, 0)) == regno)
+       return link;
+   return 0;
+ }
+ \f


+ /* Nonzero if FROM precedes TO with no intervening labels.  */
+ 
+ int
+ no_labels_between (from, to)
+      register rtx from, to;
+ {
+   register rtx p = to;
+ 
+   while (1)
+     {
+       p = PREV_INSN (p);
+       if (p == 0)
+ 	return 0;
+       if (p == from)
+ 	return 1;
+       if (GET_CODE (p) == CODE_LABEL)
+ 	return 0;
+     }
+ }
+ \f


+ /* Nonzero if X contains any volatile memory references
+    or volatile ASM_OPERANDS expressions.  */
+ 
+ int
+ volatile_refs_p (x)
+      rtx x;
+ {
+   register RTX_CODE code;
+ 
+   code = GET_CODE (x);
+   switch (code)
+     {
+     case LABEL_REF:
+     case SYMBOL_REF:
+     case CONST_INT:
+     case CONST:
+     case CONST_DOUBLE:
+     case CC0:
+     case PC:
+     case REG:
+     case CLOBBER:
+     case ASM_INPUT:
+     case ADDR_VEC:
+     case ADDR_DIFF_VEC:
+       return 0;
+ 
+     case CALL:
+       return 1;
+ 
+     case MEM:
+     case ASM_OPERANDS:
+       if (MEM_VOLATILE_P (x))
+ 	return 1;
+     }
+ 
+   /* Recursively scan the operands of this expression.  */
+ 
+   {
+     register char *fmt = GET_RTX_FORMAT (code);
+     register int i;
+     
+     for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+       {
+ 	if (fmt[i] == 'e')
+ 	  {
+ 	    if (volatile_refs_p (XEXP (x, i)))
+ 	      return 1;
+ 	  }
+ 	if (fmt[i] == 'E')
+ 	  {
+ 	    register int j;
+ 	    for (j = 0; j < XVECLEN (x, i); j++)
+ 	      if (volatile_refs_p (XVECEXP (x, i, j)))
+ 		return 1;
+ 	  }
+       }
+   }
+   return 0;
+ }
+ \f


+ /* Return nonzero if evaluating rtx X might cause a trap.  */
+ 
+ int
+ may_trap_p (x)
+      rtx x;
+ {
+   int i;
+   enum rtx_code code;
+   char *fmt;
+ 
+   if (x == 0)
+     return 0;
+   code = GET_CODE (x);
+   switch (code)
+     {
+       /* Handle these cases fast.  */
+     case CONST_INT:
+     case CONST_DOUBLE:
+     case SYMBOL_REF:
+     case LABEL_REF:
+     case CONST:
+     case PC:
+     case CC0:
+     case REG:
+       return 0;
+ 
+       /* Memory ref can trap unless it's a static var or a stack slot.  */
+     case MEM:
+       return rtx_varies_p (XEXP (x, 0));
+ 
+       /* Division by a non-constant might trap.  */
+     case DIV:
+     case MOD:
+     case UDIV:
+     case UMOD:
+       if (! CONSTANT_P (XEXP (x, 1))
+ 	  && GET_CODE (XEXP (x, 1)) != CONST_DOUBLE)
+ 	return 1;
+       if (XEXP (x, 1) == const0_rtx)
+ 	return 1;
+     default:
+       /* Any floating arithmetic may trap.  */
+       if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
+ 	return 1;
+     }
+ 
+   fmt = GET_RTX_FORMAT (code);
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     {
+       if (fmt[i] == 'e')
+ 	{
+ 	  if (may_trap_p (XEXP (x, i)))
+ 	    return 1;
+ 	}
+       else if (fmt[i] == 'E')
+ 	{
+ 	  register int j;
+ 	  for (j = 0; j < XVECLEN (x, i); j++)
+ 	    if (may_trap_p (XVECEXP (x, i, j)))
+ 	      return 1;
+ 	}
+     }
+   return 0;
+ }
diff -rc2N gcc-1.35/sdbout.c gcc-1.36/sdbout.c
*** gcc-1.35/sdbout.c	Wed Feb 22 12:28:35 1989
--- gcc-1.36/sdbout.c	Sun Aug  6 16:45:13 1989
***************
*** 25,29 ****
  #include "tree.h"
  #include "rtl.h"
- #include "c-tree.h"
  #include <stdio.h>
  #include <syms.h>
--- 25,28 ----
***************
*** 162,171 ****
      && IDENTIFIER_POINTER (TREE_PURPOSE ((link)))) \
     ? IDENTIFIER_POINTER (TREE_PURPOSE ((link))) : (char *) 0)
- 
- /* Return the structure-tag name of a structure, etc.  */
- 
- #define TYPE_TAG_NAME(type) \
-   ((TYPE_NAME (type) != 0 && TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) \
-    ? IDENTIFIER_POINTER (TYPE_NAME (type)) : 0)
  \f


  /* Tell the assembler the source file name.
--- 161,164 ----
***************
*** 271,275 ****
    if (TREE_CODE (type) == ARRAY_TYPE)
      {
!       PUT_SDB_SIZE (int_size_in_bytes (type));
      }
    return val;
--- 264,272 ----
    if (TREE_CODE (type) == ARRAY_TYPE)
      {
!       int size = int_size_in_bytes (type);
!       /* Don't kill sdb if type is not laid out or has variable size.  */
!       if (size < 0)
! 	size = 0;
!       PUT_SDB_SIZE (size);
      }
    return val;
***************
*** 280,289 ****
       tree type;
  {
!   char *name;
    if (KNOWN_TYPE_TAG (type))
      return;
!   name = TYPE_TAG_NAME (type);
!   if (!name || !*name)
      name = gen_fake_label ();
    SET_KNOWN_TYPE_TAG (type, name);
  }
--- 277,306 ----
       tree type;
  {
!   char *name = 0;
! 
    if (KNOWN_TYPE_TAG (type))
      return;
! 
!   if (TYPE_NAME (type) != 0) 
!     {
!       tree t = 0;
!       /* Find the IDENTIFIER_NODE for the type name.  */
!       if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
! 	{
! 	  t = TYPE_NAME (type);
! 	}
!       else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
! 	{
! 	  t = DECL_NAME (TYPE_NAME (type));
! 	}
! 
!       /* Now get the name as a string, or invent one.  */
!       if (t != 0)
! 	name = IDENTIFIER_POINTER (t);
!     }
! 
!   if (name == 0)
      name = gen_fake_label ();
+ 
    SET_KNOWN_TYPE_TAG (type, name);
  }
***************
*** 297,300 ****
--- 314,319 ----
    if (type == error_mark_node)
      type = integer_type_node;
+   type = TYPE_MAIN_VARIANT (type);
+ 
    switch (TREE_CODE (type))
      {
***************
*** 334,337 ****
--- 353,357 ----
        {
  	char *tag;
+ 	int size;
  	sdbout_record_type_name (type);
  	if (TREE_ASM_WRITTEN (type))
***************
*** 344,353 ****
  	    PUT_SDB_TAG (tag);
  	  }
! 	PUT_SDB_SIZE (int_size_in_bytes (type));
! 	return ((TREE_CODE (type) == RECORD_TYPE) ? T_STRUCT :
! 		(TREE_CODE (type) == UNION_TYPE) ? T_UNION :
! 		T_ENUM);
        }
      case POINTER_TYPE:
        {
  	int m = plain_type (TREE_TYPE (type));
--- 364,377 ----
  	    PUT_SDB_TAG (tag);
  	  }
! 	size = int_size_in_bytes (type);
! 	if (size < 0)
! 	  size = 0;
! 	PUT_SDB_SIZE (size);
! 	return ((TREE_CODE (type) == RECORD_TYPE) ? T_STRUCT
! 		: (TREE_CODE (type) == UNION_TYPE) ? T_UNION
! 		: T_ENUM);
        }
      case POINTER_TYPE:
+     case REFERENCE_TYPE:
        {
  	int m = plain_type (TREE_TYPE (type));
***************
*** 355,358 ****
--- 379,383 ----
        }
      case FUNCTION_TYPE:
+     case METHOD_TYPE:
        {
  	int m = plain_type (TREE_TYPE (type));
***************
*** 393,396 ****
--- 418,424 ----
  
  	case LET_STMT:
+ 	  /* Ignore LET_STMTs for blocks never really used to make RTL.  */
+ 	  if (! TREE_USED (stmt))
+ 	    break;
  	  /* When we reach the specified block, output its symbols.  */
  	  if (next_block_number == do_block)
***************
*** 407,411 ****
  
  	  /* Scan the blocks within this block.  */
! 	  sdbout_block (STMT_BODY (stmt));
  	}
        stmt = TREE_CHAIN (stmt);
--- 435,439 ----
  
  	  /* Scan the blocks within this block.  */
! 	  sdbout_block (STMT_SUBBLOCKS (stmt));
  	}
        stmt = TREE_CHAIN (stmt);
***************
*** 574,578 ****
        if (TREE_PURPOSE (link) != 0
  	  && TYPE_SIZE (type) != 0)
! 	sdbout_one_type (type, TAG_NAME (link));
      }
  }
--- 602,606 ----
        if (TREE_PURPOSE (link) != 0
  	  && TYPE_SIZE (type) != 0)
! 	sdbout_one_type (type);
      }
  }
***************
*** 588,592 ****
  
    for (link = types; link; link = TREE_CHAIN (link))
!     sdbout_one_type (link, 0);
  }
  
--- 616,620 ----
  
    for (link = types; link; link = TREE_CHAIN (link))
!     sdbout_one_type (link);
  }
  
***************
*** 601,604 ****
--- 629,648 ----
  }
  
+ /* Output types of the fields of type TYPE, if they are structs.
+    Don't chase through pointer types, since that could be circular.
+    They must come before TYPE, since forward refs are not allowed.
+ 
+    This is not actually used, since the COFF assembler rejects the
+    results.  No one knows why it rejects them.  */
+ 
+ static void
+ sdbout_field_types (type)
+      tree type;
+ {
+   tree tail;
+   for (tail = TYPE_FIELDS (type); tail; tail = TREE_CHAIN (tail))
+     sdbout_one_type (TREE_TYPE (tail));
+ }
+ 
  /* Use this to put out the top level defined record and union types
     for later reference.  If this is a struct with a name, then put that
***************
*** 609,617 ****
  
  static void
! sdbout_one_type (type, name)
!      char *name;
       tree type;
  {
    text_section ();
    switch (TREE_CODE (type))
      {
--- 653,661 ----
  
  static void
! sdbout_one_type (type)
       tree type;
  {
    text_section ();
+ 
    switch (TREE_CODE (type))
      {
***************
*** 619,622 ****
--- 663,667 ----
      case UNION_TYPE:
      case ENUMERAL_TYPE:
+       type = TYPE_MAIN_VARIANT (type);
        /* Don't output a type twice.  */
        if (TREE_ASM_WRITTEN (type))
***************
*** 624,627 ****
--- 669,679 ----
  
        TREE_ASM_WRITTEN (type) = 1;
+ #if 0  /* This change, which ought to make better output,
+ 	  makes the COFF assembler unhappy.  */
+       /* Before really doing anything, output types we want to refer to.  */
+       if (TREE_CODE (type) != ENUMERAL_TYPE)
+ 	sdbout_field_types (type);
+ #endif
+ 
        sdbout_record_type_name (type);
  
***************
*** 724,728 ****
        int current_sym_value = DECL_OFFSET (parms) / BITS_PER_UNIT;
  
!       PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (parms)));
        if (GET_CODE (DECL_RTL (parms)) == REG
  	  && REGNO (DECL_RTL (parms)) >= 0
--- 776,784 ----
        int current_sym_value = DECL_OFFSET (parms) / BITS_PER_UNIT;
  
!       if (DECL_NAME (parms))
! 	PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (parms)));
!       else
! 	PUT_SDB_DEF (gen_fake_label ());
! 
        if (GET_CODE (DECL_RTL (parms)) == REG
  	  && REGNO (DECL_RTL (parms)) >= 0
diff -rc2N gcc-1.35/stddef.h gcc-1.36/stddef.h
*** gcc-1.35/stddef.h	Sat May 14 01:05:30 1988
--- gcc-1.36/stddef.h	Thu Sep 21 01:00:22 1989
***************
*** 8,15 ****
--- 8,19 ----
  /* Unsigned type of `sizeof' something.  */
  
+ #ifndef _SIZE_T	/* in case <sys/types.h> has defined it. */
+ #define _SIZE_T
  typedef unsigned long size_t;
+ #endif /* _SIZE_T */
  
  /* A null pointer constant.  */
  
+ #undef NULL		/* in case <stdio.h> has defined it. */
  #define NULL ((void *)0)
  
diff -rc2N gcc-1.35/stmt.c gcc-1.36/stmt.c
*** gcc-1.35/stmt.c	Sat Apr 15 16:11:42 1989
--- gcc-1.36/stmt.c	Thu Sep 21 00:29:53 1989
***************
*** 58,61 ****
--- 58,62 ----
  #include "expr.h"
  #include "regs.h"
+ #include "hard-reg-set.h"
  
  #define MAX(x,y) (((x) > (y)) ? (x) : (y))
***************
*** 85,88 ****
--- 86,98 ----
  int current_function_calls_setjmp;
  
+ /* Nonzero if function being compiled can call alloca,
+    either as a subroutine or builtin.  */
+ 
+ int current_function_calls_alloca;
+ 
+ /* Nonzero if the current function returns a pointer type */
+ 
+ int current_function_returns_pointer;
+ 
  /* If function's args have a fixed size, this is that size, in bytes.
     Otherwise, it is -1.
***************
*** 100,103 ****
--- 110,119 ----
  char *current_function_name;
  
+ /* Label that will go on parm cleanup code, if any.
+    Jumping to this label runs cleanup code for parameters, if
+    such code must be run.  Following this code is the logical return label.  */
+ 
+ rtx cleanup_label;
+ 
  /* Label that will go on function epilogue.
     Jumping to this label serves as a "return" instruction
***************
*** 154,183 ****
  /* Last insn of those whose job was to put parms into their nominal homes.  */
  static rtx last_parm_insn;
- 
- static void expand_goto_internal ();
- static int expand_fixup ();
- static void fixup_gotos ();
- static void expand_cleanups ();
- static void fixup_cleanups ();
- static void expand_null_return_1 ();
- static int tail_recursion_args ();
- static void fixup_stack_slots ();
- static rtx fixup_stack_1 ();
- static rtx fixup_memory_subreg ();
- static rtx walk_fixup_memory_subreg ();
- static void fixup_var_refs ();
- static void fixup_var_refs_insns ();
- static rtx fixup_var_refs_1 ();
- static rtx parm_stack_loc ();
- static void optimize_bit_field ();
- static void do_jump_if_equal ();
  \f


  /* Functions and data structures for expanding case statements.  */
  
- static void balance_case_nodes ();
- static void emit_case_nodes ();
- static void group_case_nodes ();
- static void emit_jump_if_reachable ();
- 
  /* Case label structure, used to hold info on labels within case
     statements.  We handle "range" labels; for a single-value label
--- 170,176 ----
***************
*** 197,200 ****
--- 190,198 ----
  typedef struct case_node case_node;
  typedef struct case_node *case_node_ptr;
+ 
+ static void balance_case_nodes ();
+ static void emit_case_nodes ();
+ static void group_case_nodes ();
+ static void emit_jump_if_reachable ();
  \f


  /* Stack of control and binding constructs we are currently inside.
***************
*** 336,339 ****
--- 334,368 ----
       while (nesting_depth > initial_depth); } while (0)
  \f


+ static int warn_if_unused_value ();
+ static void expand_goto_internal ();
+ static int expand_fixup ();
+ static void fixup_gotos ();
+ static void expand_cleanups ();
+ static void fixup_cleanups ();
+ static void expand_null_return_1 ();
+ static int tail_recursion_args ();
+ static void fixup_stack_slots ();
+ static rtx fixup_stack_1 ();
+ static rtx fixup_memory_subreg ();
+ static rtx walk_fixup_memory_subreg ();
+ static void fixup_var_refs ();
+ static void fixup_var_refs_insns ();
+ static rtx fixup_var_refs_1 ();
+ static rtx parm_stack_loc ();
+ static void optimize_bit_field ();
+ static void do_jump_if_equal ();
+ \f


+ /* Emit a no-op instruction.  */
+ 
+ rtx
+ emit_nop ()
+ {
+   rtx last_insn = get_last_insn ();
+   if (!optimize
+       && (GET_CODE (last_insn) == CODE_LABEL
+ 	  || prev_real_insn (last_insn) == 0))
+     emit_insn (gen_nop ());
+ }
+ \f


  /* Return the rtx-label that corresponds to a LABEL_DECL,
     creating it if necessary.  */
***************
*** 764,768 ****
  	  if (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j] == '+')
  	    {
! 	      error ("input operand constraint contains `+'");
  	      return;
  	    }
--- 793,797 ----
  	  if (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j] == '+')
  	    {
! 	      error ("output operand constraint contains `+'");
  	      return;
  	    }
***************
*** 947,954 ****
    /* If -W, warn about statements with no side effects,
       except inside a ({...}) where they may be useful.  */
!   if (extra_warnings && expr_stmts_for_value == 0 && !TREE_VOLATILE (exp)
!       && exp != error_mark_node)
!     warning_with_file_and_line (emit_filename, emit_lineno,
! 				"statement with no effect");
    last_expr_type = TREE_TYPE (exp);
    if (! flag_syntax_only)
--- 976,987 ----
    /* If -W, warn about statements with no side effects,
       except inside a ({...}) where they may be useful.  */
!   if (expr_stmts_for_value == 0 && exp != error_mark_node)
!     {
!       if (! TREE_VOLATILE (exp) && (extra_warnings || warn_unused))
! 	warning_with_file_and_line (emit_filename, emit_lineno,
! 				    "statement with no effect");
!       else if (warn_unused)
! 	warn_if_unused_value (exp);
!     }
    last_expr_type = TREE_TYPE (exp);
    if (! flag_syntax_only)
***************
*** 958,961 ****
--- 991,1051 ----
  }
  
+ /* Warn if EXP contains any computations whose results are not used.
+    Return 1 if a warning is printed; 0 otherwise.  */
+ 
+ static int
+ warn_if_unused_value (exp)
+      tree exp;
+ {
+   switch (TREE_CODE (exp))
+     {
+     case PREINCREMENT_EXPR:
+     case POSTINCREMENT_EXPR:
+     case PREDECREMENT_EXPR:
+     case POSTDECREMENT_EXPR:
+     case MODIFY_EXPR:
+     case INIT_EXPR:
+     case NEW_EXPR:
+     case DELETE_EXPR:
+     case PUSH_EXPR:
+     case POP_EXPR:
+     case CALL_EXPR:
+     case METHOD_CALL_EXPR:
+     case RTL_EXPR:
+     case WRAPPER_EXPR:
+     case ANTI_WRAPPER_EXPR:
+     case WITH_CLEANUP_EXPR:
+       /* We don't warn about COND_EXPR because it may be a useful
+ 	 construct if either arm contains a side effect.  */
+     case COND_EXPR:
+       return 0;
+ 
+     case TRUTH_ORIF_EXPR:
+     case TRUTH_ANDIF_EXPR:
+       /* In && or ||, warn if 2nd operand has no side effect.  */
+       return warn_if_unused_value (TREE_OPERAND (exp, 1));
+ 
+     case COMPOUND_EXPR:
+       if (warn_if_unused_value (TREE_OPERAND (exp, 0)))
+ 	return 1;
+       return warn_if_unused_value (TREE_OPERAND (exp, 1));
+ 
+     case NOP_EXPR:
+     case CONVERT_EXPR:
+       /* Don't warn about values cast to void.  */
+       if (TREE_TYPE (exp) == void_type_node)
+ 	return 0;
+       /* Assignment to a cast results in a cast of a modify.
+ 	 Don't complain about that.  */
+       if (TREE_CODE (TREE_OPERAND (exp, 0)) == MODIFY_EXPR)
+ 	return 0;
+ 
+     default:
+       warning_with_file_and_line (emit_filename, emit_lineno,
+ 				  "value computed is not used");
+       return 1;
+     }
+ }
+ 
  /* Clear out the memory of the last expression evaluated.  */
  
***************
*** 980,983 ****
--- 1070,1074 ----
    resume_momentary (momentary);
    RTL_EXPR_RTL (t) = save;
+   NO_DEFER_POP;
    expr_stmts_for_value++;
    return t;
***************
*** 1002,1006 ****
    rtx saved = RTL_EXPR_RTL (t);
  
!   do_pending_stack_adjust ();
  
    if (last_expr_type == 0)
--- 1093,1097 ----
    rtx saved = RTL_EXPR_RTL (t);
  
!   OK_DEFER_POP;
  
    if (last_expr_type == 0)
***************
*** 1262,1265 ****
--- 1353,1364 ----
  }
  
+ /* Return non-zero if currently inside a loop.  */
+ 
+ int
+ inside_loop ()
+ {
+   return loop_stack != 0;
+ }
+ 
  /* Generate a jump to exit the current loop, conditional, binding contour
     or case statement.  Not all such constructs are visible to this function,
***************
*** 1292,1305 ****
  expand_null_return ()
  {
!   expand_null_return_1 (0);
  }
  
  /* Output a return with no value.  If LAST_INSN is nonzero,
!    pretend that the return takes place after LAST_INSN.  */
  
  static void
! expand_null_return_1 (last_insn)
       rtx last_insn;
  {
    clear_pending_stack_adjust ();
    do_pending_stack_adjust ();
--- 1391,1420 ----
  expand_null_return ()
  {
!   struct nesting *block = block_stack;
!   rtx last_insn = 0;
! 
!   /* Does any pending block have cleanups?  */
! 
!   while (block && block->data.block.cleanups == 0)
!     block = block->next;
! 
!   /* If yes, use a goto to return, since that runs cleanups.  */
! 
!   expand_null_return_1 (last_insn, block != 0);
  }
  
  /* Output a return with no value.  If LAST_INSN is nonzero,
!    pretend that the return takes place after LAST_INSN.
!    If USE_GOTO is nonzero then don't use a return instruction;
!    go to the return label instead.  This causes any cleanups
!    of pending blocks to be executed normally.  */
  
  static void
! expand_null_return_1 (last_insn, use_goto)
       rtx last_insn;
+      int use_goto;
  {
+   rtx end_label = cleanup_label ? cleanup_label : return_label;
+ 
    clear_pending_stack_adjust ();
    do_pending_stack_adjust ();
***************
*** 1307,1319 ****
  
    /* PCC-struct return always uses an epilogue.  */
!   if (current_function_returns_pcc_struct)
      {
!       expand_goto_internal (0, return_label, last_insn);
        return;
      }
  
!   /* Otherwise output a simple return-insn if one is available.  */ 
  #ifdef HAVE_return
!   if (HAVE_return)
      {
        emit_jump_insn (gen_return ());
--- 1422,1437 ----
  
    /* PCC-struct return always uses an epilogue.  */
!   if (current_function_returns_pcc_struct || use_goto)
      {
!       if (end_label == 0)
! 	end_label = return_label = gen_label_rtx ();
!       expand_goto_internal (0, end_label, last_insn);
        return;
      }
  
!   /* Otherwise output a simple return-insn if one is available,
!      unless it won't do the job.  */
  #ifdef HAVE_return
!   if (HAVE_return && cleanup_label == 0)
      {
        emit_jump_insn (gen_return ());
***************
*** 1324,1328 ****
  
    /* Otherwise jump to the epilogue.  */
!   expand_goto_internal (0, return_label, last_insn);
  }
  
--- 1442,1446 ----
  
    /* Otherwise jump to the epilogue.  */
!   expand_goto_internal (0, end_label, last_insn);
  }
  
***************
*** 1334,1337 ****
--- 1452,1464 ----
       tree retval;
  {
+   /* If there are any cleanups to be performed, then they will
+      be inserted following LAST_INSN.  It is desirable
+      that the last_insn, for such purposes, should be the
+      last insn before computing the return value.  Otherwise, cleanups
+      which call functions can clobber the return value.  */
+   /* ??? rms: I think that is erroneous, because in C++ it would
+      run destructors on variables that might be used in the subsequent
+      computation of the return value.  */
+   rtx last_insn = 0;
    register rtx val = 0;
    register rtx op0;
***************
*** 1360,1363 ****
--- 1487,1494 ----
      retval_rhs = NULL_TREE;
  
+   /* Only use `last_insn' if there are cleanups which must be run.  */
+   if (cleanups || cleanup_label != 0)
+     last_insn = get_last_insn ();
+ 
    /* For tail-recursive call to current function,
       just jump back to the beginning.
***************
*** 1381,1385 ****
  			    tail_recursion_reentry);
  	}
!       expand_goto_internal (0, tail_recursion_label, get_last_insn ());
        emit_barrier ();
        return;
--- 1512,1516 ----
  			    tail_recursion_reentry);
  	}
!       expand_goto_internal (0, tail_recursion_label, last_insn);
        emit_barrier ();
        return;
***************
*** 1386,1390 ****
      }
  #ifdef HAVE_return
!   if (HAVE_return && ! cleanups
        && ! current_function_returns_pcc_struct)
      {
--- 1517,1526 ----
      }
  #ifdef HAVE_return
!   /* This optimization is safe if there are local cleanups
!      because expand_null_return takes care of them.
!      ??? I think it should also be safe when there is a cleanup label,
!      because expand_null_return takes care of them, too.
!      Any reason why not?  */
!   if (HAVE_return && cleanup_label == 0
        && ! current_function_returns_pcc_struct)
      {
***************
*** 1438,1442 ****
        if (GET_CODE (val) == REG)
  	emit_insn (gen_rtx (USE, VOIDmode, val));
!       expand_null_return_1 (last_insn);
      }
    else
--- 1574,1578 ----
        if (GET_CODE (val) == REG)
  	emit_insn (gen_rtx (USE, VOIDmode, val));
!       expand_null_return_1 (last_insn, cleanups);
      }
    else
***************
*** 1449,1453 ****
  
        val = DECL_RTL (DECL_RESULT (this_function));
!       if (GET_CODE (val) == REG)
  	emit_insn (gen_rtx (USE, VOIDmode, val));
        expand_null_return ();
--- 1585,1589 ----
  
        val = DECL_RTL (DECL_RESULT (this_function));
!       if (val && GET_CODE (val) == REG)
  	emit_insn (gen_rtx (USE, VOIDmode, val));
        expand_null_return ();
***************
*** 1910,1913 ****
--- 2046,2056 ----
  #endif
  
+       /* Some systems require a particular insn to refer to the stack
+ 	 to make the pages exist.  */
+ #ifdef HAVE_probe
+       if (HAVE_probe)
+ 	emit_insn (gen_probe ());
+ #endif
+ 
        /* Reference the variable indirect through that rtx.  */
        DECL_RTL (decl) = gen_rtx (MEM, DECL_MODE (decl), address);
***************
*** 2053,2056 ****
--- 2196,2205 ----
    block->data.block.cleanups = 0;
  }
+ 
+ int
+ this_contour_has_cleanups_p ()
+ {
+   return block_stack && block_stack->data.block.cleanups != 0;
+ }
  \f


  /* Enter a case (Pascal) or switch (C) statement.
***************
*** 2093,2098 ****
    /* Make sure case_stmt.start points to something that won't
       need any transformation before expand_end_case.  */
!   if (GET_CODE (get_last_insn ()) != NOTE)
!     emit_note (0, NOTE_INSN_DELETED);
  
    thiscase->data.case_stmt.start = get_last_insn ();
--- 2242,2246 ----
    /* Make sure case_stmt.start points to something that won't
       need any transformation before expand_end_case.  */
!   emit_note (0, NOTE_INSN_DELETED);
  
    thiscase->data.case_stmt.start = get_last_insn ();
***************
*** 2358,2362 ****
  	    warning ("case value `%d' not in enumerated type `%s'",
  		     TREE_INT_CST_LOW (n->low), 
! 		     IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (TREE_TYPE (enum_node)))));
          }
      }
--- 2506,2512 ----
  	    warning ("case value `%d' not in enumerated type `%s'",
  		     TREE_INT_CST_LOW (n->low), 
! 		     IDENTIFIER_POINTER (TREE_CODE (TYPE_NAME (TREE_TYPE (enum_node))) == IDENTIFIER_NODE
! 					 ? TYPE_NAME (TREE_TYPE (enum_node))
! 					 : DECL_NAME (TYPE_NAME (TREE_TYPE (enum_node)))));
          }
      }
***************
*** 2383,2386 ****
--- 2533,2537 ----
    register struct nesting *thiscase = case_stack;
    tree index_expr = thiscase->data.case_stmt.index_expr;
+   int unsignedp = TREE_UNSIGNED (TREE_TYPE (index_expr));
  
    do_pending_stack_adjust ();
***************
*** 2474,2477 ****
--- 2625,2639 ----
  	{
  	  index = expand_expr (index_expr, 0, VOIDmode, 0);
+ 
+ 	  /* If the index is a short or char that we do not have
+ 	     an insn to handle comparisons directly, convert it to
+ 	     a full integer now, rather than letting each comparison
+ 	     generate the conversion.  */
+ 
+ 	  if ((GET_MODE (index) == QImode || GET_MODE (index) == HImode)
+ 	      && (cmp_optab->handlers[(int) GET_MODE(index)].insn_code
+ 		  == CODE_FOR_nothing))
+ 	    index = convert_to_mode (SImode, index, unsignedp);
+ 	  
  	  emit_queue ();
  	  do_pending_stack_adjust ();
***************
*** 2487,2491 ****
  	      if (TREE_CODE (index_expr) != INTEGER_CST)
  		{
! 		  index_expr = build_int_2 (INTVAL (index), 0);
  		  index_expr = convert (TREE_TYPE (index_expr), index_expr);
  		}
--- 2649,2655 ----
  	      if (TREE_CODE (index_expr) != INTEGER_CST)
  		{
! 		  index_expr
! 		    = build_int_2 (INTVAL (index),
! 				   !unsignedp && INTVAL (index) >= 0 ? 0 : -1);
  		  index_expr = convert (TREE_TYPE (index_expr), index_expr);
  		}
***************
*** 2526,2531 ****
  	      balance_case_nodes (&thiscase->data.case_stmt.case_list, 0);
  	      emit_case_nodes (index, thiscase->data.case_stmt.case_list,
! 			       default_label,
! 			       TREE_UNSIGNED (TREE_TYPE (index_expr)));
  	      emit_jump_if_reachable (default_label);
  	    }
--- 2690,2694 ----
  	      balance_case_nodes (&thiscase->data.case_stmt.case_list, 0);
  	      emit_case_nodes (index, thiscase->data.case_stmt.case_list,
! 			       default_label, unsignedp);
  	      emit_jump_if_reachable (default_label);
  	    }
***************
*** 2902,2910 ****
  	    {
  	      /* This node has children on either side.  */
! 	      emit_cmp_insn (index, expand_expr (node->high, 0, VOIDmode, 0), 0, 0, 0);
  
  	      if (node_is_bounded (node->right))
  		{
! 		  emit_jump_insn (gen_bgt_pat (label_rtx (node->right->code_label)));
  		  if (node_is_bounded (node->left))
  		    emit_jump (label_rtx (node->left->code_label));
--- 3065,3073 ----
  	    {
  	      /* This node has children on either side.  */
! 	      emit_cmp_insn (index, expand_expr (node->high, 0, VOIDmode, 0), 0, unsignedp, 0);
  
  	      if (node_is_bounded (node->right))
  		{
! 		  emit_jump_insn ((*gen_bgt_pat) (label_rtx (node->right->code_label)));
  		  if (node_is_bounded (node->left))
  		    emit_jump (label_rtx (node->left->code_label));
***************
*** 2916,2920 ****
  		{
  		  if (node_is_bounded (node->left))
! 		    emit_jump_insn (gen_blt_pat (label_rtx (node->left->code_label)));
  		  else
  		    {
--- 3079,3083 ----
  		{
  		  if (node_is_bounded (node->left))
! 		    emit_jump_insn ((*gen_blt_pat) (label_rtx (node->left->code_label)));
  		  else
  		    {
***************
*** 2921,2925 ****
  		      node->right->test_label =
  			build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
! 		      emit_jump_insn (gen_bgt_pat (label_rtx (node->right->test_label)));
  		      emit_case_nodes (index, node->left,
  				       default_label, unsignedp);
--- 3084,3088 ----
  		      node->right->test_label =
  			build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
! 		      emit_jump_insn ((*gen_bgt_pat) (label_rtx (node->right->test_label)));
  		      emit_case_nodes (index, node->left,
  				       default_label, unsignedp);
***************
*** 2940,2945 ****
  	      if (node->right->right && !node_has_low_bound (node))
  		{
! 		  emit_cmp_insn (index, expand_expr (node->high, 0, VOIDmode, 0), 0, 0, 0);
! 		  emit_jump_insn (gen_blt_pat (default_label));
  		}
  	      if (node_is_bounded (node->right))
--- 3103,3108 ----
  	      if (node->right->right && !node_has_low_bound (node))
  		{
! 		  emit_cmp_insn (index, expand_expr (node->high, 0, VOIDmode, 0), 0, unsignedp, 0);
! 		  emit_jump_insn ((*gen_blt_pat) (default_label));
  		}
  	      if (node_is_bounded (node->right))
***************
*** 2964,2968 ****
  	  if (node->left)
  	    {
! 	      emit_cmp_insn (index, expand_expr (node->high, 0, VOIDmode, 0), 0, 0, 0);
  	      if (node_is_bounded (node->right))
  		{
--- 3127,3131 ----
  	  if (node->left)
  	    {
! 	      emit_cmp_insn (index, expand_expr (node->high, 0, VOIDmode, 0), 0, unsignedp, 0);
  	      if (node_is_bounded (node->right))
  		{
***************
*** 2970,2974 ****
  		     eliminate any testing and branch directly
  		     to the target code.  */
! 		  emit_jump_insn (gen_bgt_pat (label_rtx (node->right->code_label)));
  		}
  	      else
--- 3133,3137 ----
  		     eliminate any testing and branch directly
  		     to the target code.  */
! 		  emit_jump_insn ((*gen_bgt_pat) (label_rtx (node->right->code_label)));
  		}
  	      else
***************
*** 2978,2985 ****
  		  node->right->test_label =
  		    build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
! 		  emit_jump_insn (gen_bgt_pat (label_rtx (node->right->test_label)));
  		}
! 	      emit_cmp_insn (index, expand_expr (node->low, 0, VOIDmode, 0), 0, 0, 0);
! 	      emit_jump_insn (gen_bge_pat (label_rtx (node->code_label)));
  	      if (node_is_bounded (node->left))
  		{
--- 3141,3148 ----
  		  node->right->test_label =
  		    build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
! 		  emit_jump_insn ((*gen_bgt_pat) (label_rtx (node->right->test_label)));
  		}
! 	      emit_cmp_insn (index, expand_expr (node->low, 0, VOIDmode, 0), 0, unsignedp, 0);
! 	      emit_jump_insn ((*gen_bge_pat) (label_rtx (node->code_label)));
  	      if (node_is_bounded (node->left))
  		{
***************
*** 3000,3008 ****
  	      if (!node_has_low_bound (node))
  		{
! 		  emit_cmp_insn (index, expand_expr (node->low, 0, VOIDmode, 0), 0, 0, 0);
! 		  emit_jump_insn (gen_blt_pat (default_label));
  		}
! 	      emit_cmp_insn (index, expand_expr (node->high, 0, VOIDmode, 0), 0, 0, 0);
! 	      emit_jump_insn (gen_ble_pat (label_rtx (node->code_label)));
  	      if (node_is_bounded (node->right))
  		{
--- 3163,3171 ----
  	      if (!node_has_low_bound (node))
  		{
! 		  emit_cmp_insn (index, expand_expr (node->low, 0, VOIDmode, 0), 0, unsignedp, 0);
! 		  emit_jump_insn ((*gen_blt_pat) (default_label));
  		}
! 	      emit_cmp_insn (index, expand_expr (node->high, 0, VOIDmode, 0), 0, unsignedp, 0);
! 	      emit_jump_insn ((*gen_ble_pat) (label_rtx (node->code_label)));
  	      if (node_is_bounded (node->right))
  		{
***************
*** 3020,3028 ****
  	  if (!node_has_high_bound (node))
  	    {
! 	      emit_cmp_insn (index, expand_expr (node->high, 0, VOIDmode, 0), 0, 0, 0);
! 	      emit_jump_insn (gen_bgt_pat (default_label));
  	    }
! 	  emit_cmp_insn (index, expand_expr (node->low, 0, VOIDmode, 0), 0, 0, 0);
! 	  emit_jump_insn (gen_bge_pat (label_rtx (node->code_label)));
  	  if (node_is_bounded (node->left))
  	    {
--- 3183,3191 ----
  	  if (!node_has_high_bound (node))
  	    {
! 	      emit_cmp_insn (index, expand_expr (node->high, 0, VOIDmode, 0), 0, unsignedp, 0);
! 	      emit_jump_insn ((*gen_bgt_pat) (default_label));
  	    }
! 	  emit_cmp_insn (index, expand_expr (node->low, 0, VOIDmode, 0), 0, unsignedp, 0);
! 	  emit_jump_insn ((*gen_bge_pat) (label_rtx (node->code_label)));
  	  if (node_is_bounded (node->left))
  	    {
***************
*** 3043,3053 ****
  	  if (!node_has_high_bound (node))
  	    {
! 	      emit_cmp_insn (index, expand_expr (node->high, 0, VOIDmode, 0), 0, 0, 0);
! 	      emit_jump_insn (gen_bgt_pat (default_label));
  	    }
  	  if (!node_has_low_bound (node))
  	    {
! 	      emit_cmp_insn (index, expand_expr (node->low, 0, VOIDmode, 0), 0, 0, 0);
! 	      emit_jump_insn (gen_bge_pat (label_rtx (node->code_label)));
  	    }
  	  /* We allow the default case to drop through since
--- 3206,3216 ----
  	  if (!node_has_high_bound (node))
  	    {
! 	      emit_cmp_insn (index, expand_expr (node->high, 0, VOIDmode, 0), 0, unsignedp, 0);
! 	      emit_jump_insn ((*gen_bgt_pat) (default_label));
  	    }
  	  if (!node_has_low_bound (node))
  	    {
! 	      emit_cmp_insn (index, expand_expr (node->low, 0, VOIDmode, 0), 0, unsignedp, 0);
! 	      emit_jump_insn ((*gen_bge_pat) (label_rtx (node->code_label)));
  	    }
  	  /* We allow the default case to drop through since
***************
*** 3067,3073 ****
  {
  #ifdef FRAME_GROWS_DOWNWARD
!   return -frame_offset;
  #else
!   return frame_offset;
  #endif
  }
--- 3230,3236 ----
  {
  #ifdef FRAME_GROWS_DOWNWARD
!   return -frame_offset + STARTING_FRAME_OFFSET;
  #else
!   return frame_offset - STARTING_FRAME_OFFSET;
  #endif
  }
***************
*** 3174,3177 ****
--- 3337,3343 ----
        fixup_var_refs_insns (var, XEXP (stack, 0),
  			    XEXP (XEXP (stack, 1), 1) == 0);
+       /* Update remembered end of sequence
+ 	 in case we added an insn at the end.  */
+       XEXP (XEXP (stack, 1), 0) = get_last_insn ();
        end_sequence ();
      }
***************
*** 3340,3343 ****
--- 3506,3522 ----
  	    XEXP (outerdest, 0) = copy_rtx (XEXP (outerdest, 0));
  	    PUT_MODE (XEXP (outerdest, 0), QImode);
+ 	    /* Adjust the address so the bit field starts within the byte
+ 	       addressed.  This helps certain optimization patterns.  */
+ 	    if (GET_CODE (XEXP (outerdest, 2)) == CONST_INT
+ 		&& offsettable_memref_p (XEXP (outerdest, 0)))
+ 	      {
+ 		int count = INTVAL (XEXP (outerdest, 2));
+ 		XEXP (outerdest, 0)
+ 		  = adj_offsettable_operand (XEXP (outerdest, 0),
+ 					     count / GET_MODE_BITSIZE (QImode));
+ 		XEXP (outerdest, 2)
+ 		  = gen_rtx (CONST_INT, VOIDmode,
+ 			     count % GET_MODE_BITSIZE (QImode));
+ 	      }
  	  }
  
***************
*** 3349,3352 ****
--- 3528,3544 ----
  	    XEXP (outersrc, 0) = copy_rtx (XEXP (outersrc, 0));
  	    PUT_MODE (XEXP (outersrc, 0), QImode);
+ 	    /* Adjust the address so the bit field starts within the byte
+ 	       addressed.  This helps certain optimization patterns.  */
+ 	    if (GET_CODE (XEXP (outersrc, 2)) == CONST_INT
+ 		&& offsettable_memref_p (XEXP (outersrc, 0)))
+ 	      {
+ 		int count = INTVAL (XEXP (outersrc, 2));
+ 		XEXP (outersrc, 0)
+ 		  = adj_offsettable_operand (XEXP (outersrc, 0),
+ 					     count / GET_MODE_BITSIZE (QImode));
+ 		XEXP (outersrc, 2)
+ 		  = gen_rtx (CONST_INT, VOIDmode,
+ 			     count % GET_MODE_BITSIZE (QImode));
+ 	      }
  	  }
  
***************
*** 3614,3618 ****
        if (memref
  	  && ! mode_dependent_address_p (XEXP (memref, 0))
! 	  && offsetable_address_p (0, GET_MODE (bitfield), XEXP (memref, 0)))
  	{
  	  /* Now adjust the address, first for any subreg'ing
--- 3806,3810 ----
        if (memref
  	  && ! mode_dependent_address_p (XEXP (memref, 0))
! 	  && offsettable_address_p (0, GET_MODE (bitfield), XEXP (memref, 0)))
  	{
  	  /* Now adjust the address, first for any subreg'ing
***************
*** 3644,3648 ****
  	    {
  	      SET_DEST (body)
! 		= adj_offsetable_operand (memref, offset);
  	      if (! CONSTANT_ADDRESS_P (SET_SRC (body)))
  		{
--- 3836,3840 ----
  	    {
  	      SET_DEST (body)
! 		= adj_offsettable_operand (memref, offset);
  	      if (! CONSTANT_ADDRESS_P (SET_SRC (body)))
  		{
***************
*** 3674,3678 ****
  	      SET_DEST (body) = dest;
  
! 	      memref = adj_offsetable_operand (memref, offset);
  	      if (GET_MODE (dest) == GET_MODE (memref))
  		SET_SRC (body) = memref;
--- 3866,3870 ----
  	      SET_DEST (body) = dest;
  
! 	      memref = adj_offsettable_operand (memref, offset);
  	      if (GET_MODE (dest) == GET_MODE (memref))
  		SET_SRC (body) = memref;
***************
*** 3737,3740 ****
--- 3929,3950 ----
  }
  
+ /* Return 1 if EXP returns an aggregate value, for which an address
+    must be passed to the function or returned by the function.  */
+ 
+ int
+ aggregate_value_p (exp)
+      tree exp;
+ {
+   if (TYPE_MODE (TREE_TYPE (exp)) == BLKmode)
+     return 1;
+   if (RETURN_IN_MEMORY (TREE_TYPE (exp)))
+     return 1;
+   if (flag_pcc_struct_return
+       && (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
+ 	  || TREE_CODE (TREE_TYPE (exp)) == UNION_TYPE))
+     return 1;
+   return 0;
+ }
+ \f


  /* Assign RTL expressions to the function's parameters.
     This may involve copying them into registers and using
***************
*** 3755,3758 ****
--- 3965,3970 ----
    int first_parm_offset = FIRST_PARM_OFFSET (fndecl);
    tree fntype = TREE_TYPE (fndecl);
+   /* This is used for the arg pointer when referring to stack args.  */
+   rtx internal_arg_pointer;
  
    int nparmregs
***************
*** 3774,3777 ****
--- 3986,4004 ----
  	&& (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
  	    != void_type_node)));
+   int arg_pointer_copied = 0;
+ 
+ #if ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM
+   internal_arg_pointer = arg_pointer_rtx;
+ #else
+   /* If the arg pointer reg is not a fixed reg,
+      make a copy of it, and address parms via the copy.  */
+   if (fixed_regs[ARG_POINTER_REGNUM])
+     internal_arg_pointer = arg_pointer_rtx;
+   else
+     {
+       internal_arg_pointer = copy_to_reg (arg_pointer_rtx);
+       arg_pointer_copied = 1;
+     }
+ #endif
  
    stack_args_size.constant = 0;
***************
*** 3779,3784 ****
  
    /* If struct value address comes on the stack, count it in size of args.  */
!   if ((DECL_MODE (DECL_RESULT (fndecl)) == BLKmode
!        || RETURN_IN_MEMORY (TREE_TYPE (DECL_RESULT (fndecl))))
        && GET_CODE (struct_value_incoming_rtx) == MEM)
      stack_args_size.constant += GET_MODE_SIZE (Pmode);
--- 4006,4010 ----
  
    /* If struct value address comes on the stack, count it in size of args.  */
!   if (aggregate_value_p (DECL_RESULT (fndecl))
        && GET_CODE (struct_value_incoming_rtx) == MEM)
      stack_args_size.constant += GET_MODE_SIZE (Pmode);
***************
*** 3829,3833 ****
  	 needs more alignment than PARM_BOUNDARY, regardless of data type.  */
  
!       if (PARM_BOUNDARY < TYPE_ALIGN (TREE_TYPE (parm)))
  	{
  	  int boundary = PARM_BOUNDARY;
--- 4055,4059 ----
  	 needs more alignment than PARM_BOUNDARY, regardless of data type.  */
  
!       if (PARM_BOUNDARY < TYPE_ALIGN (DECL_ARG_TYPE (parm)))
  	{
  	  int boundary = PARM_BOUNDARY;
***************
*** 3834,3839 ****
  
  	  /* Determine the boundary to pad up to.  */
! 	  if (TYPE_ALIGN (TREE_TYPE (parm)) > boundary)
! 	    boundary = TYPE_ALIGN (TREE_TYPE (parm));
  	  if (boundary > MAX_PARM_BOUNDARY)
  	    boundary = MAX_PARM_BOUNDARY;
--- 4060,4065 ----
  
  	  /* Determine the boundary to pad up to.  */
! 	  if (TYPE_ALIGN (DECL_ARG_TYPE (parm)) > boundary)
! 	    boundary = TYPE_ALIGN (DECL_ARG_TYPE (parm));
  	  if (boundary > MAX_PARM_BOUNDARY)
  	    boundary = MAX_PARM_BOUNDARY;
***************
*** 3841,3846 ****
  	  /* If the previous args don't reach such a boundary,
  	     advance to the next one.  */
  	  stack_offset.constant += boundary - 1;
! 	  stack_offset.constant &= boundary - 1;
  
  	  if (stack_offset.var != 0)
--- 4067,4075 ----
  	  /* If the previous args don't reach such a boundary,
  	     advance to the next one.  */
+ 	  boundary /= BITS_PER_UNIT;
  	  stack_offset.constant += boundary - 1;
! 	  stack_offset.constant &= ~(boundary - 1);
! 	  stack_args_size.constant += boundary - 1;
! 	  stack_args_size.constant &= ~(boundary - 1);
  
  	  if (stack_offset.var != 0)
***************
*** 3893,3897 ****
  		   memory_address (passed_mode,
  				   gen_rtx (PLUS, Pmode,
! 					    arg_pointer_rtx, stack_offset_rtx)));
  
        /* If this is a memory ref that contains aggregate components,
--- 4122,4127 ----
  		   memory_address (passed_mode,
  				   gen_rtx (PLUS, Pmode,
! 					    internal_arg_pointer,
! 					    stack_offset_rtx)));
  
        /* If this is a memory ref that contains aggregate components,
***************
*** 3906,3918 ****
  	  || stack_offset.var != 0)
  	{
  #ifdef FUNCTION_INCOMING_ARG
  	  entry_parm
  	    = FUNCTION_INCOMING_ARG (args_so_far, passed_mode,
! 				     DECL_ARG_TYPE (parm), 1);
  #else
  	  entry_parm
! 	    = FUNCTION_ARG (args_so_far, passed_mode, DECL_ARG_TYPE (parm), 1);
  #endif
  	}
        /* If this parm was passed part in regs and part in memory,
  	 pretend it arrived entirely in memory
--- 4136,4153 ----
  	  || stack_offset.var != 0)
  	{
+ 	  /* Set LAST_NAMED if this is last named arg before some
+ 	     anonymous args.  We treat it as if it were anonymous too.  */
+ 	  int last_named = (TREE_CHAIN (parm) == 0 && vararg);
  #ifdef FUNCTION_INCOMING_ARG
  	  entry_parm
  	    = FUNCTION_INCOMING_ARG (args_so_far, passed_mode,
! 				     DECL_ARG_TYPE (parm), ! last_named);
  #else
  	  entry_parm
! 	    = FUNCTION_ARG (args_so_far, passed_mode, DECL_ARG_TYPE (parm),
! 			    ! last_named);
  #endif
  	}
+ 
        /* If this parm was passed part in regs and part in memory,
  	 pretend it arrived entirely in memory
***************
*** 3923,3961 ****
  	 but for now that's not worth bothering with.  */
  
!       /* If this is the last named arg and anonymous args follow,
! 	 likewise pretend this arg arrived on the stack
! 	 so varargs can find the anonymous args following it.  */
!       {
! 	int nregs = 0;
! 	int i;
  #ifdef FUNCTION_ARG_PARTIAL_NREGS
! 	nregs = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, passed_mode,
! 					    DECL_ARG_TYPE (parm), 1);
  #endif
! 	if (TREE_CHAIN (parm) == 0 && vararg && entry_parm != 0)
! 	  {
! 	    if (GET_MODE (entry_parm) == BLKmode)
! 	      nregs = GET_MODE_SIZE (GET_MODE (entry_parm)) / UNITS_PER_WORD;
! 	    else
! 	      nregs = (int_size_in_bytes (DECL_ARG_TYPE (parm))
! 		       / UNITS_PER_WORD);
! 	  }
! 
! 	if (nregs > 0)
! 	  {
! 	    current_function_pretend_args_size
! 	      = (((nregs * UNITS_PER_WORD) + (PARM_BOUNDARY / BITS_PER_UNIT) - 1)
! 		 / (PARM_BOUNDARY / BITS_PER_UNIT)
! 		 * (PARM_BOUNDARY / BITS_PER_UNIT));
! 
! 	    i = nregs;
! 	    while (--i >= 0)
! 	      emit_move_insn (gen_rtx (MEM, SImode,
! 				       plus_constant (XEXP (stack_parm, 0),
! 						      i * GET_MODE_SIZE (SImode))),
! 			      gen_rtx (REG, SImode, REGNO (entry_parm) + i));
! 	    entry_parm = stack_parm;
! 	  }
!       }
  
        /* If we didn't decide this parm came in a register,
--- 4158,4201 ----
  	 but for now that's not worth bothering with.  */
  
!       if (entry_parm)
! 	{
! 	  int nregs = 0;
! 	  int i;
  #ifdef FUNCTION_ARG_PARTIAL_NREGS
! 	  nregs = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, passed_mode,
! 					      DECL_ARG_TYPE (parm), 1);
  #endif
! 
! #if 0 /* Replaced by new calling convention
! 	 which actually passes these args on the stack.  */
! 	  /* If this is the last named arg and anonymous args follow,
! 	     likewise pretend this arg arrived on the stack
! 	     so varargs can find the anonymous args following it.  */
! 	  if (TREE_CHAIN (parm) == 0 && vararg)
! 	    {
! 	      if (GET_MODE (entry_parm) == BLKmode)
! 		nregs = GET_MODE_SIZE (GET_MODE (entry_parm)) / UNITS_PER_WORD;
! 	      else
! 		nregs = (int_size_in_bytes (DECL_ARG_TYPE (parm))
! 			 / UNITS_PER_WORD);
! 	    }
! #endif /* 0 */
! 
! 	  if (nregs > 0)
! 	    {
! 	      current_function_pretend_args_size
! 		= (((nregs * UNITS_PER_WORD) + (PARM_BOUNDARY / BITS_PER_UNIT) - 1)
! 		   / (PARM_BOUNDARY / BITS_PER_UNIT)
! 		   * (PARM_BOUNDARY / BITS_PER_UNIT));
! 
! 	      i = nregs;
! 	      while (--i >= 0)
! 		emit_move_insn (gen_rtx (MEM, SImode,
! 					 plus_constant (XEXP (stack_parm, 0),
! 							i * GET_MODE_SIZE (SImode))),
! 				gen_rtx (REG, SImode, REGNO (entry_parm) + i));
! 	      entry_parm = stack_parm;
! 	    }
! 	}
  
        /* If we didn't decide this parm came in a register,
***************
*** 4091,4098 ****
  
  	  /* Mark the register as eliminable if we did no conversion
! 	     and it was copied from memory at a fixed offset.  */
  	  if (nominal_mode == passed_mode
  	      && GET_CODE (entry_parm) == MEM
! 	      && stack_offset.var == 0)
  	    REG_NOTES (get_last_insn ())
  	      = gen_rtx (EXPR_LIST, REG_EQUIV,
--- 4331,4342 ----
  
  	  /* Mark the register as eliminable if we did no conversion
! 	     and it was copied from memory at a fixed offset,
! 	     and the arg pointer was not copied to a pseudo-reg.
! 	     If the arg pointer is a pseudo reg, such memory-equivalences
! 	     as we make here would screw up life analysis for it.  */
  	  if (nominal_mode == passed_mode
  	      && GET_CODE (entry_parm) == MEM
! 	      && stack_offset.var == 0
! 	      && ! arg_pointer_copied)
  	    REG_NOTES (get_last_insn ())
  	      = gen_rtx (EXPR_LIST, REG_EQUIV,
***************
*** 4204,4207 ****
--- 4448,4452 ----
  	  && TREE_CODE (TREE_TYPE (decl)) != UNION_TYPE
  	  && TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE
+ 	  && DECL_RTL (decl) != 0
  	  && GET_CODE (DECL_RTL (decl)) == REG
  	  && regno_uninitialized (REGNO (DECL_RTL (decl))))
***************
*** 4209,4212 ****
--- 4454,4458 ----
  			   "`%s' may be used uninitialized in this function");
        if (TREE_CODE (decl) == VAR_DECL
+ 	  && DECL_RTL (decl) != 0
  	  && GET_CODE (DECL_RTL (decl)) == REG
  	  && regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
***************
*** 4214,4218 ****
  			   "variable `%s' may be clobbered by `longjmp'");
      }
!   for (sub = STMT_BODY (block); sub; sub = TREE_CHAIN (sub))
      uninitialized_vars_warning (sub);
  }
--- 4460,4464 ----
  			   "variable `%s' may be clobbered by `longjmp'");
      }
!   for (sub = STMT_SUBBLOCKS (block); sub; sub = TREE_CHAIN (sub))
      uninitialized_vars_warning (sub);
  }
***************
*** 4233,4241 ****
  	&& ! TREE_REGDECL (decl))
        put_var_into_stack (decl);
!   for (sub = STMT_BODY (block); sub; sub = TREE_CHAIN (sub))
      setjmp_protect (sub);
  }
  \f


! /* Generate RTL for the start of the function FUNC (a FUNCTION_DECL tree node)
     and initialize static variables for generating RTL for the statements
     of the function.  */
--- 4479,4487 ----
  	&& ! TREE_REGDECL (decl))
        put_var_into_stack (decl);
!   for (sub = STMT_SUBBLOCKS (block); sub; sub = TREE_CHAIN (sub))
      setjmp_protect (sub);
  }
  \f


! /* Generate RTL for the start of the function SUBR (a FUNCTION_DECL tree node)
     and initialize static variables for generating RTL for the statements
     of the function.  */
***************
*** 4242,4251 ****
  
  void
! expand_function_start (subr)
       tree subr;
  {
-   register int i;
-   tree tem;
- 
    this_function = subr;
    cse_not_expected = ! optimize;
--- 4488,4494 ----
  
  void
! init_function_start (subr)
       tree subr;
  {
    this_function = subr;
    cse_not_expected = ! optimize;
***************
*** 4257,4260 ****
--- 4500,4506 ----
    frame_pointer_needed = FRAME_POINTER_REQUIRED || ! flag_omit_frame_pointer;
  
+   /* Caller save not needed yet.  */
+   caller_save_needed = 0;
+ 
    /* No gotos have been expanded yet.  */
    goto_fixup_chain = 0;
***************
*** 4279,4283 ****
    current_function_pops_args = RETURN_POPS_ARGS (TREE_TYPE (subr));
  
!   current_function_name = IDENTIFIER_POINTER (DECL_NAME (subr));
  
    /* Nonzero if this is a nested function that uses a static chain.  */
--- 4525,4529 ----
    current_function_pops_args = RETURN_POPS_ARGS (TREE_TYPE (subr));
  
!   current_function_name = DECL_PRINT_NAME (subr);
  
    /* Nonzero if this is a nested function that uses a static chain.  */
***************
*** 4290,4293 ****
--- 4536,4540 ----
  
    current_function_calls_setjmp = 0;
+   current_function_calls_alloca = 0;
  
    current_function_returns_pcc_struct = 0;
***************
*** 4322,4326 ****
  
    init_pending_stack_adjust ();
!   clear_current_args_size ();
    current_function_pretend_args_size = 0;
  
--- 4569,4573 ----
  
    init_pending_stack_adjust ();
!   inhibit_defer_pop = 0;
    current_function_pretend_args_size = 0;
  
***************
*** 4332,4349 ****
       Also, final expects a note to appear there.  */
    emit_note (0, NOTE_INSN_DELETED);
  
!   /* Initialize rtx for parameters and local variables.
!      In some cases this requires emitting insns.  */
  
!   assign_parms (subr);
  
    /* Initialize rtx used to return the value.  */
  
    /* Decide whether to return the value in memory or in a register.  */
!   if (DECL_MODE (DECL_RESULT (subr)) == BLKmode
!       || RETURN_IN_MEMORY (TREE_TYPE (DECL_RESULT (subr)))
!       || (flag_pcc_struct_return
! 	  && (TREE_CODE (TREE_TYPE (DECL_RESULT (subr))) == RECORD_TYPE
! 	      || TREE_CODE (TREE_TYPE (DECL_RESULT (subr))) == UNION_TYPE)))
      {
        /* Returning something that won't go in a register.  */
--- 4579,4640 ----
       Also, final expects a note to appear there.  */
    emit_note (0, NOTE_INSN_DELETED);
+   /* Indicate the beginning of the function body,
+      as opposed to parm setup.  */
+   emit_note (0, NOTE_INSN_FUNCTION_BEG);
  
!   /* Set flags used by final.c.  */
!   if (aggregate_value_p (DECL_RESULT (subr)))
!     {
! #ifdef PCC_STATIC_STRUCT_RETURN
!       if (flag_pcc_struct_return)
! 	current_function_returns_pcc_struct = 1;
!       else
! #endif
! 	current_function_returns_struct = 1;
!     }
! }
! 
! /* Start the RTL for a new function, and set variables used for
!    emitting RTL.
!    SUBR is the FUNCTION_DECL node.
!    PARMS_HAVE_CLEANUPS is nonzero if there are cleanups associated with
!    the function's parameters, which must be run at any return statement.  */
  
! void
! expand_function_start (subr, parms_have_cleanups)
!      tree subr;
!      int parms_have_cleanups;
! {
!   register int i;
!   tree tem;
! 
!   /* If the parameters of this function need cleaning up, get a label
!      for the beginning of the code which executes those cleanups.  This must
!      be done before doing anything with return_label.  */
!   if (parms_have_cleanups)
!     cleanup_label = gen_label_rtx ();
!   else
!     cleanup_label = 0;
! 
!   /* Make the label for return statements to jump to, if this machine
!      does not have a one-instruction return and uses an epilogue,
!      or if it returns a structure, or if it has parm cleanups.  */
! #ifdef HAVE_return
!   if (cleanup_label == 0 && HAVE_return
!       && ! current_function_returns_pcc_struct
!       && ! (current_function_returns_struct && ! optimize))
!     return_label = 0;
!   else
!     return_label = gen_label_rtx ();
! #else
!   return_label = gen_label_rtx ();
! #endif
  
    /* Initialize rtx used to return the value.  */
+   /* Do this before assign_parms so that we copy the struct value address
+      before any library calls that assign parms might generate.  */
  
    /* Decide whether to return the value in memory or in a register.  */
!   if (aggregate_value_p (DECL_RESULT (subr)))
      {
        /* Returning something that won't go in a register.  */
***************
*** 4369,4402 ****
  		   value_address);
      }
    else
      /* Scalar, returned in a register.  */
  #ifdef FUNCTION_OUTGOING_VALUE
!     DECL_RTL (DECL_RESULT (subr))
!       = FUNCTION_OUTGOING_VALUE (TREE_TYPE (DECL_RESULT (subr)), subr);
  #else
!     DECL_RTL (DECL_RESULT (subr))
!       = FUNCTION_VALUE (TREE_TYPE (DECL_RESULT (subr)), subr);
  #endif
  
!   /* Mark this reg as the function's return value.  */
!   if (GET_CODE (DECL_RTL (DECL_RESULT (subr))) == REG)
!     REG_FUNCTION_VALUE_P (DECL_RTL (DECL_RESULT (subr))) = 1;
  
!   /* Make the label for return statements to jump to, if this machine
!      does not have a one-instruction return.  */
! #ifdef HAVE_return
!   if (HAVE_return && ! current_function_returns_pcc_struct)
!     return_label = 0;
!   else
!     return_label = gen_label_rtx ();
! #else
!   return_label = gen_label_rtx ();
! #endif
  
    /* If doing stupid allocation, mark parms as born here.  */
  
    if (obey_regdecls)
      {
-       parm_birth_insn = get_last_insn ();
        for (i = FIRST_PSEUDO_REGISTER; i < max_parm_reg; i++)
  	use_variable (regno_reg_rtx[i]);
--- 4660,4705 ----
  		   value_address);
      }
+   else if (DECL_MODE (DECL_RESULT (subr)) == VOIDmode)
+     /* If return mode is void, this decl rtl should not be used.  */
+     DECL_RTL (DECL_RESULT (subr)) = 0;
+   else if (parms_have_cleanups)
+     /* If function will end with cleanup code for parms,
+        compute the return values into a pseudo reg,
+        which we will copy into the true return register
+        after the cleanups are done.  */
+     DECL_RTL (DECL_RESULT (subr))
+       = gen_reg_rtx (DECL_MODE (DECL_RESULT (subr)));
    else
      /* Scalar, returned in a register.  */
+     {
  #ifdef FUNCTION_OUTGOING_VALUE
!       DECL_RTL (DECL_RESULT (subr))
! 	= FUNCTION_OUTGOING_VALUE (TREE_TYPE (DECL_RESULT (subr)), subr);
  #else
!       DECL_RTL (DECL_RESULT (subr))
! 	= FUNCTION_VALUE (TREE_TYPE (DECL_RESULT (subr)), subr);
  #endif
  
!       current_function_returns_pointer 
! 	= (TREE_CODE (DECL_RESULT_TYPE (subr)) == POINTER_TYPE);
! 
!       /* Mark this reg as the function's return value.  */
!       if (GET_CODE (DECL_RTL (DECL_RESULT (subr))) == REG)
! 	REG_FUNCTION_VALUE_P (DECL_RTL (DECL_RESULT (subr))) = 1;
!     }
  
!   /* Initialize rtx for parameters and local variables.
!      In some cases this requires emitting insns.  */
! 
!   assign_parms (subr);
  
    /* If doing stupid allocation, mark parms as born here.  */
  
+   if (GET_CODE (get_last_insn ()) != NOTE)
+     emit_note (0, NOTE_INSN_DELETED);
+   parm_birth_insn = get_last_insn ();
+ 
    if (obey_regdecls)
      {
        for (i = FIRST_PSEUDO_REGISTER; i < max_parm_reg; i++)
  	use_variable (regno_reg_rtx[i]);
***************
*** 4410,4413 ****
--- 4713,4721 ----
    for (tem = get_pending_sizes (); tem; tem = TREE_CHAIN (tem))
      expand_expr (TREE_VALUE (tem), 0, VOIDmode, 0);
+ 
+   /* Make sure there is a line number after the function entry setup code.
+      There normally is one anyway, from the following statement,
+      but there could fail to be one if there is no newline here.  */
+   force_next_line_note ();
  }
  
***************
*** 4415,4418 ****
--- 4723,4728 ----
     FILENAME and LINE are the current position in the source file.  */
  
+ /* ??? Nobody seems to emit the cleanup_label and the cleanups themselves.  */
+ 
  void
  expand_function_end (filename, line)
***************
*** 4421,4426 ****
--- 4731,4746 ----
  {
    register int i;
+   rtx decl;
    extern rtx sequence_stack;
  
+ #if 0  /* I think unused parms are legitimate enough.  */
+   /* Warn about unused parms.  */
+   if (warn_unused)
+     for (decl = DECL_ARGUMENTS (current_function_decl);
+ 	 decl; decl = TREE_CHAIN (decl))
+       if (! TREE_USED (decl) && TREE_CODE (decl) == VAR_DECL)
+ 	warning_with_decl (decl, "unused parameter `%s'");
+ #endif
+ 
    /* End any sequences that failed to be closed due to syntax errors.  */
    while (sequence_stack)
***************
*** 4431,4447 ****
    immediate_size_expand--;
  
-   /* If returning a structure, arrange to return the address of the value
-      in a place where debuggers expect to find it.  */
-   if (current_function_returns_struct)
-     {
-       rtx value_address = XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
-       tree type = TREE_TYPE (DECL_RESULT (current_function_decl));
-       rtx outgoing
- 	= hard_function_value (build_pointer_type (type),
- 			       current_function_decl);
- 
-       emit_move_insn (outgoing, value_address);
-     }
- 
    /* If doing stupid register allocation,
       mark register parms as dying here.  */
--- 4751,4754 ----
***************
*** 4475,4493 ****
    emit_line_note_force (filename, line);
  
!   /* If we require a true epilogue,
!      put here the label that return statements jump to.
!      If there will be no epilogue, write a return instruction.  */
! #ifdef HAVE_return
!   if (HAVE_return && ! current_function_returns_pcc_struct)
!     emit_jump_insn (gen_return ());
!   else
! #endif
      emit_label (return_label);
  
    /* If returning a structure PCC style,
!      really return the address of where we put the structure.
!      Do this after the return label, since all returns must
!      do it.  */
!   if (current_function_returns_pcc_struct)
      {
        rtx value_address = XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
--- 4782,4839 ----
    emit_line_note_force (filename, line);
  
!   /* Output the label for the actual return from the function,
!      if one is expected.  This happens either because a function epilogue
!      is used instead of a return instruction, or because a return was done
!      with a goto in order to run local cleanups, or because of pcc-style
!      structure returning.  */
! 
!   if (return_label)
      emit_label (return_label);
  
+   /* If we had calls to alloca, and this machine needs
+      an accurate stack pointer to exit the function,
+      insert some code to save and restore the stack pointer.  */
+ #ifdef EXIT_IGNORE_STACK
+   if (! EXIT_IGNORE_STACK)
+ #endif
+     if (current_function_calls_alloca)
+       {
+ 	rtx tem = gen_reg_rtx (Pmode);
+ 	emit_insn_after (gen_rtx (SET, VOIDmode, tem, stack_pointer_rtx),
+ 			 parm_birth_insn);
+ 	emit_insn (gen_rtx (SET, VOIDmode, stack_pointer_rtx, tem));
+       }
+ 
+   /* If scalar return value was computed in a pseudo-reg,
+      copy that to the hard return register.  */
+   if (DECL_RTL (DECL_RESULT (current_function_decl)) != 0
+       && GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) == REG
+       && (REGNO (DECL_RTL (DECL_RESULT (current_function_decl)))
+ 	  >= FIRST_PSEUDO_REGISTER))
+     {
+       rtx real_decl_result;
+ 
+ #ifdef FUNCTION_OUTGOING_VALUE
+       real_decl_result
+ 	= FUNCTION_OUTGOING_VALUE (TREE_TYPE (DECL_RESULT (current_function_decl)),
+ 				   current_function_decl);
+ #else
+       real_decl_result
+ 	= FUNCTION_VALUE (TREE_TYPE (DECL_RESULT (current_function_decl)),
+ 			  current_function_decl);
+ #endif
+       REG_FUNCTION_VALUE_P (real_decl_result) = 1;
+       emit_move_insn (real_decl_result,
+ 		      DECL_RTL (DECL_RESULT (current_function_decl)));
+       emit_insn (gen_rtx (USE, VOIDmode, real_decl_result));
+     }
+ 
+   /* If returning a structure, arrange to return the address of the value
+      in a place where debuggers expect to find it.  */
    /* If returning a structure PCC style,
!      the caller also depends on this value.
!      And current_function_returns_pcc_struct is not necessarily set.  */
!   if (current_function_returns_struct
!       || current_function_returns_pcc_struct)
      {
        rtx value_address = XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
***************
*** 4497,4511 ****
  			       current_function_decl);
  
        emit_move_insn (outgoing, value_address);
        use_variable (outgoing);
  
  #ifdef HAVE_return
!       if (HAVE_return)
! 	{
! 	  emit_jump_insn (gen_return ());
! 	  emit_barrier ();
! 	}
  #endif
-     }
  
    /* Fix up any gotos that jumped out to the outermost
--- 4843,4859 ----
  			       current_function_decl);
  
+       REG_FUNCTION_VALUE_P (outgoing) = 1;
        emit_move_insn (outgoing, value_address);
        use_variable (outgoing);
+     }
+ 
+   /* Output a return insn if we are using one.
+      Otherwise, let the rtl chain end here, to drop through
+      into the epilogue.  */
  
  #ifdef HAVE_return
!   if (HAVE_return)
!     emit_jump_insn (gen_return ());
  #endif
  
    /* Fix up any gotos that jumped out to the outermost
diff -rc2N gcc-1.35/stor-layout.c gcc-1.36/stor-layout.c
*** gcc-1.35/stor-layout.c	Sun Apr  2 20:20:10 1989
--- gcc-1.36/stor-layout.c	Tue Sep 12 18:48:57 1989
***************
*** 208,214 ****
--- 208,220 ----
  {
    register tree t;
+   /* Type-size nodes already made for small sizes.  */
+   static tree size_table[33];
  
+   if (v < 33 && size_table[v] != 0)
+     return size_table[v];
    t = build_int_2 (v, 0);
    TREE_TYPE (t) = sizetype;
+   if (v < 33)
+     size_table[v] = t;
    return t;
  }
***************
*** 223,228 ****
       tree op1, op2;
  {
!   if (TREE_LITERAL (op1) && TREE_LITERAL (op2))
!     return combine (opc, op1, op2);
  
    if (op1 == error_mark_node || op2 == error_mark_node)
--- 229,255 ----
       tree op1, op2;
  {
!   /* Handle the special case of two integer constants faster.  */
!   if (TREE_CODE (op1) == INTEGER_CST && TREE_CODE (op2) == INTEGER_CST)
!     {
!       /* And some specific cases even faster than that.  */
!       if (opc == PLUS_EXPR
! 	  && TREE_INT_CST_LOW (op1) == 0
! 	  && TREE_INT_CST_HIGH (op1) == 0)
! 	return op2;
!       if (opc == MINUS_EXPR
! 	  && TREE_INT_CST_LOW (op2) == 0
! 	  && TREE_INT_CST_HIGH (op2) == 0)
! 	return op1;
!       if (opc == MULT_EXPR
! 	  && TREE_INT_CST_LOW (op1) == 1
! 	  && TREE_INT_CST_HIGH (op1) == 0)
! 	return op2;
!       if (opc == CEIL_DIV_EXPR
! 	  && TREE_INT_CST_LOW (op1) == TREE_INT_CST_LOW (op2)
! 	  && TREE_INT_CST_HIGH (op1) == TREE_INT_CST_HIGH (op2))
! 	return size_one_node;
!       /* Handle general case of two integer constants.  */
!       return combine (opc, op1, op2);
!     }
  
    if (op1 == error_mark_node || op2 == error_mark_node)
***************
*** 271,275 ****
  \f


  /* Set the size, mode and alignment of a ..._DECL node.
!    Note that LABEL_DECL, TYPE_DECL and CONST_DECL nodes do not need this,
     and FUNCTION_DECL nodes have them set up in a special (and simple) way.
     Don't call layout_decl for them.
--- 298,304 ----
  \f


  /* Set the size, mode and alignment of a ..._DECL node.
!    TYPE_DECL does need this for C++.  It is up to language-specific
!    code to intialize the DECL_OFFSET of TYPE_DECL nodes.
!    Note that LABEL_DECL and CONST_DECL nodes do not need this,
     and FUNCTION_DECL nodes have them set up in a special (and simple) way.
     Don't call layout_decl for them.
***************
*** 296,300 ****
  
    if (code != VAR_DECL && code != PARM_DECL && code != RESULT_DECL
!       && code != FIELD_DECL && code != FRIEND_DECL)
      abort ();
  
--- 325,329 ----
  
    if (code != VAR_DECL && code != PARM_DECL && code != RESULT_DECL
!       && code != FIELD_DECL && code != TYPE_DECL)
      abort ();
  
***************
*** 393,397 ****
     and computing the overall size and required alignment of the record.
     Note that if you set the TYPE_ALIGN before calling this
!    then the struct is aligned to at least that boundary.  */
  
  static void
--- 422,429 ----
     and computing the overall size and required alignment of the record.
     Note that if you set the TYPE_ALIGN before calling this
!    then the struct is aligned to at least that boundary.
! 
!    If the type has basetypes, you must call layout_basetypes
!    before calling this function.  */
  
  static void
***************
*** 416,449 ****
    register int size_unit = BITS_PER_UNIT;
  
!   /* Handle basetypes almost like fields, but record their
!      offsets differently.  */
! 
!   for (field = TYPE_BASETYPES (rec); field; field = TREE_CHAIN (field))
      {
!       tree basetype = TREE_VALUE (field);
!       int desired_align = TYPE_ALIGN (basetype);
! 
!       /* Record must have at least as much alignment as any basetype.  */
!       record_align = MAX (record_align, desired_align);
! 
!       /* Does this basetype have the alignment it needs
! 	 by virtue of the basetypes that precede it?  */
! 
!       if (const_size % desired_align != 0)
! 	{
! 	  /* No, we need to skip space before this field.
! 	     Bump the cumulative size to multiple of field alignment.  */
! 
! 	  const_size = CEIL (const_size, desired_align) * desired_align;
! 	}
! 
!       /* Record this basetype's offset within the record.  */
!       TREE_PURPOSE (field) =
! 	convert_units (build_int (const_size), 1, BITS_PER_UNIT);
! 
!       /* Skip enough space for this basetype.  */
!       const_size += (TREE_INT_CST_LOW (TYPE_SIZE (basetype)) *
! 		     TYPE_SIZE_UNIT (basetype));
      }
  
    for (field = TYPE_FIELDS (rec); field; field = TREE_CHAIN (field))
--- 448,463 ----
    register int size_unit = BITS_PER_UNIT;
  
! #if 0
!   /* If there are basetypes, the caller should already have
!      laid them out.  Leave space at the beginning for them.  */
!   if (TYPE_SIZE (rec) != 0)
      {
!       if (TREE_CODE (TYPE_SIZE (rec)) == INTEGER_CST)
! 	const_size = TREE_INT_CST_LOW (TYPE_SIZE (rec));
!       else
! 	var_size = TYPE_SIZE (rec);
!       size_unit = TYPE_SIZE_UNIT (rec);
      }
+ #endif /* 0 */
  
    for (field = TYPE_FIELDS (rec); field; field = TREE_CHAIN (field))
***************
*** 457,461 ****
  	 and we do it *after* the record is laid out.  */
  
!       if (TREE_CODE (field) != FIELD_DECL)
  	{
  	  pending_statics = tree_cons (NULL, field, pending_statics);
--- 471,475 ----
  	 and we do it *after* the record is laid out.  */
  
!       if (TREE_CODE (field) == VAR_DECL)
  	{
  	  pending_statics = tree_cons (NULL, field, pending_statics);
***************
*** 462,465 ****
--- 476,483 ----
  	  continue;
  	}
+       /* Enumerators and enum types which are local to this class need not
+ 	 be laid out.  */
+       if (TREE_CODE (field) == CONST_DECL || TREE_CODE (field) == TYPE_DECL)
+ 	continue;
  
        /* Lay out the field so we know what alignment it needs.
***************
*** 466,470 ****
  	 For KNOWN_ALIGN, pass the number of bits from start of record
  	 or some divisor of it.  */
! 	 
        layout_decl (field, var_size ? size_unit : const_size);
        desired_align = DECL_ALIGN (field);
--- 484,488 ----
  	 For KNOWN_ALIGN, pass the number of bits from start of record
  	 or some divisor of it.  */
! 
        layout_decl (field, var_size ? size_unit : const_size);
        desired_align = DECL_ALIGN (field);
***************
*** 478,482 ****
        /* In PCC on Vax, Sony, etc., a bit field of declare type `int'
  	 forces the entire structure to have `int' alignment.  */
!       record_align = MAX (record_align, TYPE_ALIGN (TREE_TYPE (field)));
  #endif
  
--- 496,501 ----
        /* In PCC on Vax, Sony, etc., a bit field of declare type `int'
  	 forces the entire structure to have `int' alignment.  */
!       if (DECL_NAME (field) != 0)
! 	record_align = MAX (record_align, TYPE_ALIGN (TREE_TYPE (field)));
  #endif
  
***************
*** 507,510 ****
--- 526,545 ----
  	}
  
+ #ifdef PCC_BITFIELD_TYPE_MATTERS
+       if (TREE_CODE (field) == FIELD_DECL
+ 	  && TREE_TYPE (field) != error_mark_node)
+ 	{
+ 	  int type_align = TYPE_ALIGN (TREE_TYPE (field));
+ 	  register tree dsize = DECL_SIZE (field);
+ 	  int field_size = TREE_INT_CST_LOW (dsize) * DECL_SIZE_UNIT (field);
+ 
+ 	  /* A bit field may not span the unit of alignment of its type.
+ 	     Advance to next boundary if necessary.  */
+ 	  if (const_size / type_align
+ 	      != (const_size + field_size - 1) / type_align)
+ 	    const_size = CEIL (const_size, type_align) * type_align;
+ 	}
+ #endif
+ 
        /* Size so far becomes the offset of this field.  */
  
***************
*** 608,626 ****
    register tree var_size = 0;
  
-   if (TYPE_BASETYPES (rec))
-     {
-       TYPE_BASETYPES (rec) = 0;
-       error ("base class specified for union type");
-     }
- 
    for (field = TYPE_FIELDS (rec); field; field = TREE_CHAIN (field))
      {
        if (TREE_STATIC (field))
  	{
! 	  error ("field `%s' declared static in union",
! 		 IDENTIFIER_POINTER (DECL_NAME (field)));
  	  TREE_STATIC (field) = 0;
  	}
!  
        layout_decl (field, 0);
        DECL_OFFSET (field) = 0;
--- 643,661 ----
    register tree var_size = 0;
  
    for (field = TYPE_FIELDS (rec); field; field = TREE_CHAIN (field))
      {
+ #if 0 /* This should be in a language-specific file
+ 	 since it needs to use language-specific terminology.  */
        if (TREE_STATIC (field))
  	{
! 	  error_with_decl (field, "field `%s' declared static in union");
  	  TREE_STATIC (field) = 0;
  	}
! #endif
! 
!       /* Ignore enumerators and enum types local to the union.  */
!       if (TREE_CODE (field) == CONST_DECL || TREE_CODE (field) == TYPE_DECL)
! 	continue;
! 
        layout_decl (field, 0);
        DECL_OFFSET (field) = 0;
***************
*** 632,635 ****
--- 667,676 ----
        union_align = MAX (union_align, DECL_ALIGN (field));
  
+ #ifdef PCC_BITFIELD_TYPE_MATTERS
+       /* On the m88000, a bit field of declare type `int'
+ 	 forces the entire union to have `int' alignment.  */
+       union_align = MAX (union_align, TYPE_ALIGN (TREE_TYPE (field)));
+ #endif
+ 
        /* Set union_size to max (decl_size, union_size).
  	 There are more and less general ways to do this.
***************
*** 725,729 ****
  	TREE_UNSIGNED (type) = 1;
  
!       TYPE_MODE (type) = agg_mode (TYPE_PRECISION (type));
        TYPE_SIZE (type) = build_int (GET_MODE_SIZE (TYPE_MODE (type)));
        TYPE_SIZE_UNIT (type) = BITS_PER_UNIT;
--- 766,783 ----
  	TREE_UNSIGNED (type) = 1;
  
!       /* What follows is like agg_mode except that it ignores
! 	 MAX_FIXED_MODE_SIZE.  That applies only to structures.  */
!       {
! 	enum machine_mode mode, t;
! 
! 	/* Get the last mode which has this size.  */
! 	mode = BLKmode;
! 	for (t = QImode; GET_MODE_CLASS (t) == MODE_INT;
! 	     t = (enum machine_mode) ((int) t + 1))
! 	  if (GET_MODE_BITSIZE (t) == TYPE_PRECISION (type))
! 	    mode = t;
! 
! 	TYPE_MODE (type) = mode;
!       }
        TYPE_SIZE (type) = build_int (GET_MODE_SIZE (TYPE_MODE (type)));
        TYPE_SIZE_UNIT (type) = BITS_PER_UNIT;
***************
*** 738,741 ****
--- 792,797 ----
  	else if (prec <= GET_MODE_BITSIZE (DFmode))
  	  TYPE_MODE (type) = DFmode;
+ 	else if (prec <= GET_MODE_BITSIZE (TFmode))
+ 	  TYPE_MODE (type) = TFmode;
  	else
  	  abort ();
***************
*** 786,792 ****
  	    /* BLKmode elements force BLKmode aggregate;
  	       else extract/store fields may lose.  */
! 	    && TYPE_MODE (TREE_TYPE (type)) != BLKmode)
  	  {
! 	    TYPE_MODE (type) 
  	      = agg_mode (TREE_INT_CST_LOW (TYPE_SIZE (type))
  			  * TYPE_SIZE_UNIT (type));
--- 842,854 ----
  	    /* BLKmode elements force BLKmode aggregate;
  	       else extract/store fields may lose.  */
! 	    && TYPE_MODE (TREE_TYPE (type)) != BLKmode
! #ifdef STRICT_ALIGNMENT
! 	    && (TYPE_ALIGN (type) >= BIGGEST_ALIGNMENT
! 		|| TYPE_ALIGN (type) >= (TREE_INT_CST_LOW (TYPE_SIZE (type))
! 					 * TYPE_SIZE_UNIT (type)))
! #endif
! 	    )
  	  {
! 	    TYPE_MODE (type)
  	      = agg_mode (TREE_INT_CST_LOW (TYPE_SIZE (type))
  			  * TYPE_SIZE_UNIT (type));
***************
*** 816,820 ****
  	      goto record_lose;
  
! 	  TYPE_MODE (type) 
  	    = agg_mode (TREE_INT_CST_LOW (TYPE_SIZE (type))
  			* TYPE_SIZE_UNIT (type));
--- 878,882 ----
  	      goto record_lose;
  
! 	  TYPE_MODE (type)
  	    = agg_mode (TREE_INT_CST_LOW (TYPE_SIZE (type))
  			* TYPE_SIZE_UNIT (type));
***************
*** 844,848 ****
  	      goto union_lose;
  
! 	  TYPE_MODE (type) 
  	    = agg_mode (TREE_INT_CST_LOW (TYPE_SIZE (type))
  			* TYPE_SIZE_UNIT (type));
--- 906,910 ----
  	      goto union_lose;
  
! 	  TYPE_MODE (type)
  	    = agg_mode (TREE_INT_CST_LOW (TYPE_SIZE (type))
  			* TYPE_SIZE_UNIT (type));
***************
*** 852,855 ****
--- 914,918 ----
  
      case FUNCTION_TYPE:
+     case METHOD_TYPE:
        TYPE_MODE (type) = EPmode;
        TYPE_SIZE (type) = build_int (2 * POINTER_SIZE / BITS_PER_UNIT);
***************
*** 858,872 ****
        break;
  
-     case METHOD_TYPE:
-       {
- 	tree t = TREE_TYPE (type);
- 	layout_type (t);
- 	TYPE_MODE (type) = TYPE_MODE (t);
- 	TYPE_SIZE (type) = TYPE_SIZE (t);
- 	TYPE_SIZE_UNIT (type) = TYPE_SIZE_UNIT (t);
- 	TYPE_ALIGN (type) = POINTER_BOUNDARY;
-       }
-       break;
- 
      default:
        abort ();
--- 921,924 ----
***************
*** 876,879 ****
--- 928,954 ----
    if (TYPE_SIZE (type) != 0 && ! TREE_LITERAL (TYPE_SIZE (type)))
      TYPE_SIZE (type) = variable_size (TYPE_SIZE (type));
+ 
+   /* Also layout any other variants of the type.  */
+   if (TYPE_NEXT_VARIANT (type)
+       || type != TYPE_MAIN_VARIANT (type))
+     {
+       tree variant;
+       /* Record layout info of this variant.  */
+       tree size = TYPE_SIZE (type);
+       int size_unit = TYPE_SIZE_UNIT (type);
+       int align = TYPE_ALIGN (type);
+       enum machine_mode mode = TYPE_MODE (type);
+ 
+       /* Copy it into all variants.  */
+       for (variant = TYPE_MAIN_VARIANT (type);
+ 	   variant;
+ 	   variant = TYPE_NEXT_VARIANT (variant))
+ 	{
+ 	  TYPE_SIZE (variant) = size;
+ 	  TYPE_SIZE_UNIT (variant) = size_unit;
+ 	  TYPE_ALIGN (variant) = align;
+ 	  TYPE_MODE (variant) = mode;
+ 	}
+     }
  	
    if (temporary)
***************
*** 883,887 ****
  \f


  /* Create and return a type for signed integers of PRECISION bits.  */
!  
  tree
  make_signed_type (precision)
--- 958,962 ----
  \f


  /* Create and return a type for signed integers of PRECISION bits.  */
! 
  tree
  make_signed_type (precision)
***************
*** 895,906 ****
  
    TYPE_MIN_VALUE (type)
!     = build_int_2 ((precision-BITS_PER_WORD > 0 ? 0 : (-1)<<(precision-1)),
! 		   (-1)<<(precision-BITS_PER_WORD-1 > 0
! 			  ? precision-BITS_PER_WORD-1
  			  : 0));
    TYPE_MAX_VALUE (type)
!     = build_int_2 ((precision-BITS_PER_WORD > 0 ? -1 : (1<<(precision-1))-1),
! 		   (precision-BITS_PER_WORD-1 > 0
! 		    ? (1<<(precision-BITS_PER_WORD-1))-1
  		    : 0));
  
--- 970,981 ----
  
    TYPE_MIN_VALUE (type)
!     = build_int_2 ((precision-HOST_BITS_PER_INT > 0 ? 0 : (-1)<<(precision-1)),
! 		   (-1)<<(precision-HOST_BITS_PER_INT-1 > 0
! 			  ? precision-HOST_BITS_PER_INT-1
  			  : 0));
    TYPE_MAX_VALUE (type)
!     = build_int_2 ((precision-HOST_BITS_PER_INT > 0 ? -1 : (1<<(precision-1))-1),
! 		   (precision-HOST_BITS_PER_INT-1 > 0
! 		    ? (1<<(precision-HOST_BITS_PER_INT-1))-1
  		    : 0));
  
***************
*** 955,961 ****
    TYPE_MIN_VALUE (type) = build_int_2 (0, 0);
    TYPE_MAX_VALUE (type)
!     = build_int_2 (precision-BITS_PER_WORD >= 0 ? -1 : (1<<precision)-1,
! 		   precision-BITS_PER_WORD > 0
! 		   ? (1<<(precision-BITS_PER_WORD))-1 : 0);
    TREE_TYPE (TYPE_MIN_VALUE (type)) = type;
    TREE_TYPE (TYPE_MAX_VALUE (type)) = type;
--- 1030,1038 ----
    TYPE_MIN_VALUE (type) = build_int_2 (0, 0);
    TYPE_MAX_VALUE (type)
!     = build_int_2 (precision-HOST_BITS_PER_INT >= 0 ? -1 : (1<<precision)-1,
! 		   precision-HOST_BITS_PER_INT > 0
! 		   ? ((unsigned) ~0
! 		      >> (HOST_BITS_PER_INT - (precision - HOST_BITS_PER_INT)))
! 		   : 0);
    TREE_TYPE (TYPE_MIN_VALUE (type)) = type;
    TREE_TYPE (TYPE_MAX_VALUE (type)) = type;
diff -rc2N gcc-1.35/stupid.c gcc-1.36/stupid.c
*** gcc-1.35/stupid.c	Wed Feb 22 12:28:25 1989
--- gcc-1.36/stupid.c	Wed Aug 30 16:04:08 1989
***************
*** 53,57 ****
     between a variable's birth and its death.  */
  
! static short *uid_suid;
  
  /* Get the suid of an insn.  */
--- 53,57 ----
     between a variable's birth and its death.  */
  
! static int *uid_suid;
  
  /* Get the suid of an insn.  */
***************
*** 60,76 ****
  
  /* Record the suid of the last CALL_INSN
!    so we can tell whether a potential combination crosses any calls.  */
  
  static int last_call_suid;
  
  /* Element N is suid of insn where life span of pseudo reg N ends.
     Element is  0 if register N has not been seen yet on backward scan.  */
  
! static short *reg_where_dead;
  
  /* Element N is suid of insn where life span of pseudo reg N begins.  */
  
! static short *reg_where_born;
  
  /* Numbers of pseudo-regs to be allocated, highest priority first.  */
  
--- 60,90 ----
  
  /* Record the suid of the last CALL_INSN
!    so we can tell whether a pseudo reg crosses any calls.  */
  
  static int last_call_suid;
  
+ /* Record the suid of the last JUMP_INSN
+    so we can tell whether a pseudo reg crosses any jumps.  */
+ 
+ static int last_jump_suid;
+ 
+ /* Record the suid of the last CODE_LABEL
+    so we can tell whether a pseudo reg crosses any labels.  */
+ 
+ static int last_label_suid;
+ 
  /* Element N is suid of insn where life span of pseudo reg N ends.
     Element is  0 if register N has not been seen yet on backward scan.  */
  
! static int *reg_where_dead;
  
  /* Element N is suid of insn where life span of pseudo reg N begins.  */
  
! static int *reg_where_born;
  
+ /* Element N is 1 if pseudo reg N lives across labels or jumps.  */
+ 
+ static char *reg_crosses_blocks;
+ 
  /* Numbers of pseudo-regs to be allocated, highest priority first.  */
  
***************
*** 125,129 ****
  
    max_uid = i + 1;
!   uid_suid = (short *) alloca ((i + 1) * sizeof (short));
  
    /* Compute the mapping from uids to suids.
--- 139,143 ----
  
    max_uid = i + 1;
!   uid_suid = (int *) alloca ((i + 1) * sizeof (int));
  
    /* Compute the mapping from uids to suids.
***************
*** 141,144 ****
--- 155,160 ----
  
    last_call_suid = i + 1;
+   last_jump_suid = i + 1;
+   last_label_suid = i + 1;
  
    max_regno = nregs;
***************
*** 146,154 ****
    /* Allocate tables to record info about regs.  */
  
!   reg_where_dead = (short *) alloca (nregs * sizeof (short));
!   bzero (reg_where_dead, nregs * sizeof (short));
  
!   reg_where_born = (short *) alloca (nregs * sizeof (short));
!   bzero (reg_where_born, nregs * sizeof (short));
  
    reg_order = (short *) alloca (nregs * sizeof (short));
--- 162,173 ----
    /* Allocate tables to record info about regs.  */
  
!   reg_where_dead = (int *) alloca (nregs * sizeof (int));
!   bzero (reg_where_dead, nregs * sizeof (int));
! 
!   reg_where_born = (int *) alloca (nregs * sizeof (int));
!   bzero (reg_where_born, nregs * sizeof (int));
  
!   reg_crosses_blocks = (char *) alloca (nregs);
!   bzero (reg_crosses_blocks, nregs);
  
    reg_order = (short *) alloca (nregs * sizeof (short));
***************
*** 211,214 ****
--- 230,239 ----
  	}
  
+       if (GET_CODE (insn) == JUMP_INSN)
+ 	last_jump_suid = INSN_SUID (insn);
+ 
+       if (GET_CODE (insn) == CODE_LABEL)
+ 	last_label_suid = INSN_SUID (insn);
+ 
        /* Update which hard regs are currently live
  	 and also the birth and death suids of pseudo regs
***************
*** 251,255 ****
  					     PSEUDO_REGNO_MODE (r),
  					     reg_where_born[r],
! 					     reg_where_dead[r]);
  	}
        else
--- 276,281 ----
  					     PSEUDO_REGNO_MODE (r),
  					     reg_where_born[r],
! 					     reg_where_dead[r],
! 					     reg_crosses_blocks[r]);
  	}
        else
***************
*** 263,267 ****
  					   PSEUDO_REGNO_MODE (r),
  					   reg_where_born[r],
! 					   reg_where_dead[r]);
      }
  
--- 289,294 ----
  					   PSEUDO_REGNO_MODE (r),
  					   reg_where_born[r],
! 					   reg_where_dead[r],
! 					   reg_crosses_blocks[r]);
      }
  
***************
*** 280,288 ****
    register int len1 = reg_where_dead[r1] - reg_where_born[r1];
    register int len2 = reg_where_dead[r2] - reg_where_born[r2];
  
!   if (len1 != len2)
!     return len2 - len1;
  
!   return reg_n_refs[r1] - reg_n_refs[r2];
  }
  \f


--- 307,321 ----
    register int len1 = reg_where_dead[r1] - reg_where_born[r1];
    register int len2 = reg_where_dead[r2] - reg_where_born[r2];
+   int tem;
  
!   tem = len2 - len1;
!   if (tem != 0) return tem;
  
!   tem = reg_n_refs[r1] - reg_n_refs[r2];
!   if (tem != 0) return tem;
! 
!   /* If regs are equally good, sort by regno,
!      so that the results of qsort leave nothing to chance.  */
!   return r1 - r2;
  }
  \f


***************
*** 294,303 ****
     and return the number of the first of them.
     Return -1 if such a block cannot be found.
     If CALL_PRESERVED is nonzero, insist on registers preserved
!    over subroutine calls, and return -1 if cannot find such.  */
  
  static int
  stupid_find_reg (call_preserved, class, mode,
! 		 born_insn, dead_insn)
       int call_preserved;
       enum reg_class class;
--- 327,339 ----
     and return the number of the first of them.
     Return -1 if such a block cannot be found.
+ 
     If CALL_PRESERVED is nonzero, insist on registers preserved
!    over subroutine calls, and return -1 if cannot find such.
!    If CROSSES_BLOCKS is nonzero, reject registers for which
!    PRESERVE_DEATH_INFO_REGNO_P is true.  */
  
  static int
  stupid_find_reg (call_preserved, class, mode,
! 		 born_insn, dead_insn, crosses_blocks)
       int call_preserved;
       enum reg_class class;
***************
*** 304,307 ****
--- 340,344 ----
       enum machine_mode mode;
       int born_insn, dead_insn;
+      int crosses_blocks;
  {
    register int i, ins;
***************
*** 326,329 ****
--- 363,374 ----
        int regno = i;
  #endif
+ 
+       /* If we need reasonable death info on this hard reg,
+ 	 don't use it for anything whose life spans a label or a jump.  */
+ #ifdef PRESERVE_DEATH_INFO_REGNO_P
+       if (PRESERVE_DEATH_INFO_REGNO_P (regno)
+ 	  && crosses_blocks)
+ 	continue;
+ #endif
        if (! TEST_HARD_REG_BIT (used, regno)
  	  && HARD_REGNO_MODE_OK (regno, mode))
***************
*** 411,414 ****
--- 456,462 ----
  	      if (last_call_suid < reg_where_dead[regno])
  		reg_n_calls_crossed[regno] += 1;
+ 	      if (last_jump_suid < reg_where_dead[regno]
+ 		  || last_label_suid < reg_where_dead[regno])
+ 		reg_crosses_blocks[regno] = 1;
  	    }
  	}
diff -rc2N gcc-1.35/symout.c gcc-1.36/symout.c
*** gcc-1.35/symout.c	Wed Feb 22 12:28:23 1989
--- gcc-1.36/symout.c	Thu Sep  7 00:17:15 1989
***************
*** 26,30 ****
  #include <stdio.h>
  #undef NULL
! #include "stddef.h"
  
  /* Get N_SO from stab.h if we can expect the file to exist.  */
--- 26,32 ----
  #include <stdio.h>
  #undef NULL
! /* <...> used here so one can prevent use of ./stddef.h
!    by changing the -I options used.  */
! #include <stddef.h>
  
  /* Get N_SO from stab.h if we can expect the file to exist.  */
***************
*** 709,713 ****
    for (decl = decls, i = 0; decl; decl = TREE_CHAIN (decl))
      {
!       register name_address = next_address;
  
        if (filter == (TREE_PUBLIC (decl) ? 1 : 2))
--- 711,715 ----
    for (decl = decls, i = 0; decl; decl = TREE_CHAIN (decl))
      {
!       register int name_address = next_address;
  
        if (filter == (TREE_PUBLIC (decl) ? 1 : 2))
***************
*** 985,988 ****
--- 987,993 ----
  
  	case LET_STMT:
+ 	  /* Ignore LET_STMTs for blocks never really used to make RTL.  */
+ 	  if (! TREE_USED (stmt))
+ 	    break;
  	  address =
  	    symout_block (STMT_VARS (stmt), STMT_TYPE_TAGS (stmt), args,
***************
*** 989,993 ****
  			  superblock_address);
  
! 	  symout_function (STMT_BODY (stmt), 0, address);
  	}
        stmt = TREE_CHAIN (stmt);
--- 994,998 ----
  			  superblock_address);
  
! 	  symout_function (STMT_SUBBLOCKS (stmt), 0, address);
  	}
        stmt = TREE_CHAIN (stmt);
diff -rc2N gcc-1.35/texinfo.tex gcc-1.36/texinfo.tex
*** gcc-1.35/texinfo.tex	Sun Apr  2 11:24:31 1989
--- gcc-1.36/texinfo.tex	Sun Sep 24 08:14:57 1989
***************
*** 22,26 ****
  %what you give them.   Help stamp out software-hoarding!
  
! \def\texinfoversion{1.23}
  \message{Loading texinfo package [Version \texinfoversion]:}
  \message{}
--- 22,26 ----
  %what you give them.   Help stamp out software-hoarding!
  
! \def\texinfoversion{2.1}
  \message{Loading texinfo package [Version \texinfoversion]:}
  \message{}
***************
*** 292,307 ****
  \let\c=\comment
  
! \long\def\ignore #1\end ignore{}
  
- \outer\def\ifset{\parsearg\ifsetxxx}
- 
- \def\ifsetxxx #1#2\end ifset{%
- \expandafter\ifx\csname IF#1\endcsname\relax \else #2\fi}
- 
- \outer\def\ifclear{\parsearg\ifclearxxx}
- 
- \def\ifclearxxx #1#2\end ifclear{%
- \expandafter\ifx\csname IF#1\endcsname\relax #2\fi}
- 
  % Some texinfo constructs that are trivial in tex
  
--- 292,345 ----
  \let\c=\comment
  
! % Prevent errors for section commands.
! % Used in @ignore and in failing conditionals.
! \def\ignoresections{%
! \let\chapter=\relax
! \let\unnumbered=\relax
! \let\unnumberedsec=\relax
! \let\unnumberedsection=\relax
! \let\unnumberedsubsec=\relax
! \let\unnumberedsubsection=\relax
! \let\unnumberedsubsubsec=\relax
! \let\unnumberedsubsubsection=\relax
! \let\section=\relax
! \let\subsec=\relax
! \let\subsubsec=\relax
! \let\subsection=\relax
! \let\subsubsection=\relax
! \let\appendix=\relax
! \let\appendixsec=\relax
! \let\appendixsection=\relax
! \let\appendixsubsec=\relax
! \let\appendixsubsection=\relax
! \let\appendixsubsubsec=\relax
! \let\appendixsubsubsection=\relax
! }
! 
! \def\ignore{\begingroup\ignoresections\ignorexxx}
! \long\def\ignorexxx #1\end ignore{\endgroup}
! 
! % Conditionals to test whether a flag is set.
! 
! \outer\def\ifset{\begingroup\ignoresections\parsearg\ifsetxxx}
! 
! \def\ifsetxxx #1{\endgroup
! \expandafter\ifx\csname IF#1\endcsname\relax \let\temp=\ifsetfail
! \else \let\temp=\relax \fi
! \temp}
! \def\Eifset{}
! \def\ifsetfail{\begingroup\ignoresections\ifsetfailxxx}
! \long\def\ifsetfailxxx #1\end ifset{\endgroup}
! 
! \outer\def\ifclear{\begingroup\ignoresections\parsearg\ifclearxxx}
! 
! \def\ifclearxxx #1{\endgroup
! \expandafter\ifx\csname IF#1\endcsname\relax \let\temp=\relax
! \else \let\temp=\ifclearfail \fi
! \temp}
! \def\Eifclear{}
! \def\ifclearfail{\begingroup\ignoresections\ifclearfailxxx}
! \long\def\ifclearfailxxx #1\end ifclear{\endgroup}
  
  % Some texinfo constructs that are trivial in tex
  
***************
*** 308,316 ****
  \def\iftex{}
  \def\Eiftex{}
! \long\def\ifinfo #1\end ifinfo{}
  \long\def\menu #1\end menu{}
  \def\asis#1{#1}
  
! \def\node{\parsearg\nodezzz}
  \def\nodezzz#1{\nodexxx [#1,]}
  \def\nodexxx[#1,#2]{\gdef\lastnode{#1}}
--- 346,356 ----
  \def\iftex{}
  \def\Eiftex{}
! \def\ifinfo{\begingroup\ignoresections\ifinfoxxx}
! \long\def\ifinfoxxx #1\end ifinfo{\endgroup}
! 
  \long\def\menu #1\end menu{}
  \def\asis#1{#1}
  
! \def\node{\ENVcheck\parsearg\nodezzz}
  \def\nodezzz#1{\nodexxx [#1,]}
  \def\nodexxx[#1,#2]{\gdef\lastnode{#1}}
***************
*** 325,331 ****
  \let\lastnode=\relax}
  
  \let\refill=\relax
  
! \let\setfilename=\comment
  
  \def\inforef #1{\inforefzzz #1,,,,**}
--- 365,386 ----
  \let\lastnode=\relax}
  
+ \def\appendixnoderef{\ifx\lastnode\relax\else
+ \expandafter\expandafter\expandafter\appendixsetref{\lastnode}\fi
+ \let\lastnode=\relax}
+ 
  \let\refill=\relax
+   
+ % @setfilename is done at the beginning of every texinfo file.
+ % So open here the files we need to have open while reading the input.
+ % This makes it possible to make a .fmt file for texinfo.
+ \def\setfilename{%
+    \readauxfile
+    \opencontents
+    \openindices
+    \fixbackslash  % Turn off hack to swallow `\input texinfo'.
+    \comment % Ignore the actual filename.
+ }
  
! \outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
  
  \def\inforef #1{\inforefzzz #1,,,,**}
***************
*** 360,365 ****
  % Fonts for indices
  \font\indit=cmti9 \font\indrm=cmr9
  \def\indbf{\indrm} \def\indsl{\indit}
! \def\indexfonts{\let\it=\indit \let\sl=\indsl \let\bf=\indbf \let\rm=\indrm}
  
  % Fonts for headings
--- 415,422 ----
  % Fonts for indices
  \font\indit=cmti9 \font\indrm=cmr9
+ \font\indtt=cmtt9
  \def\indbf{\indrm} \def\indsl{\indit}
! \def\indexfonts{\let\it=\indit \let\sl=\indsl \let\bf=\indbf \let\rm=\indrm
! \let\tt=\indtt}
  
  % Fonts for headings
***************
*** 400,411 ****
  \newcount\fontdepth \fontdepth=0
  
  %% Add scribe-like font environments, plus @l for inline lisp (usually sans
  %% serif) and @ii for TeX italic
  
! \def\i#1{{\sl #1}}
! \let\var=\i
! \let\dfn=\i
! \let\emph=\i
! \let\cite=\i
  
  \def\b#1{{\bf #1}}
--- 457,476 ----
  \newcount\fontdepth \fontdepth=0
  
+ % Font for table of contents.
+ \font\truesecrm=cmr12
+ 
  %% Add scribe-like font environments, plus @l for inline lisp (usually sans
  %% serif) and @ii for TeX italic
  
! % \smartitalic{ARG} outputs arg in italics, followed by an italic correction
! % unless the following character is such as not to need one.
! \def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else\/\fi\fi\fi}
! \def\smartitalic#1{{\sl #1}\futurelet\next\smartitalicx}
! 
! \let\i=\smartitalic
! \let\var=\smartitalic
! \let\dfn=\smartitalic
! \let\emph=\smartitalic
! \let\cite=\smartitalic
  
  \def\b#1{{\bf #1}}
***************
*** 414,420 ****
  \def\t#1{{\tt \rawbackslash \frenchspacing #1}\null}
  \let\ttfont = \t
! \let\kbd=\t
! \let\code=\t
! \def\samp #1{`{\tt \rawbackslash \frenchspacing #1}'\null}
  \def\key #1{{\tt \uppercase{#1}}\null}
  \def\ctrl #1{{\tt \rawbackslash \hat}#1}
--- 479,484 ----
  \def\t#1{{\tt \rawbackslash \frenchspacing #1}\null}
  \let\ttfont = \t
! %\def\samp #1{`{\tt \rawbackslash \frenchspacing #1}'\null}
! \def\samp #1{`\tclose{#1}'\null}
  \def\key #1{{\tt \uppercase{#1}}\null}
  \def\ctrl #1{{\tt \rawbackslash \hat}#1}
***************
*** 422,444 ****
  \let\file=\samp
  
  \def\l#1{{\li #1}\null}		% 
  
  \def\r#1{{\rm #1}}		% roman font
! \def\sc#1{{\\smallcaps #1}}	% smallcaps font
  \def\ii#1{{\it #1}}		% italic font
  
! \def\titlefont#1{{\titlerm #1}}
  
! \def\titlepage{\begingroup \parindent=0pt \hbox{}%
! \let\oldpage=\page
! \def\page{\oldpage \hbox{}}}
  
! \def\Etitlepage{\endgroup\page\HEADINGSon}
  
! % Make altmode in file print out right
  
! \catcode `\^^[=\active \def^^[{$\diamondsuit$}
  
! \message{page headings,}
  
  %%% Set up page headings and footings.
--- 486,569 ----
  \let\file=\samp
  
+ % @code is a modification of @t,
+ % which makes spaces the same size as normal in the surrounding text.
+ \newdimen\tclosesave
+ \newdimen\tcloserm
+ \def\tclose#1{{\rm \tcloserm=\fontdimen2\font \tt \tclosesave=\fontdimen2\font
+ \fontdimen2\font=\tcloserm
+ \def\ {{\fontdimen2\font=\tclosesave{} }}%
+  \rawbackslash \frenchspacing #1\fontdimen2\font=\tclosesave}\null}
+ \let\code=\tclose
+ %\let\exp=\tclose  %Was temporary
+ 
+ % @kbd is like @code, except that if the argument is just one @key command, 
+ % then @kbd has no effect.
+ 
+ \def\xkey{\key}
+ \def\kbdfoo#1#2#3*{\def\one{#1}\def\three{#3}\def\threex{??}%
+ \ifx\one\xkey\ifx\threex\three \key{#2}
+ \else\tclose{\look}\fi
+ \else\tclose{\look}\fi}
+ 
+ \def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??*}
+ 
  \def\l#1{{\li #1}\null}		% 
  
  \def\r#1{{\rm #1}}		% roman font
! \def\sc#1{{\smallcaps #1}}	% smallcaps font
  \def\ii#1{{\it #1}}		% italic font
  
! \message{page headings,}
  
! \newskip\titlepagetopglue \titlepagetopglue = 1.5in
! \newskip\titlepagebottomglue \titlepagebottomglue = 2pc
  
! % First the title page.  Must do @settitle before @titlepage.
! \font\titlerm = cmbx12 scaled \magstep2
! \def\titlefont#1{{\titlerm #1}}
  
! \newtoks\realeverypar
! \newif\ifseenauthor
  
! \def\titlepage{\begingroup \parindent=0pt \textfonts
!    \font\subtitlerm = cmr10 scaled \magstephalf
!    \def\subtitlefont{\subtitlerm \normalbaselineskip = 12pt \normalbaselines}%
!    %
!    \font\authorrm = cmbx12 scaled \magstep1
!    \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines}%
!    %
!    % The first subtitle should have some space before it, but not the
!    % others.  They all should be ragged left.
! % This code caused a bug, since two groups were started, but only
! % one was ended.  Also, I can't see the point of this code.
! %   \begingroup \realeverypar = {\leftskip = 2in plus 3em minus 1em
! %                    \parfillskip = 0pt}%
! %   \everypar = {\vglue \baselineskip \the\realeverypar
! %                \everypar={\the\realeverypar}}%
!    %
!    % Now you can print the title using @title.
!    \def\title{\parsearg\titlezzz}%
!    \def\titlezzz##1{\leftline{\titlefont{##1}
! 		    \vskip4pt \hrule height 4pt \vskip4pt}}%
!    \vglue\titlepagetopglue
!    %
!    % Now you can put text using @subtitle.
!    \def\subtitle{\parsearg\subtitlezzz}%
!    \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}%
!    %
!    % @author should come last, but may come many times.
!    \def\author{\parsearg\authorzzz}%
!    \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi
!       {\authorfont \leftline{##1}}}%
!    %  
!    % Most title ``pages'' are actually two pages long, with space
!    % at the top of the second.  We don't want the ragged left on the second.
!    \let\oldpage = \page
! %   \def\page{\vskip4pt \hrule height 2pt \vskip\titlepagebottomglue
! %      \oldpage \endgroup\hrule height0pt\relax}%
!    \def\page{\oldpage \hbox{}}
! }
  
! \def\Etitlepage{\endgroup\page\HEADINGSon}
  
  %%% Set up page headings and footings.
***************
*** 518,522 ****
  % edge of all pages.
  \def\HEADINGSdouble{
! \pagealignmacro
  \global\pageno=1
  \global\evenfootline={\hfil}
--- 643,647 ----
  % edge of all pages.
  \def\HEADINGSdouble{
! %\pagealignmacro
  \global\pageno=1
  \global\evenfootline={\hfil}
***************
*** 528,532 ****
  % page number on top right.
  \def\HEADINGSsingle{
! \pagealignmacro
  \global\pageno=1
  \global\evenfootline={\hfil}
--- 653,657 ----
  % page number on top right.
  \def\HEADINGSsingle{
! %\pagealignmacro
  \global\pageno=1
  \global\evenfootline={\hfil}
***************
*** 681,684 ****
--- 806,814 ----
  \def\minus{$-$}
  
+ % Set sfcode to normal for the chars that usually have another value.
+ % These are `.?!:;,'
+ \def\frenchspacing{\sfcode46=1000 \sfcode63=1000 \sfcode33=1000
+   \sfcode58=1000 \sfcode59=1000 \sfcode44=1000 }
+ 
  \def\enumerate{\itemizey{\the\itemno.}\Eenumerate\flushcr}
  
***************
*** 769,772 ****
--- 899,913 ----
  \def\dots{\realbackslash dots }%
  \def\copyright{\realbackslash copyright }%
+ \def\tclose##1{\realbackslash tclose {##1}}%
+ \def\code##1{\realbackslash code {##1}}%
+ \def\samp##1{\realbackslash samp {##1}}%
+ \def\r##1{\realbackslash r {##1}}%
+ \def\i##1{\realbackslash i {##1}}%
+ \def\b##1{\realbackslash b {##1}}%
+ \def\cite##1{\realbackslash cite {##1}}%
+ \def\key##1{\realbackslash key {##1}}%
+ \def\file##1{\realbackslash file {##1}}%
+ \def\var##1{\realbackslash var {##1}}%
+ \def\kbd##1{\realbackslash kbd {##1}}%
  }
  
***************
*** 775,779 ****
--- 916,932 ----
  \def\indexdummyfont#1{#1}
  \def\indexnofonts{%
+ \let\r=\indexdummyfont
+ \let\i=\indexdummyfont
+ \let\b=\indexdummyfont
+ \let\emph=\indexdummyfont
+ \let\strong=\indexdummyfont
+ \let\cite=\indexdummyfont
+ \let\sc=\indexdummyfont
+ %Don't no-op \tt, since it isn't a user-level command
+ % and is used in the definitions of the actuve chars like <, >, |...
+ %\let\tt=\indexdummyfont
+ \let\tclose=\indexdummyfont
  \let\code=\indexdummyfont
+ \let\file=\indexdummyfont
  \let\samp=\indexdummyfont
  \let\kbd=\indexdummyfont
***************
*** 875,878 ****
--- 1028,1040 ----
  \catcode`\$=\other\catcode`\_=\other
  \catcode`\~=\other
+ % The following don't help, since the chars were translated
+ % when the raw index was written, and their fonts were discarded
+ % due to \indexnofonts.
+ %\catcode`\"=\active
+ %\catcode`\^=\active
+ %\catcode`\_=\active
+ %\catcode`\|=\active
+ %\catcode`\<=\active
+ %\catcode`\>=\active
  \def\indexbackslash{\rawbackslashxx}
  \indexfonts\rm \tolerance=9500 \advance\baselineskip -1pt
***************
*** 895,899 ****
  \ifdim\lastskip<\initialskipamount
  \removelastskip \penalty-200 \vskip \initialskipamount\fi
! \line{\secbf#1\hfill}\kern 2pt\penalty3000}}
  
  \outer\def\entry #1#2{
--- 1057,1061 ----
  \ifdim\lastskip<\initialskipamount
  \removelastskip \penalty-200 \vskip \initialskipamount\fi
! \line{\secbf#1\hfill}\kern 2pt\penalty10000}}
  
  \outer\def\entry #1#2{
***************
*** 900,904 ****
  {\parfillskip=0in \parskip=0in \parindent=0in
  \hangindent=1in \hangafter=1%
! \noindent\hbox{#1}\leaders\Dotsbox\hskip 0pt plus 1filll #2\par
  }}
  
--- 1062,1066 ----
  {\parfillskip=0in \parskip=0in \parindent=0in
  \hangindent=1in \hangafter=1%
! \noindent\hbox{#1}\dotfill #2\par
  }}
  
***************
*** 910,914 ****
  {\parfillskip=0in \parskip=0in
  \hangindent =1in \hangafter=1
! \noindent\hskip\secondaryindent\hbox{#1}\leaders\Dotsbox\hskip 0pt plus 1filll#2\par
  }}
  
--- 1072,1076 ----
  {\parfillskip=0in \parskip=0in
  \hangindent =1in \hangafter=1
! \noindent\hskip\secondaryindent\hbox{#1}\dotfill #2\par
  }}
  
***************
*** 921,924 ****
--- 1083,1087 ----
  \newdimen\doublecolumnhsize  \doublecolumnhsize = 3.11in
  \newdimen\doublecolumnvsize  \doublecolumnvsize = 19.1in
+ \newdimen\availdimen@
  
  \def\begindoublecolumns{\begingroup
***************
*** 936,942 ****
  %	      changes it to set cropmarks (P. A. MacKay, 12 Nov. 1986)
    \wd0=\hsize \wd2=\hsize \hbox to\pagewidth{\box0\hfil\box2}}
! \def\balancecolumns{\setbox0=\vbox{\unvbox255} \dimen@=\ht0
    \advance\dimen@ by\topskip \advance\dimen@ by-\baselineskip
!   \divide\dimen@ by2 \splittopskip=\topskip
    {\vbadness=10000 \loop \global\setbox3=\copy0
      \global\setbox1=\vsplit3 to\dimen@
--- 1099,1125 ----
  %	      changes it to set cropmarks (P. A. MacKay, 12 Nov. 1986)
    \wd0=\hsize \wd2=\hsize \hbox to\pagewidth{\box0\hfil\box2}}
! \def\balancecolumns{%
! % Unset the glue.
!   \setbox255=\vbox{\unvbox255}
!   \dimen@=\ht255
!   \advance\dimen@ by\topskip \advance\dimen@ by-\baselineskip
!   \divide\dimen@ by2
!   \availdimen@=\pageheight \advance\availdimen@ by-\ht\partialpage
! % If the remaining data is too big for one page,
! % output one page normally, then work with what remains.
!   \ifdim \dimen@>\availdimen@
!    {
!      \splittopskip=\topskip \splitmaxdepth=\maxdepth
!      \dimen@=\pageheight \advance\dimen@ by-\ht\partialpage
!      \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@
!      \onepageout\pagesofar
!    }
! % Recompute size of what remains, in case we just output some of it.
!   \dimen@=\ht255
    \advance\dimen@ by\topskip \advance\dimen@ by-\baselineskip
!   \divide\dimen@ by2
!   \fi
!   \setbox0=\vbox{\unvbox255}
!   \splittopskip=\topskip
    {\vbadness=10000 \loop \global\setbox3=\copy0
      \global\setbox1=\vsplit3 to\dimen@
***************
*** 959,963 ****
  
  \newwrite \contentsfile
! \openout \contentsfile = \jobname.toc
  
  % Each @chapter defines this as the name of the chapter.
--- 1142,1147 ----
  
  \newwrite \contentsfile
! % This is called from \setfilename.
! \def\opencontents{\openout \contentsfile = \jobname.toc}
  
  % Each @chapter defines this as the name of the chapter.
***************
*** 970,973 ****
--- 1154,1174 ----
  }
  
+ \def\chapternofonts{%
+ \let\rawbackslash=\relax%
+ \let\frenchspacing=\relax%
+ \def\char{\realbackslash char}
+ \def\tclose##1{\realbackslash tclose {##1}}
+ \def\code##1{\realbackslash code {##1}}
+ \def\samp##1{\realbackslash samp {##1}}
+ \def\r##1{\realbackslash r {##1}}
+ \def\i##1{\realbackslash i {##1}}
+ \def\b##1{\realbackslash b {##1}}
+ \def\cite##1{\realbackslash cite {##1}}
+ \def\key##1{\realbackslash key {##1}}
+ \def\file##1{\realbackslash file {##1}}
+ \def\var##1{\realbackslash var {##1}}
+ \def\kbd##1{\realbackslash kbd {##1}}
+ }
+ 
  \outer\def\chapter{\parsearg\chapterzzz}
  \def\chapterzzz #1{\seccheck{chapter}%
***************
*** 975,980 ****
  \chapmacro {#1}{\the\chapno}%
  \gdef\thissection{#1}\gdef\thischapter{#1}%
! \let\rawbackslash=\relax%
! \let\frenchspacing=\relax%
  \edef\temp{{\realbackslash chapentry {#1}{\the\chapno}{\noexpand\folio}}}%
  \escapechar=`\\%
--- 1176,1180 ----
  \chapmacro {#1}{\the\chapno}%
  \gdef\thissection{#1}\gdef\thischapter{#1}%
! {\chapternofonts%
  \edef\temp{{\realbackslash chapentry {#1}{\the\chapno}{\noexpand\folio}}}%
  \escapechar=`\\%
***************
*** 981,985 ****
  \write \contentsfile \temp  %
  \donoderef %
! }
  
  \outer\def\appendix{\parsearg\appendixzzz}
--- 1181,1185 ----
  \write \contentsfile \temp  %
  \donoderef %
! }}
  
  \outer\def\appendix{\parsearg\appendixzzz}
***************
*** 988,998 ****
  \chapmacro {#1}{Appendix \appendixletter}%
  \gdef\thischapter{#1}\gdef\thissection{#1}%
! \let\rawbackslash=\relax%
! \let\frenchspacing=\relax%
  \edef\temp{{\realbackslash chapentry {#1}{Appendix \appendixletter}{\noexpand\folio}}}%
  \escapechar=`\\%
  \write \contentsfile \temp  %
! \unnumbnoderef %
! }
  
  \outer\def\unnumbered{\parsearg\unnumberedzzz}
--- 1188,1197 ----
  \chapmacro {#1}{Appendix \appendixletter}%
  \gdef\thischapter{#1}\gdef\thissection{#1}%
! {\chapternofonts%
  \edef\temp{{\realbackslash chapentry {#1}{Appendix \appendixletter}{\noexpand\folio}}}%
  \escapechar=`\\%
  \write \contentsfile \temp  %
! \appendixnoderef %
! }}
  
  \outer\def\unnumbered{\parsearg\unnumberedzzz}
***************
*** 1001,1006 ****
  \unnumbchapmacro {#1}%
  \gdef\thischapter{#1}\gdef\thissection{#1}%
! \let\rawbackslash=\relax%
! \let\frenchspacing=\relax%
  \edef\temp{{\realbackslash unnumbchapentry {#1}{\noexpand\folio}}}%
  \escapechar=`\\%
--- 1200,1204 ----
  \unnumbchapmacro {#1}%
  \gdef\thischapter{#1}\gdef\thissection{#1}%
! {\chapternofonts%
  \edef\temp{{\realbackslash unnumbchapentry {#1}{\noexpand\folio}}}%
  \escapechar=`\\%
***************
*** 1007,1011 ****
  \write \contentsfile \temp  %
  \unnumbnoderef %
! }
  
  \outer\def\section{\parsearg\sectionzzz}
--- 1205,1209 ----
  \write \contentsfile \temp  %
  \unnumbnoderef %
! }}
  
  \outer\def\section{\parsearg\sectionzzz}
***************
*** 1013,1018 ****
  \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 %
  \gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}%
! \let\rawbackslash=\relax%
! \let\frenchspacing=\relax%
  \edef\temp{{\realbackslash secentry %
  {#1}{\the\chapno}{\the\secno}{\noexpand\folio}}}%
--- 1211,1215 ----
  \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 %
  \gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}%
! {\chapternofonts%
  \edef\temp{{\realbackslash secentry %
  {#1}{\the\chapno}{\the\secno}{\noexpand\folio}}}%
***************
*** 1021,1025 ****
  \donoderef %
  \penalty 10000 %
! }
  
  \outer\def\appendixsection{\parsearg\appendixsectionzzz}
--- 1218,1222 ----
  \donoderef %
  \penalty 10000 %
! }}
  
  \outer\def\appendixsection{\parsearg\appendixsectionzzz}
***************
*** 1028,1033 ****
  \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 %
  \gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}%
! \let\rawbackslash=\relax%
! \let\frenchspacing=\relax%
  \edef\temp{{\realbackslash secentry %
  {#1}{\appendixletter}{\the\secno}{\noexpand\folio}}}%
--- 1225,1229 ----
  \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 %
  \gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}%
! {\chapternofonts%
  \edef\temp{{\realbackslash secentry %
  {#1}{\appendixletter}{\the\secno}{\noexpand\folio}}}%
***************
*** 1034,1040 ****
  \escapechar=`\\%
  \write \contentsfile \temp %
! \unnumbnoderef %
  \penalty 10000 %
! }
  
  \outer\def\unnumberedsec{\parsearg\unnumberedseczzz}
--- 1230,1236 ----
  \escapechar=`\\%
  \write \contentsfile \temp %
! \appendixnoderef %
  \penalty 10000 %
! }}
  
  \outer\def\unnumberedsec{\parsearg\unnumberedseczzz}
***************
*** 1041,1046 ****
  \def\unnumberedseczzz #1{\seccheck{unnumberedsec}%
  \plainsecheading {#1}\gdef\thissection{#1}%
! \let\rawbackslash=\relax%
! \let\frenchspacing=\relax%
  \edef\temp{{\realbackslash unnumbsecentry{#1}{\noexpand\folio}}}%
  \escapechar=`\\%
--- 1237,1241 ----
  \def\unnumberedseczzz #1{\seccheck{unnumberedsec}%
  \plainsecheading {#1}\gdef\thissection{#1}%
! {\chapternofonts%
  \edef\temp{{\realbackslash unnumbsecentry{#1}{\noexpand\folio}}}%
  \escapechar=`\\%
***************
*** 1048,1052 ****
  \unnumbnoderef %
  \penalty 10000 %
! }
  
  \outer\def\subsection{\parsearg\subsectionzzz}
--- 1243,1247 ----
  \unnumbnoderef %
  \penalty 10000 %
! }}
  
  \outer\def\subsection{\parsearg\subsectionzzz}
***************
*** 1054,1059 ****
  \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 %
  \subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}%
! \let\rawbackslash=\relax%
! \let\frenchspacing=\relax%
  \edef\temp{{\realbackslash subsecentry %
  {#1}{\the\chapno}{\the\secno}{\the\subsecno}{\noexpand\folio}}}%
--- 1249,1253 ----
  \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 %
  \subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}%
! {\chapternofonts%
  \edef\temp{{\realbackslash subsecentry %
  {#1}{\the\chapno}{\the\secno}{\the\subsecno}{\noexpand\folio}}}%
***************
*** 1062,1066 ****
  \donoderef %
  \penalty 10000 %
! }
  
  \outer\def\appendixsubsec{\parsearg\appendixsubseczzz}
--- 1256,1260 ----
  \donoderef %
  \penalty 10000 %
! }}
  
  \outer\def\appendixsubsec{\parsearg\appendixsubseczzz}
***************
*** 1068,1073 ****
  \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 %
  \subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}%
! \let\rawbackslash=\relax%
! \let\frenchspacing=\relax%
  \edef\temp{{\realbackslash subsecentry %
  {#1}{\appendixletter}{\the\secno}{\the\subsecno}{\noexpand\folio}}}%
--- 1262,1266 ----
  \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 %
  \subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}%
! {\chapternofonts%
  \edef\temp{{\realbackslash subsecentry %
  {#1}{\appendixletter}{\the\secno}{\the\subsecno}{\noexpand\folio}}}%
***************
*** 1074,1080 ****
  \escapechar=`\\%
  \write \contentsfile \temp %
! \unnumbnoderef %
  \penalty 10000 %
! }
  
  \outer\def\unnumberedsubsec{\parsearg\unnumberedsubseczzz}
--- 1267,1273 ----
  \escapechar=`\\%
  \write \contentsfile \temp %
! \appendixnoderef %
  \penalty 10000 %
! }}
  
  \outer\def\unnumberedsubsec{\parsearg\unnumberedsubseczzz}
***************
*** 1081,1086 ****
  \def\unnumberedsubseczzz #1{\seccheck{unnumberedsubsec}%
  \plainsecheading {#1}\gdef\thissection{#1}%
! \let\rawbackslash=\relax%
! \let\frenchspacing=\relax%
  \edef\temp{{\realbackslash unnumbsubsecentry{#1}{\noexpand\folio}}}%
  \escapechar=`\\%
--- 1274,1278 ----
  \def\unnumberedsubseczzz #1{\seccheck{unnumberedsubsec}%
  \plainsecheading {#1}\gdef\thissection{#1}%
! {\chapternofonts%
  \edef\temp{{\realbackslash unnumbsubsecentry{#1}{\noexpand\folio}}}%
  \escapechar=`\\%
***************
*** 1088,1092 ****
  \unnumbnoderef %
  \penalty 10000 %
! }
  
  \outer\def\subsubsection{\parsearg\subsubsectionzzz}
--- 1280,1284 ----
  \unnumbnoderef %
  \penalty 10000 %
! }}
  
  \outer\def\subsubsection{\parsearg\subsubsectionzzz}
***************
*** 1094,1099 ****
  \gdef\thissection{#1}\global\advance \subsubsecno by 1 %
  \subsubsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}%
! \let\rawbackslash=\relax%
! \let\frenchspacing=\relax%
  \edef\temp{{\realbackslash subsubsecentry %
  {#1}{\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}{\noexpand\folio}}}%\
--- 1286,1290 ----
  \gdef\thissection{#1}\global\advance \subsubsecno by 1 %
  \subsubsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}%
! {\chapternofonts%
  \edef\temp{{\realbackslash subsubsecentry %
  {#1}{\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}{\noexpand\folio}}}%\
***************
*** 1102,1106 ****
  \donoderef %
  \penalty 10000 %
! }
  
  \outer\def\appendixsubsubsec{\parsearg\appendixsubsubseczzz}
--- 1293,1297 ----
  \donoderef %
  \penalty 10000 %
! }}
  
  \outer\def\appendixsubsubsec{\parsearg\appendixsubsubseczzz}
***************
*** 1108,1113 ****
  \gdef\thissection{#1}\global\advance \subsubsecno by 1 %
  \subsubsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}%
! \let\rawbackslash=\relax%
! \let\frenchspacing=\relax%
  \edef\temp{{\realbackslash subsubsecentry{#1}%
  {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}{\noexpand\folio}}}%\
--- 1299,1303 ----
  \gdef\thissection{#1}\global\advance \subsubsecno by 1 %
  \subsubsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}%
! {\chapternofonts%
  \edef\temp{{\realbackslash subsubsecentry{#1}%
  {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}{\noexpand\folio}}}%\
***************
*** 1114,1120 ****
  \escapechar=`\\%
  \write \contentsfile \temp %
! \unnumbnoderef %
  \penalty 10000 %
! }
  
  \outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz}
--- 1304,1310 ----
  \escapechar=`\\%
  \write \contentsfile \temp %
! \appendixnoderef %
  \penalty 10000 %
! }}
  
  \outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz}
***************
*** 1121,1126 ****
  \def\unnumberedsubsubseczzz #1{\seccheck{unnumberedsubsubsec}%
  \plainsecheading {#1}\gdef\thissection{#1}%
! \let\rawbackslash=\relax%
! \let\frenchspacing=\relax%
  \edef\temp{{\realbackslash unnumbsubsubsecentry{#1}{\noexpand\folio}}}%
  \escapechar=`\\%
--- 1311,1315 ----
  \def\unnumberedsubsubseczzz #1{\seccheck{unnumberedsubsubsec}%
  \plainsecheading {#1}\gdef\thissection{#1}%
! {\chapternofonts%
  \edef\temp{{\realbackslash unnumbsubsubsecentry{#1}{\noexpand\folio}}}%
  \escapechar=`\\%
***************
*** 1128,1132 ****
  \unnumbnoderef %
  \penalty 10000 %
! }
  
  % These are variants which are not "outer", so they can appear in @ifinfo.
--- 1317,1321 ----
  \unnumbnoderef %
  \penalty 10000 %
! }}
  
  % These are variants which are not "outer", so they can appear in @ifinfo.
***************
*** 1260,1307 ****
  \message{toc printing,}
  
! \def\Dotsbox{\hbox to 1em{\hss.\hss}} % Used by index macros
  
! \def\finishcontents{%
! \ifnum\pageno>0 %
! \pagealignmacro %
! \immediate\closeout \contentsfile%
! \pageno=-1		% Request roman numbered pages
! \fi}
  
  \outer\def\contents{%
! \finishcontents %
! \unnumbchapmacro{Table of Contents}
! \def\thischapter{Table of Contents}
! {\catcode`\\=0
! \catcode`\{=1		% Set up to handle contents files properly
! \catcode`\}=2
! \catcode`\@=11
! \input \jobname.toc
  }
- \vfill \eject}
  
  \outer\def\summarycontents{%
! \finishcontents %
! \unnumbchapmacro{Summary Table of Contents}
! \def\thischapter{Summary Table of Contents}
! {\catcode`\\=0
! \catcode`\{=1		% Set up to handle contents files properly
! \catcode`\}=2
! \catcode`\@=11
! \def\smallbreak{}
! \def\secentry ##1##2##3##4{}
! \def\subsecentry ##1##2##3##4##5{}
! \def\subsubsecentry ##1##2##3##4##5##6{}
! \def\unnumbsecentry ##1##2{}
! \def\unnumbsubsecentry ##1##2{}
! \def\unnumbsubsubsecentry ##1##2{}
! \let\medbreak=\smallbreak
! \input \jobname.toc
  }
! \vfill \eject}
  
! \outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
! 
! % These macros generate individual entries in the table of contents
  % The first argument is the chapter or section name.
  % The last argument is the page number.
--- 1449,1499 ----
  \message{toc printing,}
  
! % Finish up the main text and prepare to read what we've written
! % to \contentsfile.
  
! \def\startcontents#1{%
!    \ifnum \pageno>0
!       \pagealignmacro
!       \immediate\closeout \contentsfile
!       \pageno = -1		% Request roman numbered pages.
!    \fi
!    \unnumbchapmacro{#1}\def\thischapter{#1}%
!    \begingroup   		% Set up to handle contents files properly.
!       \catcode`\\=0  \catcode`\{=1  \catcode`\}=2  \catcode`\@=11
!       \raggedbottom             % Worry more about breakpoints than the bottom.
!       \advance\hsize by -1in    % Don't use the full line length.
! }
  
+   
+ % Normal (long) toc.
  \outer\def\contents{%
!    \startcontents{Table of Contents}%
!       \input \jobname.toc
!    \endgroup
!    \vfill \eject
  }
  
+ % And just the chapters.
  \outer\def\summarycontents{%
!    \startcontents{Short Contents}%
!       %
!       \let\chapentry = \shortchapentry
!       \let\unnumbchapentry = \shortunnumberedentry
!       % We want a true roman here for the page numbers.
!       \secfonts \let\rm = \truesecrm \rm
!       \advance\baselineskip by 1pt % Open it up a little.
!       \def\secentry ##1##2##3##4{}
!       \def\unnumbsecentry ##1##2{}
!       \def\subsecentry ##1##2##3##4##5{}
!       \def\unnumbsubsecentry ##1##2{}
!       \def\subsubsecentry ##1##2##3##4##5##6{}
!       \def\unnumbsubsubsecentry ##1##2{}
!       \input \jobname.toc
!    \endgroup
!    \vfill \eject
  }
! \let\shortcontents = \summarycontents
  
! % These macros generate individual entries in the table of contents.
  % The first argument is the chapter or section name.
  % The last argument is the page number.
***************
*** 1308,1349 ****
  % The arguments in between are the chapter number, section number, ...
  
! \def\chapentry #1#2#3{%
! \medbreak
! \line{#2.\space#1\leaders\hbox to 1em{\hss.\hss}\hfill #3}
  }
  
! \def\unnumbchapentry #1#2{%
! \medbreak
! \line{#1\leaders\Dotsbox\hfill #2}
! }
! 
! \def\secentry #1#2#3#4{%
! \line{\enspace\enspace#2.#3\space#1\leaders\Dotsbox\hfill#4}
! }
! 
! \def\unnumbsecentry #1#2{%
! \line{\enspace\enspace#1\leaders\Dotsbox\hfill #2}
! }
! 
! \def\subsecentry #1#2#3#4#5{%
! \line{\enspace\enspace\enspace\enspace
! #2.#3.#4\space#1\leaders\Dotsbox\hfill #5}
! }
! 
! \def\unnumbsubsecentry #1#2{%
! \line{\enspace\enspace\enspace\enspace#1\leaders\Dotsbox\hfill #2}
! }
! 
! \def\subsubsecentry #1#2#3#4#5#6{%
! \line{\enspace\enspace\enspace\enspace\enspace\enspace
! #2.#3.#4.#5\space#1\leaders\Dotsbox\hfill #6}
! }
! 
! \def\unnumbsubsubsecentry #1#2{%
! \line{\enspace\enspace\enspace\enspace\enspace\enspace#1\leaders\Dotsbox\hfill #2}
! }
  
  \message{environments,}
  
  % @tex ... @end tex    escapes into raw Tex temporarily.
  % One exception: @ is still an escape character, so that @end tex works.
--- 1500,1616 ----
  % The arguments in between are the chapter number, section number, ...
  
! % Chapter-level things, for both the long and short contents.
! \def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}}
! \def\shortchapentry#1#2#3{%
!    \line{{#2\labelspace #1}\dotfill\doshortpageno{#3}}%
  }
  
! \def\unnumbchapentry#1#2{\dochapentry{#1}{#2}}
! \def\shortunnumberedentry#1#2{%
!    \line{#1\dotfill\doshortpageno{#2}}%
! }
! 
! % Sections.
! \def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}}
! \def\unnumbsecentry#1#2{\dosecentry{#1}{#2}}
! 
! % Subsections.
! \def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}}
! \def\unnumbsubsecentry#1#2{\dosubsecentry{#1}{#2}}
! 
! % And subsubsections.
! \def\subsubsecentry#1#2#3#4#5#6{\dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}}
! \def\unnumbsubsecentry#1#2{\dosubsubsecentry{#1}{#2}}
! 
! 
! % This parameter controls the indentation of the various levels.
! \newdimen\tocindent \tocindent = 3pc
! 
! % Now for the actual typesetting. In all these, #1 is the text and #2 is the 
! % page number.
! %
! % If the toc has to be broken over pages, we would want to be at chapters 
! % if at all possible; hence the \penalty.
! \def\dochapentry#1#2{%
!    \penalty-300 \vskip\baselineskip
!    \line{\chapentryfonts #1\dotfill \dopageno{#2}}%
!    \nobreak\vskip .25\baselineskip
! }
! 
! \def\dosecentry#1#2{%
!    \line{\secentryfonts \hskip\tocindent #1\dotfill \dopageno{#2}}%
! }
! 
! \def\dosubsecentry#1#2{%
!    \line{\subsecentryfonts \hskip2\tocindent #1\dotfill \dopageno{#2}}%
! }
! 
! \def\dosubsubsecentry#1#2{%
!    \line{\subsubsecentryfonts \hskip3\tocindent #1\dotfill \dopageno{#2}}%
! }
! 
! % Space between chapter (or whatever) number and the title.
! \def\labelspace{\hskip1em \relax}
! 
! \def\dopageno#1{{\rm #1}}
! \def\doshortpageno#1{{\rm #1}}
! 
! \def\chapentryfonts{\secfonts \rm}
! \def\secentryfonts{\textfonts}
! \let\subsecentryfonts = \textfonts
! \let\subsubsecentryfonts = \textfonts
! 
  
  \message{environments,}
  
+ % Since these characters are used in examples, it should be an even number of 
+ % \tt widths. Each \tt character is 1en, so two makes it 1em.
+ % Furthermore, these definitions must come after we define our fonts.
+ \newbox\dblarrowbox    \newbox\longdblarrowbox
+ \newbox\pushcharbox    \newbox\bullbox
+ \newbox\equivbox       \newbox\errorbox
+ 
+ \let\ptexequiv = \equiv
+ 
+ {\tentt
+ \global\setbox\dblarrowbox = \hbox to 1em{\hfil$\Rightarrow$\hfil}
+ \global\setbox\longdblarrowbox = \hbox to 1em{\hfil$\mapsto$\hfil}
+ \global\setbox\pushcharbox = \hbox to 1em{\hfil$\dashv$\hfil}
+ \global\setbox\equivbox = \hbox to 1em{\hfil$\ptexequiv$\hfil}
+ % Adapted from the manmac format (p.420 of TeXbook)
+ \global\setbox\bullbox = \hbox to 1em{\kern.15em\vrule height .75ex width .85ex
+                                       depth .1ex\hfil}
+ }
+ 
+ \def\point{$\star$}
+ 
+ \def\result{\leavevmode\raise.15ex\copy\dblarrowbox}
+ \def\expansion{\leavevmode\raise.1ex\copy\longdblarrowbox}
+ \def\print{\leavevmode\lower.1ex\copy\pushcharbox}
+ 
+ \def\equiv{\leavevmode\lower.1ex\copy\equivbox}
+ 
+ % Does anyone really want this?
+ % \def\bull{\leavevmode\copy\bullbox}
+ 
+ % Adapted from the TeXbook's \boxit.
+ \dimen0 = 3em % Width of the box.
+ \dimen2 = .55pt % Thickness of rules
+ % The text. (`r' is open on the right, `e' somewhat less so on the left.)
+ \setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt}
+ 
+ \global\setbox\errorbox=\hbox to \dimen0{\hfil
+    \vbox{\hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
+       \advance\hsize by -2\dimen2 % Rules.
+       \hrule height\dimen2
+       \hbox{\vrule width\dimen2 \kern3pt          % Space to left of text.
+          \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
+          \kern3pt\vrule width\dimen2}% Space to right.
+       \hrule height\dimen2}
+     \hfil}
+ 
+ % The @error{} command.
+ \def\error{\leavevmode\lower.7ex\copy\errorbox}
+ 
  % @tex ... @end tex    escapes into raw Tex temporarily.
  % One exception: @ is still an escape character, so that @end tex works.
***************
*** 1356,1359 ****
--- 1623,1627 ----
  \catcode `\%=14
  \catcode`\"=12
+ \catcode`\==12
  \catcode`\|=12
  \catcode`\<=12
***************
*** 1525,1529 ****
  \def\setdeffont #1 {\csname DEF#1\endcsname}
  
! \newskip\defbodyindent \defbodyindent=36pt
  \newskip\defargsindent \defargsindent=50pt
  \newskip\deftypemargin \deftypemargin=12pt
--- 1793,1797 ----
  \def\setdeffont #1 {\csname DEF#1\endcsname}
  
! \newskip\defbodyindent \defbodyindent=.4in
  \newskip\defargsindent \defargsindent=50pt
  \newskip\deftypemargin \deftypemargin=12pt
***************
*** 1593,1597 ****
  \def#1{\endgraf\endgroup\medbreak}%
  \def#2{\begingroup\obeylines\activeparens\spacesplit#3}%
! \parindent=0in \leftskip=\defbodyindent %
  \begingroup\obeylines\activeparens\spacesplit#3}
  
--- 1861,1865 ----
  \def#1{\endgraf\endgroup\medbreak}%
  \def#2{\begingroup\obeylines\activeparens\spacesplit#3}%
! \parindent=0in \leftskip=\defbodyindent \rightskip=\defbodyindent %
  \begingroup\obeylines\activeparens\spacesplit#3}
  
***************
*** 1602,1608 ****
  \def#1{\endgraf\endgroup\medbreak}%
  \def#2##1 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}}}%
! \parindent=0in \leftskip=\defbodyindent %
  \begingroup\obeylines\activeparens\spacesplit{#3{#4}}}
  
  % Split up #2 at the first space token.
  % call #1 with two arguments:
--- 1870,1886 ----
  \def#1{\endgraf\endgroup\medbreak}%
  \def#2##1 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}}}%
! \parindent=0in \leftskip=\defbodyindent \rightskip=\defbodyindent %
  \begingroup\obeylines\activeparens\spacesplit{#3{#4}}}
  
+ \def\defopparsebody #1#2#3#4#5 {\begingroup\inENV %
+ \medbreak %
+ % Define the end token that this defining construct specifies
+ % so that it will exit this group.
+ \def#1{\endgraf\endgroup\medbreak}%
+ \def#2##1 ##2 {\def#4{##1}%
+ \begingroup\obeylines\activeparens\spacesplit{#3{##2}}}%
+ \parindent=0in \leftskip=\defbodyindent %
+ \begingroup\obeylines\activeparens\spacesplit{#3{#5}}}
+ 
  % Split up #2 at the first space token.
  % call #1 with two arguments:
***************
*** 1625,1632 ****
  % Use this to expand the args and terminate the paragraph they make up
  
! \def\defunargs #1{\functionparens \sl #1%
  \ifnum\parencount=0 \else \errmessage{unbalanced parens in @def arguments}\fi%
  \interlinepenalty=10000
! \endgraf\vskip -\parskip \penalty 10000}
  
  % Do complete processing of one @defun or @defunx line already parsed.
--- 1903,1915 ----
  % Use this to expand the args and terminate the paragraph they make up
  
! \def\defunargs #1{\functionparens \sl
! % Expand, preventing hyphenation at `-' chars.
! % Note that groups don't affect changes in \hyphenchar.
! \hyphenchar\sl=0
! #1%
! \hyphenchar\sl=45
  \ifnum\parencount=0 \else \errmessage{unbalanced parens in @def arguments}\fi%
  \interlinepenalty=10000
! \endgraf\penalty10000\vskip -\parskip }
  
  % Do complete processing of one @defun or @defunx line already parsed.
***************
*** 1679,1683 ****
  
  \def\defop #1 {\def\defoptype{#1}%
! \defmethparsebody\Edefop\defopx\defopheader}
  
  \def\defopheader #1#2#3{\dosubind {fn}{\code{#2}}{on #1}% Make entry in function index
--- 1962,1966 ----
  
  \def\defop #1 {\def\defoptype{#1}%
! \defopparsebody\Edefop\defopx\defopheader\defoptype}
  
  \def\defopheader #1#2#3{\dosubind {fn}{\code{#2}}{on #1}% Make entry in function index
***************
*** 1698,1702 ****
  
  \def\defcv #1 {\def\defcvtype{#1}%
! \defmethparsebody\Edefcv\defcvx\defcvheader}
  
  \def\defcvarheader #1#2#3{%
--- 1981,1985 ----
  
  \def\defcv #1 {\def\defcvtype{#1}%
! \defopparsebody\Edefcv\defcvx\defcvheader\defcvtype}
  
  \def\defcvarheader #1#2#3{%
***************
*** 1731,1735 ****
  \def\defvarargs #1{\normalparens #1%
  \interlinepenalty=10000
! \endgraf\vskip -\parskip \penalty 10000}
  
  % @defvr Counter foo-count
--- 2014,2018 ----
  \def\defvarargs #1{\normalparens #1%
  \interlinepenalty=10000
! \endgraf\penalty 10000\vskip -\parskip}
  
  % @defvr Counter foo-count
***************
*** 1796,1799 ****
--- 2079,2086 ----
  \dosetq{#1-snt}{Ynothing}}
  
+ \def\appendixsetref#1{%
+ \dosetq{#1-pg}{Ypagenumber}%
+ \dosetq{#1-snt}{Yappendixletterandtype}}
+ 
  % \xref and \pxref generate cross references to specified points.
  
***************
*** 1800,1803 ****
--- 2087,2091 ----
  \def\pxref #1{see \xrefX [#1,,,,,,,]}
  \def\xref #1{See \xrefX [#1,,,,,,,]}
+ \def\ref #1{\xrefX [#1,,,,,,,]}
  \def\xrefX [#1,#2,#3,#4,#5,#6]{%
  \setbox1=\hbox{\i{\losespace#5{}}}%
***************
*** 1805,1811 ****
  \ifdim \wd0 =0pt \setbox0=\hbox{\losespace#1{}}\fi%
  \ifdim \wd1 >0pt%
! section \unhbox0{} in \unhbox1%
  \else%
! \refx{#1-snt} [\unhbox0], page\tie \refx{#1-pg}%
  \fi }
  
--- 2093,2099 ----
  \ifdim \wd0 =0pt \setbox0=\hbox{\losespace#1{}}\fi%
  \ifdim \wd1 >0pt%
! section `\unhbox0' in \unhbox1%
  \else%
! \refx{#1-snt}{} [\unhbox0], page\tie \refx{#1-pg}{}%
  \fi }
  
***************
*** 1836,1852 ****
  \fi \fi \fi }
  
  \gdef\xreftie{'tie}
  
! % Define @refx to reference a specific cross-reference string.
  
! \def\refx#1{%
  {%
  \expandafter\ifx\csname X#1\endcsname\relax
  % If not defined, say something at least.
! \expandafter\gdef\csname X#1\endcsname {$<$undefined$>$}%
  \message {WARNING: Cross-reference "#1" used but not yet defined}%
  \message {}%
  \fi %
! \csname X#1\endcsname %It's defined, so just use it.
  }}
  
--- 2124,2151 ----
  \fi \fi \fi }
  
+ \def\Yappendixletterandtype{%
+ \ifnum\secno=0 appendix\xreftie'char\the\appendixno %
+ \else \ifnum \subsecno=0 section\xreftie'char\the\appendixno.\the\secno %
+ \else \ifnum \subsubsecno=0 %
+ section\xreftie'char\the\appendixno.\the\secno.\the\subsecno %
+ \else %
+ section\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno %
+ \fi \fi \fi }
+ 
  \gdef\xreftie{'tie}
  
! % Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
! % If its value is nonempty, SUFFIX is output afterward.
  
! \def\refx#1#2{%
  {%
  \expandafter\ifx\csname X#1\endcsname\relax
  % If not defined, say something at least.
! \expandafter\gdef\csname X#1\endcsname {$\langle$un\-def\-in\-ed$\rangle$}#2%
  \message {WARNING: Cross-reference "#1" used but not yet defined}%
  \message {}%
  \fi %
! \setbox0=\hbox{\csname X#1\endcsname}%It's defined, so just use it.
! \ifdim\wd0>0pt \unhbox0{}#2\fi
  }}
  
***************
*** 1857,1861 ****
  {\catcode`\'=\other\expandafter \gdef \csname X#1\endcsname {#2}}}
  
! {
  \catcode `\^^@=\other
  \catcode `\▶01◀=\other
--- 2156,2161 ----
  {\catcode`\'=\other\expandafter \gdef \csname X#1\endcsname {#2}}}
  
! \def\readauxfile{%
! \begingroup
  \catcode `\^^@=\other
  \catcode `\▶01◀=\other
***************
*** 1900,1904 ****
  \catcode `\#=\other
  \catcode `\&=\other
- 
  % the aux file uses ' as the escape.
  % Turn off \ as an escape so we do not lose on
--- 2200,2203 ----
***************
*** 1907,1911 ****
  % Reference to such entries still does not work the way one would wish,
  % but at least they do not bomb out when the aux file is read in.
- 
  \catcode `\{=1 \catcode `\}=2
  \catcode `\%=\other
--- 2206,2209 ----
***************
*** 1912,1924 ****
  \catcode `\'=0
  \catcode `\\=\other
! 
! 'openin 1 'jobname.aux
! 'ifeof 1 'else 'closein 1 'input 'jobname.aux
! 'fi
! }
! 
  % Open the new aux file.  Tex will close it automatically at exit.
- 
  \openout \auxfile=\jobname.aux
  
  % Footnotes.
--- 2210,2220 ----
  \catcode `\'=0
  \catcode `\\=\other
! \openin 1 \jobname.aux
! \ifeof 1 \else \closein 1 \input \jobname.aux
! \fi
  % Open the new aux file.  Tex will close it automatically at exit.
  \openout \auxfile=\jobname.aux
+ \endgroup}
+ 
  
  % Footnotes.
***************
*** 1950,1959 ****
  \message{and turning on texinfo input format.}
  
! \newindex{cp}
! \newcodeindex{fn}
! \newcodeindex{vr}
! \newcodeindex{tp}
! \newcodeindex{ky}
! \newcodeindex{pg}
  
  % Set some numeric style parameters, for 8.5 x 11 format.
--- 2246,2257 ----
  \message{and turning on texinfo input format.}
  
! \def\openindices{%
!    \newindex{cp}%
!    \newcodeindex{fn}%
!    \newcodeindex{vr}%
!    \newcodeindex{tp}%
!    \newcodeindex{ky}%
!    \newcodeindex{pg}%
! }
  
  % Set some numeric style parameters, for 8.5 x 11 format.
***************
*** 2015,2018 ****
--- 2313,2320 ----
  \catcode`\>=\active
  \def>{{\tt \gtr}}
+ \catcode`\+=\active
+ \def+{{\tt \char 43}}
+ %\catcode 27=\active
+ %\def^^[{$\diamondsuit$}
  
  \catcode`\@=0
***************
*** 2032,2042 ****
  \escapechar=`\@
  
  %% These look ok in all fonts, so just make them not special.  The @rm below
  %% makes sure that the current font starts out as the newly loaded cmr10
! \catcode`\$=\other \catcode`\%=\other \catcode`\&=\other \catcode`\#=\other
! 
! \catcode 17=0   @c Define control-q
! \catcode`\\=\active
! @let\=@normalbackslash
  
  @textfonts
--- 2334,2356 ----
  \escapechar=`\@
  
+ @c \catcode 17=0   @c Define control-q
+ \catcode`\\=\active
+ 
+ % If a .fmt file is being used, we don't want the `\input texinfo' to show up.
+ % That is what \eatinput is for; after that, the `\' should revert to printing 
+ % a backslash.
+ %
+ @gdef@eatinput input texinfo{@fixbackslash}
+ @global@let\ = @eatinput
+ 
+ % On the other hand, perhaps the file did not have a `\input texinfo'. Then
+ % the first `\{ in the file would cause an error. This macro tries to fix 
+ % that, assuming it is called before the first `\' could plausibly occur.
+ % 
+ @gdef@fixbackslash{@ifx\@eatinput @let\ = @normalbackslash @fi}
+ 
  %% These look ok in all fonts, so just make them not special.  The @rm below
  %% makes sure that the current font starts out as the newly loaded cmr10
! @catcode`@$=@other @catcode`@%=@other @catcode`@&=@other @catcode`@#=@other
  
  @textfonts
diff -rc2N gcc-1.35/toplev.c gcc-1.36/toplev.c
*** gcc-1.35/toplev.c	Thu Apr  6 11:12:29 1989
--- gcc-1.36/toplev.c	Thu Sep  7 23:21:14 1989
***************
*** 33,37 ****
--- 33,40 ----
  
  #ifdef USG
+ #undef FLOAT
  #include <sys/param.h>
+ /* This is for hpux.  It is a real screw.  They should change hpux.  */
+ #undef FLOAT
  #include <sys/times.h>
  #include <time.h>   /* Correct for hpux at least.  Is it good on other USG?  */
***************
*** 40,46 ****
  #include <sys/time.h>
  #include <sys/resource.h>
- #endif
  #endif
  
  #include "tree.h"
  #include "c-tree.h"
--- 43,50 ----
  #include <sys/time.h>
  #include <sys/resource.h>
  #endif
+ #endif
  
+ #include "input.h"
  #include "tree.h"
  #include "c-tree.h"
***************
*** 67,71 ****
--- 71,77 ----
  void error ();
  void error_with_file_and_line ();
+ void fancy_abort ();
  void set_target_switch ();
+ void print_target_switch_defaults ();
  
  /* Bit flags that specify the machine subtype we are compiling for.
***************
*** 88,92 ****
  /* Current line number in real source file.  */
  
! extern int lineno;
  
  /* FUNCTION_DECL for function now being parsed or compiled.  */
--- 94,105 ----
  /* Current line number in real source file.  */
  
! int lineno;
! 
! /* Stack of currently pending input files.  */
! 
! struct file_stack *input_file_stack;
! 
! /* Incremented on each change to input_file_stack.  */
! int input_file_stack_tick;
  
  /* FUNCTION_DECL for function now being parsed or compiled.  */
***************
*** 110,113 ****
--- 123,127 ----
  int global_reg_dump = 0;
  int jump2_opt_dump = 0;
+ int dbr_sched_dump = 0;
  
  /* 1 => write gdb debugging output (using symout.c).  -g
***************
*** 126,129 ****
--- 140,151 ----
  int optimize = 0;
  
+ /* Nonzero means `char' should be signed.  */
+ 
+ int flag_signed_char;
+ 
+ /* Nonzero means give an enum type only as many bytes as it needs.  */
+ 
+ int flag_short_enums;
+ 
  /* Nonzero for -fcaller-saves: allocate values in regs that need to
     be saved across function calls, if that produces overall better code.
***************
*** 194,197 ****
--- 216,223 ----
  int flag_volatile;
  
+ /* Nonzero means just do syntax checking; don't output anything.  */
+ 
+ int flag_syntax_only = 0;
+ 
  /* Nonzero means do stupid register allocation.  -noreg.
     This and `optimize' are controlled by different switches in cc1,
***************
*** 237,240 ****
--- 263,270 ----
  int sorrycount = 0;
  
+ /* Name of program invoked, sans directories.  */
+ 
+ char *progname;
+ 
  /* Nonzero if generating code to do profiling.  */
  
***************
*** 261,268 ****
  int flag_keep_inline_functions;
  
- /* Nonzero if we are only using compiler to check syntax errors.  */
- 
- int flag_syntax_only;
- 
  /* Nonzero means make the text shared if supported.  */
  
--- 291,294 ----
***************
*** 269,272 ****
--- 295,306 ----
  int flag_shared_data;
  
+ /* Nonzero means schedule into delayed branch slots if supported.  */
+ 
+ int flag_delayed_branch;
+ 
+ /* Copy of arguments to main.  */
+ int save_argc;
+ char **save_argv;
+ 
  /* Name for output file of assembly code, specified with -o.  */
  
***************
*** 301,305 ****
    {"shared-data", &flag_shared_data, 1},
    {"caller-saves", &flag_caller_saves, 1},
!   {"pcc-struct-return", &flag_pcc_struct_return, 1}
  };
  
--- 335,340 ----
    {"shared-data", &flag_shared_data, 1},
    {"caller-saves", &flag_caller_saves, 1},
!   {"pcc-struct-return", &flag_pcc_struct_return, 1},
!   {"delayed-branch", &flag_delayed_branch, 1}
  };
  
***************
*** 317,320 ****
--- 352,356 ----
  FILE *global_reg_dump_file;
  FILE *jump2_opt_dump_file;
+ FILE *dbr_sched_dump_file;
  
  /* Time accumulators, to count the total time spent in various passes.  */
***************
*** 330,333 ****
--- 366,370 ----
  int local_alloc_time;
  int global_alloc_time;
+ int dbr_sched_time;
  int final_time;
  int symout_time;
***************
*** 410,414 ****
       char *name;
  {
!   fprintf (stderr, "cc1: ");
    perror (name);
    exit (35);
--- 447,451 ----
       char *name;
  {
!   fprintf (stderr, "%s: ", progname);
    perror (name);
    exit (35);
***************
*** 419,423 ****
       char *name;
  {
!   fprintf (stderr, "cc1:%s: I/O error\n", name);
    exit (35);
  }
--- 456,460 ----
       char *name;
  {
!   fprintf (stderr, "%s: %s: I/O error\n", progname, name);
    exit (35);
  }
***************
*** 426,429 ****
--- 463,467 ----
  fatal (s, v)
       char *s;
+      int v;
  {
    error (s, v);
***************
*** 430,433 ****
--- 468,484 ----
    exit (34);
  }
+ 
+ /* Called from insn-extract to give a better error message when we
+    don't have an insn to match what we are looking for, rather
+    than just calling abort().  */
+ 
+ void
+ fatal_insn_not_found (insn)
+      rtx insn;
+ {
+   error ("The following insn was not recognizable:", 0);
+   debug_rtx (insn);
+   abort ();
+ }
  \f


  static int need_error_newline;
***************
*** 438,441 ****
--- 489,495 ----
  static tree last_error_function = NULL;
  
+ /* Used to detect when input_file_stack has changed since last described.  */
+ static int last_error_tick;
+ 
  /* Called when the start of a function definition is parsed,
     this function prints on stderr the name of the function.  */
***************
*** 447,451 ****
    if (! quiet_flag)
      {
!       fprintf (stderr, " %s", IDENTIFIER_POINTER (DECL_NAME (decl)));
        fflush (stderr);
        need_error_newline = 1;
--- 501,505 ----
    if (! quiet_flag)
      {
!       fprintf (stderr, " %s", DECL_PRINT_NAME (decl));
        fflush (stderr);
        need_error_newline = 1;
***************
*** 457,464 ****
     which caused an error.  Called from all error and warning functions.  */
  
! static void
  report_error_function (file)
       char *file;
  {
    if (need_error_newline)
      {
--- 511,520 ----
     which caused an error.  Called from all error and warning functions.  */
  
! void
  report_error_function (file)
       char *file;
  {
+   struct file_stack *p;
+ 
    if (need_error_newline)
      {
***************
*** 474,483 ****
        if (current_function_decl == NULL)
  	fprintf (stderr, "At top level:\n");
        else
  	fprintf (stderr, "In function %s:\n",
! 		 IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
  
        last_error_function = current_function_decl;
      }
  }
  
--- 530,555 ----
        if (current_function_decl == NULL)
  	fprintf (stderr, "At top level:\n");
+       else if (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE)
+ 	fprintf (stderr, "In method %s:\n",
+ 		 DECL_PRINT_NAME (current_function_decl));
        else
  	fprintf (stderr, "In function %s:\n",
! 		 DECL_PRINT_NAME (current_function_decl));
  
        last_error_function = current_function_decl;
      }
+   if (input_file_stack && input_file_stack->next != 0
+       && input_file_stack_tick != last_error_tick)
+     {
+       fprintf (stderr, "In file included");
+       for (p = input_file_stack->next; p; p = p->next)
+ 	{
+ 	  fprintf (stderr, " from %s:%d", p->name, p->line);
+ 	  if (p->next)
+ 	    fprintf (stderr, ",");
+ 	}
+       fprintf (stderr, ":\n");
+       last_error_tick = input_file_stack_tick;
+     }
  }
  
***************
*** 512,516 ****
      fprintf (stderr, "%s:%d: ", file, line);
    else
!     fprintf (stderr, "cc1: ");
    fprintf (stderr, s, v, v2);
    fprintf (stderr, "\n");
--- 584,588 ----
      fprintf (stderr, "%s:%d: ", file, line);
    else
!     fprintf (stderr, "%s: ", progname);
    fprintf (stderr, s, v, v2);
    fprintf (stderr, "\n");
***************
*** 533,537 ****
  	   DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
  
!   if (DECL_NAME (decl))
      fprintf (stderr, s, IDENTIFIER_POINTER (DECL_NAME (decl)), v);
    else
--- 605,611 ----
  	   DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
  
!   if (DECL_PRINT_NAME (decl))
!     fprintf (stderr, s, DECL_PRINT_NAME (decl), v);
!   else if (DECL_NAME (decl))
      fprintf (stderr, s, IDENTIFIER_POINTER (DECL_NAME (decl)), v);
    else
***************
*** 572,576 ****
    filename = ASM_OPERANDS_SOURCE_FILE (asmop);
    line = ASM_OPERANDS_SOURCE_LINE (asmop);
!   
    error_with_file_and_line (filename, line, s, v, v2);
  }
--- 646,650 ----
    filename = ASM_OPERANDS_SOURCE_FILE (asmop);
    line = ASM_OPERANDS_SOURCE_LINE (asmop);
! 
    error_with_file_and_line (filename, line, s, v, v2);
  }
***************
*** 595,599 ****
      fprintf (stderr, "%s:%d: ", file, line);
    else
!     fprintf (stderr, "cc1: ");
  
    fprintf (stderr, "warning: ");
--- 669,673 ----
      fprintf (stderr, "%s:%d: ", file, line);
    else
!     fprintf (stderr, "%s: ", progname);
  
    fprintf (stderr, "warning: ");
***************
*** 615,619 ****
  
  /* Report a warning at the declaration DECL.
!    S is string which uses %s to substitute the declaration name.  */
  
  void
--- 689,694 ----
  
  /* Report a warning at the declaration DECL.
!    S is string which uses %s to substitute the declaration name.
!    V is a second parameter that S can refer to.  */
  
  void
***************
*** 632,636 ****
  
    fprintf (stderr, "warning: ");
!   if (DECL_NAME (decl))
      fprintf (stderr, s, IDENTIFIER_POINTER (DECL_NAME (decl)), v);
    else
--- 707,713 ----
  
    fprintf (stderr, "warning: ");
!   if (DECL_PRINT_NAME (decl))
!     fprintf (stderr, s, DECL_PRINT_NAME (decl), v);
!   else if (DECL_NAME (decl))
      fprintf (stderr, s, IDENTIFIER_POINTER (DECL_NAME (decl)), v);
    else
***************
*** 651,655 ****
      fprintf (stderr, "%s:%d: ", input_filename, lineno);
    else
!     fprintf (stderr, "cc1: ");
  
    fprintf (stderr, "sorry, not implemented: ");
--- 728,732 ----
      fprintf (stderr, "%s:%d: ", input_filename, lineno);
    else
!     fprintf (stderr, "%s: ", progname);
  
    fprintf (stderr, "sorry, not implemented: ");
***************
*** 676,679 ****
--- 753,765 ----
  }
  \f


+ /* More 'friendly' abort that prints the line and file.
+    config.h can #define abort fancy_abort if you like that sort of thing.  */
+ 
+ void
+ fancy_abort ()
+ {
+   fatal ("Internal gcc abort.");
+ }
+ 
  /* When `malloc.c' is compiled with `rcheck' defined,
     it calls this function to report clobberage.  */
***************
*** 800,803 ****
--- 886,890 ----
    local_alloc_time = 0;
    global_alloc_time = 0;
+   dbr_sched_time = 0;
    final_time = 0;
    symout_time = 0;
***************
*** 924,929 ****
      }
  
    /* Open assembler code output file.  */
!  
    if (! name_specified && asm_file_name == 0)
      asm_out_file = stdout;
--- 1011,1027 ----
      }
  
+   /* If dbr_sched dump desired, open the output file.  */
+   if (dbr_sched_dump)
+     {
+       register char *dumpname = (char *) xmalloc (dump_base_name_length + 7);
+       strcpy (dumpname, dump_base_name);
+       strcat (dumpname, ".dbr");
+       dbr_sched_dump_file = fopen (dumpname, "w");
+       if (dbr_sched_dump_file == 0)
+ 	pfatal_with_name (dumpname);
+     }
+ 
    /* Open assembler code output file.  */
! 
    if (! name_specified && asm_file_name == 0)
      asm_out_file = stdout;
***************
*** 965,968 ****
--- 1063,1072 ----
      main_input_filename = name;
  
+   /* Put an entry on the input file stack for the main input file.  */
+   input_file_stack
+     = (struct file_stack *) xmalloc (sizeof (struct file_stack));
+   input_file_stack->next = 0;
+   input_file_stack->name = input_filename;
+ 
    ASM_FILE_START (asm_out_file);
  
***************
*** 1019,1022 ****
--- 1123,1127 ----
    parse_time += gettime () - start_time;
  
+   parse_time -= integration_time;
    parse_time -= varconst_time;
  
***************
*** 1033,1041 ****
  	if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
  	    && ! TREE_ASM_WRITTEN (decl))
! 	  rest_of_decl_compilation (decl, 0, 1, 1);
  	if (TREE_CODE (decl) == FUNCTION_DECL
  	    && ! TREE_ASM_WRITTEN (decl)
  	    && DECL_INITIAL (decl) != 0
! 	    && TREE_ADDRESSABLE (decl))
  	  output_inline_function (decl);
  
--- 1138,1163 ----
  	if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
  	    && ! TREE_ASM_WRITTEN (decl))
! 	  {
! 	    /* Don't write out static consts, unless we needed
! 	       to take their address for some reason.  */
! 	    if (! TREE_READONLY (decl)
! 		|| TREE_PUBLIC (decl)
! 		|| TREE_ADDRESSABLE (decl))
! 	      rest_of_decl_compilation (decl, 0, 1, 1);
! 	    /* Otherwise maybe mention them just for the debugger.  */
! #ifdef DBX_DEBUGGING_INFO
! 	    else if (DECL_INITIAL (decl) && write_symbols == DBX_DEBUG)
! 	      TIMEVAR (varconst_time, dbxout_symbol (decl, 0));
! #endif
! #ifdef SDB_DEBUGGING_INFO
! 	    else if (DECL_INITIAL (decl) && write_symbols == SDB_DEBUG)
! 	      TIMEVAR (varconst_time, sdbout_symbol (decl, 0));
! #endif
! 	  }
  	if (TREE_CODE (decl) == FUNCTION_DECL
  	    && ! TREE_ASM_WRITTEN (decl)
  	    && DECL_INITIAL (decl) != 0
! 	    && TREE_ADDRESSABLE (decl)
! 	    && ! TREE_EXTERNAL (decl))
  	  output_inline_function (decl);
  
***************
*** 1095,1098 ****
--- 1217,1224 ----
    end_final (main_input_filename);
  
+ #ifdef ASM_FILE_END
+   ASM_FILE_END (asm_out_file);
+ #endif
+ 
    /* Close the dump files.  */
  
***************
*** 1127,1136 ****
      fclose (jump2_opt_dump_file);
  
!   /* Close non-debugging input and output files.  */
  
    fclose (finput);
!   if (ferror (asm_out_file) != 0)
      fatal_io_error (asm_file_name);
-   fclose (asm_out_file);
  
    /* Print the times.  */
--- 1253,1266 ----
      fclose (jump2_opt_dump_file);
  
!   if (dbr_sched_dump)
!     fclose (dbr_sched_dump_file);
! 
!   /* Close non-debugging input and output files.  Take special care to note
!      whether fclose returns an error, since the pages might still be on the
!      buffer chain while the file is open.  */
  
    fclose (finput);
!   if (ferror (asm_out_file) != 0 || fclose (asm_out_file) != 0)
      fatal_io_error (asm_file_name);
  
    /* Print the times.  */
***************
*** 1148,1151 ****
--- 1278,1282 ----
        print_time ("local-alloc", local_alloc_time);
        print_time ("global-alloc", global_alloc_time);
+       print_time ("dbranch", dbr_sched_time);
        print_time ("final", final_time);
        print_time ("varconst", varconst_time);
***************
*** 1168,1172 ****
  rest_of_decl_compilation (decl, asmspec, top_level, at_end)
       tree decl;
!      tree asmspec;
       int top_level;
       int at_end;
--- 1299,1303 ----
  rest_of_decl_compilation (decl, asmspec, top_level, at_end)
       tree decl;
!      char *asmspec;
       int top_level;
       int at_end;
***************
*** 1186,1189 ****
--- 1317,1330 ----
  		 assemble_variable (decl, top_level, write_symbols, at_end);
  	     });
+   else if (TREE_REGDECL (decl) && asmspec != 0)
+     {
+       if (decode_reg_name (asmspec) >= 0)
+ 	{
+ 	  DECL_RTL (decl) = 0;
+ 	  make_decl_rtl (decl, asmspec, top_level);
+ 	}
+       else
+ 	error ("invalid register name `%s' for register variable", asmspec);
+     }
  #ifdef DBX_DEBUGGING_INFO
    else if (write_symbols == DBX_DEBUG && TREE_CODE (decl) == TYPE_DECL)
***************
*** 1269,1280 ****
  	 for those functions that need to be output.  */
  
!       if (TREE_PUBLIC (decl) == 0
! 	  && TREE_INLINE (decl)
! 	  && ! flag_keep_inline_functions)
  	goto exit_rest_of_compilation;
      }
  
!   if (rtl_dump_and_exit)
!     goto exit_rest_of_compilation;
  
    TREE_ASM_WRITTEN (decl) = 1;
--- 1410,1425 ----
  	 for those functions that need to be output.  */
  
!       if (((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl)
! 	    && ! flag_keep_inline_functions)
! 	   || TREE_EXTERNAL (decl))
! 	  && TREE_INLINE (decl))
  	goto exit_rest_of_compilation;
      }
  
!   if (rtl_dump_and_exit || flag_syntax_only)
!     {
!       get_temporary_types ();
!       goto exit_rest_of_compilation;
!     }
  
    TREE_ASM_WRITTEN (decl) = 1;
***************
*** 1502,1505 ****
--- 1647,1670 ----
  	     });
  
+   /* If a scheduling pass for delayed branches is to be done,
+      call the scheduling code. */
+ 
+ #ifdef HAVE_DELAYED_BRANCH
+   if (optimize && flag_delayed_branch)
+     {
+       TIMEVAR (dbr_sched_time, dbr_schedule (insns, dbr_sched_dump_file));
+       if (dbr_sched_dump)
+ 	{
+ 	  TIMEVAR (dump_time,
+ 		 {
+ 		   fprintf (dbr_sched_dump_file, "\n;; Function %s\n\n",
+ 			    IDENTIFIER_POINTER (DECL_NAME (decl)));
+ 		   print_rtl (dbr_sched_dump_file, insns);
+ 		   fflush (dbr_sched_dump_file);
+ 		 });
+ 	}
+     }
+ #endif
+ 
    /* Now turn the rtl into assembler code.  */
  
***************
*** 1570,1574 ****
--- 1735,1748 ----
    char *filename = 0;
    int print_mem_flag = 0;
+   char *p;
+ 
+   /* save in case md file wants to emit args as a comment.  */
+   save_argc = argc;
+   save_argv = argv;
  
+   p = argv[0] + strlen (argv[0]);
+   while (p != argv[0] && p[-1] != '/') --p;
+   progname = p;
+ 
  #ifdef RLIMIT_STACK
    /* Get rid of any avoidable limit on stack size.  */
***************
*** 1589,1592 ****
--- 1763,1770 ----
    /* Initialize whether `char' is signed.  */
    flag_signed_char = DEFAULT_SIGNED_CHAR;
+ #ifdef DEFAULT_SHORT_ENUMS
+   /* Initialize how much space enums occupy, by default.  */
+   flag_short_enums = DEFAULT_SHORT_ENUMS;
+ #endif
  
    /* This is zeroed by -O.  */
***************
*** 1621,1624 ****
--- 1799,1805 ----
  		  combine_dump = 1;
  		  break;
+ 		case 'd':
+ 		  dbr_sched_dump = 1;
+ 		  break;
  		case 'f':
  		  flow_dump = 1;
***************
*** 1691,1695 ****
  	      fix_register (&p[11], 0, 0);
  	    else if (! lang_decode_option (argv[i]))
! 	      error ("Invalid option `%s'", argv[i]);	      
  	  }
  	else if (!strcmp (str, "noreg"))
--- 1872,1876 ----
  	      fix_register (&p[11], 0, 0);
  	    else if (! lang_decode_option (argv[i]))
! 	      error ("Invalid option `%s'", argv[i]);
  	  }
  	else if (!strcmp (str, "noreg"))
***************
*** 1720,1723 ****
--- 1901,1905 ----
  	    fprintf (stderr, " compiled by CC.\n");
  #endif
+ 	    print_target_switch_defaults ();
  	  }
  	else if (!strcmp (str, "w"))
***************
*** 1758,1765 ****
  	  write_symbols = GDB_DEBUG;
  #ifdef DBX_DEBUGGING_INFO
! 	else if (!strcmp (str, "g"))
  	  write_symbols = DBX_DEBUG;
! 	else if (!strcmp (str, "G"))
  	  write_symbols = DBX_DEBUG;
  #endif
  #ifdef SDB_DEBUGGING_INFO
--- 1940,1957 ----
  	  write_symbols = GDB_DEBUG;
  #ifdef DBX_DEBUGGING_INFO
! 	else if (!strcmp (str, "g0"))
  	  write_symbols = DBX_DEBUG;
! 	else if (!strcmp (str, "G0"))
  	  write_symbols = DBX_DEBUG;
+ 	else if (!strcmp (str, "g"))
+ 	  {
+ 	    write_symbols = DBX_DEBUG;
+ 	    use_gdb_dbx_extensions = 1;
+ 	  }
+ 	else if (!strcmp (str, "G"))
+ 	  {
+ 	    write_symbols = DBX_DEBUG;
+ 	    use_gdb_dbx_extensions = 1;
+ 	  }
  #endif
  #ifdef SDB_DEBUGGING_INFO
***************
*** 1768,1771 ****
--- 1960,1967 ----
  	else if (!strcmp (str, "G"))
  	  write_symbols = SDB_DEBUG;
+ 	else if (!strcmp (str, "g0"))
+ 	  write_symbols = SDB_DEBUG;
+ 	else if (!strcmp (str, "G0"))
+ 	  write_symbols = SDB_DEBUG;
  #endif
  	else if (!strcmp (str, "symout"))
***************
*** 1800,1805 ****
      {
        extern char **environ;
!       caddr_t lim = (caddr_t) sbrk (0);
!       
        fprintf (stderr, "Data size %d.\n",
  	       (int) lim - (int) &environ);
--- 1996,2001 ----
      {
        extern char **environ;
!       char *lim = (char *) sbrk (0);
! 
        fprintf (stderr, "Data size %d.\n",
  	       (int) lim - (int) &environ);
***************
*** 1847,1849 ****
--- 2043,2063 ----
        }
    error ("Invalid option `%s'", name);
+ }
+ 
+ /* Print default target switches for -version.  */
+ 
+ void
+ print_target_switch_defaults ()
+ {
+   register int j;
+   register int mask = TARGET_DEFAULT;
+   fprintf (stderr, "default target switches:");
+   for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++)
+     if (target_switches[j].name[0] != '\0'
+ 	&& target_switches[j].value > 0
+ 	&& (target_switches[j].value & mask) == target_switches[j].value)
+ 
+       fprintf (stderr, " -m%s", target_switches[j].name);
+ 
+   fprintf (stderr, "\n");
  }
diff -rc2N gcc-1.35/tree.c gcc-1.36/tree.c
*** gcc-1.35/tree.c	Fri Mar 10 17:44:56 1989
--- gcc-1.36/tree.c	Sun Aug  6 17:35:29 1989
***************
*** 37,41 ****
  #include "tree.h"
  #include "obstack.h"
! #include "varargs.h"
  #include "flags.h"
  
--- 37,41 ----
  #include "tree.h"
  #include "obstack.h"
! #include "gvarargs.h"
  #include "flags.h"
  
***************
*** 141,144 ****
--- 141,147 ----
  #define MAX_HASH_TABLE 1009
  static tree hash_table[MAX_HASH_TABLE];	/* id hash buckets */
+ 
+ /* 0 while creating built-in identifiers.  */
+ static int do_identifier_warnings;
  \f


  /* Init data for node creation, at the beginning of compilation.  */
***************
*** 267,270 ****
--- 270,283 ----
    return (char *) obstack_alloc (&permanent_obstack, size);
  }
+ 
+ /* Allocate SIZE bytes in the saveable obstack
+    and return a pointer to them.  */
+ 
+ char *
+ savealloc (size)
+      int size;
+ {
+   return (char *) obstack_alloc (saveable_obstack, size);
+ }
  \f


  /* Start a level of momentary allocation.
***************
*** 503,506 ****
--- 516,543 ----
    return t;
  }
+ 
+ /* Return a copy of a chain of nodes, chained through the TREE_CHAIN field.
+    For example, this can copy a list made of TREE_LIST nodes.  */
+ 
+ tree
+ copy_list (list)
+      tree list;
+ {
+   tree head;
+   register tree prev, next;
+ 
+   if (list == 0)
+     return 0;
+ 
+   head = prev = copy_node (list);
+   next = TREE_CHAIN (list);
+   while (next)
+     {
+       TREE_CHAIN (prev) = copy_node (next);
+       prev = TREE_CHAIN (prev);
+       next = TREE_CHAIN (next);
+     }
+   return head;
+ }
  \f


  #define HASHBITS 30
***************
*** 542,546 ****
    
    /* Not found; optionally warn about a similar identifier */
!   if (warn_id_clash && len > id_clash_len)
      for (idp = hash_table[hi]; idp; idp = TREE_CHAIN (idp))
        if (!strncmp (IDENTIFIER_POINTER (idp), text, id_clash_len))
--- 579,583 ----
    
    /* Not found; optionally warn about a similar identifier */
!   if (warn_id_clash && do_identifier_warnings && len > id_clash_len)
      for (idp = hash_table[hi]; idp; idp = TREE_CHAIN (idp))
        if (!strncmp (IDENTIFIER_POINTER (idp), text, id_clash_len))
***************
*** 561,564 ****
--- 598,620 ----
    return idp;			/* <-- return if created */
  }
+ 
+ /* Enable warnings on similar identifiers (if requested).
+    Done after the built-in identifiers are created.  */
+ 
+ void
+ start_identifier_warnings ()
+ {
+   do_identifier_warnings = 1;
+ }
+ 
+ /* Record the size of an identifier node for the language in use.
+    This is called by the language-specific files.  */
+ 
+ void
+ set_identifier_size (size)
+      int size;
+ {
+   tree_code_length[(int) IDENTIFIER_NODE] = size;
+ }
  \f


  /* Return a newly constructed INTEGER_CST node whose constant value
***************
*** 602,619 ****
  
  #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
- /* This function can't be implemented if we can't do arithmetic
-    on the float representation.  */
  
! tree
! build_real_from_int_cst (type, i)
!      tree type;
       tree i;
  {
!   tree v;
!   double d;
! 
!   v = make_node (REAL_CST);
!   TREE_TYPE (v) = type;
! 
  #ifdef REAL_ARITHMETIC
    REAL_VALUE_FROM_INT (d, TREE_INT_CST_LOW (i), TREE_INT_CST_HIGH (i));
--- 658,667 ----
  
  #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
  
! REAL_VALUE_TYPE
! real_value_from_int_cst (i)
       tree i;
  {
!   REAL_VALUE_TYPE d;
  #ifdef REAL_ARITHMETIC
    REAL_VALUE_FROM_INT (d, TREE_INT_CST_LOW (i), TREE_INT_CST_HIGH (i));
***************
*** 635,639 ****
--- 683,704 ----
      }
  #endif /* not REAL_ARITHMETIC */
+   return d;
+ }
+ 
+ /* This function can't be implemented if we can't do arithmetic
+    on the float representation.  */
+ 
+ tree
+ build_real_from_int_cst (type, i)
+      tree type;
+      tree i;
+ {
+   tree v;
+   REAL_VALUE_TYPE d;
+ 
+   v = make_node (REAL_CST);
+   TREE_TYPE (v) = type;
  
+   d = real_value_from_int_cst (i);
    /* Check for valid float value for this type on this target machine;
       if not, can print error message and store a valid value in D.  */
***************
*** 991,998 ****
        case RESULT_DECL:
        case ERROR_MARK:
! 	if (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE)
  	  return 1;
  	break;
  
        case CALL_EXPR:
  	if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE)
--- 1056,1067 ----
        case RESULT_DECL:
        case ERROR_MARK:
! 	if (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE
! 	    && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE)
  	  return 1;
  	break;
  
+       case NEW_EXPR:
+ 	return 1;
+ 
        case CALL_EXPR:
  	if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE)
***************
*** 1209,1212 ****
--- 1278,1286 ----
  
    DECL_NAME (t) = name;
+   if (name)
+     {
+       DECL_PRINT_NAME (t) = IDENTIFIER_POINTER (name);
+       DECL_ASSEMBLER_NAME (t) = IDENTIFIER_POINTER (name);
+     }
    TREE_TYPE (t) = type;
    DECL_ARGUMENTS (t) = NULL_TREE;
***************
*** 1357,1364 ****
  
  tree
! build_let (filename, line, vars, body, supercontext, tags)
       char *filename;
       int line;
!      tree vars, body, supercontext, tags;
  {
    register tree t = make_node (LET_STMT);
--- 1431,1438 ----
  
  tree
! build_let (filename, line, vars, subblocks, supercontext, tags)
       char *filename;
       int line;
!      tree vars, subblocks, supercontext, tags;
  {
    register tree t = make_node (LET_STMT);
***************
*** 1366,1370 ****
    STMT_SOURCE_LINE (t) = line;
    STMT_VARS (t) = vars;
!   STMT_BODY (t) = body;
    STMT_SUPERCONTEXT (t) = supercontext;
    STMT_BIND_SIZE (t) = 0;
--- 1440,1444 ----
    STMT_SOURCE_LINE (t) = line;
    STMT_VARS (t) = vars;
!   STMT_SUBBLOCKS (t) = subblocks;
    STMT_SUPERCONTEXT (t) = supercontext;
    STMT_BIND_SIZE (t) = 0;
***************
*** 1666,1669 ****
--- 1740,1744 ----
      case ADDR_EXPR:
      case REFERENCE_EXPR:
+     case INDIRECT_REF:
        return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
  
***************
*** 1728,1734 ****
    TYPE_PRECISION (itype) = BITS_PER_WORD;
    TYPE_MIN_VALUE (itype) = build_int_2 (0, 0);
!   TREE_TYPE (TYPE_MIN_VALUE (itype)) = itype;
!   TYPE_MAX_VALUE (itype) = maxval;
!   TREE_TYPE (maxval) = itype;
    TYPE_MODE (itype) = SImode;
    TYPE_SIZE (itype) = TYPE_SIZE (sizetype);
--- 1803,1808 ----
    TYPE_PRECISION (itype) = BITS_PER_WORD;
    TYPE_MIN_VALUE (itype) = build_int_2 (0, 0);
!   TREE_TYPE (TYPE_MIN_VALUE (itype)) = sizetype;
!   TYPE_MAX_VALUE (itype) = convert (sizetype, maxval);
    TYPE_MODE (itype) = SImode;
    TYPE_SIZE (itype) = TYPE_SIZE (sizetype);
diff -rc2N gcc-1.35/tree.def gcc-1.36/tree.def
*** gcc-1.35/tree.def	Wed Feb 22 12:29:43 1989
--- gcc-1.36/tree.def	Tue Sep  5 16:31:33 1989
***************
*** 48,52 ****
  
  /* Used to hold information to identify an operator (or combination
!    of two operators) considered as a `noun' rather than a `verb'.  */
  DEFTREECODE (OP_IDENTIFIER, "op_identifier", "x", 2)
  
--- 48,53 ----
  
  /* Used to hold information to identify an operator (or combination
!    of two operators) considered as a `noun' rather than a `verb'.
!    The first operand is encoded in the TREE_TYPE field.  */
  DEFTREECODE (OP_IDENTIFIER, "op_identifier", "x", 2)
  
***************
*** 152,157 ****
     TYPE_SEP		  Expression for units from one elt to the next.
     TYPE_SEP_UNIT	  Number of bits in a unit for previous.
!    TYPE_POINTER_TO	  It is safe to assume, for an array type,
!  that TYPE_POINTER_TO (TREE_TYPE (array_type)) is always nonzero
   and holds the type to coerce a value of that array type to in C.  */
  /* Array types in C or Pascal */
--- 153,157 ----
     TYPE_SEP		  Expression for units from one elt to the next.
     TYPE_SEP_UNIT	  Number of bits in a unit for previous.
!  The field TYPE_POINTER_TO (TREE_TYPE (array_type)) is always nonzero
   and holds the type to coerce a value of that array type to in C.  */
  /* Array types in C or Pascal */
***************
*** 229,235 ****
     STMT_TYPE_TAGS is a list (chain of TREE_LIST nodes)
      pairing struct, union and enum tag names with the types they mean,
!     for tags defined in this context.  */
! DEFTREECODE (LET_STMT, "let_stmt", "s", 5)
  
  /* if-then-else statements in C and other languages.
     STMT_COND is the condition (an expression).
--- 229,242 ----
     STMT_TYPE_TAGS is a list (chain of TREE_LIST nodes)
      pairing struct, union and enum tag names with the types they mean,
!     for tags defined in this context.
  
+    A LET_STMT can be used as an expression.  Its STMT_BODY is expanded
+    in its stead.  Its TREE_USED is set if it is expanded.
+ 
+    A LET_STMT whose TREE_USED is not set is ignored when symbols
+    are output.  If the LET_STMT is passed to expand_expr but it
+    should not be ignored, set its TREE_USED by hand.  */
+ DEFTREECODE (LET_STMT, "let_stmt", "s", 6)
+ 
  /* if-then-else statements in C and other languages.
     STMT_COND is the condition (an expression).
***************
*** 332,337 ****
      `struct block' for the function's top-level binding context.
      This must be stored in the symtab structure for the function name.
-    Also, TREE_UNSIGNED (function_decl) is nonzero if the ({...})
-     construct is used in the function.
  
     DECL_SOURCE_FILE holds a filename string and DECL_SOURCE_LINE
--- 339,342 ----
***************
*** 346,350 ****
  DEFTREECODE (RESULT_DECL, "result_decl", "d", 0)
  DEFTREECODE (FIELD_DECL, "field_decl", "d", 0)
- DEFTREECODE (FRIEND_DECL, "friend_decl", "d", 0)
  \f


  /* References to storage.  */
--- 351,354 ----
***************
*** 396,407 ****
  DEFTREECODE (INIT_EXPR, "init_expr", "e", 2)
  
! /* Allocation expression.  ??? Can you please fill in a description
!    of the arguments?  */
  DEFTREECODE (NEW_EXPR, "new_expr", "e", 2)
- 
- /* Storage freeing expression.  ??? Can you please fill in a description
-    of the arguments?  */
  DEFTREECODE (DELETE_EXPR, "delete_expr", "e", 2)
  
  /* Conditional expression ( ... ? ... : ...  in C).
     Operand 0 is the condition.
--- 400,414 ----
  DEFTREECODE (INIT_EXPR, "init_expr", "e", 2)
  
! /* Use these for overloading `new' and `delete'.
!    ??? Please describe the meaning of the operands.  */
  DEFTREECODE (NEW_EXPR, "new_expr", "e", 2)
  DEFTREECODE (DELETE_EXPR, "delete_expr", "e", 2)
  
+ /* Use these for providing abstract push and pop operations for wrappers.
+    Operand 0 is the abstract stack.  Operand 1 is the value to push or pop.
+    ??? What kind of value is an "abstract stack"?  */
+ DEFTREECODE (PUSH_EXPR, "push_expr", "e", 2)
+ DEFTREECODE (POP_EXPR, "pop_expr", "e", 2)
+ 
  /* Conditional expression ( ... ? ... : ...  in C).
     Operand 0 is the condition.
***************
*** 430,434 ****
     The cleanup is executed when the value is no longer needed,
     which is not at precisely the same time that this value is computed.  */
! DEFTREECODE (WITH_CLEANUP_EXPR, "with_call_expr", "e", 3)
  
  /* Simple arithmetic.  Operands must have the same machine mode
--- 437,441 ----
     The cleanup is executed when the value is no longer needed,
     which is not at precisely the same time that this value is computed.  */
! DEFTREECODE (WITH_CLEANUP_EXPR, "with_cleanup_expr", "e", 3)
  
  /* Simple arithmetic.  Operands must have the same machine mode
***************
*** 465,468 ****
--- 472,479 ----
     as the operands.  */
  DEFTREECODE (RDIV_EXPR, "rdiv_expr", "e", 2)
+ 
+ /* Division which is not supposed to need rounding.
+    Used for pointer subtraction in C.  */
+ DEFTREECODE (EXACT_DIV_EXPR, "exact_div_expr", "e", 2)
  
  /* Conversion of real to fixed point: four ways to round,
diff -rc2N gcc-1.35/tree.h gcc-1.36/tree.h
*** gcc-1.35/tree.h	Wed Feb 22 12:27:10 1989
--- gcc-1.36/tree.h	Wed Aug  9 16:24:16 1989
***************
*** 49,57 ****
  
  #ifndef HAVE_MACHINE_MODES
! #define DEF_MACHMODE(SYM, NAME, TYPE, SIZE, UNIT)  SYM,
  
  enum machine_mode {
  #include "machmode.def"
! };
  
  #undef DEF_MACHMODE
--- 49,57 ----
  
  #ifndef HAVE_MACHINE_MODES
! #define DEF_MACHMODE(SYM, NAME, TYPE, SIZE, UNIT, WIDER)  SYM,
  
  enum machine_mode {
  #include "machmode.def"
! MAX_MACHINE_MODE };
  
  #undef DEF_MACHMODE
***************
*** 89,92 ****
--- 89,93 ----
    BUILT_IN_GETMAN,
    BUILT_IN_SAVEREGS,
+   BUILT_IN_CLASSIFY_TYPE,
  
    /* C++ extensions */
***************
*** 129,133 ****
    union tree_node *chain;
    union tree_node *type;
!   enum tree_code code : 8;
  
    unsigned external_attr : 1;
--- 130,134 ----
    union tree_node *chain;
    union tree_node *type;
!   unsigned int code : 8;
  
    unsigned external_attr : 1;
***************
*** 163,168 ****
  /* The tree-code says what kind of node it is.
     Codes are defined in tree.def.  */
! #define TREE_CODE(NODE) ((NODE)->common.code)
! #define TREE_SET_CODE(NODE, VALUE) ((NODE)->common.code = (VALUE))
  
  /* In all nodes that are expressions, this is the data type of the expression.
--- 164,169 ----
  /* The tree-code says what kind of node it is.
     Codes are defined in tree.def.  */
! #define TREE_CODE(NODE) ((enum tree_code) (NODE)->common.code)
! #define TREE_SET_CODE(NODE, VALUE) ((NODE)->common.code = (int) (VALUE))
  
  /* In all nodes that are expressions, this is the data type of the expression.
***************
*** 249,253 ****
     Cannot happen in C because it does not allow nested functions, as of now.
     For VAR_DECL nodes, PARM_DECL nodes, and
!    maybe FUNCTION_DECL or LABEL_DECL nodes.  */
  #define TREE_NONLOCAL(NODE) ((NODE)->common.nonlocal_attr)
  
--- 250,257 ----
     Cannot happen in C because it does not allow nested functions, as of now.
     For VAR_DECL nodes, PARM_DECL nodes, and
!    maybe FUNCTION_DECL or LABEL_DECL nodes.
! 
!    Also set in some languages for variables, etc., outside the normal
!    lexical scope, such as class instance variables.  */
  #define TREE_NONLOCAL(NODE) ((NODE)->common.nonlocal_attr)
  
***************
*** 358,366 ****
  #define IDENTIFIER_LENGTH(NODE) ((NODE)->identifier.length)
  #define IDENTIFIER_POINTER(NODE) ((NODE)->identifier.pointer)
- #define IDENTIFIER_GLOBAL_VALUE(NODE) ((NODE)->identifier.global_value)
- #define IDENTIFIER_LOCAL_VALUE(NODE) ((NODE)->identifier.local_value)
- #define IDENTIFIER_LABEL_VALUE(NODE) ((NODE)->identifier.label_value)
- #define IDENTIFIER_IMPLICIT_DECL(NODE) ((NODE)->identifier.implicit_decl)
- #define IDENTIFIER_ERROR_LOCUS(NODE) ((NODE)->identifier.error_locus)
  
  struct tree_identifier
--- 362,365 ----
***************
*** 369,377 ****
    int length;
    char *pointer;
-   union tree_node *global_value;
-   union tree_node *local_value;
-   union tree_node *label_value;
-   union tree_node *implicit_decl;
-   union tree_node *error_locus;
  };
  
--- 368,371 ----
***************
*** 479,482 ****
--- 473,478 ----
  #define DECL_SET_FUNCTION_CODE(NODE,VAL) ((NODE)->decl.offset = (int) (VAL))
  #define DECL_NAME(NODE) ((NODE)->decl.name)
+ #define DECL_PRINT_NAME(NODE) ((NODE)->decl.print_name)
+ #define DECL_ASSEMBLER_NAME(NODE) ((NODE)->decl.assembler_name)
  #define DECL_CONTEXT(NODE) ((NODE)->decl.context)
  #define DECL_FIELD_CONTEXT(NODE) ((NODE)->decl.context)
***************
*** 504,508 ****
    int linenum;
    union tree_node *size;
!   enum machine_mode mode;
    unsigned char size_unit;
    unsigned char align;
--- 500,504 ----
    int linenum;
    union tree_node *size;
!   enum machine_mode mode : 8;
    unsigned char size_unit;
    unsigned char align;
***************
*** 515,518 ****
--- 511,516 ----
    union tree_node *result;
    union tree_node *initial;
+   char *print_name;
+   char *assembler_name;
    struct rtx_def *rtl;	/* acts as link to register transfer language
  				   (rtl) info */
***************
*** 571,574 ****
--- 569,573 ----
  #define STMT_BIND_SIZE(NODE) ((NODE)->bind_stmt.bind_size)
  #define STMT_TYPE_TAGS(NODE) ((NODE)->bind_stmt.type_tags)
+ #define STMT_SUBBLOCKS(NODE) ((NODE)->bind_stmt.subblocks)
  
  struct tree_bind_stmt
***************
*** 578,581 ****
--- 577,581 ----
    int linenum;
    union tree_node *body, *vars, *supercontext, *bind_size, *type_tags;
+   union tree_node *subblocks;
  };
  
***************
*** 630,633 ****
--- 630,637 ----
  extern tree copy_node ();
  
+ /* Make a copy of a chain of TREE_LIST nodes.  */
+ 
+ extern tree copy_list ();
+ 
  /* Return the (unique) IDENTIFIER_NODE node for a given name.
     The name is supplied as a char *.  */
***************
*** 901,914 ****
  extern tree expand_start_stmt_expr ();
  extern tree expand_end_stmt_expr ();
! extern void expand_expr_stmt(), clear_last_expr();
! extern void expand_label(), expand_goto(), expand_asm();
! extern void expand_start_cond(), expand_end_cond();
! extern void expand_start_else(), expand_end_else();
! extern void expand_start_loop(), expand_start_loop_continue_elsewhere();
! extern void expand_loop_continue_here();
! extern void expand_end_loop();
! extern int expand_continue_loop();
! extern int expand_exit_loop(), expand_exit_loop_if_false();
! extern int expand_exit_something();
  
  extern void expand_start_delayed_expr ();
--- 905,918 ----
  extern tree expand_start_stmt_expr ();
  extern tree expand_end_stmt_expr ();
! extern void expand_expr_stmt (), clear_last_expr ();
! extern void expand_label (), expand_goto (), expand_asm ();
! extern void expand_start_cond (), expand_end_cond ();
! extern void expand_start_else (), expand_end_else ();
! extern void expand_start_loop (), expand_start_loop_continue_elsewhere ();
! extern void expand_loop_continue_here ();
! extern void expand_end_loop ();
! extern int expand_continue_loop ();
! extern int expand_exit_loop (), expand_exit_loop_if_false ();
! extern int expand_exit_something ();
  
  extern void expand_start_delayed_expr ();
***************
*** 916,922 ****
  extern void expand_emit_delayed_expr ();
  
! extern void expand_null_return(), expand_return();
! extern void expand_start_bindings(), expand_end_bindings();
! extern void expand_start_case(), expand_end_case();
! extern int pushcase(), pushcase_range ();
! extern void expand_start_function(), expand_end_function();
--- 920,926 ----
  extern void expand_emit_delayed_expr ();
  
! extern void expand_null_return (), expand_return ();
! extern void expand_start_bindings (), expand_end_bindings ();
! extern void expand_start_case (), expand_end_case ();
! extern int pushcase (), pushcase_range ();
! extern void expand_start_function (), expand_end_function ();
diff -rc2N gcc-1.35/typeclass.h gcc-1.36/typeclass.h
*** gcc-1.35/typeclass.h	Wed Dec 31 19:00:00 1969
--- gcc-1.36/typeclass.h	Sun Aug 13 15:24:27 1989
***************
*** 0 ****
--- 1,14 ----
+ /* Values returned by __builtin_classify_type.  */
+ 
+ enum type_class
+ {
+   no_type_class = -1,
+   void_type_class, integer_type_class, char_type_class,
+   enumeral_type_class, boolean_type_class,
+   pointer_type_class, reference_type_class, offset_type_class,
+   real_type_class, complex_type_class,
+   function_type_class, method_type_class,
+   record_type_class, union_type_class,
+   array_type_class, string_type_class, set_type_class, file_type_class,
+   lang_type_class
+ };
diff -rc2N gcc-1.35/va-i860.h gcc-1.36/va-i860.h
*** gcc-1.35/va-i860.h	Wed Dec 31 19:00:00 1969
--- gcc-1.36/va-i860.h	Tue Sep 12 19:58:45 1989
***************
*** 0 ****
--- 1,50 ----
+ struct __va_struct { int fixed[12]; int floating[8]; };
+ 
+ typedef struct __va_ctl
+ {
+   struct __va_struct *regs;
+   void *stack;
+   int nfixed, nfloating;
+ } va_list;
+ 
+ #define va_alist
+ 
+ #define va_dcl
+ 
+ #define va_start(pvar) \
+  (memcpy (&(pvar), (struct __va_ctl *) __builtin_saveregs (), 80))
+ #define va_end(pvar)
+ 
+ #define va_arg(pvar,type)					\
+ ({ type __va_temp;						\
+    *((__builtin_classify_type (__va_temp) < 8			\
+       && sizeof __va_temp < 8)					\
+      ? ((pvar).nfixed < 12					\
+ 	? (type *) &(pvar).regs->fixed[(pvar).nfixed++]		\
+ 	: ({							\
+ 	     int temp						\
+ 	       = ((int) ((pvar).stack + __alignof__ (type) - 1)	\
+ 		  & ~(__alignof__ (type) - 1));			\
+ 	     (pvar).stack = (void *) (temp + sizeof (type));	\
+ 	     (type *) temp; 					\
+ 	   }))							\
+      : __builtin_classify_type (__va_temp) < 9			\
+      ? ((pvar).nfloating < 8					\
+ 	? ((pvar).nfloating					\
+ 	     = (((pvar).nfloating + 2 * (sizeof __va_temp / 4) - 1) \
+ 		& ~(sizeof __va_temp / 4 - 1)),			\
+ 	   (type *) &(pvar).regs->floating[(pvar).nfloating - (sizeof __va_temp / 4)]) \
+ 	: ({							\
+ 	     int temp						\
+ 	       = ((int) ((pvar).stack + __alignof__ (type) - 1)	\
+ 		  & ~(__alignof__ (type) - 1));			\
+ 	     (pvar).stack = (void *) (temp + sizeof (type));	\
+ 	     (type *) temp; 					\
+ 	   }))							\
+      : ({							\
+ 	  int temp						\
+ 	    = ((int) ((pvar).stack + __alignof__ (type) - 1)	\
+ 	       & ~(__alignof__ (type) - 1));			\
+ 	  (pvar).stack = (void *) (temp + sizeof (type));	\
+ 	  (type *) temp; 					\
+ 	})); })
diff -rc2N gcc-1.35/va-pyr.h gcc-1.36/va-pyr.h
*** gcc-1.35/va-pyr.h	Wed Dec 31 19:00:00 1969
--- gcc-1.36/va-pyr.h	Mon Sep 11 23:56:04 1989
***************
*** 0 ****
--- 1,100 ----
+ /**
+  *
+  * 	Varargs for PYR/GNU CC
+  *
+  * WARNING -- WARNING -- DANGER
+  *
+  * The code in this file implements varargs for gcc on a pyr in
+  * a way that is compatible with code compiled by the Pyramid Technology
+  * C compiler.
+  * As such, it depends strongly on the Pyramid conventions for
+  * parameter passing.ct and indepenent implementation. 
+  * These (somewhat bizarre) paramter-passing conventions are described
+  * in the ``OSx Operating System Porting Guide''.
+  * 
+  * A quick summary is useful:
+  * 12 of the 48 register-windowed regs available for
+  * parameter passing.  Parameters of a function call that are eligible
+  * to be passed in registers are assigned registers from TR0/PR0 onwards;
+  * all other arguments are passed on the stack.
+  * Structure and union parameters are *never* passed in registers,
+  * even if they are small enough to fit.  They are always passed on
+  * the stack.
+  *
+  * Double-sized parameters cannot be passed in TR11, because
+  * TR12 is not used for passing parameters.  If, in the absence of this
+  * rule, a double-sized param would have been passed in TR11,
+  * that parameter is passed on the stack and no parameters are
+  * passed in TR11.
+  * 
+  * It is only known to work for passing 32-bit integer quantities
+  * (ie chars, shorts, ints/enums, longs), doubles, or pointers. 
+  * Passing structures on a Pyramid via varargs is a loser.
+  * Passing an object larger than 8 bytes on a pyramid via varargs may
+  * also be a loser.
+  * 
+  */
+ 
+ \f


+ /*
+  *  pointer to next stack parameter in _va_buf[0]
+  *  pointer to next parameter register in _va_buf[1]
+  *  Count of registers seen at _va_buf[2]
+  *  saved pr0..pr11 in _va_buf[3..14]
+  *  # of calls to va_arg (debugging) at _va_buf[15]
+  */
+ 
+ typedef void *_voidptr;
+ #if 1
+ 
+ typedef struct _va_regs {
+       _voidptr __stackp,__regp,__count;
+       _voidptr _pr0,_pr1,_pr2,_pr3,_pr4,_pr5,_pr6,_pr7,_pr8,_pr9,_pr10,_pr11;
+   } _va_regs;
+ 
+ typedef _va_regs _va_buf;
+ #else
+ 
+ /* _va_buf[0] = address of next arg passed on the stack
+    _va_buf[1] = address of next arg passed in a register
+    _va_buf[2] = register-# of next arg passed in a register
+  */
+ typedef _voidptr(*_va_buf);
+ 
+ #endif
+ 
+ #define va_alist \
+   _va0,_va1,_va2,_va3,_va4,_va5,_va6,_va7,_va8,_va9,_va10,_va11, \
+  __builtin_va_alist
+ 
+ #define va_dcl _voidptr va_alist;
+ 
+ #define va_list _va_buf
+ 
+ 
+ /* __asm ("rcsp %0" : "=r" ( _AP [0]));*/
+ 
+ #define va_start(_AP)  \
+ { _AP =  ((struct _va_regs) {						\
+    &(_AP._pr0), (void*)&__builtin_va_alist, (void*)0,			\
+         _va0,_va1,_va2,_va3,_va4,_va5,					\
+ 		_va6,_va7,_va8,_va9,_va10,_va11})
+  
+   
+ 	 
+ 
+ #define va_arg(_AP, _MODE)	\
+ ({_voidptr *_ap = (_voidptr*)&_AP;					\
+   register int _size = sizeof (_MODE);					\
+   register int _onstack =						\
+ 	  (_size > 8 || ( (int)(_ap[2]) > 11) ||			\
+ 	    (_size==8 && (int)(_ap[2])==11));				\
+   register int* _param_addr =  ((int*)((_ap) [_onstack]));		\
+ 									\
+   ((void *)_ap[_onstack])+=_size;					\
+     if (_onstack==0 || (int)(_ap[2])==11)				\
+       _ap[2]+= (_size >> 2);						\
+   *(( _MODE *)_param_addr);						\
+ })
+ 
+ #define va_end(_X)	}
diff -rc2N gcc-1.35/varargs.h gcc-1.36/varargs.h
*** gcc-1.35/varargs.h	Thu Apr  6 00:11:04 1989
--- gcc-1.36/varargs.h	Wed Dec 31 19:00:00 1969
***************
*** 1,37 ****
- #ifndef __GNUC__
- /* Use the system's macros with the system's compiler.  */
- #include <varargs.h>
- #else
- #ifdef __spur__
- #include "va-spur.h"
- #else
- #ifdef __mips__
- #include "va-mips.h"
- #else
- 
- /* These macros implement traditional (non-ANSI) varargs
-    for GNU C.  */
- 
- #define va_alist  __builtin_va_alist
- #define va_dcl    int __builtin_va_alist;
- #define va_list   char *
- 
- #ifdef __sparc__
- #define va_start(AP) 						\
-  (__builtin_saveregs (),					\
-   AP = ((void *) &__builtin_va_alist))
- #else
- #define va_start(AP)  AP=(char *) &__builtin_va_alist
- #endif
- #define va_end(AP)
- 
- #define __va_rounded_size(TYPE)  \
-   (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
- 
- #define va_arg(AP, TYPE)						\
-  (AP += __va_rounded_size (TYPE),					\
-   *((TYPE *) (AP - __va_rounded_size (TYPE))))
- 
- #endif /* not mips */
- #endif /* not spur */
- #endif /* __GNUC__ */
--- 0 ----
diff -rc2N gcc-1.35/varasm.c gcc-1.36/varasm.c
*** gcc-1.35/varasm.c	Tue Apr  4 20:49:31 1989
--- gcc-1.36/varasm.c	Thu Sep 21 23:34:15 1989
***************
*** 71,75 ****
  void output_constructor ();
  \f


! static enum in_section {no_section, in_text, in_data} in_section = no_section;
  
  /* Tell assembler to switch to text section.  */
--- 71,86 ----
  void output_constructor ();
  \f


! #ifdef EXTRA_SECTIONS
! static enum in_section {no_section, in_text, in_data, EXTRA_SECTIONS} in_section
!   = no_section;
! #else
! static enum in_section {no_section, in_text, in_data} in_section
!   = no_section;
! #endif
! 
! /* Define functions like text_section for any extra sections.  */
! #ifdef EXTRA_SECTION_FUNCTIONS
! EXTRA_SECTION_FUNCTIONS
! #endif
  
  /* Tell assembler to switch to text section.  */
***************
*** 118,123 ****
      DECL_RTL (decl)
        = gen_rtx (MEM, DECL_MODE (decl),
! 		 gen_rtx (SYMBOL_REF, Pmode,
! 			  IDENTIFIER_POINTER (DECL_NAME (decl))));
  
    /* Record at least one function has been defined.  */
--- 129,133 ----
      DECL_RTL (decl)
        = gen_rtx (MEM, DECL_MODE (decl),
! 		 gen_rtx (SYMBOL_REF, Pmode, DECL_ASSEMBLER_NAME (decl)));
  
    /* Record at least one function has been defined.  */
***************
*** 125,143 ****
  }
  
! /* Create the DECL_RTL for a declaration for a static or external variable
!    or static or external function.
!    ASMSPEC, if not 0, is the string which the user specified
!    as the assembler symbol name.
!    TOP_LEVEL is nonzero if this is a file-scope variable.  */
  
! void
! make_decl_rtl (decl, asmspec, top_level)
!      tree decl;
!      tree asmspec;
!      int top_level;
  {
-   register char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
-   int reg_number = -1;
- 
    if (asmspec != 0)
      {
--- 135,146 ----
  }
  
! /* Decode an `asm' spec for a declaration as a register name.
!    Return the register number, or -1 if nothing specified,
!    or -2 if the name is not a register.  */
  
! int
! decode_reg_name (asmspec)
!      char *asmspec;
  {
    if (asmspec != 0)
      {
***************
*** 145,167 ****
        extern char *reg_names[];
  
-       if (TREE_CODE (asmspec) != STRING_CST)
- 	abort ();
        for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! 	if (!strcmp (TREE_STRING_POINTER (asmspec),
! 		     reg_names[i]))
  	  break;
  
        if (i < FIRST_PSEUDO_REGISTER)
! 	reg_number = i;
        else
! 	{
! 	  name = (char *) obstack_alloc (saveable_obstack,
! 					 strlen (TREE_STRING_POINTER (asmspec)) + 2);
! 	  name[0] = '*';
! 	  strcpy (&name[1], TREE_STRING_POINTER (asmspec));
! 	  reg_number = -2;
! 	}
      }
!     
    /* For a duplicate declaration, we can be called twice on the
       same DECL node.  Don't alter the RTL already made
--- 148,189 ----
        extern char *reg_names[];
  
        for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! 	if (!strcmp (asmspec, reg_names[i]))
  	  break;
  
        if (i < FIRST_PSEUDO_REGISTER)
! 	return i;
        else
! 	return -2;
!     }
! 
!   return -1;
! }
! 
! /* Create the DECL_RTL for a declaration for a static or external variable
!    or static or external function.
!    ASMSPEC, if not 0, is the string which the user specified
!    as the assembler symbol name.
!    TOP_LEVEL is nonzero if this is a file-scope variable.
! 
!    This is never called for PARM_DECL nodes.  */
! 
! void
! make_decl_rtl (decl, asmspec, top_level)
!      tree decl;
!      char *asmspec;
!      int top_level;
! {
!   register char *name = DECL_ASSEMBLER_NAME (decl);
!   int reg_number = decode_reg_name (asmspec);
! 
!   if (reg_number == -2)
!     {
!       name = (char *) obstack_alloc (saveable_obstack,
! 				     strlen (asmspec) + 2);
!       name[0] = '*';
!       strcpy (&name[1], asmspec);
      }
! 
    /* For a duplicate declaration, we can be called twice on the
       same DECL node.  Don't alter the RTL already made
***************
*** 177,181 ****
  	error_with_decl (decl,
  			 "register name not specified for `%s'");
!       if (TREE_REGDECL (decl) && reg_number == -2)
  	error_with_decl (decl,
  			 "invalid register name for `%s'");
--- 199,203 ----
  	error_with_decl (decl,
  			 "register name not specified for `%s'");
!       else if (TREE_REGDECL (decl) && reg_number == -2)
  	error_with_decl (decl,
  			 "invalid register name for `%s'");
***************
*** 199,210 ****
  	    }
  	  if (fixed_regs[reg_number] == 0
! 	      && function_defined)
  	    error ("global register variable follows a function definition");
  	  DECL_RTL (decl) = gen_rtx (REG, DECL_MODE (decl), reg_number);
! 	  /* Make this register fixed, so not usable for anything else.  */
! 	  nregs = HARD_REGNO_NREGS (reg_number, DECL_MODE (decl));
! 	  while (nregs > 0)
! 	    global_regs[reg_number + --nregs] = 1;
! 	  init_reg_sets_1 ();
  	}
  
--- 221,235 ----
  	    }
  	  if (fixed_regs[reg_number] == 0
! 	      && function_defined && top_level)
  	    error ("global register variable follows a function definition");
  	  DECL_RTL (decl) = gen_rtx (REG, DECL_MODE (decl), reg_number);
! 	  if (top_level)
! 	    {
! 	      /* Make this register fixed, so not usable for anything else.  */
! 	      nregs = HARD_REGNO_NREGS (reg_number, DECL_MODE (decl));
! 	      while (nregs > 0)
! 		global_regs[reg_number + --nregs] = 1;
! 	      init_reg_sets_1 ();
! 	    }
  	}
  
***************
*** 260,263 ****
--- 285,289 ----
    rtx x, n;
    char *fnname;
+   int align;
  
    /* Get the function's name, as described by its RTL.
***************
*** 286,290 ****
    /* Tell assembler to move to target machine's alignment for functions.  */
  
!   ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT));
  
  #ifdef SDB_DEBUGGING_INFO
--- 312,318 ----
    /* Tell assembler to move to target machine's alignment for functions.  */
  
!   align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
!   if (align > 0)
!     ASM_OUTPUT_ALIGN (asm_out_file, align);
  
  #ifdef SDB_DEBUGGING_INFO
***************
*** 502,505 ****
--- 530,536 ----
  
    /* Switch to the proper section for this data.  */
+ #ifdef SELECT_SECTION
+   SELECT_SECTION (decl);
+ #else
    if (TREE_READONLY (decl) && ! TREE_VOLATILE (decl))
      text_section ();
***************
*** 506,513 ****
    else
      data_section ();
  
    /* Output the alignment of this data.  */
    for (i = 0; DECL_ALIGN (decl) >= BITS_PER_UNIT << (i + 1); i++);
!   ASM_OUTPUT_ALIGN (asm_out_file, i);
  
    /* Output the name(s) of this data.  */
--- 537,546 ----
    else
      data_section ();
+ #endif
  
    /* Output the alignment of this data.  */
    for (i = 0; DECL_ALIGN (decl) >= BITS_PER_UNIT << (i + 1); i++);
!   if (i > 0)
!     ASM_OUTPUT_ALIGN (asm_out_file, i);
  
    /* Output the name(s) of this data.  */
***************
*** 588,592 ****
  				       strlen (name) + 2);
    strcpy (namestring, name);
!   
    x = gen_rtx (SYMBOL_REF, Pmode, namestring);
    ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
--- 621,625 ----
  				       strlen (name) + 2);
    strcpy (namestring, name);
! 
    x = gen_rtx (SYMBOL_REF, Pmode, namestring);
    ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
***************
*** 605,609 ****
  static rtx real_constant_chain;
  
! /* Return a CONST_DOUBLE for a value specified as a pair of ints.  */
  
  rtx
--- 638,645 ----
  static rtx real_constant_chain;
  
! /* Return a CONST_DOUBLE for a value specified as a pair of ints.
!    For an integer, I0 is the low-order word and I1 is the high-order word.
!    For a real number, I0 is the word with the low address
!    and I1 is the word with the high address.  */
  
  rtx
***************
*** 856,862 ****
      {
        register tree link;
!       hi = 5;
        for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
  	hi = (hi * 603 + const_hash (TREE_VALUE (link))) % MAX_HASH_TABLE;
        return hi;
      }
--- 892,908 ----
      {
        register tree link;
! 
!       /* For record type, include the type in the hashing.
! 	 We do not do so for array types
! 	 because (1) the sizes of the elements are sufficient
! 	 and (2) distinct array types can have the same constructor.  */
!       if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
! 	hi = ((int) TREE_TYPE (exp) & ((1 << HASHBITS) - 1)) % MAX_HASH_TABLE;
!       else
! 	hi = 5;
! 
        for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
  	hi = (hi * 603 + const_hash (TREE_VALUE (link))) % MAX_HASH_TABLE;
+ 
        return hi;
      }
***************
*** 918,921 ****
--- 964,970 ----
    if (code == INTEGER_CST)
      {
+       /* Integer constants are the same only if the same width of type.  */
+       if (*p++ != TYPE_PRECISION (TREE_TYPE (exp)))
+ 	return 0;
        strp = (char *) &TREE_INT_CST_LOW (exp);
        len = 2 * sizeof TREE_INT_CST_LOW (exp);
***************
*** 951,957 ****
--- 1000,1019 ----
        register tree link;
        int length = list_length (CONSTRUCTOR_ELTS (exp));
+       tree type;
+ 
        if (bcmp (&length, p, sizeof length))
  	return 0;
        p += sizeof length;
+ 
+       /* For record constructors, insist that the types match.
+ 	 For arrays, just verify both constructors are for arrays.  */
+       if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
+ 	type = TREE_TYPE (exp);
+       else
+ 	type = 0;
+       if (bcmp (&type, p, sizeof type))
+ 	return 0;
+       p += sizeof type;
+ 
        for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
  	if ((p = compare_constant_1 (TREE_VALUE (link), p)) == 0)
***************
*** 1024,1027 ****
--- 1086,1090 ----
    if (code == INTEGER_CST)
      {
+       obstack_1grow (&permanent_obstack, TYPE_PRECISION (TREE_TYPE (exp)));
        strp = (char *) &TREE_INT_CST_LOW (exp);
        len = 2 * sizeof TREE_INT_CST_LOW (exp);
***************
*** 1052,1057 ****
--- 1115,1130 ----
        register tree link;
        int length = list_length (CONSTRUCTOR_ELTS (exp));
+       tree type;
+ 
        obstack_grow (&permanent_obstack, (char *) &length, sizeof length);
  
+       /* For record constructors, insist that the types match.
+ 	 For arrays, just verify both constructors are for arrays.  */
+       if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
+ 	type = TREE_TYPE (exp);
+       else
+ 	type = 0;
+       obstack_grow (&permanent_obstack, (char *) &type, sizeof type);
+ 
        for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
  	record_constant_1 (TREE_VALUE (link));
***************
*** 1092,1098 ****
       tree exp;
  {
!   register int hash, i;
    register struct constant_descriptor *desc;
!   char label[10];
  
    /* Make sure any other constants whose addresses appear in EXP
--- 1165,1171 ----
       tree exp;
  {
!   register int hash, i, align;
    register struct constant_descriptor *desc;
!   char label[256];
  
    /* Make sure any other constants whose addresses appear in EXP
***************
*** 1124,1127 ****
--- 1197,1203 ----
  
    /* First switch to text section, except for writable strings.  */
+ #ifdef SELECT_SECTION
+   SELECT_SECTION (exp);
+ #else
    if ((TREE_CODE (exp) == STRING_CST) && flag_writable_strings)
      data_section ();
***************
*** 1128,1135 ****
    else
      text_section ();
  
    /* Align the location counter as required by EXP's data type.  */
!   for (i = 0; TYPE_ALIGN (TREE_TYPE (exp)) >= BITS_PER_UNIT << (i + 1); i++);
!   ASM_OUTPUT_ALIGN (asm_out_file, i);
  
    /* Output the label itself.  */
--- 1204,1219 ----
    else
      text_section ();
+ #endif
  
    /* Align the location counter as required by EXP's data type.  */
! #ifdef CONSTANT_ALIGNMENT
!   align = CONSTANT_ALIGNMENT (TREE_CODE (exp), TYPE_ALIGN (TREE_TYPE (exp)));
! #else
!   align = TYPE_ALIGN (TREE_TYPE (exp));
! #endif
! 
!   for (i = 0; align >= BITS_PER_UNIT << (i + 1); i++);
!   if (i > 0)
!     ASM_OUTPUT_ALIGN (asm_out_file, i);
  
    /* Output the label itself.  */
***************
*** 1256,1260 ****
        value->un.addr.base = x;
        break;
!     
      case CONST:
        x = XEXP (x, 0);
--- 1340,1344 ----
        value->un.addr.base = x;
        break;
! 
      case CONST:
        x = XEXP (x, 0);
***************
*** 1374,1378 ****
    register int hash;
    register struct constant_descriptor *desc;
!   char label[10];
    char *found = 0;
    rtx def;
--- 1458,1462 ----
    register int hash;
    register struct constant_descriptor *desc;
!   char label[256];
    char *found = 0;
    rtx def;
***************
*** 1412,1416 ****
--- 1496,1504 ----
  
        /* First switch to text section.  */
+ #ifdef SELECT_RTX_SECTION
+       SELECT_RTX_SECTION (mode, x);
+ #else
        text_section ();
+ #endif
  
        /* Align the location counter as required by EXP's data type.  */
***************
*** 1419,1423 ****
  	align = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
  
!       ASM_OUTPUT_ALIGN (asm_out_file, exact_log2 (align));
  
        /* Output the label itself.  */
--- 1507,1512 ----
  	align = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
  
!       if (align > 1)
! 	ASM_OUTPUT_ALIGN (asm_out_file, exact_log2 (align));
  
        /* Output the label itself.  */
***************
*** 1432,1438 ****
  	  switch (mode)
  	    {
  	    case DImode:
  #ifdef ASM_OUTPUT_DOUBLE_INT
! 	      ASM_OUTPUT_DOUBLE_INT (asm_out_file, u.i[0], u.i[1]);
  #else /* no ASM_OUTPUT_DOUBLE_INT */
  #ifndef WORDS_BIG_ENDIAN
--- 1521,1529 ----
  	  switch (mode)
  	    {
+ 	      /* Perhaps change the following to use
+ 		 CONST_DOUBLE_LOW and CONST_DOUBLE_HIGH, rather than u.i.  */
  	    case DImode:
  #ifdef ASM_OUTPUT_DOUBLE_INT
! 	      ASM_OUTPUT_DOUBLE_INT (asm_out_file, x);
  #else /* no ASM_OUTPUT_DOUBLE_INT */
  #ifndef WORDS_BIG_ENDIAN
***************
*** 1604,1607 ****
--- 1695,1699 ----
  	exp = TREE_OPERAND (exp, 0);
  
+ #ifndef ASM_OUTPUT_DOUBLE_INT
        if (TYPE_MODE (TREE_TYPE (exp)) == DImode)
  	{
***************
*** 1631,1634 ****
--- 1723,1727 ----
  	  break;
  	}
+ #endif /* no ASM_OUTPUT_DOUBLE_INT */
  
        x = expand_expr (exp, 0, VOIDmode, EXPAND_SUM);
***************
*** 1649,1652 ****
--- 1742,1752 ----
  	  size -= 4;
  	}
+ #ifdef ASM_OUTPUT_DOUBLE_INT
+       else if (size == 8)
+ 	{
+ 	  ASM_OUTPUT_DOUBLE_INT (asm_out_file, x);
+ 	  size -= 8;
+ 	}
+ #endif /* ASM_OUTPUT_DOUBLE_INT */
        else
  	abort ();
***************
*** 1724,1731 ****
  {
    register tree link, field = 0;
!   register int byte;
    int total_bytes = 0;
!   int byte_offset = -1;
  
    if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
        || TREE_CODE (TREE_TYPE (exp)) == UNION_TYPE)
--- 1824,1837 ----
  {
    register tree link, field = 0;
!   /* Number of bytes output or skipped so far.
!      In other words, current position within the constructor.  */
    int total_bytes = 0;
!   /* Non-zero means BYTE contains part of a byte, to be output.  */
!   int byte_buffer_in_use = 0;
!   register int byte;
  
+   if (HOST_BITS_PER_INT < BITS_PER_UNIT)
+     abort ();
+ 
    if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
        || TREE_CODE (TREE_TYPE (exp)) == UNION_TYPE)
***************
*** 1754,1776 ****
  	  /* An element that is not a bit-field.
  	     Output any buffered-up bit-fields preceding it.  */
! 	  if (byte_offset >= 0)
  	    {
  	      ASM_OUTPUT_BYTE (asm_out_file, byte);
  	      total_bytes++;
! 	      byte_offset = -1;
  	    }
  
! 	  /* Align to this element's alignment,
! 	     if it isn't aligned properly by its predecessors.  */
! 	  if (field && (total_bytes * BITS_PER_UNIT) % DECL_ALIGN (field) != 0)
! 	    {
! 	      int byte_align = DECL_ALIGN (field) / BITS_PER_UNIT;
! 	      int to_byte = (((total_bytes + byte_align - 1) / byte_align)
! 			     * byte_align);
! 	      ASM_OUTPUT_SKIP (asm_out_file, to_byte - total_bytes);
! 	      total_bytes = to_byte;
  	    }
  
! 	  /* Output the element's initial value.  */
  	  if (field)
  	    {
--- 1860,1882 ----
  	  /* An element that is not a bit-field.
  	     Output any buffered-up bit-fields preceding it.  */
! 	  if (byte_buffer_in_use)
  	    {
  	      ASM_OUTPUT_BYTE (asm_out_file, byte);
  	      total_bytes++;
! 	      byte_buffer_in_use = 0;
  	    }
  
! 	  /* Advance to offset of this element.
! 	     Note no alignment needed in an array, since that is guaranteed
! 	     if each element has the proper size.  */
! 	  if (field != 0 && DECL_OFFSET (field) / BITS_PER_UNIT != total_bytes)
! 	    {
! 	      ASM_OUTPUT_SKIP (asm_out_file,
! 			       (DECL_OFFSET (field) / BITS_PER_UNIT
! 				- total_bytes));
! 	      total_bytes = DECL_OFFSET (field) / BITS_PER_UNIT;
  	    }
  
! 	  /* Determine size this element should occupy.  */
  	  if (field)
  	    {
***************
*** 1784,1787 ****
--- 1890,1894 ----
  	    fieldsize = int_size_in_bytes (TREE_TYPE (TREE_TYPE (exp)));
  
+ 	  /* Output the element's initial value.  */
  	  output_constant (val, fieldsize);
  
***************
*** 1802,1805 ****
--- 1909,1936 ----
  		  * DECL_SIZE_UNIT (field)));
  
+ 	  /* If this field does not start in this (or, next) byte,
+ 	     skip some bytes.  */
+ 	  if (next_offset / BITS_PER_UNIT != total_bytes)
+ 	    {
+ 	      /* Output remnant of any bit field in previous bytes.  */
+ 	      if (byte_buffer_in_use)
+ 		{
+ 		  ASM_OUTPUT_BYTE (asm_out_file, byte);
+ 		  total_bytes++;
+ 		  byte_buffer_in_use = 0;
+ 		}
+ 
+ 	      /* If still not at proper byte, advance to there.  */
+ 	      if (next_offset / BITS_PER_UNIT != total_bytes)
+ 		{
+ 		  ASM_OUTPUT_SKIP (asm_out_file,
+ 				   next_offset / BITS_PER_UNIT - total_bytes);
+ 		  total_bytes = next_offset / BITS_PER_UNIT;
+ 		}
+ 	    }
+ 
+ 	  if (! byte_buffer_in_use)
+ 	    byte = 0;
+ 
  	  /* We must split the element into pieces that fall within
  	     separate bytes, and combine each byte with previous or
***************
*** 1815,1831 ****
  	      int next_byte = next_offset / BITS_PER_UNIT;
  	      int next_bit = next_offset % BITS_PER_UNIT;
! 	      if (byte_offset < 0)
  		{
! 		  byte_offset = next_byte;
  		  byte = 0;
  		}
! 	      else
! 		while (next_byte != byte_offset)
! 		  {
! 		    ASM_OUTPUT_BYTE (asm_out_file, byte);
! 		    byte_offset++;
! 		    total_bytes++;
! 		    byte = 0;
! 		  }
  	      /* Number of bits we can process at once
  		 (all part of the same byte).  */
--- 1946,1959 ----
  	      int next_byte = next_offset / BITS_PER_UNIT;
  	      int next_bit = next_offset % BITS_PER_UNIT;
! 
! 	      /* Advance from byte to byte
! 		 within this element when necessary.  */
! 	      while (next_byte != total_bytes)
  		{
! 		  ASM_OUTPUT_BYTE (asm_out_file, byte);
! 		  total_bytes++;
  		  byte = 0;
  		}
! 
  	      /* Number of bits we can process at once
  		 (all part of the same byte).  */
***************
*** 1850,1860 ****
  #endif
  	      next_offset += this_time;
  	    }
  	}
      }
!   if (byte_offset >= 0)
      {
        ASM_OUTPUT_BYTE (asm_out_file, byte);
-       byte_offset = -1;
        total_bytes++;
      }
--- 1978,1988 ----
  #endif
  	      next_offset += this_time;
+ 	      byte_buffer_in_use = 1;
  	    }
  	}
      }
!   if (byte_buffer_in_use)
      {
        ASM_OUTPUT_BYTE (asm_out_file, byte);
        total_bytes++;
      }
diff -rc2N gcc-1.35/version.c gcc-1.36/version.c
*** gcc-1.35/version.c	Wed Apr 26 14:40:23 1989
--- gcc-1.36/version.c	Sun Sep 24 08:15:42 1989
***************
*** 1,1 ****
! char *version_string = "1.35";
--- 1,1 ----
! char *version_string = "1.36";