Changes for GCC version 2.5.0 from version 2.4.5. Changes in files you can reconstruct with Bison, etags, makeinfo, and TeX have been omitted. Some of these files are updated just by building the compiler. You can update rest of these files by executing this command make TAGS info dvi -f Makefile.in in the directory of GCC sources, provided the necessary tools (etags, makeinfo, TeX and texi2dvi) are installed. Before applying these diffs, go to the directory gcc-2.4.5 and execute the following commands: mv ChangeLog ChangeLog.7 rm populate cp-dem.c g++ c++ rm objc/mutex.h objc/todo objc/xforward.c rm config/alpha/x-alpha config/rs6000/aix32.h Then use the command patch -p1 feeding it the following diffs as input. Then rename the directory to gcc-2.5.0. diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/ChangeLog gcc-2.5.0/ChangeLog *** gcc-2.4.5/ChangeLog --- gcc-2.5.0/ChangeLog Fri Oct 22 01:20:41 1993 *************** *** 0 **** --- 1,7127 ---- + Fri Oct 22 01:20:29 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * Version 2.5.0 released. + + Thu Oct 21 13:02:48 1993 Jim Wilson (wilson@sphagnum.cygnus.com) + + * mips.h (CUMULATIVE_ARGS): Double size of adjust array. + * mips.c (function_arg): Add comment about too many adjust entries. + + Thu Oct 21 13:48:14 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * rs6000.h (HARD_REGNO_MODE_OK): Multi-word objects cannot + go into MQ, LR, or CTR. + + * configure (mips-sgi-iris5*): Disable; not working yet. + * mips/iris5.h (ASM_SPEC, LINK_SPEC, CPP_PREDEFINES): Extend a bit. + + * expmed.c (expand_divmod): Create RESULT in proper mode when trying + quotient-and-remainder insn. + + Thu Oct 21 13:14:40 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * Makefile.in (STMP_FIXPROTO): Uncomment the definition. + + * varasm.c (output_constructor): Fix previous change: + if no TYPE_DOMAIN, don't set min_index. + + Thu Oct 21 11:13:21 1993 Richard Earnshaw (rwe11@cl.cam.ac.uk) + + * fixincludes: Avoid conflicting uses of __wchar_t in cc1plus and + stdlib.h for ARM/RISCiX. + + Thu Oct 21 08:16:13 1993 Doug Evans (dje@canuck.cygnus.com) + + * Makefile.in (install-common): Remove g++ dependency. + Not built for cross compilers. + + Thu Oct 21 00:04:40 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * fixincludes (required): Accept a space instead of a tab + between #define and CTRL (or _CTRL). + + * config/m68k/m68k.c (output_move_double): Use reg_overlap_mentioned_p + when checking for overlap between source and dest. + Fix syntax for the lea insn for double overlap case. + * m68k.md (movdi, movdf, movxf): Delete the & from load case. + + * config/m88k/m88k.h (ASM_FINISH_DECLARE_OBJECT): Emit .size + only if DECLARE_ASM_NAME. + + Wed Oct 20 21:32:11 1993 Jeff Law (law@snake.cs.utah.edu) + + * pa.c (output_arg_descriptor): Do not stop searching if a USE + for the static link or struct value register is found. + + Wed Oct 20 22:43:22 1993 Michael Meissner (meissner@osf.org) + + * i386/osfrose.h (ASM_FINISH_DECLARE_OBJECT): Don't emit .size + directive if using the OSF/rose object format. + + * i386/osfrose.h, i386/osfelf.h (SWITCH_TAKES_ARG): Allow use of + System V.4 -h * and -z * switches. + (LINK_SPEC): Pass -G, -h*, -z* switches through to the ELF linker. + Map -static, -symbolic, and -shared into the appropriate -B, -d, + and -G options when invoking the ELF linker. + + Wed Oct 20 20:32:54 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * cse.c (fold_rtx): Alter previous change: don't fold the shift + if the count exceeds the width of the value inside the subreg. + + * varasm.c (copy_constant): New function. + (output_constant_def): Use it. + + * Makefile.in ($(srcdir)/INSTALL): Add --no-split. + + Wed Oct 20 19:35:35 1993 John F Carr (jfc@mit.edu) + + * alpha.h (LIB_SPEC): Link -lprof1 when profiling. + + Wed Oct 20 19:21:18 1993 Jim Wilson (wilson@cygnus.com) + + * cccp.c (sys_errlist): Conditionalize declaration for BSD 4.4. + * collect2.c, g++.c, gcc.c, protoize.c: Likewise. + * collect2.c (my_strerror): Move block local extern declarations + for sys_errlist and sys_nerr to file level. + + Wed Oct 20 18:27:28 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c (output_init_element): When initializing a union, + do it right away: never put the field on the pending list. + + * patch-header.c (main): Delete output file before opening it. + Discard directory names from progname. + * patch-header.c: Simplify and fix handling of errno.h. + (It no longer thinks errno.h always needs fixing.) + * patch-header.c (write_lbrac, write_rbrac): Only write + extern "C" if that specifically is needed. + + Wed Oct 20 18:12:21 1993 Torbjorn Granlund (tege@adder.cygnus.com) + + * pa.md (cacheflush): Split into dcacheflush and icacheflush. + Rewrite to use space regs correctly. + * pa.h (TRAMPOLINE_TEMPLATE): Rewrite. + (TRAMPOLINE_SIZE): Update with new size. + (INITIALIZE_TRAMPOLINE): Rewrite. + + Wed Oct 20 17:58:32 1993 Per Bothner (bothner@kalessin.cygnus.com) + + * varasm.c (output_constructor): Add support for non-zero + lower array bound. + * expr.c (store_constructor): Likewise. + + Wed Oct 20 15:16:34 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * toplev.c (rest_of_decl_compilation): Use ASM_FINISH_DECLARE_OBJECT + unconditionally, but define it as no-op by default. + + * config/convex/convex.h (MAX_LONG_TYPE_SIZE): Defined. + + * varasm.c (size_directive_output): New variable. + * toplev.c (rest_of_decl_compilation): Use ASM_FINISH_DECLARE_OBJECT. + * config/svr4.h (ASM_DECLARE_OBJECT_NAME): Set size_directive_output. + (ASM_FINISH_DECLARE_OBJECT): Defined. + * config/i386/osfrose.h, config/m88k/m88k.h: Likewise. + + * patch-header.c (inf_size): Move decl inside main. + (strdup): Use xmalloc rathern than malloc. + Don't use the return value of strcpy. + (INF_UNGET): Take parameter; do nothing if EOF. + (strcpy): Declaration deleted. + + Wed Oct 20 11:39:56 1993 Jim Wilson (wilson@sphagnum.cygnus.com) + + * xm-mips.h (HAVE_VPRINTF): Define for BSD 4.4. + + * mips.c (mips_output_filename): When emitting stabs, don't + disable them if using gas. + (mips_output_lineno): Likewise. + + * sparc.h (INITIALIZE_TRAMPOLINE): Emit 3 flush instrutions. + * sparc.md (flush): Add pattern. + + Wed Oct 20 10:47:54 1993 Michael Meissner (meissner@osf.org) + + * configure (mips-dec-bsd, mips-dec-osf): Fix a typo in the last + change. + + Wed Oct 20 07:57:06 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * rs6000.h, aix31.h (RS6000_CROR_BIT_NUMBER): Deleted. + (RS6000_CALL_GLUE): New macro. + * rs6000.c (print_operand, case '.'): Use RS6000_CALL_GLUE + instead of RS6000_CROR_BIT_NUMBER. + (print_operand, case 'E', case 0): Use "return", not "break". + * rs6000.md (call): Don't use CROR or NOP; just use "%.". + + * c-common.c (check_format_info): Consider "char", "signed char", + and "unsigned char" types as equivalent. + + * loop.c (find_and_verify_loops): Properly continue loop after + moving a block of code near a loop exit. + + Wed Oct 20 02:01:50 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * Makefile.in (extraclean): Delete file djefoo. + (stmp-fixproto): Depend on stmp-headers, not LIBGCC2_DEPS. + + Tue Oct 19 23:11:16 1993 James Van Artsdalen (james@bigtex.cactus.org) + + * config/i386/isc.h (LONG_DOUBLE_TYPE_SIZE): Define as 64 bits + due to FP emulator bugs in the target kernel. + * config/i386/sco.h: Likewise (kernel bugs are only suspected). + + Tue Oct 19 21:21:34 PDT 1993 Ralph Campbell (ralphc@pyramid.com) + + * configure (mips-dec-bsd): New alternative. + * config/mips/dec-bsd.h: New file. + + Tue Oct 19 18:49:40 1993 Jim Wilson (wilson@sphagnum.cygnus.com) + + * c-typeck.c (digest_init): For arrays, use comptypes to compare + types instead of comparing pointers. + + Tue Oct 19 11:24:16 1993 Steve Chamberlain (sac@phydeaux.cygnus.com) + + * reload1.c (reload): Cope when inherited register is larger than + one word. + (choose_reload_regs): Ditto. + + Tue Oct 19 18:09:18 1993 David Edelsohn (edelsohn@npac.syr.edu) + + * rs6000.md (define_function_unit): Add support for RIOS2 + asymmetric integer units. + + Tue Oct 19 17:48:37 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * function.c (assign_parms): Properly set parm_reg_stack_loc for + args that are a CONCAT. + + * clipper.md (movdi): Force use of "o" alternative if + operand 1 is a MEM. + + * alpha.h (HAVE_ATEXIT): New macro. + + * reload.c (push_reload, find_reloads): If an operand is + a SUBREG of a PLUS, force a reload and reload what is inside. + + * dbxout.c (print_int_cst_octal): Fix bug in last change. + + Tue Oct 19 17:42:23 1993 Richard Earnshaw (rwe11@cl.cam.ac.uk) + + * arm.c: Include reload.h + (arm_reload_out_hi): New function. + (output_call): Don't look inside operands[0]. + * arm.h: Add function definitions for shift_instr, + output_mov_long_double_fpu_from_arm, + output_mov_long_double_arm_from_fpu, + and output_mov_long_double_arm_from_arm. + (FLOAT_WORDS_BIG_ENDIAN): Define to 1. + (SECONDARY_OUTPUT_RELOAD_CLASS): return GENERAL_REGS for HImode + outputs. + (ASM_OUTPUT_LONG_DOUBLE, ASM_OUTPUT_DOUBLE, ASM_OUTPUT_FLOAT): + output floating point constants as hex, make order correct given + definition of FLOAT_WORDS_BIG_ENDIAN. + (PRINT_OPERAND): Delete redundant code when handling CONST_DOUBLE. + * arm.md: (reload_outhi): New pattern. + (movhi): Handle reloads better. + (restorehi): Delete. Also tidy up commented out code. + (call): Make this a define_expand. + (matcher for above): only accept MEM(reg) + (call_value): Handle as for (call). + * xm-arm.h (HOST_FLOAT_WORDS_BIG_ENDIAN): Define to 1. + + Tue Oct 19 13:25:03 1993 Mike Stump (mrs@rtl.cygnus.com) + + * cp-type2.c (build_m_component_ref): Fix typo, type must be set, + after changing component. Fixes problem introduced on Thu Sep 9 + 21:22:40 1993. + + Tue Oct 19 01:09:56 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * configure (m68000-convergent-sysv*): Untangle from m68k-*-lynxos. + + * Makefile.in (stmp-fixproto): Depend on LIBGCC2_DEPS. + (crtbegin.o, crtend.o): Specify -fno-inline-functions. + + * config/mips/iris5.h: New file. + * config/mips/mips.c (mips_asm_file_start): Handle ABICALLS_ASM_OP. + * configure (mips-sgi-iris5*): New configuration. + + Mon Oct 18 16:16:26 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * cse.c (note_mem_written): (mem (scratch)) means clobber everything. + + * gen-protos.c: Include ctype.h. + + * expmed.c (extract_split_bit_field): Change shift count calculation + in little-endian case. + + * Makefile.in (stmp-fixproto): Added dependency on fixproto script. + + Mon Oct 18 11:26:08 1993 Jim Wilson (wilson@sphagnum.cygnus.com) + + * c-typeck.c (process_init_element): Align structure elements + that are subaggregates. + + * c-decl.c (finish_decl): After preserve_initializer call, set + TREE_PERMANENT bit in initializer. + + * combine.c (can_combine_p): Don't combine instructions across a + volatile insn. + * rtlanal.c (volatile_insn_p): New function. + + Sun Oct 17 03:04:49 1993 Torbjorn Granlund (tege@adder.cygnus.com) + + * configure (powerpc-ibm-aix*): Set cpu_type. + * config.sub: Recognize powerpc. + + Sun Oct 17 21:37:57 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * reload1.c (eliminate_regs_in_insn): Rerecognize some loads and + stores. + * pa.md (indexing loads and stores): Provide variants which avoid + reload problems with shift-add operations. + + * pa.h (READONLY_DATA_SECTION): Disable. + + Thu Oct 14 12:38:27 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * cse.c (fold_rtx): Special case handling for folding + a subreg of the result of a left shift. + + Thu Oct 14 00:05:42 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * alpha.h (DBX_CONTIN_LENGTH): Set to 4000. + + * expr.c (do_jump_for_compare): Don't blow up if aren't any insns + in this sequence yet. + + * alpha.h (LINK_SPEC): Now OK to pass -O3 to linker. + (ASM_OUTPUT_LOOP_ALIGN, ASM_OUTPUT_ALIGN_CODE): Work around + bug in DEC assembler. + + Wed Oct 13 21:47:58 1993 Ian Lance Taylor (ian@cygnus.com) + + * fixincludes: Remove erroneous parens from Alpha OSF/1 . + + Wed Oct 13 16:08:54 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * config/m68k/sun3.h (CPP_PREDEFINES): Don't define _CROSS_TARGET_ARCH. + + * fold-const.c (invert_truthvalue): Handle SAVE_EXPR. + + * Makefile.in (install-collect2): Depend on install-dir. + (install-info, install-float-h-cross): Likewise. + + Wed Oct 13 15:51:02 1993 Stephen L. Moshier (moshier@world.std.com)\ + + * real.h (FLOAT_WORDS_BIG_ENDIAN): New macro. + (HOST_FLOAT_WORDS_BIG_ENDIAN): Likewise, for host. + (REAL_VALUE_TO_TARGET_DOUBLE (default version)): Use them. + (efixi, efixui): Return HOST_WIDE_INT. + (REAL_VALUE_FROM_INT): Cast inputs to HOST_WIDE_INT. + * real.c (FLOAT_WORDS_BIG_ENDIAN, HOST_FLOAT_WORDS_BIG_ENDIAN): + Use everywhere in place of WORDS_BIG_ENDIAN, HOST_WORDS_BIG_ENDIAN, + except in reference to endian-ness of integers. + (etrunci, etruncui, efixi, efixui, ereal_from_int, ereal_to_int, + ltoe, ultoe, eifrac, euifrac): Change `long' to `HOST_WIDE_INT'. + + Wed Oct 13 15:47:37 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-parse.in (initdcl, notype_initdcl): Call decl_attributes + before init as well as after. + + * config/ns32k/pc532.h (FRAME_POINTER_REQUIRED): + Require a frame pointer if fn calls setjmp. + + Wed Oct 13 15:27:01 1993 Jim Wilson (wilson@cygnus.com) + + * jump.c (jump_optimize): When moving a range of instructions, + include all NOTEs before the range, not just line number notes. + + Wed Oct 13 11:01:51 1993 Per Bothner (bothner@wombat.gnu.ai.mit.edu) + + * patch-header.c: #include before . + + Wed Oct 13 11:57:33 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * rs6000.md (seq): Fix typo: had "xubfic" instead of "subfic". + + * va-m88k.h (_VA_LIST_): Define. + + * alpha.c (ignore_line_number): No longer used. + + * mips-tdump.c (print_global_hdr): Fix typo in cast in ctime call. + + * cccp.c (main): Don't catch SIGPIPE if no such signal. + + * x-alpha: File deleted, all shipped OSF systems have `ranlib'. + + * fold-const.c (optimize_bit_field_compare, decode_field_reference): + Don't do anything if get_inner_reference returned its argument. + + * bi-reverse.c: Avoid defining NULL; can cause duplicate definition + errors. + + Wed Oct 13 07:58:28 1993 Michael Meissner (meissner@osf.org) + + * i386/osfrose.h (ASM_OUTPUT_ADDR_DIFF_ELT): Define like in V.4. + (FUNCTION_PROFILER, FUNCTION_PROLOGUE): Don't load up %eax with + the pointer value before calling indirect, just call indirect the + memory address to save some cycles in profiling. + + Tue Oct 12 12:41:12 1993 Jim Wilson (wilson@sphagnum.cygnus.com) + + * cse.c (record_jump_cond): At end, make missing equivalences + first, and then merge them. + + Tue Oct 12 21:30:29 1993 Doug Evans (dje@cygnus.com) + + * va-h8300.h (__va_rounded_size): Fix typo in #ifdef. + + Tue Oct 12 20:19:22 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * bc-emit.c: Include stdio.h last. + * combine.c: Include stdio.h after gvarargs.h. + + Tue Oct 12 13:28:18 1993 Per Bothner (bothner@kalessin.cygnus.com) + + * fixproto: Re-write. We now assume that there are two + source directories (source_dir_all and source_dir_std). These + are handled differently. All files in source_dir_all (normally + ./include) are processed, but in source_dir_std (normally + /usr/include) we only process the standard ANSI/Posix ones where + we might be able to add missing prototypes. + * scan-decls.c (scan_decls): Rewrote from being a program whose + output is piped to patch-header, to a subroutine called by + patch-header. This should be somewhat more efficient. + * Makefile.in (scan-decls): Removed rule to make program. + * patch-header.c (recognized_macro, recognized_extern, + recognized_function): New functins, with logic moved out from + read_scan_file, so they can be called by scan_decls. + * patch-header (main): Read the original header file into a + buffer (rather than reading it with stdio). This should be more + efficient, partly because we can re-write it in place. + (inf_skip_spaces, inf_read_upto, inf_scan_ident): New functions, + based on skip_spaces, read_upto, and scan_ident in scan.c, but + these read from the in-memory buffer mentioned above. + * scan-types.sh: Don't check for sigset_t, since it can be a + struct, whose name cannot be simplify replaced by its definition. + * Makefile.in (deduced.h): Don't pass -nostdinc. + + Tue Oct 12 18:36:32 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) + + Changes to support native ecoff and embedded stabs debugging + for the Alpha. + + * alpha.c (output_prolog): Put out file and line number if sdb + debugging format, put out .ent directive, signal start of function for + alpha_output_filename and set up debugging auto/arg offsets. + (output_epilog): Signal end of function for alpha_output_filename. + (alpha_output_filename, alpha_output_lineno): New functions. + * alpha.h (TARGET_SWITCHES): Add gas option. + (ASM_DECLARE_FUNCTION_NAME): Moved output of .ent directive to + output_prolog. + (DBX_NO_XREFS): Removed, gdb understands cross references and the + native debugger can't handle embedded stabs. + (ASM_FILE_START): Replace output of .file directive + by ASM_OUTPUT_SOURCE_FILENAME call. + (TARGET_GAS, MASK_GAS, SDB_DEBUGGING_INFO, DBX_DEBUGGING_INFO, + MIPS_DEBUGGING_INFO, PREFERRED_DEBUGGING_TYPE, DEBUGGER_AUTO_OFFSET, + DEBUGGER_ARG_OFFSET, ASM_OUTPUT_SOURCE_LINE, + ASM_OUTPUT_SOURCE_FILENAME, DEFAULT_GDB_EXTENSIONS, ASM_STABS_OP, + ASM_STABN_OP, ASM_STABD_OP, SDB_ALLOW_FORWARD_REFERENCES, + SDB_ALLOW_UNKNOWN_REFERENCES, PUT_SDB_DEF, PUT_SDB_PLAIN_DEF, + PUT_SDB_TYPE, PUT_SDB_BLOCK_START, PUT_SDB_BLOCK_END, + PUT_SDB_FUNCTION_START, PUT_SDB_FUNCTION_END, PUT_SDB_EPILOGUE_END, + ASM_FINAL_SPEC, CODE_MASK, MIPS_IS_STAB, MIPS_MARK_STAB, + MIPS_UNMARK_STAB, SHASH_SIZE, THASH_SIZE): New macros. + * alpha-gdb.h: New file. + * configure (alpha-*-osf*): Handle --with-stabs and --with-gnu-as. + * mips-tfile.c (add_local_symbol): Index in the external symbol + must point to local symbol table entry for procedures. + + Mon Oct 11 16:14:53 1993 Ian Lance Taylor (ian@cygnus.com) + + * fixincludes: If a file is referenced with double quotes from + a fixed file, make sure it is copied into the fixed include + directory. + Remove DPS/XDPSlib.h special-case code. + + Tue Oct 12 08:05:28 1993 David Edelsohn (edelsohn@npac.syr.edu) + + * rs6000/powerpc.h: New file. + * configure (powerpc-ibm-aix*): New target. + * rs6000.h (MASK and TARGET): Add new flags for POWER2 and PowerPC + with square root. + (ASSEMBLER_DIALECT): New macro. + (CONDITIONAL_REGISTER_USAGE): Set MQ register fixed if not POWER. + (SHIFT_COUNT_TRUNCATED): Conditional on POWER. + (ASM_OUTPUT_REG_{PUSH,POP}): Mnemonics dependencies. + * rs6000.c (rs6000_override_options): Use new TARGET flags and + add some more cpu choices. + (output_prolog, output_epilog): Support new mnemonics and avoid + using lm/stm when not POWER. + * rs6000.md: Update define_function_units. + Put both old and new mnemonics in all templates. + Add target tests to pattern conditional field throughout. + (one_cmplsi2): Make POWER and PowerPC variants. + (mulsi3): Convert to define_expand which calls appropriate POWER + or PowerPC pattern. + (divsi3, udivsi3): Add patterns for PowerPC case. Update divsi3 + define_expand for PowerPC case. + (ashlsi3, lshrsi3, ashrsi3, extendqisi2, extendqihi2): Convert to + define_expand which calls appropriate POWER or PowerPC pattern. + (floating-point): Add PowerPC single-precision FP, and SF/DF sqrt + insns for 603, 604, 620. + (call insns): Use "nop" for magic TOC restore. + (move data, nop): Use PowerPC extended mnemonics. + + Tue Oct 12 07:58:36 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * alpha.h (SETUP_INCOMING_VARARGS): If not TARGET_FPREGS, + save another copy of the integer regs where the FP regs would + have gone. + + * tree.h (struct tree_type): symtab_address is now a union of + pointer and integer. + (TYPE_SYMTAB_ADDRESS): Refer to the integer. + (TYPE_SYMTAB_POINTER): New macro to refer to pointer. + * sdbout.c (KNOWN_TYPE_TAG, SET_KNOWN_TYPE_TAG): Refer to + TYPE_SYMTAB_POINTER and remove casts. + (tag_of_ru_type): Likewise. + + * reload1.c (reload): Fix typo in RELOAD_FOR_INSN case when + accounting for reloads. + + * expr.c (convert_modes): Reset OLDMODE from X after we strip + a SUBREG due to a promoted variable. + + * dbxout.c (dbxout_type, case INTEGER_TYPE): Output bounds in + octal if type wider than HOST_WIDE_INT. + (print_int_cst_octal): Trim bound by precision of its type. + Avoid warning on what may be shift into sign bit. + + * bi-reverse.c: Add missing #include for hconfig.h. + + * fixincludes: Quote braces when looking for DONE files. + + * final.c (dialect_number): New variable. + (init_final): Initialize it. + (output_asm_insn, asm_fprintf): Support ASSEMBLER_DIALECT. + + Tue Oct 12 01:34:16 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c (digest_init): If traditional, allow unbraced scalar + to initialize the first element of an aggregate. + + * cccp.c (output_line_command): Output the `4' flag only if cplusplus. + (do_line): Handle the `4' flag. + + * final.c (final_scan_insn): Call walk_alter_subreg for operands + that are PLUS or MULT, before constrain_operands. + + Mon Oct 11 15:18:45 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * real.c (debug_real): New function. + + * regclass.c (reg_scan_mark_refs): XEXP (x, 0) in EXPR_LIST may be 0. + + * config/m68k/m68k.md (cmphi): Turn on constraints to support cmpm.w. + + Mon Oct 11 13:20:54 1993 Jim Wilson (wilson@sphagnum.cygnus.com) + + * unroll.c (unroll_loop): Set map->const_equiv_map_size to + new_maxregnum. + (copy_loop_body): When set const_age_map entry for split dest reg, + verify that it is within the bounds of the map. + (find_splittable_regs): Count number of biv sets, not number of + bivs. Don't pass result to find_splittable_givs. + (find_splittable_givs): Delete parameter result. Add local + variable result. + + Mon Oct 11 07:43:31 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * expr.c (expand_assignment): When assigning an INDIRECT_REF to + a RESULT_DECL, the size and source rtx were swapped. + + * function.c (trampoline_address): Don't allocate anything + from parent function's current obstack. + + * regclass.c (reg_scan): Don't call reg_scan_mark_refs on notes + if there aren't any. + (reg_scan_mark_refs, case INSN_LIST, EXPR_LIST): New cases. + + * cse.c (simplify_binary_operation): Test value of + SHIFT_COUNT_TRUNCATED if it is defined. + * combine.c (subst, shift and rotate cases): Likewise. + * a29k.h, alpha.h, fx80.h, i960.h, mips.h, pa.h, pyr.h, rs6000.h: + Define SHIFT_COUNT_TRUNCATED to have a value of 1. + * sparc.h, tahoe.h, we32k.h: Likewise. + + Mon Oct 11 02:40:22 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * regclass.c (regno_last_note_uid): New vector. + (reg_scan): Initialize regno_last_note_uid. + Call reg_scan_mark_refs for the notes. Pass its new arg. + (reg_scan_mark_refs): New arg NOTE_FLAG. Pass it recursively. + Set regno_last_note_uid. + * regs.h (regno_last_note_uid): Declared. + * jump.c (jump_optimize): Use regno_last_note_uid when deciding + whether a register is set and never used. + + Sun Oct 10 22:51:01 1993 Stephen Moshier (moshier@world.std.com) + + * real.c (asctoeg): Fix backward condition in last change. + + Sun Oct 10 22:33:17 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * configure (hppa1.0-*-mach*): Use collect2. + (hppa1.1-*-mach*): Likewise. + + * pa.c (legitimize_pic_address): Delete unused variables. + (output_block_move, output_ior): Likewise. + (hppa_builtin_saveregs): Likewise. + (emit_move_sequence): Add parens as suggested by -Wall. + (compute_frame_size): Likewise. + (output_ascii): Return type is "void". + (hppa_expand_prologue, import_milli): Likewise. + + * pa.c (output_function_prologue): Pass the highest register + number saved for ENTRY_GR and ENTRY_FR directives rather + than the number of registers saved. + (hppa_expand_prologue): Account for %r4 when it's being + used as a frame pointer. + + Sun Oct 10 18:42:49 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c (start_init): Don't set require_constant_elements + for scalar types. + + * c-parse.in (stmt): Don't call default_conversion on top-level + expressions. + + * c-typeck.c (convert_for_assignment): Allow silent conversion to + a pointer from an integer 0 that resulted from arithmetic. + + * varasm.c, c-pragma.c (enum pragma_state): Defined. + + * config/i386/i386.c (restore_386_machine_status) + (save_386_machine_status): New functions. + (clear_386_stack_locals): Store those functions in + save_machine_status, restore_machine_status. + (struct machine_function): New structure definition. + + * function.h (struct function): New field `machine'. + * function.c (save_machine_status, restore_machine_status): New vars. + (push_function_context, pop_function_context): Use them. + + * explow.c (emit_stack_save): Cast enum array index to int. + + Sun Oct 10 12:49:39 1993 Richard Earnshaw (rwe11@cl.cam.ac.uk) + + * arm.c (const_ok_for_arm): Cast constants to unsigned HOST_WIDE_INT. + (output_prologue): Sanity check the finite state machine. + (output_epilogue): Delete unused variable. + (final_prescan_insn): Always clear arm_target_insn when FSM goes to + state 0. + * arm.h (OPTIMIZATION_OPTIONS): Don't set flag_omit_frame_pointer, + since this inhibits debugging. + (ASM_OUTPUT_INTERNAL_LABEL): Always clear arm_target_insn when FSM + goes to state 0. + + Sun Oct 10 08:56:58 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * alpha.h (ALPHA_COSTS): Add missing arg to call to rtx_cost. + + * combine.c (force_to_mode, case ASHIFTRT): Verify that result of + making a LSHIFTRT remains a shift. + + * tree.c (save_tree_status): Function_maybepermanent_obstack is the + function_obstack of parent function. + (restore_tree_status): Only free objects later than + maybepermanent_firstobj in function_maybepermanent_obstack. + (make_node): Fix logic error in PARM_DECL code. + Put PARM_DECL in parent function's saveable obstack. + * function.c (put_reg_into_stack): Allocate fixup structure in + saveable obstack. + + * expr.c (expand_assignment): Don't short circuit store_expr + when TO is a VAR_DECL since it needs special handling if promoted. + + * combine.c (subst, case SUREG): Only call force_to_mode if both + inner and outer modes are MODE_INT. + + * mips-tfile.c (WORD_ALIGN): Fix typo in last change. + + * c-common.c (check_format_info): Support X/Open formats like "%1$d". + + Sat Oct 9 22:29:17 1993 Per Bothner (bothner@wombat.gnu.ai.mit.edu) + + * configure: If no target is specified, try getting one + with config.guess. + * config.guess: New file. + + Sat Oct 9 19:50:24 1993 Pat Rankin (rankin@eql.caltech.edu) + + * c-common.c (check_format_info): Avoid ?: conditional for function + to be called. + + * config/vax/xm-vms.h [VAXC] (bc_check_for_full_enumeration_handling) + (current_function_has_nonlocal_goto) + (output_deferred_addressed_constants): New macros to shorten + external names exceeding 31 characters. + + * make-cc1.com: Move alloca handling before bytecode construction + so that VAX C won't need two different values for LIBS. Eliminate a + comment about make-like functionality that referred to a capability + which has not been implemented. + + Sat Oct 9 21:53:53 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * fixincludes: Unquote a quoted `t' in a #define _IO line, for AIX + 3.2 sys/stropts.h #define _IO(t,v). + (sys/spinlock.h): Don't copy it if it doesn't exist. + (DPS/XDPSlib.h): Change "XDPS.h" to , for AIX. + + Sat Oct 9 15:00:00 1993 DJ Delorie (dj@ctron.com) + + * configure.bat: Change $(srcdir)/ to $(srcdir)\ in commands. + + Sat Oct 9 15:17:22 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * expr.c (expand_expr, case ABS_EXPR): Don't copy twice into + volatile MEM. + + * expr.c (expand_expr): Never reset ORIGINAL_TARGET. + Pass ORIGINAL_TARGET to lang_expand_expr, not TARGET. + + Sat Oct 9 13:27:10 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * tree.c (pop_momentary_nofree): New function. + * c-parse.in (initdcl, notype_initdcl, init): Undo previous change. + (init): Use pop_momentary_nofree if the initializer has real data. + + Sat Oct 9 12:55:26 1993 Stephen Moshier (moshier@world.std.com) + + * real.c (asctoeg): Allocate local buffer dynamically. Count + any lost significant digits before the decimal point. + + Fri Oct 8 16:33:42 1993 Mike Stump (mrs@rtl.cygnus.com) + + * cp-tree.h (OFFSET_REF): Override OFFSET_REFs from the back-end, as + we need to do something more complex with them. + * cp-tree.def (CP_OFFSET_REF): Very similar to OFFSET_REFs, but + allow the front-end to handle them. + + Fri Oct 8 14:40:29 1993 Jason Merrill (jason@deneb.cygnus.com) + + * cp-error.c (dump_expr, REAL_CST): Support printing of real values + when REAL_IS_NOT_DOUBLE (prints out rep in hex). + + Fri Oct 8 13:54:03 1993 Mike Stump (mrs@cygnus.com) + + * cp-type2.c (store_init_value): Move pointer to member function + initilization code to... + * cp-type2.c (digest_init): here. Allows nested pointer to member + functions to work. + * cp-decl.c (build_ptrmemfunc_type): Use a real union instead of a + magic union, as the initialization code doesn't like them. + * cp-tree.h (TYPE_PTRMEMFUNC_FN_TYPE): Changed to go though the + union. + * cp-tree.h (DELTA2_FROM_PTRMEMFUNC, PFN_FROM_PTRMEMFUNC): Accessor + macros to go thought union. Allows us to change pointer to member + functions a little easier. + * cp-typeck.c (get_member_function_from_ptrfunc, + build_binary_op_nodefault): Changed to use new accessor macros. + * cp-typeck.c (build_ptrmemfunc): Use new union instead. Also, make + sure TREE_CONSTANT is set for CONSTANT things. + * cp-decl.c (pfn_or_delta2_identifier): Added to cache + get_identifier calls. + * cp-tree.h (pfn_or_delta2_identifier): Declare it. + * cp-decl.c (init_decl_processing): Setup pfn_or_delta2_identifier. + + Fri Oct 8 19:03:09 1993 Jim Wilson (wilson@sphagnum.cygnus.com) + + * xcoffout.h (DBX_STATIC_BLOCK_START): For N_LCSYM, force change + to text section to avoid assembler bug. + + * mips.md (movsi_unaligned): Change in comment "loads" to "stores". + + * calls.c (emit_library_call_value): Compute struct_value_size, + and pass it to emit_call_1. + + Fri Oct 8 16:13:17 1993 H.J. Lu (hlu@nynexst.com) + + * config/i386/linux.h (STARTFILE_SPEC): Handle -p and -pg + outermost. Also add support for cross-linking. + + Fri Oct 8 15:20:58 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * Makefile.in (cp-error.o, cp-errfn.o): Add dependency rules. + + Fri Oct 8 08:00:51 1993 Eric Youngdale (eric@kafka) + + * linux.h: Only include i386/gstabs.h if LINUX_ELF is not defined. + + * linuxelf.h: Copy a lot of stuff from the SVr4 configuration: + include "i386/i386.h", "i386/att.h" and "svr4.h". + (MD_EXEC_PREFIX, MD_STARTFILE_PREFIX): Undefine. + (ASM_FILE_START, RETURN_IN_MEMORY, ASM_OUTPUT_ADDR_DIFF_ELT) + (JUMP_TABLES_IN_TEXT_SECTION, DBX_REGISTER_NUMBER): Copy from sysv4.h. + (TARGET_VERSION): Define to print "i386 Linux/ELF". + (LINUX_ELF): Define, before we include "i386/linux.h" + (YES_UNDERSCORE): Undefine. + + Fri Oct 8 13:40:44 1993 Michael Meissner (meissner@osf.org) + + * i386/osfrose.h, i386/osfelf.h (CPP_SPEC): If buliding for shared + libraries, define __SHARED__. + + * i386/osfrose.h (FUNCTION_PROFILER): If half-pic, call mcount in a + half-pic fashion. + (FUNCTION_PROLOGUE): If half-pic call through _mcount_ptr in a + half-pic fashion. + + * halfpic.c (half_pic_external): New function to declare a halfpic + identifier as always external. + + * halfpic.h (half_pic_external): declare function. + (HALF_PIC_EXTERNAL): Declare accessor macro. + + Fri Oct 8 15:03:56 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + Cygnus<->FSF C++ front-end merge. + Thu Oct 7 11:45:32 1993 Jason Merrill (jason@deneb.cygnus.com) + + * Makefile.in (CPLUS_OBJS): Change error.o to cp-errfn.o + + * cp-*.c, cp-parse.y: Rename lang_error and its kin to cp_error + and the like to accomodate rms's belief structure. + + * error.c: Moved to cp-errfn.c to accomodate rms's belief structure + + Wed Oct 6 15:05:49 1993 Jason Merrill (jason@deneb.cygnus.com) + + * cp-pt.c (mangle_class_name_for_template): Always use type_as_string + for printing out type parameters. Nuke id and type variables. + + * cp-error.c (dump_expr, INTEGER_CST): Support printing of character + literals and large integers + (dump_char): New function + (dump_type): Deal with ** and *& more prettily + + * cp-pt.c (mangle_class_name_for_template): Strip out code for + printing template parameters, replace with call to expr_as_string. + + * cp-method.c (build_overload_value): descend through + TREE_OPERAND on NOP_EXPRs as well as NON_LVALUE_EXPRs. + + * cp-decl.c (poplevel_class): Add assertion that + class_binding_level is not NULL. + + Tue Oct 5 11:11:25 1993 Jason Merrill (jason@deneb.cygnus.com) + + Patches to support proper handling of system includes without munging: + + * cp-lex.h: Declare in_c_header, a flag meaning 'implicitly wrap this + file in extern "C" { }'. + + * cp-lex.c: Define in_c_header. + (check_newline): If in_c_header when changing files, + pop_lang_context(). + (check_newline): If "4" seen on #line line, push_lang_context(C). + + * cccp.c: Add a new field c_system_include_path to struct + file_name_list which indicates that the directory contains C-language + system includes. + (*various*): Set this flag correctly + (is_system_include): Return 2 if C-language system include. + (output_line_command): Output " 4" after " 3" for C-language system + include. + + * cp-tree.h (SET_CLASSTYPE_INTERFACE_UNKNOWN_X): Coerce X to boolean + value + + Mon Oct 4 17:03:48 1993 Jason Merrill (jason@deneb.cygnus.com) + + * cp-tree.h: Add declaration for flag_external_templates + + * cp-decl.c (start_decl): Don't declare flag_external_templates + + * cp-pt.c: Ditto + + * cp-parse.y (template_instantiate_once): Ditto + + * cp-lex.c (reinit_parse_for_method): Ditto + (cons_up_default_function): Ditto + (extract_interface_info): Don't set interface_unknown + if (processing_template_defn && !flag_external_templates) + + * cp-error.c (dump_type): Deal properly with pointers to member + functions. + + * cp-pt.c (instantiate_class_template): If !flag_external_templates, + increment interface_unknown so that nested classes will be dealt with + properly. + (end_template_instantiation): If !flag_external_templates, + decrement interface_unknown. + + * cp-lex.c (cons_up_default_function): Remove redundant check + for processing_template_defn && !flag_external_templates + (reinit_parse_for_method): Ditto + + * cp-parse.y (template_instantiate_once): Don't mess with + interface_unknown + + Mon Oct 4 15:47:34 1993 Mike Stump (mrs@cygnus.com) + + * cp-decl.c (duplicate_decls): Move setting of TREE_CHAIN after + all possible return 0;s as we only want to do this when we know + that we are dealing with a duplicate. + + * cp-decl.c (start_function): Remove my_friendly_abort 19. Allows + one to declare a built-in as extern inline. + + Mon Oct 4 12:47:33 1993 John F Carr (jfc@mit.edu) + + * cp-lex.c (consume_string): Change variable `c' to int so return + value of getch can be assigned to it safely. Compare return value + of getch to EOF, not -1. + + Mon Oct 4 11:42:46 1993 Jason Merrill (jason@deneb.cygnus.com) + + * toplev.c (error and its kin): Use #defines for the argument + lists for ease of adding arguments, and of moving to vfprintf when + dje adds it. + + * error.c (lang_thing and its children): Do the same thing. + + * cp-typeck.c (build_binary_op): Do away with the kludge, now that + error accepts more arguments. + + Sun Oct 3 16:34:39 1993 Jason Merrill (jason@deneb.cygnus.com) + + * cp-error.c: Remove all traces of in_parmlist + + Sun Oct 3 13:54:57 1993 Mike Stump (mrs@cygnus.com) + + * cp-call.c (convert_harshness_ansi, convert_harshness_old): Handle + pointer to function members properly. + + Fri Oct 1 16:42:30 1993 Mike Stump (mrs@cygnus.com) + + * cp-error.c (dump_function_decl, dump_function_name): Make static + to match prototype. + + Fri Oct 1 15:23:31 1993 Mike Stump (mrs@cygnus.com) + + * cp-typeck.c (build_ptrmemfunc): Move some code into the virtual + conditional part. Fixes problem with core core dumping when the + class that we want to build a pointer to member function for doesn't + have any virtual functions. + + Thu Sep 30 18:15:29 1993 Jason Merrill (jason@deneb.cygnus.com) + + * cp-parse.y (id_scope): Print the name of the invalid scope. + (unary_expr): Add .scope new typespec '(' typespec ')' expansion + which just gives an error. + + * cp-typeck.c (build_binary_op): Print more helpful message for + a missing member operator (print the desired type involved). + Very kludgey due to error()'s two-arg limit. + + * error.c (lang_thing): Abort if more than NARGS (currently 2) are + passed, since this is likely to cause a seg fault elsewhere anyway. + + Thu Sep 30 14:19:28 1993 Jason Merrill (jason@deneb.cygnus.com) + + * g++int.texi: Add error reporting section, make `makeinfo'able + + * cp-type2.c (my_friendly_abort): Deal with recursive calls + + Thu Sep 30 12:24:33 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl2.c (grok_array_decl): Don't pedwarn on reversing the array + and its index in `a[b]'. + + * cp-typeck.c (build_conditional_expr): Make pointer type mismatch + in a conditional expression get a pedwarn. + (build_binary_op_nodefault): Make comparison between different + pointer types lacking a cast get a pedwarn. + (build_modify_expr): Don't strip the NOP_EXPRs, since we're using + the rhs in a non-lvalue context. + (convert_for_assignment): Allow conversion of 0 to a pointer, but + not a 0 that results from casting or folding. + + Thu Sep 30 11:24:59 1993 Jason Merrill (jason@deneb.cygnus.com) + + * cp-typeck.c (build_modify_expr): For memberwise assignment, + put nop_expr (reference_type (lhstype)) at the end of of the list so + that the expression has the correct type. + + * error.c (lang_thing): Don't rely on STDC array initialization + + Tue Sep 28 18:20:05 1993 Mike Stump (mrs@cygnus.com) + + * cp-init.c (build_virtual_init): Use get_binfo and + convert_pointer_to_real, to find the right basetype to convert to, + instead of trying to use convert_pointer_to, as convert_pointer_to + doesn't handle complex MI situations. Cures a bogus "cannot + convert a pointer of type `B' to a pointer of type `A'" when the + compiler is initializing virtual table pointers. + + Mon Sep 27 14:54:42 1993 Mike Stump (mrs@cygnus.com) + + * cp-call.c (build_method_call): Use get_binfo and + convert_pointer_to_real, to find the right basetype to convert to, + instead of trying to use convert_pointer_to, as convert_pointer_to + doesn't handle complex MI situations. Cures a bogus "cannot + convert a pointer of type `B' to a pointer of type `A'" when the + compiler is setting up the `this' pointer. + * cp-cvt.c (convert_pointer_to): Just call convert_pointer_to_real + to implement functionality. + * cp-cvt.c (convert_pointer_to_real): New routine. Uses new + functionality in get_base_distance to figure out which exact + parent we want to convert to. + * cp-search.c (get_base_distance_recursive, get_base_distance): + Modify to support searching for a specific PARENT given as a binfo + from our hierarchy. + * cp-typee.h (convert_pointer_to_real): Declare new routine. + + Mon Sep 27 13:02:51 1993 Jason Merrill (jason@deneb.cygnus.com) + + * cp-type2.c (my_friendly_abort): Undo previous change + + * cp-*.c: Use lang_error instead of error_with_decl, + error_with_aggr_type, etc. Not complete; I only changed the easy + cases and a few of the more obscure ones. Please convert calls + over when you're working on an appropriate section. + + * cp-method.c: Strip out error reporting code + + * Makefile.in (CPLUS_OBJS): Add error.o and cp-error.o + + * cp-error.c: New file, contains call-back functions for C++. + The actual output code is an extensively overhauled version of the + code from cp-method.c. + Don't call my_friendly_* to avoid undesirable recursion. + + * error.c: New file, provides call-back mechanism for language- + dependent error reporting. + + Fri Sep 24 13:52:27 1993 Jason Merrill (jason@deneb.cygnus.com) + + * cp-type2.c (my_friendly_abort): Don't die quietly if + errorcount or sorrycount are positive, die loudly. + + Fri Oct 8 13:58:13 1993 Doug Evans (dje@cygnus.com) + + * loop.c (scan_loop): When skipping consecutive insns, + don't count notes. + + Fri Oct 8 10:41:07 1993 Chip Salzenberg (chip@fin.uucp) + + * c-common.c (check_function_format): Correct error in last + change. + + Fri Oct 8 08:10:03 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-parse.in (initdcl, notype_initdcl): Call push_momentary and + pop_momentary here. + (init): Not here. + + Fri Oct 8 06:35:07 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * dbxout.c (dbxout_type, case INTEGER_TYPE): Correctly check + for type smaller than `integer'. + + * expr.c (expand_expr, case MAX_EXPR): Don't use TARGET directly + if it is a volatile MEM. + + * i386/t-aix, i386/t-isc, i386/t-osfrose, i386/t-sco, mips/t-osfrose: + Remove LIMITS_H; hasn't been used for a while. + + * configure: Add EXTRA_PASSES like we add EXTRA_HEADERS. + Correct EXTRA_HEADERS handling to accept multiple names. + (mips-*-*): Set extra_passes to mips-tfile and mips-tdump when + we use t-mips, t-bsd, t-svr[34], and t-ultrix. + * Makefile.in (mips-tfile, mips-tfile.o, mips-tdump, mips-tdump.o): + New rules. + * mips-tfile.c: Don't define memory functions on Alpha. + (Ptrdiff_t): Always `long'. + (WORD_ALIGN): Make portable. + * mips/t-bsd, t-mips, t-svr3, t-svr4, t-ultrix: Remove + definition of EXTRA_PASSES and remove rules for mips-* files. + + * dbxout.c (dbxout_parms): Don't confuse a parameter at an + offset of zero from AP or FP with one that has variable size. + + * calls.c (emit_library_call): Fix typo in last change; should + use Pmode instead of SImode. + + Fri Oct 8 00:34:39 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-decl.c (finish_decl): Error if block-scope static var + has incomplete type. + + * expr.c (expand_expr, case VAR_DECL): If decl wasn't laid out, + lay it out now, and fix the rtl's mode. + + Thu Oct 7 12:30:10 1993 Chip Salzenberg (chip@fin.uucp) + + * c-decl.c (complete_array_type): Correctly set MAXINDEX to + one less than array size. + + Thu Oct 7 20:44:41 1993 Torbjorn Granlund (tege@adder.cygnus.com) + + * c-typeck.c (build_binary_op): For *_DIV_EXPR, set shorten based + on orig_op0. + + Thu Oct 7 18:19:17 1993 Jim Wilson (wilson@cygnus.com) + + * xm-mips.h (HAVE_VPRINTF): Correct typo, is VPRINTF not VFPRINTF. + + * Makefile.in (LIB2FUNCS): Add _fixtfdi, _fixunstfdi, _floatditf. + + Thu Oct 7 14:58:02 1993 Michael Meissner (meissner@osf.org) + + * configure (i386-osf): ELF on OSF/1 does not need collect2. + + Thu Oct 7 17:38:25 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * cccp.c (main): New option -lang-c-c++-comments. + + Thu Oct 7 16:40:38 1993 Michael Meissner (meissner@osf.org) + + * config/i386/osfrose.h (OSF_PROFILE_BEFORE_PROLOGUE): New macro + to determine whether profiling goes before the function prologue + or after. New style profiling goes before in order to save + getting and saving the function's callers address or have mcount + 'know' there is a frame pointer. Old style profiling using mcount + and some ELF PIC profiling goes after the prologue. + (FUNCTION_PROLOGUE): Redefine in order to get new style profiling + before the function prologue if desired. + (FUNCTION_PROFILER): Do not put a profile call if it already has + been put out in the prologue. Change new style profiling to call + through _mcount_ptr instead of _real_mcount. Propigate ROSE brain + damage regarding mcount being in the users name space to ELF. + (SUBTARGET_SWITCHES): Make -mmcount default again instead of + -mno-mmcount. + + * i386.h (FINALIZE_PIC): Add macro to set the variable + current_function_uses_pic_offset_table if either -p or -a switches + are used. + + Thu Oct 7 17:07:57 1993 Ian Lance Taylor (ian@cygnus.com) + + * rtl.c (byte_mode, word_mode): Move to emit-rtl.c. + (init_rtl): Move initialization of byte_mode and word_mode to + init_emit_once. + * emit_rtl.c (byte_mode, word_mode): Moved from rtl.c. + (init_emit_once): Moved in initialization of bytes_mode and + word_mode from init_rtl. + + Thu Oct 7 11:11:25 1993 Jason Merrill (jason@deneb.cygnus.com) + + * cccp.c (struct file_name_list): Add new field c_system_include_path. + (*various*): Set this flag correctly + (is_system_include): Return 2 if C-language system include. + (output_line_command): Output " 4" after " 3" for C-language system + include. + + Thu Oct 7 14:45:20 1993 Doug Evans (dje@canuck.cygnus.com) + + * Makefile.in (install-dir): Fix typo. + (install-common): Remove obsolete comment. + (install-common): Install native g++ only if not cross. + + Thu Oct 7 11:27:45 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * calls.c (emit_library_call, emit_library_call_value): + Allocate a temp slot if arg must be passed by reference. + + * gcc.c (read_specs): Fix call to bzero. + + Thu Oct 7 08:53:57 1993 Torbjorn Granlund (tege@adder.cygnus.com) + + * alpha.md: Clean up usage of commutative declarator `%'. + + Thu Oct 7 08:14:46 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * i860/xm-fx2800.h (HAVE_VPRINTF): Fix typo; was HAVE_VFPRINTF. + + * xm-alpha.h: Always declare malloc, realloc, etc, to be void *. + + * combine.c (force_to_mode): Sign-extend constant being truncated. + + Wed Oct 6 18:53:43 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * bi-lexer.c (xmalloc, xrealloc): Cast the result of malloc, realloc. + + Wed Oct 6 15:30:39 1993 Michael Meissner (meissner@osf.org) + + * i386/osfrose.h (FUNCTION_PROFILER): Define to pass the function + address, its caller, and the unique label address through the + _real_mcount pointer, unless -mmcount is used, in which case use + the old calling sequence. + (SUBTARGET_SWITCHES): Add -mmcount, -mno-mcount support. + + Wed Oct 6 15:29:40 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * pa.c (output_function_prologue): Pass on information about the + number of callee saved general and floating point registers which + are saved by the current function's prologue. + (hppa_expand_prologue): Keep track of the number of callee + register saves done for general and floating point registers. + + Wed Oct 6 13:50:03 1993 Ian Lance Taylor (ian@cygnus.com) + + * cexp.y (MAX_CHAR_TYPE_SIZE, MAX_INT_TYPE_SIZE, + MAX_LONG_TYPE_SIZE, MAX_WCHAR_TYPE_SIZE): Define. + (yylex): Use them instead of the non-MAX versions, to avoid + dependencies on target_flags. + + Wed Oct 6 13:47:13 1993 Jim Wilson (wilson@mole.gnu.ai.mit.edu) + + * combine.c (try_combine): New variable i3_subst_into_i2. + Set it for special case of substituting i3 into i2. Use it near + end to detect when special case succeeded. Move i2notes to + i3notes for this special case. + (distribute_notes, REG_UNUSED case): Ignore all REG_UNUSED notes + except those from I3. + + Wed Oct 6 13:14:13 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c (build_c_cast): When making a CONSTRUCTOR, provide + the dummy first operand. + + * real.c (real_value_truncate): Correct etrunci argument + in case SImode. + + Wed Oct 6 06:55:05 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * final.c (asm_fprintf): Add cases for 'w' and 'l'. + + * Makefile.in (bi-opcode.o): Includes hconfig.h. + * bi-lexer.c: Remove declarations of malloc and realloc. + * bi-opcode.c: Include hconfig.h. + * bi-parser.y: Remove declaration of malloc. + + * regclass.c (record_reg_classes): Check if operands are the same + by seeing if they are the same register. + + * cse.c (record_jump_cond): Rehash OP1 if OP0's insert_regs returns + nonzero. + + * calls.c (expand_call): Add yet another assignment to MEM_IN_STRUCT_P. + + Wed Oct 6 00:08:28 1993 Jim Wilson (wilson@mole.gnu.ai.mit.edu) + + * sparc.c (uns_small_int, uns_arith_operand): New functions. + * sparc.md (umulsidi3): Use uns_arith_operand not arith_operand. + (const_umulsidi3): Use uns_small_int not small_int. + + * sparc.h (SELECT_CC_MODE): Add support for ASHIFT. + * sparc.md (ashlsi3+1, ashlsi3+2): New patterns to replace shift + and compare with addcc. + + Tue Oct 5 16:25:32 1993 Jim Wilson (wilson@cygnus.com) + + * sched.c (sched_analyze_2): Make volatile asms depend on all + pseudo registers. + + * mips.c (mips_expand_prologue): Handle structure return values as + the first argument if necessary. + + * mips.h (CLASS_MAX_NREGS): For DFmode and !TARGET_FLOAT64 case, + return 2 not 4. + (CLASS_UNITS): Take size parameter instead of num (words). + + * c-typeck.c (output_init_element): When try to copy FIELD if it + is an interger constant, first check to make sure it is nonzero. + + * reorg.c (fill_simple_delay_slots): When take insn from a + following unconditional branch target, if new_label is zero, must + set it to the result of find_end_label (). + + * iris3.h (INITIALIZE_TRAMPOLINE, TRANSFER_FROM_TRAMPOLINE): + Delete. + * mips.h (INITIALIZE_TRAMPOLINE): Delete #ifndef/#endif. Change + function name from __enable_execute_stack to __gcc_flush_cache. + (TRANSFER_FROM_TRAMPOLINE): Likewise. Delete code calling + mprotect. Uncomment code calling cacheflush. + + Tue Oct 5 16:11:53 1993 Jason Merrill (jason@deneb.cygnus.com) + + * toplev.c (error and its kin): Use #defines for the argument + lists for ease of adding arguments and add one arg. + + Tue Oct 5 16:05:11 1993 Tor Egge (tegge@pvv.unit.no) + + * cccp.c (rescan): Don't expand an identifier after a '#'. + + Tue Oct 5 15:15:52 1993 Chip Salzenberg (chip@fin.uucp) + + Move format warning code to c-common.c for use with C++. + * c-tree.h (init_function_format_info, record_function_format, + check_function_format): Declare. + * c-common.c: Include ; avoid home-grown ISDIGIT. + (decl_attributes): Call record_function_format with DECL_NAME + and also DECL_ASSEMBLER_NAME. + (struct format_char_info): Moved here from c-typeck.c. + (print_char_table): Likewise; renamed from print_table. + (scan_char_table): Likewise; renamed from scan_table. + (struct function_format_info): Likewise; add assembler_name. + (function_format_list): Make list, not array. + (init_function_format_info): Likewise; renamed from + init_format_info_table. + (record_function_format): Likewise; renamed from + record_format_info; record assembler_name. + (check_format_info): Likewise; renamed from check_format. + (check_function_format): New interface that does not require + knowledge of struct function_format_info. + * c-decl.c (init_decl_processing): Call init_function_format_info. + * c-typeck.c (struct format_char_info, print_table, scan_table, + struct function_info, function_info_entries, function_info_table, + record_format_info, init_format_info_table, check_format): Moved + to c-common.c. + (build_function_call): Call check_function_format. + + Tue Oct 5 14:08:18 1993 Wolfgang Stukenbrock (wgstuken@informatik.uni-erlangen.de) + + * gcc.c (choose_temp_base): Correct size allocated for temp_filename. + + Tue Oct 5 06:34:34 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * tree.c (contains_placeholder_p): Return 0 for CONSTRUCTOR. + (substitute_in_expr): Don't allow CONSTRUCTOR. + + * tree.c (make_node, case 'd'): Refine in which obstack + PARM_DECLs are allocated. + + * calls.c (expand_call): Properly test if we need to promote + operand; use convert_modes instead of convert_to_mode. + * expr.c (convert_modes): Properly handle extending constants + since we might be changing signedness. + + * gcc.c (read_specs): Make a null entry at end of `compilers' + when reading new entry from file. + + * tree.c (contains_placeholder): Return 0 for WITH_RECORD_EXPR. + + * bi-arity.c, bi-lexer.c, bi-opname.c, bi-parser.y: Include hconfig.h. + * Makefile.in (bi-arity.o, bi-lexer.o, bi-opname.o, bi-parser.o): + Likewise. + + * bc-emit.c (dconst[012], dconstm1): Remove redundant definition. + + Tue Oct 5 06:24:43 1993 Lisa Repka (lisa@MicroUnity.com) + + * varasm.c (decode_rtx_const, case CONST_DOUBLE): Only use mode + of X if it is not VOIDmode. + + Tue Oct 5 00:45:30 1993 James Van Artsdalen (james@bigtex.cactus.org) + + * i386/i386.c (output_to_reg): Handle XFmode write to MEM by + reading back value after write if source doesn't die. + * i386/i386.md (pushxf,movxf,extenddfxf2,extendsfxf2): Likewise. + + * i386/i386.md (movxf,extenddfxf2,extendsfxf2): Don't emit fld + before calling output_to_reg: output_to_reg does that now. + + * i386/i386.h (FIXED_REGISTERS): Don't fix hard reg st7 if XFmode + is enabled. + + * reg-stack.c (move_for_stack_reg): If the 387 regstack is not + full when doing an XFmode write from 387 to MEM, copy the source + reg and write the copy. + + Mon Oct 4 18:40:51 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * regclass.c (record_reg_classes): There is no alt_cost + for a pair of matching args if they are the same pseudo reg. + + * varasm.c (bc_output_ascii): New function. + (assemble_string): Use it. + (assemble_static_space, assemble_variable): Put braces around uses + of BC_OUTPUT_COMMON and BC_OUTPUT_LOCAL. + + Mon Oct 4 18:03:04 1993 Stephen L Moshier (moshier@world.std.com) + + * expr.c (bc_init_mode_to_opcode_maps, bc_expand_expr): Cast enum + array indices to int. + (bc_load_memory, bc_store_memory): Likewise. + (bc_runtime_type_code): Cast enum logical operand to int. + * bc-emit.c (bc_emit_bytecode): Cast enum array indices to int. + * bc-optab.c (deduce_conversion, emit_typecode_conversion): Likewise. + (bc_init_mode_to_code_map, preferred_typecode): Likewise. + (bc_expand_binary_operation, bc_expand_unary_operation): Likewise. + (bc_expand_increment): Likewise. + * bc-typecd.h: Cast enum arithmetic and logical operands to int. + + Mon Oct 4 05:52:21 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * a29k.c (incoming_regs): Only use 16 registers for parameter + passing. + + * tree.c (build_string): Remove previous change and comment why + string text has to be in saveable_obstack. + * varasm.c (output_constant_def): Remove last change; no longer needed. + + Sun Oct 3 18:51:19 1993 James Van Artsdalen (james@bigtex.cactus.org) + + * i386/i386.c (output_op_from_reg): Handle 3-word XFmode values. + (output_to_reg): Likewise. + (output_move_double): Handle XFmode operands. + (output_move_const_single): Use REAL_VALUE_TO_TARGET_SINGLE. + (print_operand): Add letter `T', size `12'. Use REAL_VALUE + macros to convert floating point operands. + (convert_387_op): Add XFmode to case FLOAT_EXTEND. + + * i386/i386.h (LONG_DOUBLE_TYPE_SIZE): Define as 96. + (FIXED_REGISTERS): If XFmode enabled, hard reg st7 is fixed. + (ASM_OUTPUT_DOUBLE): Use REAL_VALUE_... macros. + (ASM_OUTPUT_FLOAT): Likewise. + (ASM_OUTPUT_LONG_DOUBLE): New macro. + (PRINT_REG): Add size case 12. + (DEBUG_PRINT_REG): Likewise. + + * i386/i386.md: (tstxf_cc, tstxf, cmpxf, cmpxf_cc, cmpxf_ccfpeq, + swapxf, movxf, extenddfxf2, extendsfxf2, truncxfsf2, truncxfdf2, + fixuns_truncxfsi2, fix_truncxfdi2, fix_truncxfsi2, floatsixf2, + floatdixf2, addxf3, subxf3, mulxf3, divxf3, negxf2, absxf2, + sqrtxf2): New patterns. + + * i386/next.h,i386/osfrose.h,i386/sysv4.h + (ASM_OUTPUT_DOUBLE,ASM_OUTPUT_FLOAT): Use REAL_VALUE_ macros. + (ASM_OUTPUT_LONG_DOUBLE): New macro. + + * i386/bsd.h,i386/sco4.h (ASM_OUTPUT_DOUBLE): Deleted, + use default version. + + * i386/next.h,i386/sco.h (VALUE_REGNO): Add case XFmode. + + Sun Oct 3 16:35:05 1993 Michael Meissner (meissner@wombat.gnu.ai.mit.edu) + + * collect2.c (read_file): Fix typo in prototype. + + Sun Oct 3 18:32:46 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * Makefile.in (bytecode.realclean): Don't delete bi-lexer.c. + + Sun Oct 3 19:45:02 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * gcc.c (default_compilers): Add rules for Ada. + * toplev.c (lang_options): Add temporary parameter "gnat". + + * tree.c (staticp): DECL_EXTERNAL is not defined for CONSTRUCTOR. + + * tree.def (PLACEHOLDER_EXPR, WITH_RECORD_EXPR): New tree codes. + * tree.c (save_expr): Don't evaluate something containing a + PLACEHOLDER_EXPR. + (contains_placeholder_p, substitute_in_{expr,type}): New functions. + * tree.h: Add declarations for new functions. + * calls.c (expand_call): Pass objects who size depends on the + contents of the object by invisible reference. + * function.c (assign_parms): Likewise. + * explow.c (expr_size): If the size contains a PLACEHOLDER_EXPR, + surround it with a WITH_RECORD_EXPR. + * expr.c (store_expr): Use expr_size value, not size_int. + (store_constructor): Handle case of variable position and allow + it to contain a PLACEHOLDER_EXPR. + (get_inner_reference): Make a WITH_RECORD_EXPR if required. + (expand_expr, case PLACEHOLDER_EXPR, WITH_RECORD_EXPR): New cases. + (expand_expr, case ARRAY_REF): Make WITH_RECORD_EXPR expressions + when needed. + + * calls.c (expand_call): Set MEM_IN_STRUCT_P in stack slot if + appropriate. + + * varasm.c (output_constant_def): Copy string as well as string + node when deferring output of constants. + + * configure (i370-*): Renamed tm-mvs.h to mvs.h. + * config/i370/mvs.h: Renamed from tm-mvs.h. + + Sun Oct 3 12:50:57 1993 Richard Earnshaw (rwe11@cl.cam.ac.uk) + + * arm.h (function definitions): Add new functions definitions. + (arm_condition_codes): make this externally visible. + (STARTFILE_SPEC): Move to riscix.h and riscix1-1.h. + (CPP_PREDEFINES): Move old defn to riscix.h and riscix1-1.h, add + generaic default definition. + (CPP_SPEC): Define for generic implementation, pass cpu variant + defn to pre-processor. + (TARGET_VERSION): Indicate this is generic variant. + (TARGET_6): New macro, set when compiling for arm6 in 32bit mode. + (ARM_EXTRA_TARGET_SWITCHES): New macro, hook for os dependent files + to make additions to TARGET_SWITCHES. Default to null. + (processor_type): new enum type defining processor variant for + attributes. + (arm_cpu_attr): Macro to get at cpu type from attributes. + (TARGET_WHEN_DEBUGGING): remove non-generic definitions + (OVERRIDE_OPTIONS): Set processor type for attributes. + (OPTIMIZE_OPTIONS): Set flag_force_mem. + (PROMOTE_MODE): Promote byte constants unsigned. + (ENABLE_XF_PATTERNS): Define, do not enable XFmode insns by default + -- it tends to crash riscix. + (REAL_ARITHMETIC): Define. + (CONSTANT_ALIGNMENT): Align string constants so that we can access + them faster. + (TARGET_FLOAT_FORMAT): Is IEEE_FLOAT_FORMAT. + (FIRST_PSEUDO_REGISTER): Increase to support fake registers. + (FIXED_REGISTERS): Describe behaviours of fake regs. + (CALL_USED_REGISTERS): Likewise. + (HARD_REGNO_NREGS): Deal with fake frame and argument registers. + (HARD_REGNO_MODE_OK): Likewise. + (FRAME_POINTER_REGNUM): Make this a fake register) + (HARD_FRAME_POINTER_REGNUM): Define. set to reg 11 (fp). + (FRAME_POINTER_REQUIRED): It is if TARGET_APCS. + (ARG_POINTER_REGNUM): Set to new fake register. + (CC_REGNUM): Define, set to fake register. + (REG_ALLOC_ORDER): Adjust to get better allocation in small functions. + Add fake registers. + (REG_CLASS_CONTENTS): Add new fakes. + (REGNO_REG_CLASS): Likewise. + (CONST_OK_FOR_LETTER_P): Add recognition for negated and inverted + constant integers. + (EXTRA_CONSTRAINT): Add 'Q' to recognize MEM (REG). Add 'S' for + symbols in the text segment. + (CONST_DOUBLE_OK_FOR_LETTER_P): Add 'H' for negated fp constants. + (SECONDARY_OUTPUT_RELOAD_CLASS): Define. Needed to store DFmode held + in SImode regs. + (REGISTER_MOVE_COST): Make this more expensive than memory for + float<->int moves. + (USE_RETURN_INSN): Define, call function. + (ELIMINABLE_REGS): Define to eliminate fake regs. + (CAN_ELIMINATE): Likewise. + (INITIAL_ELIMINATION_OFFSET): Likewise. + (INITIAL_FRAME_POINTER_OFFSET): Delete. + (REGNO_OK_FOR_BASE_P): Add fake regs. + (MAX_REGS_PER_ADDRESS): Is only 2; shifting by reg not allowed in addr. + (CONSTANT_ADDRESS_P): Accept addresses with the symbol_ref flag set. + (LEGITIMATE_CONSTANT): Accept negated floats; also constant addresses. + (ENCODE_SECTION_INFO): Mark strings that will go in the text segment + with the symbol_ref flag. + (REG_OK_FOR_BASE_P [!REG_OK_STRICT]): Add new fakes. + (REG_OK_FOR_PRE_POST_P [!REG_OK_STRICT]): Likewise. + (REG_OK_FOR_PRE_POST_P [REG_OK_STRICT]): Likewise. + (GO_IF_LEGITIMATE_INDEX): constant FLOAT indicees must be word + aligned; be more restrictive about multi-reg ints; allow all legal + shift operations; check boundary conditions more carefully. + (DEFAULT_SIGNED_CHAR): Remove os dependent alternatives. + (LOADS_ZERO_EXTEND): Define; only QImode loads do. + (HAVE_VPRINTF): Move to xm-arm.h + (SHIFT_COUNT_TRUNCATED): Not true -- Delete. + (CONST_COSTS): Define; give the cost of constants. + (RTX_COSTS): Define; give the cost of rtl. + (MEMORY_MOVE_COST): Is expensive. + (BRANCH_COST): Set high to get conditional instructions. + (ADDRESS_COST): Are all the same. + (NOTICE_UPDATE_CC): Delete. + (EXTRA_CC_MODES): Add a no overflow mode and floating point modes. + (EXTRA_CC_NAMES): Likewise. + (SELECT_CC_MODE): Return the appropriate mode. + (STORE_FLAG_VALUE): Define. + (PREDICATE_CODES): Define, show what they are. + (ARM_OS_NAME): Supply generic version. + (ASM_FILE_START): Print appropriate OS name. + (REGISTER_NAMES): Add fakes. + (DBX_OUTPUT_MAIN_SOURCE_FILENAME): set desc field to compiler version + number expected by dbx (RISCIX hack). + (ASM_OUTPUT_INTERNAL_LABEL): Don't reset arm_ccfsm_state if label isn't + a code ('L') label. + (ASM_OUTPUT_LONG_DOUBLE): Define for XFmode. + (ASM_OUTPUT_DOUBLE): Use REAL_ARITMETIC routines. + (ASM_OUTPUT_FLOAT): Likewise. + (ASM_OUTPUT_OPCODE): Change of arm_ccfsm_state is now handled by insns + that need to change it. + (PRINT_OPERAND): %d is replaced by appropriate condition characters, + %D by the inverse of those given. CONST_DOUBLEs use REAL_ARITHMETIC + functions. + (PRINT_OPERAND_ADDRESS): Support all the shift types. + (INIT_CUMULATIVE_ARGS): Add missing bracket. + + * riscix.h: New file -- OS dependent defintitions for riscix 1.2 and + above. + + * riscix1-1.h: New file -- OS dependent definitions for riscix before + version 1.2 + + * rix-gas.h: New file -- riscix 1.2 and above, but with an assembler + which supports stabs. + + * arm.c (arm_compare_op0, arm_compare_op1, arm_compare_fp): New + variables. + (arm_cpu): New variable. + (lr_save_eliminated): New variable. + (arm_condition_codes): delete definition. + (return_used_this_function): New variable. + (use_return_insn): New function. + (const_ok_for_arm): Use HOST_WIDE_INT; rewrite to work if + HOST_WIDE_INT > 32 bits. + (fpa_consts_inited, strings_fpa): New variables. + (init_fpa_table): New function, initialize above. + (const_double_rtx_ok_for_fpu): Rewrite using fpa_consts_inited and + REAL_ARITHMETIC functions. + (neg_const_double_rtx_ok_for_fpu): New function. + (s_register_operand): New function, as register_operand, but don't + accept SUBREG (MEM). + (reload_memory_operand): New function. + (arm_rhs_operand): Use s_register_operand. + (arm_rhsm_operand): New function. + (arm_add_operand): New function. + (arm_not_operand): New function. + (fpu_rhs_operand): Use s_register_operand. + (fpu_add_operand): New function. + (di_operand): Use s_register_operand. + (di_operand, case MEM): address must be offsettable. + (index_operand): Use s_register_operand. + (const_shift_operand): New function. + (shift_operator): Also accept MULT by power of two. + (equality_operator): New function. + (minmax_operator): New function. + (cc_register): New function. + (minmax_code): New function. + (adjacent_mem_locations): New function. + (load_multiple_operation): New function. + (store_multiple_operation): New function. + (arm_gen_load_multiple): New function. + (arm_gen_store_multiple): New function. + (gen_compare_reg): New function. + (arm_backwards_branch): New function. + (short_branch): New function. + (arm_insn_not_targeted): New function. + (fp_immediate_constant): New function. + (eliminate_lr2ip): New function. + (output_call_mem): New function. + (output_mov_long_double_fpu_from_arm): New function. + (output_mov_long_double_arm_from_fpu): New function. + (output_mov_long_double_arm_from_arm): New function. + (output_move_double): output constants using output_move_immediate; + sign_extend CONST_INTs; handle PRE/POST INCs. + (shift_instr): Handle MULT. + (output_shift_compare): New function. + (pattern_really_clobbers_lr): New function. + (function_really_clobbers_lr): New function. + (output_return_instruction): New function. + (output_prologue): Determine whether tail calling is possible, + compensate for this when saving registers. Re-initialize + return_used_this_function; use HARD_FRAME_POINTER_REGNUM, when + saving floating point regs. + (output_epilogue): Epilogue isn't needed if return_used_this_function; + use HARD_FRAME_POINTER_REGNUM when restoring floating point regs + and there is a stack frame; Arm 6 requires different return + instruction. + (output_load_symbol): New function. + (final_prescan_insn): Add support for RETURN patterns; can also + conditionalize and target a RETURN; use attributes to determine + whether condition codes are set or clobbered; add new case CALL_INSN + to switch, fail if Arm 6; support a jump inside a parallel; call + recog () before returning to recover from using attributes on other + insns. + + * arm.md (type): New attribute for scheduling. + (cpu): New attribute for cpu type for use in conds attribute. + (conds): New attribute to describe actions on condition codes, set in + insns. + (length): New attribute, set in insns. + (write_conflict): New attribute describing conflicts with the write + buffer. + (fpa): New function unit for floating point co-processor. + (write_buf): New function unit for Arm 6 write buffer. + Most patterns: use s_register_operand instead of register_operand. + Most patterns: Don't use general operand and then expect reload to + do the work. + (adddi3): op0 can be the same as ops1 or 2; clobbers condition codes. + New unnamed patterns to add an SImode operand to a DImode op. + (addsi3): accept constants that can be catered for using sub. + New unnamed patterns that set conditions on add. + (incscc): new pattern, conditional increment. + New split to add some numbers in two insns. + (addsf3): Use REAL_ARITHMETIC; support -ve immediates. + (adddf3): Likewise. + (FLOAT_EXTEND and ADD): New unnamed patterns. + (addxf3): New pattern. + (subdi3): Allow input and output operands to overlap exactly. + (SUB DImode and SImode): New unnamed patterns. + (subsi3): Don't accept a constant as last operand, it will never be + matched. + (SUB and set CC) New unnamed patterns. + (decscc): new pattern, conditional decrment. + (subdf3): Fix bad case alternative. + (FLOAT_EXTEND and SUB): New unnamed patterns. + (subxf3): New pattern. + (mulsi3): Allow op2 to be the same as op0 + (MULT and set CC): New unnamed patterns. + (MULT and ADD): Ops 2 and 3 can match op 0. + (MULT, ADD and set CC): New unnamed patterns. + (mulsf3): use fmls for faster multiply. + (FLOAT_EXTEND and MULT): New unnamed patterns. + (mulxf3): New pattern. + (divsf3): use dvfs and rdfs for faster divide. + (FLOAT_EXTEND and DIV): New unnamed patterns. + (divxf3): New pattern. + (FLOAT_EXTEND and MOD): New unnamed patterns. + (modxf3): New pattern. + (anddi3): op 0 can be the same as ops1 or 2. + (*_EXTEND and AND): New unnamed patterns + (andsi3): Also accept constants that can be handled with bic + instruction. + (AND and set CC): New unnamed patterns. + (andcbsi3): Delete, this can't be generated any more. + (NOT then AND): New unnamed patterns. + (NOT then AND and set CC): Likewise. + (iordi3): Ops 1 and 2 can match op 0. + (*_EXTEND and IOR): New unnamed patterns. + (iorsi3): Only accept a valid rhs operand for op 2. + (IOR and set CC): New unnamed patterns. + (xordi3): New pattern. + (*_EXTEND and XOR): New unnamed patterns. + (xorsi3): Only accept a valid rhs operand for op 2. + (XOR and set CC): New unnamed patterns. + (split pattern): Complex pattern with NOT, AND, and IOR, can + sometimes produce better code if reordered. + (AND (IOR () NOT ())): Special pattern to recognize spilt above. + ([su]{min,max}si3): New patterns. + (set memory from MIN/MAX operation): New pattern. + (Arithmetic on MIN/MAX operation): New pattern. + (ashlsi3, ashrsi3, lshrsi3, rotrsi3): Only accept a valid rsh for op2. + (unnamed LSHIFT pattern): likewise. + (SHIFT and set CC): New unnamed patterns. + (SHIFT and NOT): New unnamed pattern. + (SHIFT, NOT and set CC): New unnamed patterns. + (negdi2): operand1 can be the same as op 0. + (FLOAT_EXTEND and NEG): New unsigned pattern. + (negxf2): New pattern. + (abssi2): New pattern. + (ABS and NEG): New unnamed pattern. + (FLOAT_EXTEND and ABS): New unnamed pattern. + (absxf2): New pattern. + (FLOAT_EXTEND and SQRT): New unnamed pattern. + (sqrtxf2): New pattern. + ({sin,cos}{sf,df,xf}2): New patterns. + (FLOAT_EXTEND and SIN/COS): New unnamed patterns. + (one_cmpldi2): New pattern. + (NOT and set CC): New unnamed patterns. + (floatsixf2, fix_truncsfsi2, fix_truncdfsi2, fix_truncxfsi2): New + patterns. + (truncxfsf2, truncxfdf2): New patterns. + (zero_extendsidi2, zero_extendqidi2, extendsidi2): New patterns. + (ZERO_EXTEND and set CC): New patterns. + (extend{sf,df}xf2): New patterns. + (movdi): Constrains must accept PRE/POST INC/DEC. + (movsi): make an expand that splits up integers and unsupported + moves. + (unnamed pattern to match movsi): New, don't allow things to + be moved back together again. + (REG-REG copy and set CC): New unnamed pattern. + (restorehi): use plus_constant in expansion code, not PLUS in RTL part. + (storehi, storeinthi): likewise. + (movhi): Break up impossible moves. + (pattern to match movhi): Don't allow impossible moves to be put + back together. + (movqi): Break up impossible moves. + (pattern to match movqi): Don't allow impossible moves to be put + back together; convert negative constants into mvn instruction. + (movsf): Use REAL_ARITHMETIC for constants; add alternatives for + moving GENERAL_REGS to and from memory. + (movdf): Make this an expand; split out impossible moves. + (reload_outdf): New pattern. + (pattern to match movdf): Don't allow impossible moves to be put back + together; add alternatives for moving GENERAL_REGS to and from memory; + rearrange and weight to get optimal register allocation. + (movxf): New pattern. + (load_multiple): New expand pattern. + (pattern to load multiple, pattern to load multiple with write-back): + New unnamed patterns. + (store_multiple): New expand pattern. + (pattern to store multiple, pattern to store multiple with write-back): + New unnamed patterns. + (movstrsi): Expand short moves as a series of load/store multiples with + write-back. + (cmp*): Make these expands; just set some state variables. + (CC = COMPARE op, op): New unnamed patterns. + (CC = COMPARE op, NEG op): New unnamed pattern. + (CC = COMPARE op, SHIFT op): New unnamed pattern. + (FLOAT_EXTEND then COMPARE): New unnamed patterns. + (CC = CC): New unnamed (dummy) pattern to allow cse to combine repeated + compares. + (b{eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu}): Make these expand patterns, + use gen_compare_reg(). + (pattern to match branches, pattern to match inverted brances): New + unnamed patterns. + (s{eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu}): New expands. + (pattern to match store_flag operations): New unnamed pattern. + (pattern to match NOT store_flag, pattern to match NEG store_flag): + New unnamed patterns. + (jump): handle arm_ccfsm_state explicitly. + (CALL (MEM)): New unnamed patterns. + (return): New pattern. + (conditional RETURN): New unnamed patterns; + (table_jump (MEM)): New unnamed pattern. + (indirect_jump (MEM)): New unnamed pattern. + Replace shift-arithmetic patterns with new versions that catche all + cases. + (Old peephole patterns (commented out)): remove. + (shift-arithmetic and set CC): New unnamed patterns. + (reload patterns for all shift-arithmetic patterns): New patterns. + Add many new patterns to merge store_flag patterns, arithmetic and + shifting. + New patterns to match conditional comparisons. + (movcond): New pattern. + (arith (MEM, MEM+4)): New unnamed pattern to spot load multiple + possibility. + (patterns to match extended pre-increment): New unnamed patterns. + (peepholes to match extended post-increment): New. + (peephole to match move and set conds): Needed because combine misses + this one. + (peepholes to match load/store multiples): New. + (CALL, RETURN): New peephole. + (CALL, JUMP): New peephole. + (save_stack_nonlocal, restore_stack_nonlocal): New expands for + non-local gotos. + special split to break up some conditional arithmetic sequences + before scheduling. + + *configure (arm-*-riscix1.[01]*, arm-*-riscix*): New configurations. + *config.sub: Recognize operating system "riscix*"; recognize acorn as + vendor. + + Sat Oct 2 17:24:44 1993 James Van Artsdalen (james@bigtex.cactus.org) + + * i386.md (addhi3): Use byte opcodes when the low byte of a word + is known to be zero. + + Sat Oct 2 14:11:06 1993 John F Carr (jfc@Athena.mit.edu) + + * combine.c (can_combine_p): Allow an insn with a REG_EQUIV note + that reads memory to be moved past an insn that writes memory. + + Sat Oct 2 14:04:03 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * regclass.c (record_reg_classes): Skip to next alternative + when we skip normal cost computation. + + * collect2.c: Add prototypes to static declarations. + (PROTO): New macro. + (dup2, putenv): Functions return integers; add type and returns. + + * varasm.c (make_decl_rtl): Set TREE_SIDE_EFFECTS on global if + -fvolatile-global. + + * tree.c (build_string): Make lifetime of string the same as + tree node. + + Sat Oct 2 04:55:44 1993 Doug Evans (dje@canuck.cygnus.com) + + * a29k/a29k.h, a29k/unix.h, alpha/alpha.h, arm/arm.h, clipper/clix.h, + convex/convex.h, elxsi/elxsi.h, fx80/fx80.h, gmicro/gmicro.h, + h8300/h8300.h, i370/tm-mvs.h, i386/386bsd.h, i386/aix386ng.h, + i386/gas.h, i386/go32.h, i386/linux.h, i386/lynx.h, i386/mach.h, + i386/next.h, i386/osfelf.h, i386/osfrose.h, i386/sco.h, i386/sco4.h, + i386/sco4dbx.h, i386/scodbx.h, i386/sequent.h, i386/sun.h, + i386/sysv3.h, i386/sysv4.h, i860/fx2800.h, i860/i860.h, i860/mach.h, + i860/sysv3.h, i860/sysv4.h, i960/i960.h, m68k/3b1.h, m68k/3b1g.h, + m68k/altos3068.h, m68k/apollo68.h, m68k/crds.h, m68k/ctix.h, + m68k/dpx2.h, m68k/hp2bsd.h, m68k/hp320.h, m68k/hp3bsd.h, + m68k/hp3bsd44.h, m68k/isi.h, m68k/lynx.h, m68k/m68kv4.h, + m68k/mot3300.h, m68k/news.h, m68k/next.h, m68k/pbb.h, m68k/plexus.h, + m68k/sun2.h, m68k/sun3.h, m68k/sun3mach.h, m68k/tower-as.h, + m68k/tower.h, m88k/dgux.h, m88k/luna.h, m88k/m88k.h, m88k/sysv3.h, + m88k/sysv4.h, mips/bsd-4.h, mips/bsd-5.h, mips/dec-osf1.h, + mips/iris3.h, mips/mips.h, mips/news4.h, mips/news5.h, + mips/nws3250v4.h, mips/osfrose.h, mips/svr3-4.h, mips/svr3-5.h, + mips/svr4-4.h, mips/svr4-5.h, mips/ultrix.h, ns32k/encore.h, + ns32k/merlin.h, ns32k/ns32k.h, ns32k/pc532-mach.h, ns32k/pc532.h, + ns32k/sequent.h, ns32k/tek6000.h, ns32k/tek6100.h, ns32k/tek6200.h, + pa/pa-ghpux.h, pa/pa-gux7.h, pa/pa-hpux.h, pa/pa-hpux7.h, + pa/pa-utahmach.h, pa/pa.h, pa/pa1-utahmach.h, pyr/pyr.h, romp/romp.h, + rs6000/aix31.h, rs6000/mach.h, rs6000/rs6000.h, sh/sh.h, sparc/lite.h, + sparc/lynx.h, sparc/pbd.h, sparc/sol2.h, sparc/sparc.h, sparc/sysv4.h, + spur/spur.h, tahoe/harris.h, tahoe/tahoe.h, vax/ultrix.h, vax/vax.h, + vax/vaxv.h, vax/vms.h, we32k/we32k.h + (CPP_PREDEFINES): Add system/cpu/machine assertions where missing. + + Fri Oct 1 22:11:17 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * gvarargs.h: Test __sequent__ like __BSD_NET2__. + + Fri Oct 1 17:19:54 1993 Torbjorn Granlund (tege@adder.cygnus.com) + + * cse.c (insert_regs): Always return something. + (simplify_unary_operation): Remove unused variable. + (cse_process_notes): Likewise. + (invalidate_skipped_block): Likewise. + (cse_set_around_loop): Likewise. + + * pa-ghpux.h (LINK_SPEC): Pass "-a -archive" when + debugging. + * pa-hpux.h (LINK_SPEC): Likewise. + * pa-ghpux.h (LIB_SPEC): Make sure to add space between flags. + * pa-gux7.h (LIB_SPEC): Likewise. + * pa-hpux.h (LIB_SPEC): Likewise. + * pa-hpux7.h (LIB_SPEC): Likewise. + + Fri Oct 1 22:17:12 1993 Eric Youngdale (eric@kafka) + + * vmsconfig.com: Write out the definitions from Makefile.in for + the symbols BC_ALL and BI_OBJ into files BC_ALL.OPT and + BI_ALL.opt. Remove "bytecode " from compiler options files so + compiler will link correctly. + + * make-cc1.com (bc_generate): New VMS DCL function. Takes a BC + header file that needs to be generated, and builds it. + + * make-cc1.com: Compile entries listed in BI_ALL.OPT, and then call + bc_generate for every header file listed in BC_ALL.OPT + + Fri Oct 1 21:13:17 1993 H.J. Lu (hlu@nynexst.com) + + * config/i386/linux.h (LIB_SPEC): Handle -p anmd -pg outermost. + + Fri Oct 1 18:23:57 1993 Jim Wilson (wilson@cygnus.com) + + * reload1.c (gen_input_reload): Handle PLUS with MEM operand + exactly the same as a PLUS with a REG operand. + * reload.c (form_sum): Undo Sep 28 change. + + * Makefile.in (cc1, cc1plus, cc1obj): Delete superfluous + dependencies on bytecode. + (stamp-bcarity, stamp-bcopcode, stamp-bcopname): Create stamp files. + + Fri Oct 1 18:17:56 1993 Doug Evans (dje@canuck.cygnus.com) + + * configure (cpp_md_flags): New variable. + (links): Build link from md.pre-cpp if cpp_md_flags defined. + (CPP_MD, CPP_MD_FLAGS, MD_FILE): New macros for Makefile. + * Makefile.in (md): New dependency. + (MD_FILE): New macro. + (clean): Remove file md if md.pre-cpp exists. + (distclean): Remove md.pre-cpp. + + Fri Oct 1 15:44:48 1993 Michael Meissner (meissner@osf.org) + + * halfpic.h (toplevel): Enclose the whole file inside a #ifndef + NO_HALF_PIC conditional. + + * i386/x-osfrose (CCLIBFLAGS, GCC_CFLAGS): Define NO_HALF_PIC so + that the two common variables in halfpic.h don't get created. + + * mips/x-osfrose (CCLIBFLAGS, GCC_CFLAGS): Ditto. + + Fri Oct 1 10:46:15 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * a29k.h (R_KR): New macro. + (FIRST_PSEUDO_REGISTER, FIXED_REGISTERS, CALL_USED_REGISTERS): + Adjust for more registers present. + (REG_ALLOC_ORDER, REG_CLASS_CONTENTS, REGISTER_NAMES): Likewise. + (HARD_REGNO_NREGS, HARD_REGNO_MODE_OK, REGNO_REG_CLASS): Likewise. + (CONDITIONAL_REGISTER_USAGE): Swap names rather than replacing them. + * a29k.c (gpc_reg_operand): Include kernel registers. + + * a29k.h (TARGET_LARGE_MEMORY): New flag; change value for + all others. + (ENCODE_SECTION_INFO): New macro. + (TARGET_SWITCHES): Add "normal" and change values. + + * a29k.c (call_operand, case SYMBOL_REF): Handle TARGET_LARGE_MEMORY + and SYMBOL_REF_FLAG. + + Thu Sep 30 23:25:13 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * reorg.c (optimize_skip): Do not thread a jump to a new target if + doing so would invalidate the insn in the jump's delay slot. + + Thu Sep 30 14:21:03 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * bi-lexer.c (scan_string): Do xmalloc if buffer is null and + xrealloc if it's not, not the other way around. + + Thu Sep 30 10:57:30 1993 Jan Brittenson (bson@nutrimat.gnu.ai.mit.edu) + + * bc-emit.c (bc_end_function, seg_data): Use bcopy instead of memcpy. + + Thu Sep 30 05:53:58 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * fold-const.c (fold, case PLUS_EXPR, MINUS_EXPR): Properly handle + case when ARG1 splits and VARSIGN is -1. + + Wed Sep 29 19:41:18 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c (build_modify_expr): Check whether recursive calls + return error_mark_node. + + Wed Sep 29 18:35:30 1993 Leonid Baraz (lbaraz@iil.intel.com) + + * rtl.h (GEN_INT): Add missing cast to HOST_WIDE_INT. + * jump.c (rtx_renumbered_equal_p, case CONST_INT): Use INTVAL, + not XINT. + + Wed Sep 29 17:32:03 1993 Doug Evans (dje@canuck.cygnus.com) + + * glimits.h (UINT_MAX, ULONG_MAX, ULONG_LONG_MAX): + redefine in a simpler way. + + Wed Sep 29 17:25:17 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) + + * fixincludes (sys/spinlock.h): change references of + "../machine/*.h" to + + Wed Sep 29 07:09:50 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * rs6000.c (reg_or_short_operand): Remove redundant test. + + * sched.c: Add prototypes for static function. + (add_dependence, remove_dependence, regno_use_in): Now static. + (schedule_insns): Have dummy version also take FILE * parameter. + + Wed Sep 29 01:29:31 1993 Paul Eggert (eggert@twinsun.com) + + * cccp.c (quote_string): New function. + (special_symbol, write_output, output_line_command): Use it to escape + special characters in file names when outputting #line directives. + (do_line): Parse escape sequences in #line directives' file names. + * c-lex.c, cp-lex.c (check_newline, yylex, real_yylex): Likewise. + (ignore_escape_flag): Remove var. + + Tue Sep 28 21:27:26 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu + + * function.c (push_temp_slots, pop_temp_slots): Always change level. + * cp-expr.c (cplus_expand_expr): Push and pop temp slots around + making new temp slots and freeing them. + * expr.c (expand_assignment, expand_expr, do_jumps): Likewise. + * integrate.c (expand_inline_function): Likewise. + + Tue Sep 28 18:50:57 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * reload.c (find_reloads): Don't call find_reloads_toplev + (or anything like that) for match_operator operands. + + * config/ns32k/ns32k.c (output_move_double): Special code for + pushing from an address that uses the sp. Use PUSHOP for pushes, + not POPOP. + + * config/ns32k/ns32k.h (FUNCTION_EPILOGUE, FUNCTION_PROLOGUE): + Add %$ in adjspb/adjspd insns. + * config/ns32k/ns32k.md (recognizer for subtracting const from reg 17): + Add %$ in adjspb/adjspd insns. + + * bytetypes.h (QItype, HItype, SItype, DItype): Use __signed__. + + * Makefile.in (stamp-bcopname, stamp-bcopcode): + Use shorter names for temporary files. + (bc-emit.o): Depend on bc-arity.h. + + * bi-opname.c, bi-arity.c, bi-opcode.c (xmalloc): New function. + * bi-opname.c, bi-arity.c: Include stdio.h. + + * function.c (expand_main_function): Put back accidentally + deleted previous change to use NAME__MAIN. + + * glimits.h (INT_MAX, LONG_MAX, LONG_LONG_MAX): Delete parens. + (__glimits__evconcat__, __glimits__concat__): New macros. + (UINT_MAX, ULONG_MAX, ULONG_LONG_MAX): Use them. + + * cccp.c (output_dots): New function. + (do_include): Call it (to indent output for print_include_names). + + Tue Sep 28 18:22:31 1993 Jim Wilson (wilson@cygnus.com) + + * reload1.c (eliminate_regs): All recursive calls now pass INSN + instead of NULL_RTX. Second assignment to ref_outside_mem changed + to be same as first assignment. + + * combine.c (force_to_mode, LSHIFTRT case): Avoid shifts larger + than HOST_BITS_PER_WIDE_INT. + + * sched.c (schedule_insns): Don't zero reg_n_calls_crossed for + pseudos live across multiple blocks. + + * fixincludes ({sparc,sun3,sun3x,sun4,sun4c,sun4m}/asm_linkage.h, + {sun4c,sun4m}/debug/asm_linkage.h: Replace /**/ with ##. + + * reorg.c (mark_target_live_regs): When scanning insns, ignore + CLOBBERs in addition to USEs. + + * life.h: Comment that this is for sparclite w/o FPU. + * sparc.h (CPP_SPEC): Handle -mf930 and -mf934. + (TARGET_SWITCHES): Add -mf930 and -mf934 options. -msparclite no + longer does -mno-fpu. + + * fixinc.svr4, fixincludes (math.h): Put #ifndef around HUGE_VAL + define. + * math-68881.h, math-3300.h (HUGE_VAL): Add #undef before HUGE_VAL + define, instead of surrounding it with #ifndef/#endif. + + * sparc/bsd.h: New file. + * configure (sparc-*-bsd*): New configuration. + + * reload.c (form_sum): Change the way that form_sum canonicalizes + addresses, so that it never creates (PLUS (PLUS MEM CONST_INT) REG) + but instead canonicallizes this to (PLUS (PLUS REG CONST_INT) MEM). + + Tue Sep 28 16:00:25 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * bc-emit.c: Include gvarargs.h, not varargs.h. + Don't include string.h. + (seg_align): Use bzero, not memset. + + Mon Sep 27 20:53:01 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c (pop_init_level): Add special case for nonincremental + scalar initializers. + + * protoize.c: Declare rindex unconditionally. + + * c-decl.c (init_decl_processing): Use signed_type and unsigned_type + to set signed_wchar_type_node and unsigned_wchar_type_node. + + Mon Sep 27 20:31:01 1993 Paul Eggert (eggert@twinsun.com) + + * dbxout.c (dbxout_init, dbxout_source_file): Quote special + characters when outputting source file names. + * config/a29k/a29k.h, config/a29k/unix.h, config/alpha/alpha.h, + config/i386/aix386ng.h, config/i386/bsd.h, config/i386/gas.h, + config/i386/sun386.h (ASM_FILE_START): Likewise. + * config/elxsi/elxsi.h, config/m68k/3b1.h, config/m68k/crds.h, + config/m68k/mot3300.h, config/m68k/tower-as.h, config/m88k/m88k.h, + dwarfout.c (ASM_OUTPUT_SOURCE_FILENAME): Likewise. + * xcoffout.h, config/i386/i386iscgas.h, config/i860/fx2800.h + (DBX_OUTPUT_MAIN_SOURCE_DIRECTORY, DBX_OUTPUT_MAIN_SOURCE_FILENAME): + Likewise. + * xcoffout.h (DBX_OUTPUT_MAIN_SOURCE_FILE_END): Likewise. + * config/mips/mips.c (mips_output_filename): Likewise. + * toplev.c (output_file_directive): Likewise. + (output_quoted_string): New function. + + Mon Sep 27 19:31:57 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * bi-lexer.c (xrealloc): Handle 0 passed as BLOCK. + + * Makefile.in (stamp-bcopname, stamp-bcopcode, stamp-bcarity): + Renamed from stamp-bc-... to fit in 14 chars. + Don't rm the .h files. + (STAGESTUFF): Add some bc and bi files. + + * c-lex.c (yylex): Handle i together with f or l in float constant. + + Mon Sep 27 19:00:18 1993 Ian Lance Taylor (ian@cygnus.com) + + * cccp.c (special_symbol, initialize_builtins): If + NO_BUILTIN_SIZE_TYPE is defined, never refer to SIZE_TYPE. + Likewise for NO_BUILTIN_PTRDIFF_TYPE and PTRDIFF_TYPE. + + Mon Sep 27 18:59:09 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * reload1.c (eliminate_regs, SET case): Check for INSN_LIST + along with EXPR_LIST. + + Mon Sep 27 14:29:17 1993 Kresten Krab Thorup (krab@iesd.auc.dk) + + * objc/typedstream.h (objc_read_object): Add declaration. + + Mon Sep 27 17:00:38 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * configure: Handle option --with-elf. + (i[34]86-*-linux*): Use linuxelf.h if --with-elf. + (i[34]86-*-osfelf): Config deleted. + (i[34]86-*-osfrose): Handle --with-elf. + * config/i386/linuxelf.h: New file. + + Mon Sep 27 14:19:33 1993 Jan Brittenson (bson@nutrimat.gnu.ai.mit.edu) + + * expr.c (bc_expand_constructor): Delete cast of argument to + bc_emit_instruction to HOST_WIDE_INT. Move assignment of ptroffs + to separate line. + + Mon Sep 27 10:32:28 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * Makefile.in (stmt.o, expr.o, emit-rtl.o): Add missing dependency + on bc-typecd.def. + (bi-run.o): Fix formatting. + + Mon Sep 27 10:26:43 1993 Jan Brittenson (bson@nutrimat.gnu.ai.mit.edu) + + * Makefile.in (bi-arity.h, bc-opcode.h, bc-opname.h): Use + move-if-changed. + (stamp-bc-arity, stamp-bc-opcode, stamp-bc-opname): New targets. + + Sun Sep 26 23:11:34 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * pa.h (ASM_FILE_START): Remove last change for $LIT$ subspace, + not all HPUX linkers handle it correctly. + + Sun Sep 26 20:51:36 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * stmt.c (expand_exit_loop_if_false, bc_expand_start_cond): + Use xjumpifnot, not jumpifnot. + + * Makefile.in (bi-arity, bi-opcode, bi-opname): Delete $(LEXLIB). + + * varasm.c (assemble_string): Put braces around ASM_OUTPUT_ASCII. + + Sat Sep 25 08:30:16 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * expr.c (expand_expr, case COND_EXPR): Set MEM_IN_STRUCT_P + properly for TEMP. + + * combine.c (BYTE_LOADS_EXTEND, LOAD_EXTEND): Deleted. + (subst, force_to_mode, nonzero_bits, num_sign_bit_copies): + Use new macros LOAD_EXTEND_OP and WORD_REGISTER_OPERATION instead + of BYTE_LOADS_*_EXTEND and LOAD_EXTEND. + * expr.c (do_store_flag): Likewise. + * reload.c (push_reload, find_reloads): Likewise. + * reload1.c (eliminate_regs): Likewise. + * a29k.h, alpha.h, clipper.h, arm.h, i960.h, m88k.h, mips.h: + Use WORD_REGISTER_OPERATION and LOAD_EXTEND_OP and delete + BYTE_LOADS_{SIGN,ZERO}_EXTEND. + * pa.h, romp.h, rs6000.h, sh.h, sparc.h: Likewise. + + Sat Sep 25 06:19:20 1993 Jan Brittenson (bson@nutrimat.gnu.ai.mit.edu) + + * bi-lexer.l: Deleted. + + * bi-lexer.c: New file. + + * Makefile.in (bi-lexer): Deleted. + (bi-lexer.l): Deleted. + + Fri Sep 24 16:59:03 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + Cygnus<->FSF C++ front-end merge. + + Tue Sep 21 19:17:29 1993 Mike Stump (mrs@cygnus.com) + + * cp-decl.c (build_ptrmemfunc_type): Set CLASSTYPE_GOT_SEMICOLON + just in case. + * cp-decl.c (start_function): Exclude pointer to member functions in + IS_AGGR_TYPE test. + * cp-method.c (dump_type_prefix, dump_type_suffix, dump_type): + Handle pointer to member functions. + + Tue Sep 21 10:47:10 1993 Mike Stump (mrs@cygnus.com) + + * cp-tree.c (finish_struct): Since we know which base class we want + the binfo for, get it directly, instead of searching for it. Cures + a compiler_error in binfo_value. + + Thu Sep 16 20:33:25 1993 Mike Stump (mrs@cygnus.com) + + * cp-cvt.c (convert_pointer_to): Make error more specific and more + readable. + + Thu Sep 16 20:14:18 1993 Mike Stump (mrs@cygnus.com) + + * cp-lex.c (consume_string): Add second argument so that we can use + this routine for character constants too. Also, handle eof inside + the string or character constant better. Make static, as it isn't + used anyplace else. + + * cp-lex.c (reinit_parse_for_block): Add second argument to + consume_string. Add support for character constants. + + * cp-tree.h (consume_string): Remove declaration, not used any place + else. + + Wed Sep 15 12:44:13 1993 Per Bothner (bothner@kalessin.cygnus.com) + + * cp-gc.c (build_t_desc): Make sure finish_table is called + for the methods and ivars tables. + + Mon Sep 13 14:40:23 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-pt.c (unify): Use the referent type if necessary. + + Fri Sep 10 16:34:37 1993 Mike Stump (mrs@cygnus.com) + + * cp-typeck.c (build_binary_op_nodefault): Add missing fourth + argument to build_binary_op calls, and eliminate bogus delta2 + check. + + Fri Sep 10 14:52:59 1993 Mike Stump (mrs@cygnus.com) + + * cp-typeck.c (build_binary_op_nodefault): Make sure delta2's match + when comparing pointers to _virtual_ member functions. + + Fri Sep 10 14:27:45 1993 Mike Stump (mrs@cygnus.com) + + * cp-typeck.c (convert_for_assignment): Revert a cast. + * cp-typeck.c (build_binary_op_nodefault): Add missing fourth + argument to build_binary_op calls. + + Thu Sep 9 21:22:40 1993 Mike Stump (mrs@cygnus.com) + + Complete re-vamp of pointer to member functions. Implements + complete semantics. Cures problems on CONVEX, i960 and alpha. + + * cp-tree.h (get_member_function_from_ptrfunc, build_ptrmemfunc): + New routines. + * cp-decl.c (build_ptrmemfunc_type): New routine, builds canonical + pointer to member function types. + * cp-decl.c (grokdeclarator): Use new type for POINTER_TYPE to + METHOD_TYPEs. + * cp-method.c (build_overload_name): Make the old mangling to show + through when mangling the new pointer to member function type. + + * cp-tree.h (TYPE_PTRMEMFUNC_P, TYPE_PTRMEMFUNC_FN_TYPE, + TYPE_GET_PTRMEMFUNC_TYPE, TYPE_SET_PTRMEMFUNC_TYPE): New macros + for pointer to member function code. + * cp-init.c (resolve_offset_ref): Handle pointer to member functions + specially. + * cp-type2.c (store_init_value): Make new pointer to member + functions initializable. + * cp-typeck.c (convert_for_assignment): Make new pointer to member + functions assignable. + * cp-type2.c (build_m_component_ref): Make new pointer to member + functions work. + * cp-typeck.c (build_x_function_call, build_function_call_real, + build_binary_op): Ditto. + * cp-class.c (add_virtual_function): Don't set the high bit on + DECL_VINDEXs. + + * cp-typeck.c (get_member_function_from_ptrfunc): New routine to + resolve a pointer to member function. + * cp-typeck.c (build_ptrmemfunc): New routine to build CONSTRUCTORs + for new pointer to member functions. Used by to generate + initialization and assignment expressions. + * cp-typeck.c (build_binary_op_nodefault): Implement == and != for + new pointer to member functions. + * cp-typeck.c (unary_complex_lvalue): Handle & in more reasonable + ways to make new pointer to member functions work. + + * cp-parse.y (expr_no_commas): Don't dereference the second + argument, this is now done in build_m_component_ref as needed. + * cp-typeck.c (build_x_binary_op): Ditto. + + Other misc work. + + * cp-call.c (build_field_call, build_scoped_method_call, + build_method_call): Second arg to build_indirect_ref should be + NULL_PTR, not NULL or 0. + * cp-class.c (build_vbase_path, build_vfn_ref, popclass): Ditto. + * cp-cvt.c (convert_from_reference): Ditto. + * cp-decl2.c (setup_vtbl_ptr, finish_file): Ditto. + * cp-init.c (emit_base_init, build_virtual_init, + expand_aggr_vbase_init_1, expand_recursive_init_1, + get_member_function, resolve_offset_ref, build_new, build_delete, + build_vec_delete): Ditto. + * cp-search.c (dfs_init_vbase_pointers, init_vbase_pointers, + build_vbase_vtables_init): Ditto. + * cp-type2.c (build_x_arrow, build_functional_cast): Ditto. + * cp-typeck.c (build_modify_expr): Ditto. + + Instead of calling get_identifier with the same value all the time, + call it once, and re-use the cached value. + + * cp-decl.c (pfn_identifier, index_identifier, delta_identifier, + delta2_identifier): New cached calls to get_identifier. + * cp-tree.h (this_identifier, pfn_identifier, index_identifier, + delta_identifier, delta2_identifier): Allow them to be accessed + everywhere. + * cp-decl.c (init_decl_processing): Initialize pfn_identifier, + index_identifier, delta_identifier and delta2_identifier and + use a cached get_identifier call. + * cp-class.c (delta_name, pfn_name): Removed, use delta_identifier + and pfn_identifier instead. + * cp-class.c (popclass): Use a cached get_identifier call for `this'. + + Tue Sep 7 16:01:14 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-search.c (immediately_derived): New function. + (get_binfo): Use it. + (compute_visibility): Rewrite how private inheritance is handled, so + it actually works. Use the new immediately_derived fn. + + Mon Sep 6 14:44:46 1993 Jim Wilson (wilson@sphagnum.cygnus.com) + + * cp-decl.c (grokfndecl): Add empty statement after foundaggr label. + + Sat Sep 4 16:12:27 1993 Jason Merrill (jason@deneb.cygnus.com) + + * cp-decl.c (grokfndecl): Require class or enum argument to + operators. + + * cp-init.c (build_member_call): Make destructor without object + error more useful, don't complain of missing destructor. + + Thu Sep 2 15:51:54 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl.c (globalize_nested_type): Make sure the type in question + has a lang_specific area before trying to clear DECL_CLASS_CONTEXT. + + Wed Sep 1 13:40:30 1993 Chip Salzenberg (chip@fin) + + * cp-decl.c (start_function): Call duplicate_decls when user + redefines a builtin function. + + Thu Sep 2 15:38:43 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-pt.c (instantiate_class_template): Only kick back the local + value if we're setting things up for the parser. + + Wed Sep 1 12:54:38 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-init.c (emit_base_init): Don't complain if the base has no + constructor; we should try to use the default constructor instead. + + Wed Sep 1 11:57:00 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-call.c (find_scoped_type): Undo the sorry for now, it's hitting + a lot of code that it shouldn't be. + + Mon Aug 30 13:08:48 1993 Mike Stump (mrs@cygnus.com) + + * cp-typeck.c (build_x_unary_op): unary & on an expression of + RECORD_TYPE that has an incomplete type gives the simple address of + the object, and should not give an error about method not found. + + Mon Aug 30 11:06:26 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-pt.c (instantiate_class_template): Don't try to instantiate a + template that's already being worked on. + + * cp-init.c (perform_member_init): Make an uninitialized reference + be a pedwarn, not a warning. + + * cp-class.c (finish_struct): Make declaration of a negative width + for a bit-field be an error, not a warning. + + Sat Aug 28 09:40:47 1993 Michael Tiemann (tiemann@blues.cygnus.com) + + * cp-call.c (find_scoped_type): Add a `sorry' call if we hit an + uninstantiated type. + + Thu Aug 26 13:53:23 1993 Jason Merrill (jason@deneb.cygnus.com) + + * cp-call.c (build_scoped_method_call): Don't produce an error + if the type has no destructor. + + * cp-decl.c (record_builtin_type): Don't set TYPE_HAS_DESTRUCTOR + after all. + + Wed Aug 25 19:10:24 1993 Jason Merrill (jason@deneb.cygnus.com) + + * cp-call.c (build_method_call): Check for class type value as + well + + * cp-tree.h (IDENTIFIER_CLASS_TYPE_VALUE): Create macro + (IDENTIFIER_HAS_CLASS_TYPE_VALUE): Ditto + + * cp-init.c (is_aggr_typedef): Check for class type value as well + (for template destructors) + (build_delete): Don't assert aggregate type, don't check + TREE_GETS_DELETE if built-in type. + + Fri Sep 24 15:57:14 1993 Richard Earnshaw (rwe11@cl.cam.ac.uk) + + * rtl.h: (HARD_FRAME_POINTER_REGNUM): New macro. + (hard_frame_pointer_rtx): New variable + * combine.c: (combinable_i3_pat): Don't add REG_DEAD notes for + HARD_FRAME_POINTER_REGNUM. + (subst, case SUBREG): Don't change register number or mode if it + is HARD_FRAME_POINTER_REGNUM. + * cse.c: (FIXED_REGNO_P): HARD_FRAME_POINTER_REGNUM is fixed. + (CHEAP_REG): HARD_FRAME_POINTER_REGNUM is cheap. + (FIXED_BASE_PLUS): Allow hard frame pointer as base. + (NONZERO_BASE_PLUS_P): Likewise. + (cannon_hash, case REG): Add HARD_FRAME_POINTER_REGNUM to list of + special registers for SMALL_REGISTER_CLASSES. + (find_best_addr): Addresses containing HARD_FRAME_POINTER_REGNUM + cannot be replaced. + (cse_main): value in HARD_FRAME_POINTER_REGNUM is preserved across + calls. + * dbxout.c: (dbxout_symbol): FRAME_POINTER_REGNUM has been eliminated + by now, use HARD_FRAME_POINTER_REGNUM. + * emit-rtl.c: (hard_frame_pointer_rtx): New variable. + (gen_rtx): return hard_frame_pointer_rtx if generating rtl + for HARD_FRAME_POINTER_REGNUM. + (enit_emit_once): Generate initial rtl for hard_frame_pointer_rtx. + * explow.c: (copy_all_regs): Don't copy HARD_FRAME_POINTER_REGNUM. + * flow.c: (life_analysis): Mark HARD_FRAME_POINTER_REGNUM as live at + the end of the function. + (insn_dead_p): Don't delete insns that set the hard frame pointer. + (mark_set_1): Don't add death information about + HARD_FRAME_POINTER_REGNUM. + (mark_used_regs, case REG): Don't put HARD_FRAME_POINTER_REGNUM in + regs_ever_live. Don't mark it as needed either. + * function.c: (instantiate_virtual_regs_1, case MEM): references to + MEM via the hard frame pointer shouldn't be copied. + * genattrtab.c: (hard_frame_pointer_rtx): New Dummy definition. + * global.c: (global_alloc): Make sure that it is always possible to + eliminate FRAME_POINTER_REGNUM into HARD_FRAME_POINTER_REGNUM. + * jump.c: (thread_jumps): Value in HARD_FRAME_POINTER_REGNUM is never + modified by a call. + * local-alloc.c: (find_free_reg): Make sure we will always be able + to eliminate FRAME_POINTER_REGNUM into HARD_FRAME_POINTER_REGNUM. + * loop.c: (invariant_p, case REG): hard_frame_pointer_rtx is + invariant. + * reload.c: (immune_p): Constants never overlap hard frame pointer + references. + (find_reloads_address): Compute invalid references to the hard + frame pointer in a register; also (reg + const) + and (reg + reg + const). + + * reload1.c: (init_reload): use HARD_FRAME_POINTER_REGNUM instead of + FRAME_POINTER_REGNUM. + (reload): Only prohibit elimination of HARD_FRAME_POINTER_REGNUM, not + FRAME_POINTER_REGNUM if frame_pointer_needed. Never prohibit + elimination of FRAME_POINTER_REGNUM into HARD_FRAME_POINTER_REGNUM. + Mark HARD_FRAME_POINTER_REGNUM as live at the start of a block if + it is still needed after elimination. + (eliminate_regs): For non-local goto's, don't delete stores into the + hard frame pointer. + (eliminate_regs_in_insn): adjust comment. + (mark_not_eliminable): if frame_pointer_rtx and hard_frame_pointer_rtx + are not the same, then frame_pointer_rtx is eliminable; + hard_frame_pointer_rtx never is if it is set.. + (order_regs_for_reload): HARD_FRAME_POINTER_REGNUM is a bad spill reg. + (choose_reload_regs): HARD_FRAME_POINTER_REGNUM is a bad choice. + * reorg.c: (mark_referenced_resource): if frame_pointer_needed, + HARD_FRAME_POINTER_REGNUM is also a referenced resource. + (mark_target_live_regs): value in HARD_FRAME_POINTER_REGNUM is not + call-clobbered. + (dbr_schedule): HARD_FRAME_POINTER_REGNUM should be valid at the + end of a function. + * rtlanal.c: (rtx_unstable_p): HARD_FRAME_POINTER_REGNUM is not + an unstable register. + (rtx_varies_p, case REG): hard_frame_pointer_rtx is invariant. + (rtx_addr_can_trap_p, case REG): hard_frame_pointer_rtx won't trap. + * sched.c: (memrefs_conflict_p): We can work out whether references + via hard_frame_pointer_rtx are likely to conflict. + (attach_deaths, case REG): Don't add death notes for + HARD_FRAME_POINTER_REGNUM. + * sdbout.c: (sdbout_symbol): Use HARD_FRAME_POINTER_REGNUM instead of + FRAME_POINTER_REGNUM. + * stmt.c: (expand_goto): Set hard_frame_pointer_rtx when restoring + the frame. Use it when restoring other registers. + (expand_end_bindings): ARG_POINTER_REGNUM will be eliminated into + HARD_FRAME_POINTER_REGNUM, not FRAME_POINTER_REGNUM; adjust code + accordingly. + * stupid.c: (stupid_find_reg): never use HARD_FRAME_POINTER_REGNUM. + + Fri Sep 24 15:05:14 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * reload1.c (eliminate_regs): Specially handle the case where INSN + is a note (an EXPR_LIST or INSN_LIST). + (eliminate_regs_in_insn): Pass the notes as INSN, + when calling eliminate_insn to process the notes. + + Fri Sep 24 11:29:26 1993 Michael Meissner (meissner@osf.org) + + * i386/osfrose.h (SET_ASM_OP): Define. + + Fri Sep 24 04:47:33 1993 Jan Brittenson (bson@nutrimat.gnu.ai.mit.edu) + + * Makefile.in (toplev.o): Add bytecode.h and bc-emit.h to list + of dependencies. + (stmt.o): Add bytecode.h, bc-typecd.h, bc-opcode.h, bc-optab.h, + and bc-emit.h to list of dependencies. + (expr.o): Add bytecode.h, bc-opcode.h, bc-typecd.h, bc-optab.h, + bc-emit.h, and modemap.def to list of dependencies. + (emit-rtl.o): Add bytecode.h, bc-opcode.h, bc-typecd.h, + bc-optab.h, bc-emit.h, bc-opname.h to list of dependencies. + (integrate.o, regclass.o, varasm.o, function.o): Add bytecode.h to + list of dependencies. + + Thu Sep 23 23:58:58 1993 James Van Artsdalen (james@bigtex.cactus.org) + + * att.h (ASM_OUTPUT_ASCII): Enclose macro in "do { .. } while (0)". + * sun386.h (ASM_OUTPUT_ASCII): Likewise. + + Thu Sep 23 11:55:47 1993 Ted Lemon (mellon@ncd.com) + + * toplev.c (lang_options): Add -fallow-single-precision. + + Thu Sep 23 00:40:28 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * Makefile.in (bi-parser.c): Supply explicit rule. + Add bi-parser.h as target. + Put these files in srcdir. + + * bc-emit.c (bc_gen_rtx): Call gen_rtx. + (bc_print_rtl): #if 0 the contents. + + * Makefile.in (bc-optab.o, bc-emit.o): Add missing deps. + (bi-parser.c, bi-lexer.c): Don't depend on .h files here. + + * varasm.c (handle_pragma_weak): Test HANDLE_PRAGMA_WEAK + and WEAK_ASM_OP and SET_ASM_OP. + + * Makefile.in (stmt.o): Fix typo. + + * emit-rtl.c (gen_label_rtx): If output_bytecode, make a CODE_LABEL + but with different contents. + + * rtl.h (BYTECODE_LABEL, BYTECODE_OFFSET, BYTECODE_BC_LABEL): + (BYTECODE_UID): New macros. + (struct rtx_def): Delete elements label, offset, bc_label, uid. + + * Makefile.in (bc-arity.h, bc-opcode.h, bc-opname.h): Use `./'. + (bi-arity, bi-opcode, bi-opname, bi-lexer): Use host compiler. + Link with HOST_LIBS and depend on HOST_LIBDEPS. + (bi-unparse): Deleted. + (bytecode.distclean): Don't do anything with bi-unparse + (bi-arity.o, bi-opcode.o, bi-opname.o, bi-parser.o, bi-reverse.o) + (bi-lexer.o): Use host compiler. + + * expr.c (expand_increment): Don't store directly ito a subreg + that is narrower than a word. + + Wed Sep 22 22:18:35 1993 Chip Salzenberg (chip@fin.uucp) + + * combine.c (init_reg_last_arrays): New function. + (combine_instructions): Use it. + (force_to_mode): Narrow mask to fit mode (except VOIDmode). + (record_value_for_reg): When zeroing reg_last_set_value, also + zero reg_last_set_{mode,nonzero_bits,sign_bit_copies}. + (record_dead_and_set_regs): Likewise. + + Wed Sep 22 22:13:07 1993 James Van Artsdalen (james@bigtex.cactus.org) + + * bc-emit.c (bc_initialize): Add MODE arg to REAL_VALUE_ATOF calls. + + * Makefile.in (bi-lexer.c): File is in $(srcdir). + + * reg-stack.c (record_label_references): Don't follow a null label + reference chain. + + Wed Sep 22 15:56:27 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * Makefile.in (bi-arity, bi-opcode, bi-opname, bi-unparse, bi-lexer): + Make the rules explicit. Don't use $^. + (bi-run.o, bi-parser.o, bi-lexer.o): Eliminate $<. + (bc-arity.h, bc-opcode.h, bc-opname.h): Eliminate $< and $@. + + * c-typeck.c (set_init_index): Handle and allow CONST_DECL. + (build_c_cast): When making a CONSTRUCTOR for a union cast, + specify its type. + + * Makefile.in (bi-lexer.o, bi-parser.o): Use ALL_CFLAGS. + + * bi-arity.c (main): Make sure there's some value within + each pair of braces. + + * expr.c (bc_adjust_stack): Use VALIDATE_STACK_FOR_BC, + not VALIDATE_STACK. + * bc-emit.c (bc_emit_bytecode): Likewise. + (bc_emit_instruction) [! __GNUC__]: Don't really use bc-typecd.def. + + * varasm.c (bc_assemble_integer): Make definition static. + + * expr.c (bc_strdup): Don't use strcpy's value. + + * bytetypes.h: New file. Typedefs moved from bytecode.h. + (union stacktype): Moved here. + * bytecode.h: Typedefs deleted. + * bi-run.h: (union stacktype): Deleted. + (BI_PARAMS): Don't continue the parmlist. + * bc-emit.c: Include bytetypes.h, if __GNUC__. + + Wed Sep 22 15:49:47 1993 Ted Lemon (mellon@ncd.com) + + * c-decl.c (flag_allow_single_precision): New variable. + (c_decode_option): Handle -fallow-single-precision. + * c-tree.h (flag_allow_single_precision): Declared. + * c-typeck.c (default_conversion): Implement -fallow-single-precision. + + Wed Sep 22 11:18:24 1993 Mike Stump (mrs@cygnus.com) + + * cp-class.c (finish_struct): Move special C++ only code that + handles anonymous unions inside structures here. + * stor-layout.c (layout_record): From here. + + Wed Sep 22 14:14:55 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * enquire.c (FPROP): Recognize 80387 or 68881 XFmode format. + + * c-typeck.c (build_component_ref): For a field in an anonymous union, + make two nested COMPONENT_REFs. + (lookup_field): Additional arg INDIRECT. + + Wed Sep 22 14:45:42 1993 Kresten Krab Thorup (krab@iesd.auc.dk) + + * tm.texi (CLEAR_INSN_CACHE): New macro. + * libgcc2.c (__clear_cache): add case for new CLEAR_INSN_CACHE. + + * libgcc2.c (__enable_execute_stack): Add case for NeXT/__MACH__. + * config/m68k/next.h (INITIALIZE_TRAMPOLINE): Append call to + __enable_execute_stack. + (CLEAR_INSN_CACHE): New macro. + + * varasm.c (output_constructor): Use the type given + by the constructor expression only if available. Otherwise + use the type of the declared type. + + Tue Sep 21 19:51:26 1993 Andrew McCallum (mccallum@vein.cs.rochester.edu) + + * objc/Object.[hm] (-compare:, -shouldNotImplement:): Added. + + * objc/archive.c (objc_write_type, objc_write_types): Take + take char** args for writing strings in stead of char* to + match NeXT. Also correct some typos in error messages. + + Tue Sep 21 18:35:04 1993 Per Bothner (bothner@kalessin.cygnus.com) + + * c-typeck.c (push_member_name): Take a decl instead of a string. + Allow DECL_NAME to be NULL (anonymous fields). + * c-typeck.c (push_init_level, process_init_element): Change + callers appropriately. + + Tue Sep 21 16:44:17 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * libgcc2.c (L_bb): Test inhibit_libc. + + * Makefile.in (ENQUIRE, CROSS_TEST): New variables. + (all.cross): Use them. + + * mips-tfile.c, mips-tdump.c [CROSS_COMPILE]: Include mips/a.out.h. + + * arm.h, clipper.h, i386.h, i860.h, pyr.h, spur.h: + (INIT_CUMULATIVE_ARGS): Pass just the return value type + to aggregate_value_p. + + Tue Sep 21 10:50:19 1993 Jan Brittenson (bson@nutrimat.gnu.ai.mit.edu) + + * emit-rtl.c (gen_label_rtx, emit_line_note): add conditional for + bytecode. + + * expr.c (mode_to_const_map, mode_to_load_map, mode_to_store_map): + new variable. + (bc_init_mode_to_opcode_maps): new function; initialize maps. + (expand_assignment, expand_expr, expand_increment): add + conditional for bytecode. + (bc_expand_expr, bc_load_memory, bc_store_memory, + bc_allocate_local, bc_allocate_variable_array, bc_load_externaddr, + bc_strdup, bc_load_externaddr_id, bc_load_localaddr, + bc_load_parmaddr, bc_canonicalize_array_ref, + bc_expand_component_address, bc_push_offset_and_size, + bc_expand_address, bc_runtime_type_code, bc_gen_constr_label, + bc_expand_constructor, bc_store_field, bc_store_bit_field, + bc_load_bit_field, bc_adjust_stack): new function. + + * function.c (put_var_into_stack, expand_main_function): do + nothing for bytecode. + (bc_build_calldesc): new function. + (init_function_start): use it if outputting bytecode. + (expand_function_start, expand_function_end): add conditional for + bytecode. + (bc_expand_function_start, bc_expand_function_end): new function. + + * integrate.c (output_inline_function): signal error for bytecode. + + * regclass.c (fix_register): signal error for bytecode. + + * stmt.c (struct nesting): new members bc_stack_level, skip_label). + (struct goto_fixup): new members bc_target, label, bc_handled, + bc_stack_level. + (emit_nop, expand_computed_goto, expand_label, expand_goto, + expand_goto_internal, fixup_gotos, expand_asm, + expand_asm_operands, expand_expr_stmt, expand_start_expr_stmt, + expand_end_expr_stmt, expand_start_cond, expand_start_else, + expand_end_cond, expand_start_loop, expand_loop_continue_here, + expand_end_loop, expand_exit_loop_if_false, expand_null_return, + expand_return, expand_start_bindings, expand_end_bindings, + expand_decl, expand_start_case, pushcase, + check_for_full_enumeration, expand_end_case): add conditional for + bytecode. + (bc_expand_goto_internal, bc_expand_fixup, bc_fixup_gotos, + bc_expand_start_cond, bc_expand_end_cond, bc_expand_start_else, + bc_expand_end_bindings, bc_expand_decl, + bc_expand_variable_local_init, bc_expand_decl_init, + bc_expand_start_case, bc_pushcase, + bc_check_for_full_enumeration_handling, bc_expand_end_case, + bc_new_uid): new function. + + * toplev.c (output_bytecode): new variable. + (f_options): add entry for -fbytecode. + (fatal_insn_not_found, compile_file, rest_of_decl_compilation, + rest_of_compilation, main): add conditional for bytecode. + + * config/m68k/m68k.c config/m68k/m68k.h: add bytecode specific + definitions. + + * varasm.c (text_section, data_section, make_function_rtl, + make_decl_rtl, assemble_asm, assemble_start_function, + assemble_zeros, assemble_string, assemble_variable, + assemble_external, assemble_external_libcall, assemble_label, + assemble_name, assemble_static_space, + assemble_trampoline_template, assemble_integer, assemble_real, + decode_addr_const, output_constant_def, output_constant_pool, + output_constant, output_constructor): add conditional for + bytecode. + (bc_output_constructor, output_byte_asm, bc_make_rtl, + bc_output_data_constructor, bc_assemble_integer): + new function. + (handle_pragma_weak): break out asm writing code from + handle_pragma_token, move to varasm.c, so bytecode-specific + macros can access static varasm data and functions. + + * c-pragma.c (handle_pragma_token): use handle_pragma_weak. + + * function.h (enum pragma_state): moved from c-pragma.c + + * bc-config.h, bc-emit.c, bc-optab.c, bc-optab.h, bc-trans.h, + bc-typecd.def, modemap.def, bytecode.def, bc-emit.h, bc-typecd.h, + bi-arity.c, bi-defs.h, bi-lexer.c, bi-opcode.c, bi-opname.c, + bi-parser.c, bi-parser.h, bi-reverse.c, bi-run.c, bi-run.h, + bi-unparse.c: new file. bc-* are exclusively compiler files, bi-* + are interpreter files. + + * Makefile.in: add rules and/or dependencies for bc-emit.o, + bc-optab.o, bytecode, bi-arity, bi-opcode, bi-opname, bi-lexer, + bi-run.o, bi-parser.c, bi-parser.o, bi-lexer.o bi-arity.o, + bi-opcode.o, bi-opname.o, bi-reverse.o, bc-arity.h, bc-opcode.h, + bc-opname.h, bytecode.mostlyclean, bytecode.distclean, + bytecode.realclean + + + Tue Sep 21 10:20:55 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * jump.c (jump_optimize): Try putting RETURN at end of function + both at start and at end of our optimization. + + Mon Sep 20 17:22:13 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * expr.c (expand_expr): Handle flag_volatile here. + * c-typeck.c (build_indirect_ref): TREE_THIS_VOLATILE no longer + depends on flag_volatile. + + Mon Sep 20 15:21:31 1993 Doug Evans (dje@cygnus.com) + + * gstddef.h: Back out change of Sep 15 (handles Sun lossage). + Prevented bootstrapping. + + Mon Sep 20 12:21:56 1993 Kresten Krab Thorup (krab@iesd.auc.dk) + + * objc/archive.c (objc_read_string): Allocate n+1 chars instead of + just n. + + Sun Sep 19 13:06:37 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * function.c (combine_temp_slots): Handle deletion properly. + Free the RTL that is allocated. + * rtl.c (rtx_free): New function. + + * config/m68k/m68k.c (output_move_double): Handle register overlap + case that occur in soft-float XFmode. Code basically copied from + i386.c. + + Sun Sep 19 14:40:08 JDT 1993 Michael Ben-Gershon (mybg@cs.huji.ac.il) + + * cse.c (simplify_unary_operation): If REAL_ARITHMETIC is defined, + and a FIX operation is applied to convert a CONST_DOUBLE to an INT, + the CONST_DOUBLE must first be rounded to zero. + + Sun Sep 19 12:49:05 1993 James Van Artsdalen (james@bigtex.cactus.org) + + * Makefile.in (objc-headers): Depend on stmp-fixinc to build the + include/ subdirectory first. + + Sun Sep 19 09:45:16 1993 Richard Earnshaw (rwe11@cl.cam.ac.uk) + + * gstddef.h (size_t): Acorn RISCiX requires __size_t defined. + + Sun Sep 19 09:08:09 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * genrecog.c (preds): Correct typo in name of `comparison_operator'. + (add_to_sequence): If PREDICATE_CODES specified, warn if we find a + predicate not in that list. + + * reload.c (find_reloads): Reject an alternative if two operands + match the same output and we have to do a reload. + + * rs6000.c (rs6000_override_options): Change processor type to + "rios1"; allow "rios" as synonym. + Add synonyms for "mpc6xx". + * rs6000.h (enum processor_type): Change from RIOS to RIOS1. + (PROCESSOR_DEFAULT): Likewise. + * rs6000.md (attribute "cpu"): Change from "rios" to "rios1"; all + uses changed. + + * xm-alpha.h: Add extern declaration for alloca. + + * a29k.h (PREDICATE_CODES): Fix typos and add missing entries. + * alpha.h, i860.h i960.h, m88k.h, mips.h, rs6000.h: Likewise. + + Sat Sep 18 09:27:03 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * expr.c (convert_move): Use emit_library_call_value. + + Sat Sep 18 08:01:44 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * alpha.h (REG_ALLOC_ORDER): Add missing entries. + + * combine.c (recog_for_combine): Fix typos in previous change. + + * reload.c (earlyclobber_operand_p): New function. + (combine_reloads): Use it. + (find_reloads): Set reload_earlyclobbers earlier. + (refers_to_regno_for_reload_p): Count something being stored into + if it is an earlyclobber operand. + + Fri Sep 17 21:40:02 1993 Per Bothner (bothner@cygnus.com) + + * fold-const.c (invert_truthvalue): Instead of aborting, + build a TRUTH_NOT_EXPR when unable to optimize. + (The aborts were not a problem for C, which always first + calls truthvalue_conversion, but that should not be + necessary for a language with real Booleans.) + + Fri Sep 17 20:38:53 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c (output_init_element): Update constructor_bit_index + for union types. + + * libgcc2.c: Declare __fixunsxfdi only if really have XFmode. + Likewise for __fixunstfdi. + + Fri Sep 17 18:08:37 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * combine.c (recog_for_combine): Always reject a PARALLEL containing + our special CLOBBER. + + * cse.c (fold_rtx, case MINUS): Copy result obtained from + hash table. + + * cse.c (fold_rtx, case SUBREG): If paradoxical SUBREG of a + constant, return the constant. + + * c-typeck.c (lookup_field): Use HOST_WIDE_INT instead of long or + int when we want integer wide enough to hold a pointer difference. + + Fri Sep 17 16:03:22 1993 Per Bothner (bothner@cygnus.com) + + * dbxout.c (dbxout_type): For CHAR_TYPE and BOOLEAN_TYPE (in + languages that have them - not C), adopt an AIX convention + to distinguish these from other types. + + Fri Sep 17 09:02:06 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * expr.h (emit_library_call_value): Fix declaration. + + Thu Sep 16 12:05:44 1993 Ian Lance Taylor (ian@cygnus.com) + + * Makefile.in (fixinc.ready): New target, like libgcc2.ready, + depending on xgcc and cpp. + (stmp-fixinc): Depend on fixinc.ready instead of xgcc and cpp. + (clean): Remove fixinc.ready. + + Thu Sep 16 10:22:17 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * reload.c (find_reloads): For PLUS operand, call find_reloads_toplev. + + * optabs.c (expand_complex_abs): Fix typo in prev change. + + Thu Sep 16 02:06:11 1993 Jim Wilson (wilson@cygnus.com) + + * flags.h (current_function_has_nonlocal_goto): Declare. + * function.h (struct function): New field has_nonlocal_goto. + * function.c (current_function_has_nonlocal_goto): New var. + (push_function_context): Save it. + (pop_function_context): Restore it. + (init_function_start): Init it. + * integrate.c (function_cannot_inline_p): Don't inline if it's set. + * stmt.c (expand_goto): Set it. + + * reorg.c (mark_set_resources): For CALL_INSN, if followed by a + NOTE_INSN_SETJMP note, then assume that all registers are clobbered. + Handle case where CALL_INSN is in a sequence. + + Wed Sep 15 17:38:38 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * gstddef.h: Delete the conditional that used to semi-avoid + interference with sys/stdtypes.h on Sun. (fixincludes makes + it ok.) + + Wed Sep 15 16:17:09 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * pa.h (ASM_FILE_START): Fix access information for $LIT$ + subspace. + + Wed Sep 15 14:53:49 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * config/ns32k/ns32k.md: Add peepholes for stack adjust plus pushes. + + Wed Sep 15 13:38:24 1993 Doug Evans (dje@canuck.cygnus.com) + + * c-typeck.c (lookup_field): New function (for chill). + (build_component_ref): Call it. + + Wed Sep 15 08:12:32 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * libgcc2.c: Declare __fixunsxfdi and __fixunstfdi. + + * integrate.c (copy_for_inline, copy_rtx_and_substitute): + Always preserve the volatil flag when copying ASM_OPERANDS. + + Tue Sep 14 21:56:20 1993 Jim Wilson (wilson@cygnus.com) + + * c-typeck.c (valid_compound_expr_initializer): New function. + (digest_init): Handle compound expressions as initializers when + pedantic. + + * varasm.c (immed_double_const, immed_real_const_1): Don't touch + const_double_chain if not inside a function. + + Tue Sep 14 16:22:03 1993 Per Bothner (bothner@wombat.gnu.ai.mit.edu) + + * c-typeck.c (digest_init): Compare types using comptypes + instead of comparing pointers. (Helps Chill front end.) + + Tue Sep 14 12:16:52 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * calls.c (emit_library_call_value): Finish making it work. + * optabs.c (expand_float): Use emit_library_call_value. + (expand_unop, expand_binop): Likewise. + (expand_complex_abs): Likewise. + Also pass SUBMODE as output mode to emit_library_call_value. + * function.c (aggregate_value_p): Allow type node as argument. + + * config/ns32k/ns32k.h (FUNCTION_PROLOGUE, FUNCTION_EPILOGUE): + If omitting frame pointer, output an adjspd if necessary. + Use movd to save registers if four or less need saving. + Set DEPTH properly. + + * reload.c (find_dummy_reload): New args inmode, outmode. + (find_reloads): Pass new args. + (push_reload): Likewise. + + Mon Sep 13 12:52:03 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c (set_init_index): Don't allow variable indices. + + * c-decl.c (complete_array_type): Handle TREE_PURPOSE + of array constructor elements. + + * expr.c (store_constructor): Handle TREE_PURPOSE of array constructor. + (expand_expr, ARRAY_REF case): Likewise. + + * varasm.c (output_constructor): Handle index value in + the TREE_PURPOSE, for array constructors. + + * c-typeck.c (output_init_element): When putting an elt into a + CONSTRUCTOR, always set the TREE_PURPOSE (even for arrays). + Copy the node if it's an INTEGER_CST. + (output_pending_init_elements): If have gap and not incremental, + advance constructor_unfilled_fields or constructor_unfilled_index. + + Sun Sep 12 23:00:25 1993 Per Bothner (bothner@wombat.gnu.ai.mit.edu) + + * expr.c (expand_expr, case ARRAY_REF): Coerce lower bound (if + non-zero) to sizetype before subtraction. + + Sun Sep 12 16:18:18 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c (push_init_level): Pop any implicit levels + that have been filled up. + Don't die if constructor_type is 0. + (process_init_element): If VALUE is 0 for union type, + update constructor_bit_index. + + Sun Sep 12 10:59:08 1993 Bill Cox (bill@cygnus.com) + + * c-typeck.c (digest_init): Remove obsolete comments on args + TAIL, OF_WHAT. + + Sun Sep 12 08:45:36 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * loop.c (basic_induction_var): New arg MODE. + Use it to call convert_modes. + (strength_reduce): Supply the new arg to basic_induction_var. + + * expmed.c (expand_shift): Use convert_modes. + (emit_store_flag): Likewise. + + Sat Sep 11 16:44:15 1993 Doug Evans (dje@canuck.cygnus.com) + + * collect2.c (main): Provide upward compatibility with old version + of collect (avoids infinite mutual recursion between the two). + + Sat Sep 11 13:05:07 1993 Per Bothner (bothner@wombat.gnu.ai.mit.edu) + + * c-typeck.c (constructor_no_implicit): New variable. + If set, dis-allows eliding of braces in initializers. + (Set by Chill front-end.) + * c-typeck.c (process_init_element): Use it. + + Sat Sep 11 15:55:25 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * stor-layout.c (layout_record): Turn off PCC_BITFIELD_TYPE_MATTERS + rounding of field bitpos, if maximum_field_alignment is nonzero. + + Fri Sep 10 08:52:01 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c (check_init_type_bitfields): Check for mismatch + between field's mode and its type's mode. + + * expr.c (protect_from_queue): Don't alter an existing MEM. + (convert_modes): Use X's mode (not OLDMODE) unless it is VOIDmode. + + Fri Sep 10 01:01:32 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * config.sub: Recognize operating system `netbsd*'. + + Thu Sep 9 18:09:14 1993 Per Bothner (bothner@wombat.gnu.ai.mit.edu) + + * c-typeck.c (really_start_incremental_init, push_init_level): + Add support for arrays with non-zero lower bounds. (Used by Chill.) + + Thu Sep 9 19:20:59 1993 Jim Wilson (wilson@cygnus.com) + + * tree.c (make_node): Put PARM_DECLs of nested functions onto + parent's saveable obstack. + + Thu Sep 9 14:17:00 1993 Ian Lance Taylor (ian@cygnus.com) + + * Makefile.in (CROSS_LIBGCC1): New variable. Rule to use when + building libgcc1.a for a cross compiler. Defaults to + libgcc1.cross. + * cross-make (LIBGCC1): Default to $(CROSS_LIBGCC1) rather than + libgcc1.cross. + * config/i386/t-next, config/i386/t-sol2, config/m88k/t-dgux, + config/m88k/t-luna, config/m88k/t-dgux-gas, + config/m88k/t-luna-gas, config/m88k/t-m88k, + config/m88k/t-m88k-gas, config/m88k/t-sysv4, + config/m68k/t-next, config/mips/t-bsd, config/mips/t-bsd-gas, + config/mips/t-mips, config/mips/t-mips-gas, + config/mips/t-osfrose, config/mips/t-svr3, + config/mips/t-svr3-gas, config/mips/t-svr4, + config/mips/t-svr4-gas, config/mips/t-ultrix, config/pa/t-pa, + config/sparc/t-sol2, config/h8300/t-h8300, config/sh/t-sh, + config/t-libc-ok (CROSS_LIBGCC1): Defined to be libgcc1.null. + + Thu Sep 9 09:48:54 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * expr.c (expand_expr): Set ignore for COND_EXPR with VOID_TYPE. + + * expr.c (convert_modes): New function. + (convert_to_mode): Use that. + * expr.h (convert_modes): Declared. + * optabs.c (expand_twoval_binop): Use convert_modes. + (expand_complex_abs): Likewise. + (emit_cmp_insn): Likewise. + (expand_inline_function): Likewise. + * expmed.c (expand_divmod): Likewise. + (emit_store_flag): Likewise. + * loop.c (basic_induction_var): Likewise. + * integrate.c (expand_inline_function): Likewise. + + * optabs.c (widen_operand): New arg OLDMODE. + (expand_binop, expand_unop): Fix calls to widen_operand. + + Wed Sep 8 18:25:50 1993 Doug Evans (dje@cygnus.com) + + * sparc.c, sparc.h, sparc.md: Cosmetic changes only. Just + reordered code a little. + + Wed Sep 8 14:49:59 1993 Jim Wilson (wilson@cygnus.com) + + * dbxout.c (dbxout_parms): For parameters in registers, if use + DECL_RTL, then must use TREE_TYPE instead of DECL_ARG_TYPE. + + * mips.md (fix_truncdfsi2, fixtruncsfsi2): Mark SImode scratch + register as early clobbered when dest is in memory. + + * fixincludes (sbusdev/audiovar.h): Fix wrongly edited // comments + nested within /* */ comments. + + * gcc.c (process_command): Don't warn for -x after last input file + if spec_lang is zero. + + * fixinc.mips (bsd43/bsd43.h): Change /**/ to ##. + + * expr.c (convert_move): When truncating, call force_reg first if + it is something that gen_lowpart won't understand. + + * sys-protos.h (getrlimit, getrusage, setrlimit): Return int not void. + + Wed Sep 8 11:28:41 1993 John Hassey (hassey@dg-rtp.dg.com) + + * m88k.c (output_call): Avoid use of jsr.n r1, this loses on + the 88110. + + Wed Sep 8 10:51:07 1993 David Edelsohn (edelsohn@npac.syr.edu) + + * rs6000.h: (MASK_*, TARGET_*): Add target masks and tests. + (TARGET_SWITCHES): Add target switches for various architectures + and mnemonics options. + (TARGET_OPTIONS): Add cpu type as special target option. + (OVERRIDE_OPTIONS): Call rs6000_override_options to decipher. + + * rs6000.c (rs6000_cpu, rs6000_cpu_string): New variables. + (rs6000_override_options): New function. + + * rs6000.md (define_attr): Expand list of instruction attributes. + (define_function_unit): Compute delay information based + upon processor type and expand functional unit types. + (mulsi3, divsi3, divmodsi4, divsf3, divdf3, muldf3, movsf): + Use expanded attributes. + (load with update): Likewise. + + Wed Sep 8 06:34:32 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c (output_init_element): When adding to + constructor_pending_elts, copy field. + + Wed Sep 8 06:15:58 1993 David Gershovich (dgirsh@iil.intel.com) + + * expmed.c (make_tree, case CONST_INT): Properly set high part if + unsigned. + + * optabs.c (expand_binop): Must always widen second operand + of shift. + + Wed Sep 8 05:16:59 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c (push_init_level): Diagnose extra brace group at end + of record. Set constructor_type to 0. + (pop_init_level): Don't output anything if constructor_type is 0. + (process_init_element): Do nothing if constructor_type is 0. + + Tue Sep 7 19:11:20 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * c-common.c (c_build_type_variant): Allocate new type in same + obstack as old one. + + Tue Sep 7 17:45:50 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c (digest_init): Fix error message text. + + Tue Sep 7 14:32:51 1993 Leonid Baraz (lbaraz@iil.intel.com) + + * sched.c (schedule_block): Correct type of BIT. + + * fold-const.c (fold): Don't try to process an RTL_EXPR. + + Tue Sep 7 06:18:50 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * dbxout.c (dbxout_type): Handle enum constants bigger than one word. + Don't print big unsigned values as negative. + * c-decl.c (build_enumerator): Choose type properly for wide constants. + (finish_enum): Always set type of the enumerators to the enum type. + * c-typeck.c (default_conversion): For enum that's unsigned, + if it's at least as wide as int, convert to an unsigned type. + + * config/i386/sol2.h (LIB_SPEC, LINK_SPEC, SWITCH_TAKES_ARG): + Definitions copied from sparc/sol2.h. + (CPP_SPEC): Copied from sparc/sol2.h, but deleted -msparclite. + + Mon Sep 6 14:43:20 1993 Richard Earnshaw (rwe11@cl.cam.ac.uk) + + * genextract.c (insn_name_ptr): Define for debugging. + (walk_rtx, case MATCH_OP_DUP): Expand recog_dup_loc using XEXP not + XVECEXP. + + Mon Sep 6 13:28:03 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * rtlanal.c (modified_between_p): Handle vectors. + (modified_in_p): New function. + (refers_to_regno_p): If setting AP, FP, or SP, we clobber the + virtual registers. + * optabs.c (emit_libcall_block): Don't move insns that reference + things set in previous insns. + + Mon Sep 6 08:35:34 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * config/mips/mips.h: Don't declare abort. + + Mon Sep 6 01:03:58 1993 Jim Wilson (wilson@cygnus.com) + + * protoize (abort): Correct volatile function declaration. + + Sun Sep 5 18:23:09 1993 Doug Evans (dje@canuck.cygnus.com) + + * Makefile.in (USER_H): Add va-h8300.h. + + * collect2.c (our_file_name, last_file_name): deleted. + (our_file_names): New variable. + (is_in_prefix_list): New function. + (find_a_file): Call is_in_prefix_list. + (main): Make COLLECT_NAMES a list of our invocations. + If we've invoked ourselves, try again with ld_file_name. + + Sun Sep 5 16:00:47 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * function.c (assign_parms): When parm needs conversion on entry, + don't store it back in the slot where it was passed. + + Sun Sep 5 14:51:14 1993 Jim Wilson (wilson@sphagnum.cygnus.com) + + * c-decl.c (grokdeclarator): For PARM_DECLs, only call + c_build_type_variant is constp or volatilep is true. + + Sun Sep 5 06:44:09 1993 David Edelsohn (edelsohn@npac.syr.edu) + + * rs6000.c: (print_operand): Convert fprintf of single letters + to putc and convert fprintf of constant strings to fputs. + Output '%u' operand as hexadecimal. + + Sat Sep 4 11:16:18 1993 Craig Burley (burley@gnu.ai.mit.edu) + + * c-common.c (truthvalue_conversion): A complex value is nonzero + if either part is nonzero, not if both parts are nonzero. + + Fri Sep 3 19:02:41 1993 Paul Eggert (eggert@twinsun.com) + + * c-decl.c (build_enumerator): Apply default conversion to + constant-expression. + + Fri Sep 3 18:03:47 1993 Chris Lang (chrisl@mirc00.ncms.org) + + * cccp.c (skip_if_group): Check for traditional mode when + skipping ahead to next #, ignore unless at beginning of line. + + Fri Sep 3 18:00:15 1993 Michael Meissner (meissner@osf.org) + + * i386/osfrose.h, i386/osfelf.h (LINK_SPEC): Pass -v and -dn on to + the ELF linker, which now accepts these switches. + + Fri Sep 3 13:34:22 1993 Doug Evans (dje@cygnus.com) + + * i386/x-linux: Add -Iinclude to BOOT_CFLAGS. + + Fri Sep 3 01:54:19 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * pa.h (READONLY_DATA_ASM_OP): Define. + (READONLY_DATA_SECTION): Define. + (EXTRA_SECTIONS): Add in_readonly_data. + (EXTRA_SECTION_FUNCTIONS): Add readonly_data. + + Thu Sep 2 19:19:14 1993 Holger Teutsch (holger@hotbso.rhein-main.de) + + * clipper.h : Improve generated code for C400 Clipper. + (TARGET_SWITCHES): New options `c300' `c400'. + (TARGET_C300, TARGET_C400): New defines. + (TARGET_DEFAULT): Define as TARGET_C300. + (CONDITIONAL_REGISTER_USAGE): New define. + + Thu Sep 2 17:47:57 1993 Doug Evans (dje@canuck.cygnus.com) + + * glimits.h (__INT_MAX__, __LONG_MAX__, __LONG_LONG_MAX__): New macros. + (INT_MAX, LONG_MAX, LONG_LONG_MAX): Use them. + (UINT_MAX, ULONG_MAX, ULONG_LONG_MAX): Ditto. + + Thu Sep 2 14:26:28 1993 Michael Meissner (meissner@osf.org) + + * i386/osfrose.h (YES_UNDERSCORES): Delete macro, since we have + redefined all of the macros that are based on using it. + (CPP_SPEC, CC1_SPEC): Remove #ifndef NO_UNDERSCORE version. + OSF/ELF will now omit the leading underscore by default. + (LINK_SPEC): Pass -dy through to ELF linker. Do not pass -v to + ELF linker. + + * i386/osfelf.h (CPP_SPEC, CC1_SPEC): Remove #ifndef NO_UNDERSCORE + version. OSF/ELF will now omit the leading underscore by default. + (LINK_SPEC): Pass -dy through to ELF linker. Do not pass -v to + ELF linker. + + + * final.c (tree.h): Include tree.h to get the declaration for + decl_printable_name. + (last_filename): Global to hold last filename encountered in a + NOTE. + (add_bb): New function to do common code for emitting a basic + block profiling increment. Remember the current function, and if + debugging, line number and filename for each basic block. + (add_bb_string): New function to remember strings for profiling + basic blocks. + (end_final): Bump name array size to 20. Use BSS to store profile + block count array unless -fno-common. Eliminate redefining name + within for loop block. Add a length field and three new parallel + arrays for basic blocks to hold function name, and if debugging, + line number and file name for basic block profiling. + (final_start_function): Save a printable version of the current + function name away if profiling basic blocks. + (final_end_function): Forget the current printable version of the + current function name if profiling basic blocks. + (final): Move basic block profiling support to just call add_bb. + (final_scan_insn): Ditto. + (output_source_line): Save filename in last_filename. If the file + name was changed and profiling basic blocks, remember the new file + name for the next call to add_bb. + + * libgcc2.c (L_bb): If BLOCK_PROFILER_CODE is defined, expand it + here directly. If BLOCK_PROFILER_CODE is not defined, add code + that appends basic block profile information into a text file + bb.out. Move sun3 specific block profiling code to m68k/sun3.h. + + * Makefile.in (final.o): Final.c now includes tree.h. + + * m68k/sun3.h (BLOCK_PROFILER_CODE): Move the sun3 specific basic + block profiling code here from libgcc2.c. + + Wed Sep 1 19:00:06 1993 Jim Wilson (wilson@mole.gnu.ai.mit.edu) + + * rs6000.md (truncdfsf2): Round to single instead of doing nothing. + + * jump.c (jump_optimize): When optimize conditional jump around + unconditional jump, handle case where prev_label can be zero. + + * c-decl.c (finish_decl): For static const variables, preserve + initializers instead of discarding them. + + Wed Sep 1 18:43:01 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * reload.c (find_reloads): Bump REJECT for a hard register; just + not for a pseudo. + + * rs6000.md: Clean up hex constants a bit in emitted insns. + + * rs6000.c (input_operand): Allow "easy" FP constants. + * rs6000.h (SECONDARY_MEMORY_NEEDED): New macro. + * rs6000.md (movdf): Simplify by taking advantage of + having SECONDARY_MEMORY_NEEDED. + Fix bugs relating to order in which moves are done. + + Wed Sep 1 18:08:36 1993 Jim Wilson (wilson@cygnus.com) + + * reload.c (find_reloads_address_1): Handle SUBREGs same as REGs. + + Wed Sep 1 18:03:45 1993 Mike Stump (mrs@mole.gnu.ai.mit.edu) + + * collect2.c (is_ctor_dtor): Make sizeof argument match the + string. + + Wed Sep 1 15:01:48 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * Makefile.in (start.encap): Build g++ here also. + + Tue Aug 31 16:30:53 1993 Jim Wilson (wilson@cygnus.com) + + * combine.c (make_compound_operation): Handle the case + (and (xor/ior (lshift...) (lshift...)) ...). + (make_field_assignment): In get_pos_from_mask call, only invert + bits in mode mask. + + * reload.c (push_reload): Abort is secondary_reload wants same + class as an input reload. + + * Makefile.in (libgcc1.a, libgcc2.a): Don't use set -e. + * configure (i[34]86-*-lynxos, m68k-*-lynxos, sparc-*-lynxos): Use + xm-lynx.h, x-lynx. Don't run fixincludes. + * x-lynx, xm-lynx.h: New files. + + * Makefile.in (xsys-protos.h): Use fixtmp.c not tmp.c, and delete + it afterwards. + + * function.c (assign_stack_temp): When allocate a slot too large, + split extra off into a slot of its own. + (combine_temp_slots): New function. + (free_temp_slots, pop_temp_slots): Call combine_temp_slots. + + Tue Aug 31 06:35:37 1993 David Edelsohn (edelsohn@npac.syr.edu) + + * rs6000.md: (zero_extendqisi2, zero_extendqihi2): Change anonymous + patterns to use 16-bit and 32-bit hexadecimal values and masks + instead of bit ranges if constant. + (rotlsi3, lshrsi3, move condition codes, scc insns): Likewise. + + Tue Aug 31 06:25:52 1993 Paul Eggert (eggert@twinsun.com) + + * c-decl.c (struct c_function): Remove unneeded enum_next_value. + (push_c_function_context, pop_c_function_context): Don't save it. + + Mon Aug 30 16:16:56 1993 Paul Eggert (eggert@twinsun.com) + + * c-decl.c (get_parm_info, store_parm_decls): If PROMOTE_PROTOTYPE, + promote all integral types shorter than int, including short enums. + * c-typeck.c (convert_arguments): Likewise. + * cp-decl.c (grokparms): Likewise. + * cp-except.c (finish_exception_decl): Likewise. + * cp-typeck.c (convert_arguments): Likewise. + + Sun Aug 29 18:34:25 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * rs6000.h (TARGET_NO_FP_IN_TOC): New; deleted TARGET_FP_IN_TOC. + (TARGET_SWITCHES): Rearrange to have three TOC choices. + (ASM_OUTPUT_SPECIAL_POOL_ENTRY): Use TARGET_NO_FP_IN_TOC. + * rs6000.c (output_toc): Likewise. + + Sat Aug 28 15:04:35 1993 Jim Wilson (wilson@cygnus.com) + + * mips.h (SELECT_SECTION): Simplify sdata_section test. + + * lynx.h (CPP_SPEC): Use include_v not include-v. + (LINK_SPEC): Add missing `-' before `k' option. + (PREFERRED_DEBUGGING_TYPE): Define to DBX_DEBUG. + (SDB_DEBUGGING_INFO): Define. + (MD_EXEC_PREFIX): Define to /usr/local/lib/gcc-. + (LINK_LIBGCC_SPECIAL_1): Define. + (NAME__MAIN, SYMBOL__MAIN): Define. + + * sparc.h (EXTRA_CONSTRAINT): Delete 'S'. + * sparc.md (call+1, call+2, call_value+1, untyped_call+1): Split + into two patterns, one using address_operand and 'p', the other + immediate_operand and 'i'. + + Fri Aug 27 15:43:19 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * combine.c (nonzero_bits): Fix reversed test for when we + need to insert extra bits when sizes differ. + (nonzero_bits, case EQ): Always return STORE_FLAG_VALUE when returning + integer mode; remove now-redundant test. + + * rs6000.h (LINK_SPEC): Add -bexport:/usr/lib/libg.exp when -g. + + Fri Aug 27 13:17:28 1993 Jim Wilson (wilson@cygnus.com) + + * rs6000.c (print_operand_address): When TARGET_MINIMAL_TOC, use + r30 instead of r2 for TOC references. + (output_prologue): If TARGET_MINIMAL_TOC, and the constant pool + is needed, then setup r30. + (output_toc): When TARGET_MINIMAL_TOC, use .long instead of .tc. + * rs6000.h (TARGET_MINIMAL_TOC): New macro. + (TARGET_SWITCHES): Add -mminimal-toc and -mno-minimal-toc. + (ELIMINABLE_REGS): Add elimination for r30. + (CAN_ELIMINATE): Add case for r30. + (INITIAL_ELIMINATION_OFFSET): Add case for r30. + (toc_section): When TARET_MINIMAL_TOC, initialize toc_table. + + Thu Aug 26 17:59:38 1993 Doug Evans (dje@cygnus.com) + + * gstdarg.h, gvarargs.h: Add support for H8/300H. + * va-h8300.h: New file. + + Thu Aug 26 15:15:27 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + Cygnus<->FSF C++ front-end merge. + Wed Aug 25 17:55:58 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-class.c (alter_visibility): Properly grok protected visibility. + + Wed Aug 25 12:55:17 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-typeck.c (c_sizeof): If we're given an OFFSET_TYPE, work with + the type it refers to. + + * cp-decl.c (finish_function): Properly handle inline functions, + don't just call rest_of_compilation. + + * cp-decl2.c (flag_inline_debug): Deleted, never used. + (lang_f_options): Deleted -finline-debug. + * toplev.c (lang_options): Likewise. + + Tue Aug 24 16:06:23 1993 Mike Stump (mrs@poseidon.cygnus.com) + + * cp-dem.c: Deleted. See demangler in the binutils distribution. + + Tue Aug 24 14:24:34 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl.c (start_function): Don't get ready to complain about a + built-in C-linkage function against a C++-linkage function. + + Tue Aug 24 13:54:43 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) + + * g++.c: also include + + Tue Aug 24 05:39:57 1993 Michael Tiemann (tiemann@blues.cygnus.com) + + * cp-parse.y (id_scope): Renamed from scoped_id. Also added handler + for case when rule appears after `dont_see_typename' action. Now + handles pointer-to-member syntax. + + Mon Aug 23 14:04:34 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-parse.y (datadef): Disallow forward declaration of an enum. + + * cp-class.c (finish_struct): Set LAST_X to X, so we keep the chain + in some semblance of sanity. Makes more than one nested typedef + work properly. + * cp-decl.c (grokdeclarator): Rewrite how class-local typedefs are + handled to generate a TYPE_DECL that's useful. + + * cp-decl.c (start_function): Don't error out if it's a static + function; don't return 0, which can cause other problems. + + Sun Aug 22 18:00:57 1993 Michael Tiemann (tiemann@blues.cygnus.com) + + * cp-decl.c (duplicate_decls): Set DECL_OVERLOADED flag on "C" + functions so that they are treated properly when "C++" functions of + the same name are declared before they are. + + Sun Aug 22 13:31:44 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + Fix how we handle binding levels, and tweak Niklas's new scoping + code to work 100%. This work should significantly improve how + g++ handles the use of nested classes. + * cp-tree.h (NEW_CLASS_SCOPING): Default to 1 now! + * cp-decl.c (pop_binding_level): Set current_binding_level to be + class_binding_level if it's non-NULL. Change code that looks for + our method of climbing back up the binding levels when we're + dealing with a parm. + (pushlevel_class): Call push_binding_level, not pushlevel. + (poplevel_class): Don't weird out if level is 0. DO NOT set + class_binding_level to the level_chain, this was the biggest bug + that made the pushes and pops to end up being unbalanced. + Call pop_binding_level instead of manually putting the level on + the free_binding_level chain. + (pop_from_top_level): Don't call poplevel if previous_class is + non-NULL. + (finish_function): Call expand_start_bindings and + expand_end_bindings in a balanced way. + (finish_function): Don't flail around screwing with the RTL for + the function in a very special case, just always call + rest_of_compilation as we normally would. + (finish_method): Call poplevel, not pop_binding_level. + * cp-class.c (pushclass): Don't call unuse_fields. + * cp-tree.c (break_out_calls): Always call copy_node, not just + when changed++ == 0. + * cp-search.c (bridge_obstack): Deleted. + (push_class_decls): Use search_obstack, not bridge_obstack. + (init_search_processing): Don't init bridge_obstack anymore. + + * cp-init.c (build_new): Don't clear LOOKUP_COMPLAIN on flags, since + we need to honor the visibility of what we find. + + Sat Aug 21 12:07:26 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl.c (grokdeclarator): Give an error about an array of + offset types and method types, in addition to reference types. + Also make sure to set `type' to be error_mark_node for each. + + * cp-parse.y (primary, PLUSPLUS/MINUSMINUS): Resolve the OFFSET_REF + here. + * cp-typeck.c (build_x_unary_op): Not here. + + * cp-class.c (finish_struct): Set DECL_CLASS_CONTEXT only if it's + a virtual function. + * cp-decl.c (grokfndecl): Communicate the virtual bit to function + decls that overload a virtual function from a base class. + * cp-search.c (dfs_pushdecls): Look at DECL_CLASS_CONTEXT if it's + a virtual function. + + Fri Aug 20 13:35:54 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + Make the g++ driver work with MS-DOS. + * g++.c (P_tmpdir, {R,W,X}_OK) [__MSDOS__]: Defined. + (choose_temp_base_try, choose_temp_base, perror_exec, + run_dos) [__MSDOS__]: New functions for the g++ program to operate + correctly under MS-DOS. + (temp_filename, temp_filename_length) [__MSDOS__]: New variables. + (main): Fix off-by-one error in allocation of arglist. When + running the main GCC program, handle running it under OS/2, MS-DOS, + as well as on a system that has execvp(2). Only find the location + of the GCC executable if we're not using DOS. + + * cp-decl.c (poplevel): Only call remember_end_note if we haven't + already created the block. Set TREE_USED on the block. + (duplicate_decls): If the type of either the old or new decl is an + error_mark_node, we've already issued an error so set types_match + to be 1 now. + (xref_defn_tag): Mark the TYPE_DECL as ignored if doing dwarf + debugging. + + * cp-parse.y (base_init, nodecls): Call keep_next_level to make + sure the BLOCK node is kept with the outermost curly braces of a + function. + (compstmt): For `{ }', insert a .pushlevel and do all of the other + stuff we need in every other compstmt situation, to generate proper + debugging for such things and handle the binding levels properly for + them. + + Thu Aug 19 18:24:25 1993 Mike Stump (mrs@cygnus.com) + + * cp-init.c (build_vec_delete): Wrap void COND_EXPR in NOP_EXPR, so + that the backend does not abort when trying to use the void mode + expression. Fixes make check (tString.o) in libg++. + + Thu Aug 19 12:21:12 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-typeck.c (build_x_unary_op): When we receive an OFFSET_REF, + resolve it before looking for a way to handle the operation. + + * cp-method.c: Include ctype.h. + + Thu Aug 19 12:00:08 1993 Mike Stump (mrs@cygnus.com) + + * cp-class.c, cp-search.c (NEW_SEARCH, NEW_CONVERT, + CHECK_convert_pointer_to_single_level): Remove ability to revert to + old code, and remove checks. Cleans-up the code a little. + + Thu Aug 19 00:41:55 1993 Mike Stump (mrs@cygnus.com) + + * cp-init.c (expand_aggr_init): Avoid faulting, give error instead. + + Wed Aug 18 22:43:25 1993 Mike Stump (mrs@cygnus.com) + + * cp-lex.h (RID_BIT_TYPE, RIDBIT_SETP, RIDBIT_NOTSETP, RIDBIT_SET, + RIDBIT_RESET, RIDBIT_RESET_ALL, RIDBIT_ANY_SET): New RID macros, + replaces RIDBIT macro. The new macros allow us to easily expand + past 32 RIDs. + * cp-decl.c (grokvardecl, grokdeclarator): Use them. + + * cp-decl.c (grokdeclarator): Implement `mutable' keyword. + * cp-lex.c (init_lex, ): Ditto. + * cp-lex.h (enum rid): Ditto. + * cp-ptree.c (print_lang_decl): Ditto. + * cp-tree.h (struct lang_decl_flags, DECL_MUTABLE_P): Ditto. + * cp-typeck.c (build_component_ref_1, build_component_ref): Ditto. + * gplus.gperf (mutable): Ditto. + * cp-hash.h: Regenerate. + + * cp-tree.h (struct lang_type): Fill out type_flags to multiple of 4 + bytes for MIPS. + + Fri Aug 13 16:07:46 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-lex.c (DEBUG_DEFAULT_FUNCTIONS): Take out the #undef, so we can + use the command line to turn this on. + + * cp-decl.c (grokdeclarator): Look for IDENTIFIER_TEMPLATE in the + name of current_class_type, not in current_class_type itself. + + * cp-decl.c (pushdecl): Change to also check TREE_PUBLIC on the decl + in question, and do a pedwarn_with_decl instead of + warning_with_decl for conflicting extern declarations. + + Fri Aug 13 12:26:41 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-tree.h: Delete all the old PARANOID stuff, it's suffered + serious bit rot. + (PRINT_LANG_DECL, PRINT_LANG_TYPE): Deleted, not used anymore. + (LANG_ID_FIELD, SET_LANG_ID): New macros. + ({,SET_}IDENTIFIER_{LABEL_VALUE, IMPLICIT_DECL, AS_DESC, AS_LIST, + ERROR_LOCUS}): Redefine these macros to use the new LANG_ID_FIELD + and SET_LANG_ID ones, so everything is much cleaner and readable. + + * cp-decl.c (pushtag) [NEW_CLASS_SCOPING]: Push into the template's + class scope before trying to push the decl, and then pop back out. + (globalize_nested_type) [NEW_CLASS_SCOPING]: Asserts 348 and 349 + aren't correct, shadow can come out to be null in some situations. + + Thu Aug 12 10:56:50 1993 Mike Stump (mrs@cygnus.com) + + * cp-method.c (build_overload_name): Allow the debugger to + deterministically demangle names with more than 9 nested class + levels. + + Thu Aug 12 00:46:54 1993 Mike Stump (mrs@cygnus.com) + + * cp-search.c (pushd_stack_level): Fix memory corruption problem. + Don't assume that the obstack won't move, because they will. Among + other things, the fix allows one to nest classes upto 240 levels + deep, instead of 60 or so. + + Thu Aug 12 00:38:05 1993 Per Bothner (bothner@kalessin.cygnus.com) + + * cp-decl2.c (finish_file): Use new get_file_function_name(). + * cp-tree.h (FILE_FUNCTION_FORMAT): No longer needed. + + Fri Aug 6 11:37:08 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl.c (pop_binding_level) [DEBUG_CP_BINDING_LEVELS]: Don't + call abort, since we need to see where things end up. + + Fri Aug 6 11:13:57 1993 Mike Stump (mrs@cygnus.com) + + * cp-class.c (finish_struct): Blast away old DECL_SIZE on + base_layout_decl so that the old value is not reused, but rather the + new value in the TREE_TYPE (TYPE_SIZE ()) will be. + + Thu Aug 5 18:45:26 1993 Mike Stump (mrs@cygnus.com) + + * cp-init.c (emit_base_init): Move vbase vtable pointer init to very + end of base initialization code. Completes July 30 change. The + dynamic type of a virtual base should not be the type of the current + constructor, until after all bases are initialized. + + Thu Aug 26 06:00:09 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * expr.c: (apply_args_register_offset): Don't use ANSI-style + definition. + + Wed Aug 25 19:37:26 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * expmed.c (store_bit_field): Do not use bitfield instructions for + STRICT_ALIGNMENT machines if the MEM's alignment isn't as big as + the MEM's mode. + + Wed Aug 25 19:17:13 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * c-typeck.c (format_char_info_print_table, "p"): Allow width. + + Tue Aug 24 18:36:31 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * rs6000.c (output_{pro,epi}log): Don't need no-ops after calls + to functions to save and restore FP regs. + + Tue Aug 24 15:43:43 1993 Michael Meissner (meissner@osf.org) + + * osfrose.h (SUBTARGET_SWITCHES): Add -mlarge-align and + -mword-align to control whether alignments of > 4 are honored. + (ASM_OUTPUT_ALIGN_CODE): If -mlarge-align allow alignments > 4. + (ASM_OUTPUT_ALIGN): Ditto. + (ASM_OUTPUT_LOOP_ALIGN): Always do a .align 2. + (FUNCTION_BLOCK_PROFILER): Define. + (BLOCK_PROFILER): Define. + + Tue Aug 24 14:04:11 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * pa.c (compute_frame_size): Always align stack to 64 byte + boundary. + + * pa.h (STACK_BOUNDARY): Stack pointer is 512 bit (64 byte) + aligned. + + * pa.c (output_call): Use ASM_OUTPUT_INTERNAL_LABEL instead of + output_asm_label. + + Tue Aug 24 11:24:27 1993 Kresten Krab Thorup (krab@iesd.auc.dk) + + * Merge of Objective C related changes since June 1. + + * objc/xforward.c, objc/mutex.h: Files removed. + * objc/encoding.[ch]: New files. + * objc/todo: File removed. + + Tue Jun 1 00:05:12 1993 Kresten Krab Thorup (krab@iesd.auc.dk) + + * expr.c (apply_args_register_offset): New function + (apply_args_reg_offset): New variable + (apply_args_size): Added initialization of apply_args_reg_offset. + + * objc-act.c (offset_is_register): New variable + (forwarding_offset): Use apply_args_register_offset to get + register offset. + (encode_method_def, encode_method_prototype): Prepend argument + offset by '+' if passed in register. + (apply_args_register_offset): Added declaration. + + Sun Jun 6 20:57:03 1993 Kresten Krab Thorup (krab@iesd.auc.dk) + + * objc/encoding.h, objc/encoding.c: New files. + * objc/Object.m (-performv): Use new objc_msg_sendv. + * objc/sendmsg.c (objc_msg_sendv): Use new encoding facilities. + * objc/objc.h (arglist_t): Data-definition changed. + * objc/xforward.c: File removed. + * objc/Makefile (sendmsg.c, fflags, xforward): Targets removed; + (OBJC_O): Added encoding.o; + (OBJC_H): Added encoding.h, removed mutex.h. + + * objc/objc.h (nil_method): Don't define it, import it from sendmsg.c. + + Wed Jun 16 17:39:56 1993 Kresten Krab Thorup (krab@iesd.auc.dk) + + * objc/objc-api.h: (CLS_SETNUMBER): Clear old number + * objc/sendmsg.c (__objc_update_dispatch_table_for_class): + Don't free dtable... (memory leak to make posing work) + * objc/class.c (class_pose_as): lazy copy dtables. + #include sarray.h + + Tue Jun 22 21:39:11 1993 Kresten Krab Thorup (krab@xiv) + + * objc/class.c (class_pose_as): Rewritten + * objc/sendmsg.c (__objc_update_dispatch_table_for_class): + Free old dispatch table and install a new. + + Tue Aug 24 00:41:35 1993 Kresten Krab Thorup (krab@iesd.auc.dk) + + * objc-act.c (generate_method_descriptors, generate_ivar_lists, + generate_dispatch_tables): Reorganized use of constructors. + (build_descriptor_table_initializer, build_ivar_list_initializer, + build_dispatch_table_initializer): Removed argument `int *size'. + + Tue Aug 24 00:52:04 1993 Kresten Krab Thorup (krab@iesd.auc.dk) + + * objc/sendmsg.c (__objc_install_dispatch_table_for_class): + Dynamically expand dispatch table when full. + + Mon Aug 23 19:37:33 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * pa.h (TARGET_TRAILING_COLON): Delete switch. TARGET_GAS now + controls the use of trailing colons. + + Mon Aug 23 18:46:14 1993 Frederic Pierresteguy (F.Pierresteguy@frcl.bull.fr) + + * config/m68k/dpx2g.h (ASM_LONG): Move from dpx2.h. + + * configure (m68k-bull-sysv): Add support for working with native + assembler. + * config/m68k/dpx2.h (MOTOROLA): Define this. + (VERSADOS): This the name of the DPX2 assembler. Define this in case. + (USG): Define this. + (SGS_NO_LI): define this to suppress jump table usage. + (TARGET_DEFAULT): Define this to 3 inside the conditional USE_GAS + since bitfields do not work a clean way on DPX2. + (EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS, SELECT_SECTION, + SELECT_RTX_SECTION): #undef these. + (READONLY_DATA_SECTION): Define to data_section. + (*_ASM_OP, ASM_OUTPUT_*): Define these accordingly to the native + assembler syntax. + (LONG_DOUBLE_TYPE_SIZE): Set to 64 to not use XFmode. + (REAL_ARITHMETIC): Define this to use the software floating point + emulator. + (JUMP_TABLES_IN_TEXT_SECTION): Define this to 1. + (FUNCTION_PROLOGUE, FUNCTION_EPILOGUE): Override m68k.h default. + (ASM_OUTPUT_ASCII): add a new variable to take care of the lentgh of + the operand field which must be < 80 chars. + (PRINT_OPERAND_ADDRESS): Override m68k.h default. + (PUT_SDB_TYPE): Output type in decimal. + (PUT_SDB_FUNCTION_[START|END]): Override sdbout.c default. + (PUT_SDB_BLOCK_[START|END]): Override sdbout.c default. + + Mon Aug 23 18:33:26 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * fold-const.c (twoval_comparison_p): Add new arg, SAVE_P; all + callers changed. + (fold, case EQ_EXPR): If SAVE_P is true after call to + twoval_comparison_p, call save_expr on the expression we make. + + Mon Aug 23 07:57:41 1993 Michael Meissner (meissner@osf.org) + + * i386/osfrose.h (CC1_SPEC, CPP_SPEC): If NO_UNDERSCORE is + defined, the ELF compiler defaults to -mno-underscores to remove + leading underscores. Clean up ROSE -pic options so that they are + never passed when building ELF objects. + * i386/osfelf.h: Likewise. + + Sun Aug 22 23:36:24 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * expr.c (expand_builtin_apply): Fix typo. + + * pa.md (untyped_call): New define_expand. + + Fri Aug 20 12:24:50 1993 Ian Lance Taylor (ian@spiff.gnu.ai.mit.edu) + + * gcc.c (main): Correct August 6 change. + + Thu Aug 19 19:19:19 1993 Jim Wilson (wilson@cygnus.com) + + * combine.c (simplify_shift_const, XOR case): When applying + distributive law, use shift_mode and GET_MODE (varop) instead of + result_mode. + + Thu Aug 19 08:28:50 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * rs6000.md (scc): Fix typo in scc with compare and set. + + * combine.c (can_combine_p): Don't reject SUBREG assignments here. + (subst): Instead, do it here, but also allow it in as a + nested SUBREG since the inner one will be eliminated. + (simplify_and_const_int): Convert (and (neg X) (const_int 1)) + to a shift when X is known to be either 0 or 1. + + * fold-const.c (fold): Handle EQ_EXPR and NE_EXPR where both + args are comparisons or BIT_AND_EXPR with constant 1. + + Wed Aug 18 23:37:05 1993 Jim Wilson (wilson@cygnus.com) + + * mips.h (SELECT_SECTION): Put object in sdata only if size is + known, i.e. greater than 0. + + Wed Aug 18 17:48:51 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * combine.c (try_combine): Don't split a PARALLEL of a SIGN_EXTEND + and the object being sign extended if we have made assumptions + about the form the I2DEST. + + * combine.c (nonzero_bits): Handle case when BYTE_LOADS_EXTEND is + not on and we are asked for something in a mode wider than it. + + Wed Aug 18 02:21:35 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * pa.md (movdf insn): Distinguish between offsettable and + nonoffsettable memory locations when loading/storing a GR. + (movdi insn): Likewise. Loading a DImode constant can take as + many as 4 insns (length of 16 bytes). + + * pa.md (zero_extendqihi2): No need to explicitly set a length; + the defaults are correct. + (zero_extendqisi2, floatsisf2, floatsidf2): Likewise. + (fix_truncdfsi2, fix_truncsfdi2, fix_truncdfdi2): Likewise. + + * pa.c (emit_move_sequence): Check both reload_in_progress and + reload_completed when choosing a scratch/temporary register. + + * pa.h (TARGET_KERNEL): Delete switch and all references to it. + * pa.c (emit_move_sequence): Always handle secondary reloads for + symbolic addresses. + (secondary_reload_class): Symbolic operands always need a secondary + reload from R1_REGS if their target class is not R1_REGS. + * pa.md (HIGH for symbolic operands): TARGET_KERNEL version is now + the only choice. Delete ! TARGET_KERNEL version. + + * pa.h (DEFAULT_GDB_EXTENSIONS): GDB extensiosn are on by default. + * pa-hpux.h (DEFAULT_GDB_EXTENSIONS): Turn GDB extensions off. + * pa-hpux7.h (DEFAULT_GDB_EXTENSIONS): Likewise. + + * pa.h (TARGET_GAS): New target flag to control use of GAS + specific assembler directives. + (TARGET_SWITCHES): Support -mgas and -mno-gas. + (ASM_DECLARE_FUNCTION_NAME): If TARGET_GAS then emit .PARAM + directives for static functions so argument relocations work. + * pa-ghpux.h (TARGET_DEFAULT): Enable TARGET_GAS. + * pa-gux7.h, pa-utahmach.h, pa.h (TARGET_DEFAULT): Likewise. + * pa1-ghpux.h, pa1-utahmach.h, pa1.h (TARGET_DEFAULT): Likewise. + + * pa.c (hppa_legitimize_address): Rework address computation for + x[n - m] so that problems with implicit space register selection + are avoided. + + * pa.h (EXTRA_CONSTRAINT): Delete unused 'S' constraint. + * pa.md (call_internal_symref): Make pattern unavailable if + TARGET_LONG_CALLS. + (call_value_internal_symref): Likewise. + + Mon Aug 16 18:47:56 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + From parkes@uiuc.edu: + * encore.h, ns32k.h (ASM_OUTPUT_ADDR_DIFF_ELT): Use .double instead + of .word. + * ns32k.h (CASE_VECTOR_MODE): Now SImode; was HImode. + * ns32k.md (tablejump): Now SImode and uses cased. + + * fold-const.c (fold, case EQ_EXPR): Re-enable converting + signed MOD operations to unsigned when inside comparisons + against zero, but only when the second operand of the MOD + is an integral power of two. + + Mon Aug 16 12:38:28 1993 John Hassey (hassey@dg-rtp.dg.com) + + * fixinc.dgux: Fixed va_list problem in _int_varargs.h + + Mon Aug 16 11:26:57 1993 Kevin Buettner (kev@spuds.geg.mot.com) + + * configure (m88k-mot-sysv4*): Added new configuration for m88k + delta machines running svr4. + + * config/m88k/mot-sysv4.h: New file. + + Mon Aug 16 11:16:32 1993 Richard Earnshaw (rwe11@cl.cam.ac.uk) + + * combine.c: (use_crosses_set_p): Check for partially overlapping + hard regs. + + Sun Aug 15 20:17:20 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * reorg.c (find_end_label): If a suitable RETURN insn exists at + the end of the current function, place a label in front of it for + the end_of_function_label. + + Fri Aug 13 16:40:03 1993 Pat Rankin (rankin@eql.caltech.edu) + + * c-typeck.c (check_format): For scan of "%[", skip over scan set + til closing ']' to avoid processing it as ordinary format characters. + + Fri Aug 13 16:02:23 1993 Chip Salzenberg (chip@fin.uucp) + + * c-common.c (declare_hidden_char_array): New function to + factor out duplicate code in declare_function_name. + Don't set DECL_EXTERNAL (which is illegal without TREE_PUBLIC) + to prevent output; instead, set TREE_ASM_WRITTEN. + (declare_function_name): Use declare_hidden_char_array. + + Fri Aug 13 14:58:52 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * config/ns32k/encore.h (ASM_OUTPUT_ALIGN_CODE): Override as no-op. + + Fri Aug 13 14:29:17 1993 Stephen Moshier (moshier@world.std.com) + + * sparc.h (LONG_DOUBLE_TYPE_SIZE): Define to 128. + + * real.c (GET_REAL, PUT_REAL): Add TFmode versions. + (MAXDECEXP, MINDECEXP): New decimal exponent limits + that vary with definition of LONG_DOUBLE_TYPE_SIZE. + (endian, ereal_atof, real_value_truncate, einfin, emdnorm, asctoeg): + Add cases for TFmode. + (etartdouble): New function converts REAL_VALUE_TYPE to TFmode + for use by ASM_OUTPUT_LONG_DOUBLE. + (edivm, emulm): Ifdef out, replace by faster multiply and divide. + (etoe113, toe113, e113toe): New type conversions for TFmode. + (asctoe113, e113toasc): New TFmode binary <-> decimal conversions. + (at top level): Define constants ezero, eone, emtens, etens, ... + in a new 20-byte format when LONG_DOUBLE_TYPE_SIZE = 128 and + set NE to 10. Otherwise, the internal format remains 12 bytes wide. + (etoudi, etodi, ditoe, uditoe): New functions, signed and unsigned + DImode float and fix, for real.c used in a libgcc-of-last-resort. + (esqrt): New function, correctly rounded square root for libgcc. + (etodec): Delete ifdef'd version. + (eroundi, eroundui): Rename to efixi, efixui and always + round towards zero. + + From frank@atom.ansto.gov.au (Frank Crawford): + (etoibm, toibm, ibmtoe): New conversions for IBM 370 float format. + (e53toe, e64toe, toe64, etoe53, toe53, etoe24, toe24, asctoe53, + asctoeg, make_nan): Ifdef for IBM. + + * real.h (REAL_VALUE_TYPE): Define array at least 20 bytes wide + if LONG_DOUBLE_TYPE_SIZE is 128 bits. + (etartdouble): Declare and use for REAL_VALUE_TO_TARGET_LONG_DOUBLE + when long double is TFmode. + (REAL_VALUE_FIX, REAL_VALUE_UNSIGNED_FIX): Must always round + towards zero. + + Fri Aug 13 07:50:42 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * expr.c (expand_expr, case SAVE_EXPR): Set MEM_IN_STRUCT_P + appropriately when the result is a MEM. + + * integrate.c (expand_inline_function): Copy args that are in + hard regs instead of substituting them directly into insns. + + * rs6000.md (subsi3): Merge alternatives. + (comparison patterns): Eliminate generation of "sfi."; no such + instruction exists. + + Thu Aug 12 21:24:01 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * config/m68k/sun3.h (CPP_PREDEFINES): Define _CROSS_TARGET_ARCH. + + Thu Aug 12 19:02:47 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * rs6000.md (attribute "type"): Add new type, "branch". + (attribute "length"): New attribute; put on all insns that don't + have default length. + (branch patterns): If conditional branch won't reach, take + conditional branch around an unconditional branch. + + * rs6000.md (plus): Split (plus (COMPARISON FOO ...) ...) at FOO. + + Thu Aug 12 14:04:40 1993 Michael Meissner (meissner@osf.org) + + * i386/osfrose.h (SUBTARGET_SWITCHES): Add -munderscores and + -mno-underscores. + (CPP_SPEC): If -mno-underscores, define __NO_UNDERSCORES__. + (LPREFIX): Redefine, to take -m{,no-}underscores into account. + (ASM_GENERATE_INTERNAL_LABEL): Ditto. + (ASM_OUTPUT_INTERNAL_LABEL): Ditto. + (ASM_OUTPUT_LABELREF): Ditto. + + * i386/osfelf.h (CPP_SPEC): If -mno-underscores, define + __NO_UNDERSCORES__. + + * c-decl.c (pushdecl): Don't give nested warning messages if + DECL_IN_SYSTEM_HEADER is set in order not to give warnings when + defining new instances of __FUNCTION__ and __PRETTY_FUNCTION__. + + Thu Aug 12 13:42:04 1993 Jim Wilson (wilson@wookumz.gnu.ai.mit.edu) + + * sparc.c (legitimize_pic_address): Delete 4th arg SCRATCH. + Fix all callers. + (emit_move_sequence): Delete 3rd arg SCRATCH_REG. Fix all + callers. If operand1 is an invalid PIC address, then legitimize + it before doing anything else. + * sparc.h (SECONDARY_INPUT_RELOAD_CLASS): Delete case for invalid + PIC addresses. + (CONSTANT_ADDRESS_P): Reject invalid PIC addresses. + (LEGITIMATE_PIC_OPERAND_P): New macro. + (GO_IF_LEGITIMATE_ADDRESS): Reject invalid PIC addresses. + (LEGITIMIZE_ADDRESS): Fix call to legitimize_pic_address. + * sparc.md (reload_insi): Delete. + (*): Fix all callers of legitimize_pic_address and emit_move_sequence. + + * sched.c (sched_analyze_insn): Handle USE before a JUMP_INSN just + like a USE before a CALL_INSN. + * function.c (thread_prologue_and_epilogue_insns): For the + epilogue, put USE insns immediately before the return insn. + + * sparc.h (ASM_OUTPUT_DOUBLE): Always use REAL_VALUE_TO_TARGET_DOUBLE. + (ASM_OUTPUT_FLOAT): Always use REAL_VALUE_TO_TARGET_SINGLE. + + Wed Aug 11 19:48:24 1993 Per Bothner (bothner@kalessin.cygnus.com) + + * tree.c (get_file_function_name): New function + for language-independent constructor name generation. + * objc-act.c (build_module_descriptor): Use it. + * tree.h (CONSTRUCTOR_NAME_FORMAT): Removed. + + Wed Aug 11 19:50:05 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * reorg.c (try_merge_delay_insns): Fix typo. + (fill_simple_delay_slots): Only access the JUMP_LABEL field + if the INSN needing delay slots is a JUMP_INSN. + + Wed Aug 11 15:09:52 1993 Michael Meissner (meissner@osf.org) + + * c-typeck.c (output_init_element): Don't call default_conversion + for a STRING_CST if type is directly suitable for it. + (digest_init): Eliminate a lot of code that checks the variable + 'element', since element is always 0 in these code paths. + + Wed Aug 11 17:59:28 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * combine.c (combine_instructions): Fix typo on test of basic block + number. + + Wed Aug 11 17:44:38 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * configure (m68k-hp-bsd4.4*): Add missing *; + move before m68k-hp-bsd*. + + Wed Aug 11 09:21:56 1993 Ian Lance Taylor (ian@cygnus.com) + + * fixincludes: Get SIZE_TYPE by invoking gcc rather than cc; gcc + location is passed in as fourth argument. + * Makefile.in (stmp-fixinc): Depend upon xgcc and cpp; pass + objdir/xgcc -Bobjdir/ as fourth argument to $(FIXINCLUDES). + + Tue Aug 10 15:12:11 1993 Jim Wilson (wilson@cygnus.com) + + * cse.c (cse_insn): After inserting src_eqv, check to see if it is + identical to any uninserted SET_SRCs, and if so, set their src_elt + to src_eqv_elt. + + Tue Aug 10 12:56:46 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * pa.h (DOLLARS_IN_IDENTIFIERS): Define as 2. + + Mon Aug 9 19:02:49 1993 Per Bothner (bothner@wombat.gnu.ai.mit.edu) + + Merged fixproto stuff from Cygnus. + + Fri Aug 6 12:23:04 1993 Per Bothner (bothner@kalessin.cygnus.com) + + * fixproto, Makefile.in: Rename tmp.[ci] -> fixtmp.[ci]. + + Tue Aug 3 22:24:58 1993 Per Bothner (bothner@kalessin.cygnus.com) + + * fixproto: Find not only nested directories, but also + links to directories. + + Mon Aug 2 18:58:35 1993 Per Bothner (bothner@kalessin.cygnus.com) + + * fixproto: Add kludge to getting hit by double globbing. + * scan-types.sh: Fix to emit #define, not a typedef. + * patch-header.c (main): Make sure to print a space after + a function name when we didn't see a '('. + * Makefile.in (stmp-fixproto): Fix so (/*...*/) becomes (). + + Fri Jul 30 17:18:22 1993 Per Bothner (bothner@kalessin.cygnus.com) + + * fixproto: Append seen files to fixproto.list file, + instead of done_files variable (which could become too long). + * fixproto: Don't generate a huge rel_souce_files variable + (which might become too long); instead loop over directories. + * fixproto: Remove signal() from list of required functions + for signal.h, because we can't grok its complicted prototype. + * Makefile.in (mostlyclean): Also delete fixproto.list. + + Thu Jul 29 12:43:53 1993 Per Bothner (bothner@kalessin.cygnus.com) + + * scan-decls.c (skip_to_enclosing_brace): New function. + * scan-decls.c (main): After a parameter list, skip + any following function body (usually for inline functions). + + * fixproto: Fix to make sure stdlib.h and unistd.h get + the proper required_list, even when they need to be created. + * fixproto: Direct cpp error messages to /dev/null. + * patch-header.c: Make less verbose. + + Wed Jul 28 16:12:39 1993 Per Bothner (bothner@kalessin.cygnus.com) + + * fixproto: Rewrite to use a case statement instead of eval to + set required_list and extra_check_list. + * fixproto: Simplify remaining call to tr improving portability. + + * scan-decl: Recognize inline functions, emitting typecode 'I'. + * patch-header (read_scan_file): Handle inline functions. + * patch-header (read_scan_file): Fix thinko. Rename variable. + + Mon Aug 9 17:47:48 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c (build_c_cast): For (void *) (FOO *) 0, return a nop_expr + so it doesn't count as a null pointer constant. + (convert_for_assignment, build_binary_op): Pedantically warn about + that case if looking for a null_pointer_constant. + (build_conditional_expr): Likewise. + + * ns32k.c (output_move_double): Fix typos in last change. + + * expr.c (store_expr): Don't return TEMP if it's a MEM. + + Mon Aug 9 15:26:27 1993 Jim Wilson (wilson@cygnus.com) + + * varasm.c (assembler_variable): For XCOFF_DEBUG, restore section + if dbxout_symbol call changes it. + + * sched.c (schedule_insns): Don't emit a NOTE at the end of the last + basic block if that would put it between a JUMP_INSN and a BARRIER. + + * mips.h (OPTIMIZATION_OPTIONS): Use |=, not &= to set -mpgopt. + * mips.c (function_arg, DFmode case): Set regbase to GP_ARG_FIRST + if cum->arg_number greater than or equal to 2. + + Mon Aug 9 07:31:07 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * optabs.c (widen_operand): New function. + (expand_binop, expand_unop): Call it. + + Sun Aug 8 17:32:04 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * combine.c (num_sign_bit_copies): Properly handle case when MODE is + narrower than that of X. + (simplify_shift_const): Remove change of July 26. + + Sun Aug 8 17:26:57 1993 Jim Wilson (wilson@cygnus.com) + + * sparc.c (sparc_type_code): Support range types. + + * expr.c (expand_increment): Call save_expr on inner expression if + it is itself an increment expression. + + * configure (*-*-riscos*): Set broken_install. + (mips-*-riscos[56789]sysv4): Use xm-sysv4.h. + * mips/xm-sysv4.h: New file. + * mips/svr3-5.h, mips/svr4-5.h (_SC_PAGE_SIZE): Define to + _SC_PAGESIZE if that exists. + + * sparc.h (CONST_DOUBLE_OK_FOR_LETTER_P): Use fp_zero_operand. + * sparc.c (reg_or_0_operand): Use fp_zero_operand. + (fp_zero_operand): New function. + + * c-typeck.c (build_array_ref): Force array to be allocated on the + stack if it is accessed by out-of-bound constant integer subscript. + + * configure (mips-*): Standardize indentation. + (mips-*-*bsd*): Use t-bsd and t-bsd-gas. + (mips-*-*sysv4*): Use t-svr4 and t-svr4-gas. + (mips-*-*sysv*): Use t-svr3 and t-svr3-gas. + * mips/t-bsd, mips/t-bsd-gas, mips/t-svr3, mips/t-svr3-gas, + mips/t-svr4, mips/t-svr4-gas: New files. + + Sun Aug 8 11:33:51 1993 John F Carr (jfc@Athena.mit.edu) + + * expmed.c (SLOW_UNALIGNED_ACCESS): Define, but allow override. + (store_bit_field): Test that instead of STRICT_ALIGNMENT. + Also, allow fetching as non-bitfield if memory is aligned enough. + (extract_bit_field): Install code here like that in store_bit_field. + + Sun Aug 8 04:26:21 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * expr.c (expand_assignment): If WANT_VALUE is 0, return NULL. + (store_expr): Likewise. + Rename arg SUGGEST_REG to WANT_VALUE. + Never return TARGET if WANT_VALUE unless BLKmode. + Instead, return TEMP or a value copied from TARGET. + Pass 0 for WANT_VALUE in recursive calls that ignore value. + + * varasm.c (contains_pointers_p): New function. + (assemble_variable): Use that. + + * toplev.c (rest_of_decl_compilation): Don't look at DECL_IGNORED_P. + Don't output a read-only initialized extern variable. + + * c-common.c (declare_function_name): Set DECL_EXTERNAL in the decls. + + Sat Aug 7 22:25:42 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c (process_init_element): Don't call clear_momentary + if value is 0. + + Sat Aug 7 15:53:06 1993 Doug Evans (dje@canuck.cygnus.com) + + * caller-save.c (MAX_MOVE_MAX, MAX_UNITS_PER_WORD): New macros. + (regno_save_mode, regno_save_mem): Use them. + * tm.texi (MAX_MOVE_MAX, MAX_UNITS_PER_WORD): Document them. + + * c-decl.c (init_decl_processing): Make long long available to + use for SIZE_TYPE and PTRDIFF_TYPE. + + Sat Aug 7 14:47:12 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * config/ns32k/ns32k.md (strict_low_part add/subtract recognizers): + Use %2, not %1, in template. + + Sat Aug 7 07:40:28 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * reload.c (find_reloads): Don't combine two reloads if their + reload_reg_rtx values differ. + + * alpha.c (add_long_const): New function. + (output_{pro,epi}log): Use it. + If register save area is more than 32768 from SP, compute its + address into a register. + + * expmed.c (expand_divmod): Clean up code and documentation, + especially in areas related to when copies are made. + + * reload.c (push_reload, find_reloads): Treat (subreg (pseudo)) + and (subreg (mem)) the same. + If we have (subreg:M1 (mem:M2 ...) ...), never do anything + special if M1 and M2 are the same size. + + * tree.c (print_obstack_name): New function; derived from + original debug_obstack. + (debug_obstack): Call print_obstack_name. + * print-tree.c (print_node): Print obstack node is contained in. + + Sat Aug 7 04:47:43 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-decl.c (finish_decl): Allow file-scope static incomplete array. + + Fri Aug 6 13:03:27 1993 Jim Wilson (wilson@sphagnum.cygnus.com) + + * expr.c (expand_expr, case PLUS_EXPR): Goto binop2 not + both_summands if we should not be returning a plus. + + Fri Aug 6 16:35:50 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * config/m68k/m68k.md (call and call_value pic recognizers) [HPUX_ASM]: + Output plain bsr, without `@PLTPC'. + + Fri Aug 6 16:12:08 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * alpha.c (reg_or_6bit_operand): New function. + * alpha.h (PREDICATE_CODES): Add reg_or_6bit_operand to list. + * alpha.md (shifts): Use reg_or_6bit_operand for shift counts. + + Fri Aug 6 15:57:58 1993 Ian Lance Taylor (ian@cygnus.com) + + * gcc.c (main): If standard_startfile_prefix is a relative path, + prepend standard_exec_prefix/MACHINE/VERSION and, if + GCC_EXEC_PREFIX is defined, GCC_EXEC_PREFIX/MACHINE/VERSION. + + * configure: If config.status did not change, don't update its + modification time. + + Fri Aug 6 15:23:49 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c (output_init_element): Fix backward test in last change. + Use TYPE_MAIN_VARIANT. + + Fri Aug 6 06:43:09 1993 Michael Meissner (meissner@osf.org) + + * g++.c (fancy_abort): Provide function in case user does + #define abort fancy_abort when building GCC. + + Fri Aug 6 00:15:21 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * cccp.c (main): If -v, print header search dir list. + + * c-typeck.c (output_init_element): Call default_conversion here. + Set constructor_erroneous, etc., here. + (process_init_element): Not here. + + Thu Aug 5 20:55:47 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + Cygnus<->FSF merge. + + Thu Aug 5 17:07:20 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-class.c (build_vtable, prepare_fresh_vtable): Turn on + WRITABLE_VTABLES stuff that I disabled July 30th. + * cp-pt.c: Include flags.h to get write_symbols. + + Thu Aug 5 15:50:25 1993 Mike Stump (mrs@cygnus.com) + + * cp-class.c (finish_struct): Make DWARF conditional code, really + DWARF conditional (write_symbols == DWARF_DEBUG). + * cp-decl.c (pushtag): Ditto. + * cp-decl2.c (finish_vtable_vardecl): Ditto. + * cp-pt.c (end_template_instantiation): Ditto. + * cp-search.c (dfs_debug_mark): Ditto. + + Wed Aug 4 15:42:19 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-typeck.c (build_object_ref): Pass the original basetype, not + the type value of it, into build_scoped_ref (completes change of + Jul 1). + + Wed Aug 4 14:40:35 1993 Mike Stump (mrs@cygnus.com) + + * cp-class.c (related_vslot): Additional check to make sure vslots + are related. + * cp-class.c (modify_vtable_entries): Use DECL_CONTEXT, not + DECL_CLASS_CONTEXT when finding the vtable to put the virtual + function in, as otherwise we might not be able to find secondary + vtables. Ensures that the virtual function pointer will be put in + the correct vtable, instead of the wrong one. + * cp-class.c (modify_vtable_entry): Delete unused argument context. + * cp-class.c (modify_vtable_entries): Ditto. + + Tue Aug 3 08:24:50 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-init.c (nc_nelts_field_id): New variable to cache the value of + the "nelts" identifier, to avoid unnecessary calls to get_identifier. + (init_init_processing): Use it. + (build_new): Likewise. + (build_vec_delete): Likewise. + + * cp-decl2.c (walk_vtables): Make sure the type of VARS isn't an + error_mark_node when we're running down the list. + + * cp-decl.c (grokdeclarator): Give an error and return an + error_mark_node, instead of saying sorry, when we're dealing with a + structure that's not yet been defined. Make sure type isn't an + error_mark_node when looking for an anonymous type. + + * cp-pt.c (end_template_instantiation): If we're supplying dwarf + debug info, set up the TYPE_STUB_DECL and output the rest of the + debug output for the decl. + + * cp-search.c (pop_search_level): Change from a macro into a + function, so we can more easily debug it. + + * cp-search.c (dfs_debug_mark): Only mark the type name as ignored + if we aren't doing dwarf debugging. + + * cp-typeck.c (build_unary_op): Only allow the prefix operators to + be lvalues, not the postfix ones. + + * cp-decl.c (duplicate_decls): Delete the code that saved and + restored the UID of a decl, it's no longer necessary. + + * cp-call.c (compute_conversion_costs_ansi): Avoid generating + warnings when we call build_type_conversion. + + Mon Aug 2 17:56:36 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl.c (start_function): Complain about redeclaration of a + template function, being careful to only deal with pre-parsed + declarations that *are* in fact from templates. + + Fri Jul 30 18:03:10 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-class.c, cp-decl.c, cp-pt.c, cp-tree.h: Delete all of the old + code for DEBUG_CP_BINDING_LEVELS, and replace it with a new, cleaner, + and more usable format. + + Fri Jul 30 17:06:24 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-class.c (build_vtable, prepare_fresh_vtable): Temporarily + disable the change of June 20th making vtables readonly by default. + + Fri Jul 30 14:47:09 1993 Mike Stump (mrs@cygnus.com) + + * cp-init.c (emit_base_init): Make sure we initialize the pointer to + vtables even when we are not in charge. Fixes virtual calls to derived + objects that have a static base type, so that they call derived + functions, not base functions. + * cp-search.c (build_vbase_vtables_init): Change comments to reflect + uses of last argument more accurately. Also rename last argument to + a better name. + + Wed Jul 28 16:23:52 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-search.c (build_type_pathname): Deleted fn. + * cp-class.c (build_type_pathname): Moved to here and made static, + since prepare_fresh_vtable is the only fn that ever uses it. + * cp-tree.h (build_type_pathname): Deleted prototype. + + * g++.c (error) [!HAVE_VFPRINTF]: Move before fatal to avoid an + implicit declaration. + + Wed Jul 28 13:49:58 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) + + * Makefile.in (g++-cross): Add an explicit $(srcdir) for g++.c, pass + the quotes as part of GCC_NAME + + * g++.c: only define GCC_NAME if it's already undefined + + Tue Jul 27 10:48:30 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl.c (finish_decl): Don't error on uninitialized const + arrays. Use error, not error_with_decl, so we know what really + brought about the problems. + + * g++.c: New file, written in C so we don't do so many exec's, as we + did with the shell script. + * g++, c++: Deleted. + * Makefile.in (STAGESTUFF): Added g++ and g++-cross. + (all.cross): Added g++-cross. + (all.build): Depend upon g++. + (g++, g++-cross): New rules. + (install-common): Depend upon g++. Changed installation of g++/c++ + to install the g++ program, and link c++ to it. Likewise for + g++-cross and c++-cross. + + Mon Jul 26 09:40:37 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-typeck.c (build_unary_op) [case ADDR_EXPR]: When taking the + address of an increment/decrement operation, act on the thing + being incremented, not the ..._EXPR itself. + + Fri Jul 23 08:33:32 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-call.c (build_method_call): Check DECL_STATIC_FUNCTION_P, not + TREE_STATIC, when validating a method call in a static call context. + + Thu Aug 5 19:18:00 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * tree.h (TYPE_OBSTACK): New macro. + (struct tree_type): Add new field obstack. + * tree.c (make_node, copy_node): Set TYPE_OBSTACK. + (build_type_variant, build_type_copy, build_pointer_type): Put + new node in same obstack as old node; use push/pop obstacks. + * stor-layout.c (layout_type): Put size-related nodes in same + obstack as type. + + * reload.c (push_reload, find_reloads): Refine when we reload + inside a SUBREG by respecting BYTE_LOADS_*_EXTEND; see comments + in push_reload. + + Thu Aug 5 14:17:59 1993 Michael Meissner (meissner@osf.org) + + * i386/osfrose.h (ASM_DECLARE_FUNCTION_SIZE): Enable setting the + size for elf functions. + + Thu Aug 5 01:44:37 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * toplev.c (rest_of_compilation): If not optimizing, turn off + DECL_INLINE for functions declared as inline. Avoid turning on + DECL_INLINE when -finline-functions is used without -O. + + Thu Aug 5 00:06:45 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * collect2.c (handler): Check whether c_file and o_file are 0. + + Wed Aug 4 18:06:26 1993 Samuel A. Figueroa (figueroa@cs.nyu.edu) + + * i386/gas.h (ASM_FILE_START): Write out two backslashes for each + backslash in the filename. + + Wed Aug 4 18:00:43 1993 Holger Teutsch (holger@hotbso.rhein-main.de) + + * clipper.md (movdf+2): Allow `f' register as source operand in + first alternative. + + Wed Aug 4 07:35:03 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * reload1.c (eliminate_regs_in_insn): Always do elimination in + REG_NOTES if we changed anything in the insn. + + * genattrtab.c: Include gvarargs.h after hconfig.h, like elsewhere. + + Wed Aug 4 01:32:27 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c (output_init_element): Call digest_init before + calling output_constant. Always pass 0, 0 for last 2 args + to digest_init. + + * expr.c (do_tablejump) [PIC_CASE_VECTOR_ADDRESS]: If pic, + copy INDEX to a register early, to avoid invalid address later. + + Tue Aug 3 23:56:49 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * gcc.c (process_command): Don't check whether file `-' exists. + + Tue Aug 3 18:52:13 1993 John Hassey (hassey@dg-rtp.dg.com) + + * configure (m88k-dg-dgux*): Use fixinc.dgux. + * x-dgux (INSTALL_HEADERS): Definition deleted. + * fixinc.dgux: New file. + + Tue Aug 3 17:34:53 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * calls.c (store_one_arg): Don't pass ARG->STACK as TARGET if it + is a different mode than the expression (i.e., a promoted mode). + + * combine.c (force_to_mode): Now pass actual AND mask instead + of number of bits; generalize appropriately. + Move most cases from simplify_and_const_int in. + (simplify_and_const_int): Remove most code from here; call + force_to_mode instead. + (subst, make_extraction, make_compound_operation): Change calls + to force_to_mode. + (make_field_assignment): Likewise. + (simplify_comparison): Add call to force_to_mode when + doing a sign bit comparison. + * optabs.c (code_to_optab): New variable. + (init_optab): Initialize it. + * expr.h: Declare code_to_optab. + + Tue Aug 3 15:40:16 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * gstddef.h: Test and define __INT_WCHAR_T_H. + + Mon Aug 2 22:42:10 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * configure (i[34]86-sequent-sysv*): New alternative. + * config/i386/seq-sysv3.h: New file. + + * combine.c (struct undo): Rename `rtx' fields to `r'. + (undo_all, SUBST, gen_rtx_combine): Corresponding changes. + + Mon Aug 2 18:53:23 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * combine.c (subst): Move simple operations inside IF_THEN_ELSE + if the IF_THEN_ELSE is in the second operand as well as the first. + (subst, case NEG): Use plus_constant to make a PLUS. + (subst, case MINUS): Simplify (minus 1 (comparison foo bar)). + (subst, case EQ): Add a number of missing cases where + comparisons may be replaced with arithmetic or logical ops. + (subst, case IF_THEN_ELSE): Handle (if_then_else COND (OP Z C1) Z) + in a more general manner. + (simplify_and_const_int): Make AND with gen_binary in case we + can simplify it. + + Mon Aug 2 14:45:43 1993 Frederic Pierresteguy (F.Pierresteguy@frcl.bull.fr) + + * genattrtab.c (substitute_address): In prototype, don't specify + the arg types of the arg functions. + + * config/m68k/x-dpx2 (CLIB): Fix typo. + + Mon Aug 2 06:36:53 1993 John F Carr (jfc@Athena.mit.edu) + + * local-alloc.c (block_alloc): Don't attempt to allocate a + SCRATCH if it will not fit in scratch_list. + + Mon Aug 2 00:02:54 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * calls.c (expand_call): Check properly for volatile function. + + Sun Aug 1 04:18:23 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-common.c (decl_attributes): Support attributes `volatile' + with alias `noreturn', and `const'. + * c-parse.in (attrib): Accept those attributes. + + * c-typeck.c (build_binary_op): Warn about ordered comparison + between pointers to complete and incomplete types. + + * c-parse.in (stmt): In an expr stmt, call default_conversion + for arrays and for functions. + + * c-decl.c (finish_struct): No pedwarn for field with enum type + if size matches int. + (grokdeclarator): No error for void type for extern or global var. + + * c-typeck.c (digest_init): No error for a STRING_CST that already + went through digest_init. + (parser_build_binary_op): Generate a NON_LVALUE_EXPR, not NOP_EXPR, + around a constant value. + + * config/m68k/amix.h (ASM_OUTPUT_INTERNAL_LABEL) + (ASM_GENERATE_INTERNAL_LABEL): Definitions deleted. + + * expr.c (do_tablejump): Use PIC_CASE_VECTOR_ADDRESS if defined. + * config/m68k/m68k.h (PIC_CASE_VECTOR_ADDRESS): Defined. + (GO_IF_LEGITIMATE_ADDRESS): If pic, accept LABEL+INDEX. + + * c-decl.c (grokdeclarator): Warn here for volatile fn returning + non-void type. + (start_function): Not here. + + * c-decl.c (grokdeclarator): Don't pass on const and volatile + fron function value type to function type. + + Sat Jul 31 01:48:08 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c (digest_init): Finish getting rid of tail. + Also get rid of old_tail_contents. Don't set free_tree_list. + (free_tree_list): Var deleted. + + * c-typeck.c (process_init_element): Treat string constants specially + only for arrays of integers. + + Fri Jul 30 06:49:58 1993 Torbjorn Granlund (tege@sics.se) + + * expmed.c (mult_is_very_cheap): Delete. + (mult_cost): Delete. + (init_expmed): Delete computation of mult_cost and mult_is_very_cheap. + (expand_mult): Compute mult_cost here for every constant multiplier. + (synth_mult): Return found algorithms through a struct pointer. + + Fri Jul 30 06:45:35 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * fold-const.c (fold, case NOP_EXPR): Delete a pair of conversions + back to the original type when intermediate type is at least as wide. + + * combine.c: Remove change of July 21. + (this_basic_block): New variable. + (combine_instructions): Set it. + (try_combine, distribute_links): Use it and basic_block_head + to see if we've gone to a new basic block instead of trying + to reproduce calculation done in flow. + + * stmt.c (expand_return): Don't use jumps for "return x == y" if + they are expensive. + + Fri Jul 30 02:03:12 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * config/i386/i386.md (ffssi2 and ffshi2 recognizers): + Generate unique labels by hand. + + Thu Jul 29 01:47:21 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c (push_init_level): For braces around scalar, just warn. + (process_init_element): Special handling for {"foo"}. + (struct constructor_stack): New field `replacement_value'. + (push_init_level, really_start_incremental_init): Clear new field. + (pop_init_level): Return the replacement_value if any. + At top level in initializer, output that value, + and set the array size from it. + + * c-typeck.c (digest_init): Delete arg TAIL. Fix all calls. + + * objc-act.c (build_shared_structure_initializer): + Call default_conversion for NAME. + (add_objc_string): Make an ADDR_EXPR to return. + (init_objc_symtab): Make ADDR_EXPR for UOBJC_SELECTOR_TABLE_decl. + + * objc-act.c: Build all CONSTRUCTORs with types. + (build_constructor): New function. All CONSTRUCTOR builds changed. + (init_def_list, init_objc_symtab): New arg TYPE. + (init_module_descriptor): Likewise. + (init_objc_symtab): Pass TYPE arg to init_def_list. + (generate_objc_symtab_decl): Pass TYPE arg to init_objc_symtab. + (build_module_descriptor): Pass TYPE arg to init_module_descriptor. + (build_descriptor_table_initializer): New arg TYPE. + (generate_method_descriptors): Pass TYPE arg to + build_descriptor_table_initializer. + (generate_protocols): Pass TYPE arg to build_protocol_initializer. + (uild_protocol_initializer): New arg TYPE. + (build_ivar_list_initializer): New arg TYPE. + (generate_ivar_lists): Pass TYPE arg to build_ivar_list_initializer. + (build_dispatch_table_initializer): New arg TYPE. + (generate_dispatch_tables): Pass TYPE arg to + build_dispatch_table_initializer. + (build_category_initializer): New arg TYPE. + (build_shared_structure_initializer): New arg TYPE. + (generate_category): Pass TYPE arg to build_category_initializer. + (generate_shared_structures): Pass TYPE arg to + build_shared_structure_initializer. + + * config/i386/x-ncr3000 (CC, OLDCC): Deleted. + * config/i386/xm-sysv4.h [__HIGHC__]: Include alloca.h. + + * convert.c (convert_to_integer): Don't pass truncate into ABS_EXPR. + + * configure: Ignore -enable... and --enable... options. + + Wed Jul 28 20:15:05 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * Makefile.in (compare): Add ./ in tail command. + + Wed Jul 28 15:36:11 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * integrate.c (copy_rtx_and_substitute, case LABEL_REF): If + we turn off LABEL_REF_NONLOCAL_P, increment function_call_count. + + * integrate.c (copy_for_inline, case LABEL_REF): Properly copy + LABEL_REF with LABEL_REF_NONLOCAL_P set. + Copy LABEL_OUTSIDE_LOOP_P flag. + (copy_rtx_and_substitute, case LABEL_REF): Likewise. + (copy_rtx_and_substitute, case CONST): Make recursive call for + a LABEL_REF in the constant pool. + + * c-iterate.c (iterator_loop_{pro,epi}logue): Set TREE_SIDE_EFFECTS + on the MODIFY_EXPRs we make. + Pass const0_rtx as TARGET to expand_expr. + * cp-cvt.c (build_up_reference): Set TREE_SIDE_EFFECTS on MODIFY_EXPR. + * stmt.c (expand_return): Likewise. + + Wed Jul 28 12:17:39 1993 Michael Meissner (meissner@osf.org) + + * i386/osfrose.h (SUBTARGET_OVERRIDE_OPTIONS): Use this instead of + OVERRIDE_OPTIONS. + + Wed Jul 28 13:45:13 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * expr.c (expand_expr, case ADDR_EXPR): Treat CONCAT like REG. + + * c-decl.c (start_function): Warn if volatile fn returns non-void. + + Wed Jul 28 13:22:15 1993 Jim Wilson (wilson@cygnus.com) + + * c-parse.in (simple_if, if_prefix, stmt): Undo Jul 7 change. + (if_prefix): Store stmt_count in $$ not $1. + (stmt): Add comment explaining why empty-if warning is here. + + * sparc.c (shift_operand): New function. + * sparc.md (ashlsi3, ashrsi3, lshrsi3): Use shift_operand. + + * loop.c (strength_reduce): Don't ignore a giv that depends on a + reversed biv. + + * mips/x-sysv (ALLOCA): Define. + * mips-5.h (STARTFILE_SPEC): Define. + * x-iris3: New file. + * configure (mips-sgi-*): Use x-iris3 instead of x-iris. + * Makefile.in (libgcc.a): Do `chmod +w *' between two ar commands. + + * i960.h (INITIAL_FRAME_POINTER_OFFSET): Negate, and subtract 64 + bytes. + + * sched.c (schedule_block): Do not emit line number notes before + other notes. + + * varasm.c (assemble_variable): flag_no_common applies only if + external linkage. + + * calls.c (expand_call): For unaligned arguments on + BYTES_BIG_ENDIAN machines, correct bitfield offset calculations. + * expr.c (move_block_from_reg): New argument SIZE. If SIZE less + than word and BYTES_BIG_ENDIAN, shift block left to align it + before storing it to memory. + * expr.h (move_block_from_reg): Add new argument to prototype. + * function.c (assign_parms): Pass extra argument SIZE to + move_block_from_reg calls. + (locate_and_pad_parm): For !ARGS_GROW_DOWNWARD case, move downward + padding pad_below call after round_up call. + * mips.c (function_arg): Shift all structures less than 4 bytes, + not just those which are QImode or HImode. + * a29k.h, alpha.h, i960.c, m88k.c, pa.c, romp.h, rs6000.h: + Add new parameter to move_block_from_reg calls. + + Wed Jul 28 12:40:06 1993 Doug Evans (dje@canuck.cygnus.com) + + * expmed.c (store_split_bitfield): Fix handling of bitfields that + cross word boundaries, can only handle a word at a time. + (extract_split_bitfield): Likewise. + + Wed Jul 28 06:44:50 1993 John Hassey (hassey@dg-rtp.dg.com) + + * configure: Use m88k/x-sysv3 for m88k-*-sysv3. + * m88k/x-sysv3: New file, use gnu alloca. + + Tue Jul 27 13:53:06 1993 Per Bothner (bothner@wombat.gnu.ai.mit.edu) + + * fixproto: Pass '-' to tr as the 1-character range '---'. + * cross-make: Define STMP_FIXPROTO to empty for cross. + * patch-header.c (read_scan_file): Minor re-write to avoid + obstack_copy0, since that uses the non-portable bcopy(). + * Makefile.in (patch-header): Use $(HOST_OBSTACK). + * gen-protos.c (main): Disable obnoxious warning message. + + Tue Jul 27 16:42:44 1993 John F Carr (jfc@Athena.mit.edu) + + * fold-const.c (optimize_bit_field_compare): Preserve volatility + of bitfield. + + Tue Jul 27 01:33:25 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c (convert_for_assignment): Mismatch in signedness + of pointer targets should not inhibit warnings for const mismatch. + + * function.c (assign_parms): Don't copy too much when extending + parm_reg_stack_loc. + + * config/m88k/m88k.h (ASM_DECLARE_OBJECT_NAME): Don't make a .size + if the size is not known. Use DECL, not decl. + * config/svr4.h, config/i386/osfrose.h: Likewise. + + * c-typeck.c (set_init_index): Add pedantic warning. + (set_init_label): Likewise. + + Tue Jul 27 14:22:48 1993 Frederic Pierresteguy (F.Pierresteguy@frcl.bull.fr) + + * gstddef.h (_WCHAR_T_H): Test this and define this. + + * configure (m68k-bull-sysv): Test for --stabs; + generate either native coff or dbx-in-coff debugging information. + + * config/m68k/dpx2.h (CPP_PREDEFINES): added -D_POSIX_SOURCE + -D_XOPEN_SOURCE -D_BULL_SOURCE to the list. + (CPP_SPEC): removed ansi definition. + * config/m68k/dpx2g.h (DBX_DEBUGGING_INFO): Remove this to let gcc + deals with gas and coff. + * config/m68k/dpx2cdbx.h: New file for gas and dbx-in-coff. + * config/x-dpx2 (CLIB): removed -lc_s and added -lmalloc. + (X_CFLAGS): removed -D_SYSV and added -D_POSIX_SOURCE -D_XOPEN_SOURCE + -D_BULL_SOURCE to deal with the posix stuff. + + Mon Jul 26 17:42:22 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c (digest_init): Add `static' to definition. + + * combine.c (simplify_shift_const): Inhibit hacks based on + num_sign_bit_copies if shift_mode differs from the mode of varop. + + * toplev.c (main): When -W sets warn_uninitialized, avoid later warning + if warn_uninitialized is not supported. + + Mon Jul 26 14:14:02 BST 1993 Richard Earnshaw (rwe11@cl.cam.ac.uk) + + * collect2.c (NAME__MAIN, SYMBOL__MAIN): Add default definitions. + (write_c_file, scan_prog_file [OBJECT_FORMAT_ROSE]): + Use macros instead of explicitly __main. + + * function.c (expand_main_function): Likewise. + + * libgcc2.c (__main): Use macro SYMBOL__MAIN instead of invoking + directly. + + Mon Jul 26 16:03:33 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * fold-const.c (fold, case EQ_EXPR): Remove code that converts + mod to unsigned mod; it isn't correct for negative operands. + + * toplev.c (strip_off_ending): Allow .ad* for Ada. + + Mon Jul 26 14:06:04 1993 Bill Cox (bill@majipoor.cygnus.com) + + * c-decl.c (print_lang_decl, print_lang_type): Correct function + headers to match prototype, and calls. + + Sun Jul 25 17:01:34 1993 Per Bothner (bothner@kalessin.cygnus.com) + + * fixproto: New script to add prototypes and otherwise clean up + system include files (especially for C++ and also gcc -Wimplicit). + * scan-decl.c: New program used by fixproto to analyze header + files (it extracts declarations from cpp output). + * patch-header.c: New program used by fixproto to analyze and + patch header files. + * scan.c: New file. Routines used by scan-decls and + patch-header. + * scan.h: New file. Common declarations. + * gen-protos.c: New file. Massages a list of prototypes. + * Makefile.in: Add fixproto support. + * populate: Deleted. Superseded by fixproto. + + Sun Jul 25 03:56:18 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c (start_init): Fill in p->next. + + * config/i386/i386.md (movstrictqi): Change q<-g alternative to q<-m. + + Sat Jul 24 18:17:55 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * expr.c (emit_move_insn_1): For complex stack push, + don't use change_address. + + Sat Jul 24 15:05:50 1993 Per Bothner (bothner@kalessin.cygnus.com) + + * fixincludes (unistd.h): Generalize AIX fix (for using + C++ keyword new) to unistd.h as well as stdio.h. + * fixincludes (sys/wait.h): Fix NeXT problem with + a 'wait(union wait*)' prototype that breaks Posix.1. + * fixincludes (math.h): For C++, patch AIX's use of + 'class' as function name. + + Sat Jul 24 02:48:31 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * function.c (put_reg_into_stack): New subroutine. + (put_var_into_stack): Use that; handle CONCAT. + + * varasm.c (assemble_variable): For array whose size comes from + the initializer, determine proper alignment here. + (assemble_align): New function. + + * c-typeck.c: Handle gaps in record initializers. + (constructor_bit_index): New variable. + (constructor_stack): New field bit_index. + (really_start_incremental_init, push_init_level): Save and init it. + (pop_init_level): Restore it. + (output_init_element): Update constructor_bit_index. + Use it to output gaps. + (pop_init_level): Speed up by using constructor_bit_index. + + * c-typeck.c (process_init_element): Accept STRING_CST for subarray. + + * loop.c (mark_loop_jump): Handle weird cases like jumping to + a symbol_ref. + + Fri Jul 23 15:55:14 1993 Doug Evans (dje@canuck.cygnus.com) + + * c-tree.h: Fix prototypes for print_lang_decl, print_lang_type. + + Fri Jul 23 15:06:05 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c (start_init): Second arg is now a tree. + + Fri Jul 23 08:26:43 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + Cygnus<->FSF merge. + Thu Jul 22 09:54:05 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl.c (push_overloaded_decl): Fix typo in warning msg. + + Tue Jul 20 13:13:18 1993 Mike Stump (mrs@cygnus.com) + + * cp-class.c (build_vtable, prepare_fresh_vtable): Make the vtables + readonly by default. + + Mon Jul 19 13:16:58 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-tree.h (NEW_CLASS_SCOPING): Turn this off for now. + + Mon Jul 19 11:04:51 1993 Jason Merrill (jason@rtl.cygnus.com) + + * cp-class.c (build_vfn_ref): Rename `index' to `idx'. + + Fri Jul 16 07:44:49 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-class.c (finish_struct): Check both if the type has a default + constructor, and if it has a non-const copy constructor, so we'll know + not to generate a const copy constructor for the type we're working on. + * cp-lex.c (cons_up_default_function): Add other front-end debugging + info. + (default_copy_constructor_body): And take it out of here. + + * cp-expr.c (cplus_expand_expr): Add missing arguments to expand_expr. + + Thu Jul 15 16:54:33 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-lex.c (default_copy_constructor_body): Also check to copy + anonymous unions, since they don't show up as FIELD_DECLs. + (largest_union_member): New function. + + Thu Jul 15 16:23:18 1993 Mike Stump (mrs@cygnus.com) + + * cp-expr.c (cplus_expand_expr): Use resolve_offset_ref to handle + OFFSET_REFs, as anything else would be wrong. + + Thu Jul 15 13:23:40 1993 Mike Stump (mrs@cygnus.com) + + * cp-tree.h (CLASSTYPE_INTERFACE_KNOWN, + SET_CLASSTYPE_INTERFACE_UNKNOWN_X, SET_CLASSTYPE_INTERFACE_UNKNOWN, + SET_CLASSTYPE_INTERFACE_KNOWN): New access methods. + * cp-class.c (import_export_vtable, duplicate_tag_error, + finish_struct): Use new access method. + * cp-decl.c: (grokfndecl, grokdeclarator, xref_tag): Ditto. + * cp-gc.c (build_t_desc): Ditto. + * cp-lex.c (set_vardecl_interface_info, make_lang_type): Ditto. + * cp-pt.c (end_template_instantiation, do_pending_expansions): + Ditto. + * cp-search.c (dfs_debug_mark): Ditto. + + * cp-decl.c (grok_reference_init): Reword error message. + + Wed Jul 14 09:17:18 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-cvt.c (convert_to_reference): Adjust change of May 30th to + accept more things (and still handle ARM p308 properly). Disable + the old way, but leave it to be properly fixed later. + + Tue Jul 13 22:43:38 1993 Mike Stump (mrs@cygnus.com) + + * cp-decl.c (get_binfo_from_vfield): New function. + * cp-decl.c (finish_function): Use get_binfo_from_vfield to get the + binfo used to find the vtable for this vfields. Corrects problem + with vtable pointers being wrong during called member functions, + called from destructors. + + Tue Jul 13 11:52:37 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl.c (grokdeclarator): Don't pedwarn about a duplicate long + for `long long', until we figure out how we really want to handle it. + + Sat Jul 10 14:54:36 1993 Chip Salzenberg (chip@fin.uucp) + + * cp-tree.h (warn_redundant_decls, warn_missing_braces): Declared. + * cp-decl.c (warn_redundant_decls): Not declared here. + * cp-decl2.c (warn_missing_braces): Defined. + (lang_decode_option): Handle -Wmissing-braces. + * cp-type2.c (process_init_constructor): Test warn_missing_braces. + + * cp-typeck.c (build_binary_op_nodefault): Make warning + message distinguish between right/left and shift/rotate. + + * cp-decl.c (init_decl_processing): When making SIZETYPE, + start with name in SIZE_TYPE. If -traditional, use a signed + version of that type, if it is unsigned. + + * cp-typeck.c (c_sizeof, build_c_cast): Set TREE_OVERFLOW in + addition to TREE_CONSTANT_OVERFLOW. + + * cp-decl.c (finish_enum): Store layout results into variant types. + + * cp-typeck.c (internal_build_compound_expr): When pedantic, don't + simplify a COMPOUND_EXPR, so that it won't be mistaken for an + lvalue or an integer constant expression. + + * cp-parse.y (program): After extdefs, pop any unpopped binding lvls. + + * cp-decl.c (grokdeclarator, ARRAY_REF case): Build array type, + and then build the variant array type. + + * cp-lex.c (real_yylex): Avoid invalid shift for erroneous empty + char const. + + * cp-decl.c (complete_array_type): Make maxindex -1 for empty + constructor. + + * cp-type2.c (initializer_constant_valid_p): Allow cast of ptr to + wider integer. + + * cp-decl.c (pushdecl): Copy DECL_FRAME_SIZE for inline function decls. + + * cp-decl.c (finish_decl): Do not allocate static var of + unknown size. + (complete_array_type): Use 0 as default maxindex. + + Fri Jul 23 07:18:20 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * function.c (aggregate_value_p): An ARRAY_TYPE is also an aggregate. + + Fri Jul 23 01:54:28 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * gcc.c (main): Improve "No input files" error message. + + Thu Jul 22 23:00:11 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * reorg.c (relax_delay_slots): Do not redirect a jump if doing so + invalidates insns in the jump's delay slots. + (redirect_with_delay_slots_safe_p): New function. + + Thu Jul 22 18:01:29 1993 John Hassey (hassey@dg-rtp.dg.com) + + * invoke.texi, m88k.h, m88k.c: Changed serialize-volatile + to use tb1 instead of fldcr, fldcr has problems on 88110. + Made serialize-volatile the default behavior for all models. + + Thu Jul 22 11:19:28 PDT 1993 Ron Guilmette (rfg@netcom.com) + + * fixinc.svr4 (making LIB absolute): Just concat with $ORIG_DIR. + + * configure: Use `sed' rather than `cat' to put `MAYBE_TARGET_DEFAULT' + definition in. (This is a work-around for an NFS bug.) + + Thu Jul 22 14:59:38 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c: Output most constructors an element at a time. + (digest_init): Deleted code for raw constructors. + (process_init_constructor): Function deleted. + (start_init, finish_init): New functions. + (really_start_incremental_init) + (push_init_level, check_init_type_bitfields, pop_init_level) + (set_init_index, set_init_label, process_init_element) + (output_init_element, output_pending_init_elements): New functions. + * c-tree.h: Declare most of those functions. + + * c-parse.in (cast_expr): Use new initializer parsing functions. + (initdcl, notype_initdcl): Likewise. + (init): Likewise. + (initlist_maybe_comma, initlist1): These replace initlist. + (initelt): New nonterminal. + Change specified index syntax to `[INDEX]='. + Change specified field syntax to `.NAME='. + + * varasm.c (output_constant_def_contents): New function. + (output_constant_def): Use it. + (deferred_constants): New list of constants not yet output. + (defer_addressed_constants): New function. + (output_deferred_addressed_constants): New function. + (make_decl_rtl): Don't ever replace old rtl; + instead, change its mode if necessary. + + Wed Jul 21 15:50:19 1993 Jim Wilson (wilson@cygnus.com) + + * expr.c (expand_expr, COMPONENT_REF case): For unaligned object + in an aligned union, set MEM_IN_STRUCT_P if create a MEM rtx. + + * sparc.c (output_move_double): Only set highest_first if first reg + of dest overlaps memory src address. Otherwise, if addreg1 set and + is same as second reg of dest, suppress trailing decrement. + + * sparc.md (movdi+1): Delete & from r/i constraint. + + From rfg@netcom.com: + * fixinc.svr4 (): Don't apply specialized fixes to + if we are on Solaris. They are not needed in that case. + + * combine.c (nonlocal_label_list): New variable. + (combine_instructions): Set it. + (try_combine, distribute_links): CALL_INSN terminates a basic + block if nonlocal_label_list is set. + + * config/mips/{bsd-4.h, bsd-5.h, iris3.h, mips.h, news4.h, + news5.h, nws3250v4.h, osfrose.h, svr3-4.h, svr3-5.h, svr4-4.h, + svr4-5.h, ultrix.h} (CPP_SPEC): Define LANGUAGE_ASSEMBLY, not + LANGUAGE_C, when compiling a .s file. + + * m68k.h (TARGET_SWITCHES): Recognize -m68851, -mno-68851, + -m68302, -mno-68302, -m68332, -mno-68332. + + * lynx.h, i386/lynx.h, m68k/lynx.h, sparc/lynx.h: New files. + * i386.h (OVERRIDE_OPTIONS, SUBTARGET_OVERRIDE_OPTIONS): Define. + * m68k.h (TARGET_SWITCHES): Add SUBTARGET_SWITCHES. + (OVERRIDE_OPTIONS): Add SUBTARGET_OVERRIDE_OPTIONS. + (SUBTARGET_SWITCHES, SUBTARGET_OVERRIDE_OPTIONS): Define. + * sparc.h (TARGET_SWITCHES): Add SUBTARGET_SWITCHES. + (OVERRIDE_OPTIONS): Add SUBTARGET_OVERRIDE_OPTIONS. + (SUBTARGET_SWITCHES, SUBTARGET_OVERRIDE_OPTIONS): Define. + + * fixincludes (sys/types.h sys/stdtypes.h): Delete newline before + do. + (machine/cpu.h): Delete space in `2>& 1'. + + * config.sub (lynx): Recognize as vendor. + (lynxos): Recognize as OS. + * configure (i386-*-lynxos, sparc-*-lynxos, m68k-*-lynxos): + Recognize as new configurations. + + * gcc.c (link_command_spec): Move %{T*} after %{L*} and %D. + + * optabs.c (expand_binop): Synthesize double word shifts and + rotates from single word shifts. + * sparc.md (ashldi3, lshrdi3): Obsolete, deleted. + + Wed Jul 21 15:55:18 1993 Ian Lance Taylor (ian@cygnus.com) + + * fixinc.svr4: When fixing ftw.h, preserve remainder of + ftw and nftw declaration; don't just rewrite it. + + Tue Jul 20 23:35:36 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * collect2.c (is_ctor_dtor): Delete leading _'s from sym names + in `special' table, in neither-dots-nor-dollars case. + + Tue Jul 20 18:49:09 1993 Michael Meissner (meissner@osf.org) + + * i386/osfrose.h, i386/osfelf.h (CC1_SPEC): Don't turn on + -mhalf-pic if ELF. + + * i386/osfrose.h (ASM_FILE_END): Put filename, sans directory into + the .ident string. + + Tue Jul 20 15:07:06 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * combine.c: Add prototypes for static functions. + (subst, case IF_THEN_ELSE): Add missing arg to make_compound_operation. + (make_compound_operation, case ASHIFTRT): Delete extra gen_unary arg. + + Mon Jul 19 18:15:48 1993 John F Carr (jfc@Athena.mit.edu) + + * rs6000.c (current_file_function_operand): New function. + * rs6000.h (ENCODE_SECTION_INFO): New macro. + (PREDICATE_CODES): Add current_file_function_operand. + * rs6000.md: Add variants of call and call_value patterns for + calls to functions defined in the same file. Omit the TOC pointer + reload after such calls. + + Mon Jul 19 13:17:52 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * reorg.c (fill_simple_delay_slots): Try filling any insn needing + delay slots with a JUMP_INSN. + + Mon Jul 19 00:33:24 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * varasm.c (assemble_variable): New arg DONT_OUTPUT_DATA. + * toplev.c (rest_of_decl_compilation): Pass 0 as DONT_OUTPUT_DATA. + + Sun Jul 18 15:38:04 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c (c_expand_return): Set TREE_SIDE_EFFECTS + for the MODIFY_EXPR that we make. + + * stmt.c (expand_return): When expanding assignment into DECL_RESULT, + ignore the "value"--do it for effect. + + * fold-const.c (fold): Handle CONJ_EXPR. + * c-typeck.c (build_unary_op): Support CONJ_EXPR. + Change BIT_NOT_EXPR to CONJ_EXPR if arg is complex. + + Sun Jul 18 14:22:05 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * function.c (init_function_start): Initialize trampoline_list here. + (expand_function_end): Not here. + + Sun Jul 18 01:24:54 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * c-typeck.c (common_type): Use TYPE_MAIN_VARIANT when preferring + long int to int (when width is the same). + + * varasm.c (assemble_variable): Move debugging output calls + to after section has been selected. Select the section again + if the debugging output call changes the section. + * dbxout.c (dbxout_symbol_location): Call in_text_section + to decide whether to use DBX_STATIC_CONST_VAR_CODE. + + * objc-act.c (synth_module_prologue): Call layout_type for the array + type used for _OBJC_SELECTOR_TABLE. + + Sat Jul 17 00:41:52 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * expr.c (expand_increment): Convert constant subtract to add + before setting single_insn. Compensate for this when choosing + the tree code to pass to `build'. + + * toplev.c (rest_of_compilation): If function is extern inline, + even if we can't inline it, don't compile it. + + Fri Jul 16 21:33:50 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * dwarfout.c (dwarfout_init): Report failure of getpwd. + + Fri Jul 16 15:59:07 1993 Ian Lance Taylor (ian@cygnus.com) + + * config/m68k/hp320.h (LINK_LIBGCC_SPECIAL, SPACE_AFTER_L_OPTION) + (LIB_SPEC): Move outside of USE_GAS conditional. + + Fri Jul 16 14:26:25 1993 David d `zoo' Zuhn (zoo@cygnus.com) + + * config.sub: if [ "$os" ] --> if [ x"$os" != x"" ] + + Fri Jul 16 05:50:35 1993 Paul Eggert (eggert@twinsun.com) + + * c-typeck.c (check_format): With -Wformat, warn about + printf("%ld", 1) even if sizeof (int) == sizeof (long), + since the code isn't portable. Similarly for "%d" vs 1L. + + * c-typeck.c (convert_arguments) [PROMOTE_PROTOTYPES]: + With -Wconversion, use unpromoted type to check for signedness changes. + + Thu Jul 15 13:04:48 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * fixincludes (stdlib.h): Check carefully for definition of size_t. + + Wed Jul 14 19:05:51 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * fixincludes: Fix size_t definition in stdlib.h as in types.h. + Also a conditional to prevent repeated definition. + + Wed Jul 14 14:53:26 1993 Ian Lance Taylor (ian@cygnus.com) + + * fixincludes: Don't discard comment end characters on lines that + look like "#endif */". Fixes Esix 4.0.4 problem. + + Wed Jul 14 12:20:13 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * pa.c (emit_move_sequence): Use cint_ok_for_move instead of + checking each condition ourselves. + + * pa-utahmach.h (CPP_PREDEFINES): Do not define HPUX_SOURCE, hp700 + or HP700. + * pa1-utahmach.h (CPP_PREDEFINES): Do not define hp9000s800, + hp9k8, HPUX_SOURCE, or hp800. + + * Allow unconditional jumps in delay slots of call and millicode + call instructions. + * pa.h (TARGET_JUMP_IN_DELAY): New target flag to allow/disallow + jump instructions in call delay slots. + (TARGET_SWITCHES): Add -mjump-in-delay and -mno-jump-in-delay. + Provide -mno alternatives for most options. + (output_call): Declare. + * pa.c (output_call): New function to output a function call or + millicode call, possibly with a jump in the delay slot. + (output_mul_insn): Accept additional argument, use output_call. + (output_div_insn): Likewise. + (output_mod_insn): Likewise. + (jump_in_call_delay): New function to determine if the given + JUMP_INSN is in the delay slot of a call or millicode call. + * pa.md (uncond_branch): New type attribute. Explicitly disallow + uncond_branch in most delay slots. + (in_call_delay attribute): New test for delay slot of call insns. + Allow uncond_branches in the delay slot if TARGET_JUMP_IN_DELAY. + (define_delay for calls, millicode calls, branches, returns, etc): + Broken up into two define delays. One for calls and millicode + calls, a second for branches, returns, etc. + (millicode insns): Pass the current insn down to + output_{mul,div,mod}_insn. + (jump insn): Use "uncond_branch" type attribute. Length of this + insn varies if it is in the delay slot of a call. + (call_internal_symref): Use output_call. + (call_value_internal_symref): Likewise. + (call_internal_reg): Use %r syntax instead of just register numbers. + (call_value_internal_reg): Likewise. + + Wed Jul 14 02:19:11 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * rtl.def (CONCAT): New rtx code. + * emit-rtl.c (gen_lowpart_common, gen_highpart): Handle CONCAT. + (operand_subword): Likewise. + (gen_reg_rtx): For complex mode, return a CONCAT of two pseudos. + * stmt.c (expand_decl): Make a CONCAT, for decls of complex type. + * dbxout.c (dbxout_symbol_location): Subroutine broken out from + dbxout_symbol. Handle CONCAT here. + (dbxout_symbol_name): New subroutine. Handle anonymous decls too. + (dbxout_reg_parms): Simplify using dbxout_symbol_location. + Handle CONCAT. + + * c-typeck.c (build_c_cast): When casting to union, if value is array + or function, do default_conversion. + + Wed Jul 14 00:52:23 1993 Jim Blandy (jimb@wookumz.gnu.ai.mit.edu) + + * config.sub: Add case for Bull dpx/2. + + Mon Jul 12 17:26:53 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * fixincludes: When looking for #define CTRL, + accept multiple spaces between the two words. + + * reload1.c (reload): Don't free scratch_list or scratch_block if 0. + + Mon Jul 12 17:12:31 1993 Paul Eggert (eggert@twinsun.com) + + * c-common.c (unsigned_conversion_warning): Just use `warning', + not `pedwarn'; these diagnostics are not required by Standard C. + * c-typeck.c (convert_for_assignment): Use `convert_and_check', + not `convert', for converting arithmetic types, since + `convert_and_check' no longer reports an error + where it should just warn. + + Mon Jul 12 16:44:37 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * config/i386/i386.md (ffssi2, ffshi2): Assume bsf produces + garbage if input is 0. Use jumps to load output in that case. + + * config/vax/vax.h (INITIALIZE_TRAMPOLINE): Add code to + do an rei to clear the insn cache. + + Sun Jul 11 18:13:47 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * config/ns32k/ns32k.c (output_move_double): Do the low reg first, + when only the high reg has an overlap. + + * c-typeck.c (convert_arguments): Don't warn about sign change + for an INTEGER_CST inside NOP_EXPR, if value not fits new type. + Delete the code to check for VAL having enumeration type. + + * i860.c (output_move_double): Fix typos in Jun 28 change. + + Sat Jul 10 16:05:26 1993 Jim Wilson (wilson@sphagnum.cygnus.com) + + * i860.c (output_move_double): Only set highest_first if first reg + of dest overlaps memory src address. Otherwise, if addreg1 set and + is same as second reg of dest, suppress trailing decrement. + + Sat Jul 10 19:49:31 1993 Jeffrey A. Law (law@mole.gnu.ai.mit.edu) + + * jump.c (jump_optimize): Correctly identify branches to the end + of a function so that they may be turned into RETURN insns. + + Sat Jul 10 17:37:12 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * collect2.c (main): Allocate COLLECT_NAME string with xmalloc. + + Sat Jul 10 14:44:29 1992 Chip Salzenberg (chip@fin.uucp) + + * basic-block.h (REGSET_ELT_TYPE): Make unsigned to avoid + signed arithmetic overflow. + * hard-reg-set.h (HARD_REG_ELT_TYPE): New unsigned type to + avoid signed arithmetic overflow. + (HARD_REG_SET): Define as HARD_REG_ELT_TYPE, or array thereof. + (HARD_CONST): Always cast to HARD_REG_ELT_TYPE. + (*_HARD_REG_*): Use unsigned HARD_CONST and HARD_REG_ELT_TYPE + types instead of assuming HOST_WIDE_INT. + + Sat Jul 10 10:25:16 1993 Karl Berry (karl@cs.umb.edu) + + * fixincludes: Check for symlinks being available in /tmp. + + Sat Jul 10 02:01:08 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * config/m68k/3b1.h (MY_ISCOFF, OBJECT_FORMAT_COFF, NO_SYS_SIGLIST): + New definitions. + + Fri Jul 9 20:40:29 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * pa.md (dbra and movb patterns): Fix constraints so that FP + registers are never preferred. + + Fri Jul 9 17:36:35 1993 Holger Teutsch (holger@hotbso.rhein-main.de) + + * va-clipper.h: Make var/stdargs compatible with apogee's acc. + (__gnuc_va_list): Replace __va_f and __va_r with __va_reg. + (__va_list, _SYS_INT_STDARG_H): New defines. + (va_arg): Corresponding changes. + + * config/clipper/clipper.c (clipper_builtin_saveregs) : Dito. + + Fri Jul 9 13:39:08 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + Cygnus<->FSF merge. + Fri Jul 9 12:17:20 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-typeck.c (build_array_ref): Force the array to be allocated on + the stack if it is accessed by a out-of-bound constant integer + subscript. + + * cp-decl.c (pushdecl): Undo change to generate a new _TYPE node for + a typedef. + + Thu Jul 8 16:25:52 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl.c (pushtag): Don't mark the binding layer marker; for + dwarf debugging, do mark the TYPE_DECL we created as ignored. + + * cp-tree.h (IN_CHARGE_NAME): Define to not need DOLLAR_IN_LABEL. + (VTBL_PTR_TYPE): Likewise. + (VTABLE_DELTA_NAME, VTABLE_INDEX_NAME, VTABLE_PFN_NAME, + VTABLE_DELTA2_NAME): Use two leading underscores. + + Thu Jul 8 14:31:40 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-tree.h (TREE_ANON_UNION_ELEM): Deleted, it's never set. + * cp-decl.c (build_default_constructor): Delete checking + TREE_ANON_UNION_ELEM. + * cp-init.c (emit_base_init): Likewise. + * cp-type2.c (my_friendly_abort): Update count. + + * cp-type2.c (build_functional_cast): Disable assert 323 (see + comments for explanation). + + * cp-typeck.c (comp_target_parms): Return 0 if strict is != 0, not + just > 0. + + * cp-decl.c (init_decl_processing): Don't set WARN_RETURN_TYPE. + + Wed Jul 7 18:36:59 1993 Niklas Hallqvist (niklas@della.appli.se) + + Add the changes to redo how we handle scoping. [Merged by bpk.] + + * cp-class.c ({pop,push}_nested_class): New functions to use + instead of plain {push,pop}class. These functions will see to + that static entities of enclosing classes will be visible. + * cp-tree.h ({pop,push}_nested_class): Declare them. + * cp-decl.h ({finish,start}_function): Use these new functions + instead of plain {push,pop}class calls. + (grokdeclarator): Ditto. + * cp-decl2.c (build_push_scope): Ditto. + * cp-class.c (popclass): Only call pop_class_decls if MODIFY is + set. + + * cp-decl.c (start_decl): Maybe call pushdecl_class_level instead of + pushdecl. This is used for nested types. + (grokdeclarator): Remove the {push,pop}level calls around the + indirect recursion occuring when groking class-local typedefs. + Remove the error check of such typedefs hiding other fields in the + same scope. Remove the pushdecl_class_level call since start_decl + does the work now. + + Class scoping (and type value caching) redone. The new behaviour + is triggered by NEW_CLASS_SCOPING being defined to 1. The old + behavior is accomplished by defining it to the value 0. The entries + below describes the effective changes when NEW_CLASS_SCOPING is set + to non-zero. + + * cp-class.c (set_class_shadows): Add prototype. + (previous_class_values): New variable. + (pushclass): Adapted to not use previous_class_type & unuse_fields. + Removed setting of IDENTIFIER_CLASS_VALUE. + (popclass): Adapted to not use previous_class_type. Don't reset + IDENTIFIER_CLASS_VALUE. Moved call of pop_class_decls. + (maybe_push_cache_obstack): New function. + * cp-decl.c (current_class_depth): Add extern decl. + (previous_class_values): Add extern decl. + (pop_decl_level): Don't reset IDENTIFIER_CLASS_VALUE. + (set_class_shadows): New function. + (poplevel_class): Adjust setting of IDENTIFIER_CLASS_VALUE to only + happen if we're not leaving a toplevel class. + (push_to_top_level): Don't use adjust_type_value. + (set_identifier_type_value): Reverse the choice between class and + local scope when installing the type value. + (set_identifier_local_value): Set the type value if we're seeing a + TYPE_DECL. + (set_nested_typename): Added comment. + (pushtag): Don't call set_identifier_type_value. Leave out + setting of IDENTIFIER_CLASS_VALUE. + (adjust_type_value): Removed. + (pushdecl): Don't call adjust_type_value. + (pushdecl_class_level): Call push_class_level_binding. Set the + type value if we're seeing a TYPE_DECL. + (push_class_level_binding): New function whose guts came from + pushdecl_class_level. + (globalize_nested_type): See to that both the class_shadowed and + type_shadowed lists in the binding stack gets updated correctly. + Don't call set_identifier_type_value on the DECL_NESTED_TYPENAME. + Clear DECL_CLASS_CONTEXT as well as DECL_CONTEXT. Install a + correct IDENTIFIER_{CLASS,TYPE}_VALUE if needed. + (grokdeclarator): Prefer pushdecl_class_level over pushtag when + recording a nested typedef. + (build_enumerator): Don't install a method-local enumerator into + class scope. + * cp-decl2.c (grokfield): Don't call set_identifier_type_value. + * cp-search.c (closed_envelopes): New list containing information + of what decls should be pushed when entering a class scope. + (dfs_pushdecls): Build and maintain the closed_envelopes list + instead of managing the IDENTIFIER_CLASS_VALUEs directly. + (dfs_compress_decls): Adapted to recognize the envelopes + dfs_pushdecls has installed in the IDENTIFIER_CLASS_VALUE slots. + (push_class_decls): Tell overload_template_name to push the + template decls into class scope instead of building a new level. + Added code to open up the envelopes in closed_envelopes and + install the class/type values in the class binding contour with + proper shadowing. + (dfs_popdecls): Removed. + (pop_class_decls): Removed the actual decl-popping code, leaving + just the obstack freeing pop_search_level call. The popping is + automatically handled by poplevel now. + * cp-tree.h (NEW_CLASS_SCOPING): A new macro constant defaulted to + the value 1. + (adjust_type_value): Prototype removed. + (push_class_level_binding): Added prototype. + + Wed Jul 7 11:04:09 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl.c (pushdecl): When processing a typedef statement, + generate a whole new ..._TYPE node. Be careful that the type we're + looking at isn't an error_mark_node. + + * cp-class.c (finish_struct): Set the DECL_CONTEXT on the type we've + found. + * cp-decl.c (pushtag): Mark the TYPE_DECL as ignored when using + dwarf debugging; don't ignore it if it's anonymous for dwarf + debugging. Put the DECL_CONTEXT in the TYPE_CONTEXT of TYPE. + (globalize_nested_type): Remember to set TYPE_CONTEXT. + * cp-pt.c (overload_template_name): Set DECL_CONTEXT. + * cp-search.c (compute_visibility): Set DECL_CONTEXT if the context + is NULL. + + * cp-class.c (finish_struct): Mark the tag as ignored for dwarf + debugging. + + * cp-except.c (EHS_type): Don't make it static. + * cp-class.c (finish_struct): Don't create a default copy + constructor for the EHS_type. + + * cp-class.c (get_vtable_name): Leave the numbers in the name for + the vtable, so we're uniform with what prepare_fresh_vtable is + doing. Introduces a binary incompatability. + + * cp-tree.c (build_cplus_method_type): Mark the first argtype (the + this pointer) as artificial. + + * cp-init.c (do_friend): Don't allow a friend of a class that's not + yet been defined; instead, complain. Make sure we mark every decl + that comes in as being a friend of something. + + * cp-decl2.c (grokclassfn): Mark the __in_chrg parameter as + artificial. Don't mark it as readonly, and for destructors make + sure the first arg in the arg_types chain has TREE_SIDE_EFFECTS set, + so it's seen as artificial. + (finish_vtable_vardecl): For dwarf debugging, make the vtable's + VAR_DECL node be ignored. + + * cp-decl.c (redeclaration_error_message): Use comptypes to see if + OLDDECL and NEWDECL have the same type. + * cp-typeck.c (comptypes): Compare the main variants of the types, + after we've checked the qualifiers that could have been used on them. + + * cp-call.c (EVIL_RETURN, QUAL_RETURN, TRIVIAL_RETURN, ZERO_RETURN): + Rewrite definitions to not use do/while(0), to avoid bogus warnings + on compilers that can't deal with a return inside it. Change all + uses of them to do `return FOO_RETURN'. + + Tue Jul 6 13:00:44 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl.c (duplicate_decls): Set GIVE_ERROR so we know where the + previous declaration was for empty parameter name list declarations. + + * cp-class.c (finish_struct): Clean up error message about anonymous + classes. + + * cp-class.c (finish_struct): Don't play with TAIL when we're + dealing with a TYPE_DECL of a RECORD_TYPE; the list continues on + just fine, and TAIL is only used for managing FN_FIELDS. + + * cp-decl.c (pushlevel): Change cast to HOST_WIDE_INT. + * cp-search.c (breadth_first_search): Likewise. + + Fri Jul 2 19:24:55 1993 Steve Chamberlain (sac@rtl.cygnus.com) + + * cp-method.c: Include "cp-class.h" + + Fri Jul 2 18:16:10 1993 Michael Tiemann (tiemann@blues.cygnus.com) + + * cp-call.c (build_overload_call_real): Don't look at a required + template instantiation and a speculative template instantiation as + two different functions if they are really the same function. + + Thu Jul 1 22:28:46 1993 Michael Tiemann (tiemann@blues.cygnus.com) + + * cp-tree.h: Don't include "cp-class.h" here. + * cp-call.c, cp-cvt.c: Include it here instead. + + Thu Jul 1 18:42:03 1993 Mike Stump (mrs@cygnus.com) + + * cp-decl.c (duplicate_decls): Fix typo. (olddecl->olddecls) + + Thu Jul 1 18:34:12 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + New implementation of argument matching. This is now much cleaner + to read, and is designed such that it should be easy to tweak + things when incorrect decisions are made based on the candidates + being examined. + + * cp-decl2.c (flag_ansi_overloading): New variable. + (lang_f_options): Add -fansi-overloading. + * toplev.c (lang_options): Add -fansi-overloading and + -fno-ansi-overloading. + + * cp-class.h (harshness_code): New struct. + (candidate): New members `h' and `h_len' used by new method. New + anonymous union `v', with ansi_harshness and old_harshness. + Deleted member `harshness' (used by old method, now in `v'). + Change every file that uses harshness to refer to it in the union + as appropriate. + (EVIL_CODE, CONST_CODE, ELLIPSIS_CODE, USER_CODE, STD_CODE, + PROMO_CODE, QUAL_CODE, TRIVIAL_CODE): New macros. + + * cp-call.c (EVIL_RETURN, QUAL_RETURN, TRIVIAL_RETURN, + ZERO_RETURN): New macros. + (rank_for_overload): Renamed to rank_for_overload_old. + (rank_for_overload_ansi): New function for new method. + (rank_for_overload): Call the appropriate fn based on the new flag. + (rank_for_ideal): New function for new method. + (compute_harshness): Renamed to compute_harshness_old. + (compute_harshness_ansi): New function for new method. + (compute_conversion_costs): Renamed to compute_conversion_costs_old. + (compute_conversion_costs_ansi): New function for new method. + (compute_conversion_costs): Call the appropriate fn based on the + new flag. + (ideal_candidate): Renamed to ideal_candidate_old. + (ideal_candidate_ansi): New function for new method. + (ideal_candidate): Call the appropriate fn based on the new flag. + (strictly_better): New function for new method. + (build_method_call): Change things to use the new method if + -fansi-overloading is set. + (build_overload_call_real): Likewise. + * cp-cvt.c (convert_to_aggr): Likewise. + + * cp-call.c (build_overload_call_real): Only use the speed hack + to trigger immediately if the OVERLOAD_NAME has a global value if we + aren't using the new overloading scheme. + + * cp-cvt.c (build_type_conversion): Only accept using an `operator + double' if there isn't a conflicting `operator int', if + -fansi-overloading is on. + + Thu Jul 1 17:54:44 1993 Mike Stump (mrs@cygnus.com) + + * cp-decl.c (duplicate_decls): Propagate some changes from C + front-end. Conflicts with built-in functions are now only warnings. + + Thu Jul 1 15:43:48 1993 Mike Stump (mrs@cygnus.com) + + * cp-call.c (build_field_call): Use real type if type is a + REFERENCE_TYPE. + * cp-parse.y (primary): Cleanup and move some code out into new + function build_object_ref. + * cp-tree.h (build_object_ref): New function. + * cp-typeck.c (build_object_ref): Define new function. + * cp-typeck.c (build_x_function_call): Return error_mark_node if + first argument is, and handle when TREE_PURPOSE is a binfo and comes + from lookup_fnfields. + + Thu Jul 1 13:48:46 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-lex.c (readescape): Don't complain for \% unless pedantic. + + Wed Jun 30 10:35:50 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl2.c (bad_specifiers): Moved to cp-decl.c. New args + `inlinep' and `object' (old object renamed to type), so we can see + where the thing was declared. Use error_with_decl instead of error. + * cp-decl.c (grokdeclarator): Pass INLINEP and DECL down; move calls + so we'll have a valid DECL to give it. + * cp-tree.h (bad_specifiers): Deleted prototype. + + * cp-call.c (build_scoped_method_call): If it's a reference, work + with the actual type. + * cp-type2.c (build_scoped_ref): Likewise. + + Tue Jun 29 19:49:57 1993 Mike Stump (mrs@poseidon.cygnus.com) + + * cp-lex.c (default_copy_constructor_body): Hack broken code to work + marginally better than how it worked before, so that PlotFile3D's + make check of libg++ works. + + Tue Jun 29 12:44:48 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-typeck.c (mark_addressable): Don't complain about taking the + address of an object with register storage class; it's legal in C++. + + * cp-typeck.c (convert_arguments): Only warn about passing an object + through an ellipsis. + + * cp-parse.y (typed_declspecs): Make sure the TYPESPEC we hit + upon is non-null. + + Tue Jun 29 11:58:03 1993 Tony Deigh (tonyd@bostech.com) + + * cp-decl.c (grokdeclarator): Look at the decl as a FUNCTION_TYPE + before seeing if its TYPE_MAIN_VARIANT matches or it's a friend; + this way, we can properly detect declaration of another class's + methods inside another class. Solves chainon aborts. + + Tue Jun 29 09:47:36 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-class.c (finish_struct): Use pedwarn_with_decl for warnings + about non-static const/ref in class without a ctor, so the line + number is helpful. + + Tue Jun 29 02:46:39 1993 Mike Stump (mrs@cygnus.com) + + * cp-cvt.c (build_up_reference): Delete unneed cast. + * cp-typeck.c (convert_for_assignment): Likewise. + + Mon Jun 28 19:19:34 1993 Mike Stump (mrs@rtl.cygnus.com) + + * cp-lex.c (real_yylex): Use pedwarn to warn about using catch, try + and throw as identifiers. + + Mon Jun 28 11:13:17 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-method.c (hack_identifier): Only look for visibility if we have + a basetype path. + + * cp-decl.c (grokdeclarator): Also forbid the subscripting operator, + and class member access operator being declared as a non-member + function. + + * cp-init.c (add_friend): Pedwarn on duplicate friend decls. + + * cp-init.c (is_friend_type): New function. + (is_friend): Call it; rewrite in minor ways, to clean the code up. + * cp-tree.h (is_friend_type): Add prototype. + * cp-search.c (compute_visibility): Also check if the + CURRENT_CLASS_TYPE is a friend of CONTEXT, which can buy us access + to the field in question. + + * cp-init.c (sort_member_init): Disable assert that was wrong. + + * cp-class.c (finish_struct): Make declaration of a non-static const + or reference member get a pedwarn if the class it's in has no + constructor. + + * cp-decl2.c (grokfield): Fix up the error message about member + initialization. + + * cp-typeck.c (c_expand_return): Make sure we don't set + CURRENT_FUNCTION_RETURNS_VALUE if we set CURRENT_FUNCTION_RETURNS_NULL. + + * cp-method.c (dump_init): Don't emit digit_buffer if we're giving + an enum's tag. + + Fri Jul 9 16:45:25 1993 David d `zoo' Zuhn (zoo@cygnus.com) + + * config.sub: Make -solaris reflect the most recent major release. + + Fri Jul 9 16:18:20 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * Change length attributes to use bytes instead of instruction + counts. + * pa.h (CASE_VECTOR_MODE): Change to DImode. + * pa.c (compute_movstrsi_length): Return length in bytes. + (pa_adjust_insn_length): Return adjustment in bytes. + (output_cbranch): Handle lengths as bytes. + (output_bb, output_dbra, output_movb): Likewise. + * pa.md (default length define_attr): Lengths are in bytes now. + (asm_attributes): Likewise. + (delay slot attributes): Deal with lengths in bytes. + (explicit length computations): Compute length in bytes. + + * Make more dbra insns and support movb insns. + * pa.h (output_dbra, output_movb): Declare. + * pa.md (dbra pattern): Use output_dbra. + (dbra pattern #2): New pattern. Also use output_dbra. + (movb, inverted movb): New patterns. + * pa.c (pa_adjust_insn_length): dbra and movb insns which have + their output in a FP register do not need adjustment. + (output_cbranch, output_bb): Handle conditional jump to the + following instruction. + (output_dbra): New function extracted from dbra pattern. + (output_movb): New function. + (eq_neq_comparison_operator): New function. + (movb_comparison_operator): New function. + + Fri Jul 9 01:07:52 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * config/m68k/mot3300.h (ASM_OUTPUT_OPCODE): Don't add .w suffix + to jump insns. + + * combine.c, cse.c: Include stdio.h before rtl.h. + + Wed Jul 7 18:06:45 1993 Jim Wilson (wilson@wookumz.gnu.ai.mit.edu) + + From moshier@world.std.com: + * sparc.c (singlemove_string): Convert SFmode by REAL_VALUE... macros. + * sparc.h (ASM_OUTPUT_FLOAT, ASM_OUTPUT_DOUBLE): + Use REAL_VALUE_TO_DECIMAL to generate decimal string. + (REAL_ARITHMETIC): Define. + + * sparc.h (SECONDARY_MEMORY_NEEDED_RTX): Use + STARTING_FRAME_OFFSET. + (STARTING_FRAME_OFFSET): Set to -16. + + * c-parse.in (simple_if): Save stmt_count, and print empty body + warning here. + (if_prefix): Don't save stmt_count here. + (stmt): Don't print empty body warning here. + + * combine.c (simplify_comparison): Add parentheses to satify gcc. + * sparc.c (sparc_frw_save_restore): Likewise. + * expr.c (convert_to_mode): Move misplaced parentheses. + + Wed Jul 7 16:37:26 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * Improve code for conditional branches and dbra insns on the PA. + * pa.c (pa_adjust_insn_length): Rewrite so that it only adjusts + insns which really need adjustment. + (output_cbranch): Rework so that output templates are simpler. + Use shorter sequence for long backwards conditional branches with + a filled delay slot that is nullified. More agressively use "skip" + instructions. More agressively nullify the delay slot if nothing + useful could be placed there. + (output_bb): Likewise. + (forward_branch_p): New function. + * pa.md (conditional branches): Use the full displacement range + for the branch target. Update length computations to match current + reality. + (branch on bit patterns): Likewise. + (decrement_and_branch_until_zero): Re-enable pattern. Rewrite to + be simpler and more efficient. Also handle case where loop counter + is in a FP register. + + Wed Jul 7 11:19:03 1993 Ian Lance Taylor (ian@cygnus.com) + + * glimits.h (MB_LEN_MAX): Don't override the value from the system + . Just define it if it is not already defined. + + * collect2.c (main): Search for ld in the compiler directories. + + Wed Jul 7 13:40:55 1993 Jim Wilson (wilson@kropotkin.gnu.ai.mit.edu) + + * collect2.c (fork_execute, scan_prog_file): Use "fork" in error + messages instead of "vfork" when vfork is defined to fork. + + Tue Jul 6 16:38:36 1993 Jim Wilson (wilson@wookumz.gnu.ai.mit.edu) + + * sparc.c (sparc_type_code): Recognize SET_TYPE. For special + Fortran/Pascal types, just return qualifiers instead of aborting. + + * c-decl.c (insert_block): Correct typo in comment. + + * combine.c (simplify_and_const_int, LSHIFTRT case): Must be at + least as many sign bit copies as bits in mask. + + * c-typeck.c (build_conditional_expr): All simplified results + must go through pedantic_non_lvalue. + * cp-typeck.c (build_conditional_expr): Likewise. + * fold-const.c (fold, COND_EXPR case): Likewise. + (pedantic_non_lvalue): New function. + * tree.h (pedantic_non_lvalue): Add declaration. + + * fold-const.c (invert_truthvalue): Check for ERROR_MARK input. + + * m68k.h (LEGITIMATE_BASE_REG_P): New macro. + (INDIRECTABLE_1_ADDRESS_P, GO_IF_INDEXABLE_BASE, + LEGITIMATE_INDEX_REG_P): Accept SUBREG everywhere REG is accepted. + + * sparc.h (EXTRA_CONSTRAINT): For 'T', pass address not mem to + strict_memory_address_p call. For 'U', don't accept unallocated + pseudo-reg when strict. + + * sparc.c (output_move_quad): Implement CNSTOP case. + + * i960.h (ASM_OUTPUT_COMMON): Use SIZE not ROUNDED. + + Tue Jul 6 02:12:15 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * cse.c (simplify_binary_operation, case MINUS): Fix backwards + test added in last change. + + * config/i386/sun.h (SIZE_TYPE): Deleted. + + * c-typeck.c (convert_arguments): Don't warn for -Wconversion + about signedness of an arg that's extended from narrower unsigned type. + + * c-decl.c (duplicate_decls): Don't warn for non-extern var decl + following an extern one (for -Wredundant-decls). + + Mon Jul 5 17:50:27 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * reload1.c (emit_reload_insns): Don't use gen_lowpart_common to + get reload register into proper mode. + * reload.c (subst_reloads): Likewise. + + * combine.c (subst, case PLUS): Simplify (plus (comp A B) -1), etc. + + * fold-const.c (fold, case EQ_EXPR, LE_EXPR): If comparing results + of signed MOD with zero, use an unsigned MOD. + + * calls.c: Fix typo: had ARGS_GROW_DOWNARD. + + * configure (rs6000-ibm-aix): Use default files for aix3.2 and + aix31.h for aix3.[01]. Add new file x-aix31. + * rs6000.c (input_operand): Fix missing operand on a return. + (print_operand): Add new code '.'. + (rs6000_sa_size): Delete unused variable `i'. + (output_prolog, output_epilog): Use new RS6000_CROR_BIT_NUMBER. + * rs6000.h (CPP_PREDEFINES): Define _AIX32. + (ASM_DECLARE_FUNCTION_NAME, TEXT_SECTION_ASM_OP): Use ".text[PR]" as + csect name. + (RS6000_CROR_BIT_NUMBER): New macro. + (PRINT_OPERAND_PUNCT_VALID_P): Allow `.' as valid. + * rs6000.md (call patterns): Use %. in cror. + * x-rs6000 (CLIB): No longer need -lm. + * aix31.h, x-aix31.h: New files. + * aix32.h: Deleted. + + Mon Jul 5 17:44:09 1993 John F Carr (jfc@Athena.mit.edu) + + * romp.md (movhi): When storing a constant in an HImode register, use + cal16 instead of cal so that the high bits are clear (combine + requires this). + + Mon Jul 5 17:15:27 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * objc-act.c (encode_type_qualifiers): Add casts to enums in indices. + + Mon Jul 5 02:25:54 1993 Doug Evans (dje@wookumz.gnu.ai.mit.edu) + + * Makefile.in: Parameterize libgcc.a and install-libgcc + (LIBGCC and INSTALL_LIBGCC). + + * tree.c (get_narrower): Preserve unsignedness when bitschange == 0. + + Sun Jul 4 02:55:46 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * expmed.c (store_split_bit_field, extract_split_bit_field): + Handle fields split across more than 2 aligned units. + + * expr.c (store_field): Test STRICT_ALIGNMENT at run time. + (expand_expr, COMPONENT_REF case): Fetch unaligned field as bitfield. + + * collect2.c (error, fatal, fatal_perror): Say collect2, not collect. + + * c-parse.in (primary): In statement expression case, + if compstmt returns something other than a BLOCK, + return it unchanged. + + Sat Jul 3 20:32:43 1993 Minh Tran-Le (tranle@intellicorp.com) + + * fixinc.svr4: Added fixup for __STDC__ == 0 and __STDC__ == 1 + cases found in sequent PTX-2.0.x headers. + + Sat Jul 3 18:54:07 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * pa.c (call_operand_address): Do not accept registers anymore. + * pa.md (call expanders): Emit different patterns for named calls + and indirect calls. + (call_internal_symref, call_internal_reg): New patterns. + (call_internal): Deleted. Now handled by call_interal_{symref,reg}. + (call_value_internal_symref, call_value_internal_reg): New patterns. + (call_value_internal): Deleted. Now handled by + call_value_internal_{symref,reg). + + Sat Jul 3 16:40:52 1993 Doug Evans (dje@wookumz.gnu.ai.mit.edu) + + * collect2.c (main): Give ld_file_name an initial value. + + Fri Jul 2 16:36:56 1993 Jim Wilson (wilson@wookumz.gnu.ai.mit.edu) + + * sparc.md (ashldi3+2): Change lshift to ashift. + + * sparc.md (zero_extendhisi2, extendhisi2, extendqihi2, + extendqisi2): Preserve the SUBREG_WORD value of subreg operands. + (ashldi3): Delete, obsoleted by lshldi3 pattern. + (lshldi3): Rename to ashldi3 for consistency with SImode shifts. + + Fri Jul 2 01:10:56 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * Makefile.in (install-headers-tar): Ignore exit status of the + first tar command. + + Thu Jul 1 14:31:45 1993 Doug Evans (dje@canuck.cygnus.com) + + * flow.c (find_auto_inc): In *p=expr;q=p+size case, avoid clobbering q + if referenced in expr. + + Fri Jul 2 01:26:01 1993 Paul Eggert (eggert@twinsun.com) + + * tree.h (pushcase, pushcase_range): Add a new converter + function argument that specifies how to convert case labels to the + nominal type. + * stmt.c (pushcase, pushcase_range): Likewise. + * c-parse.in (label): Use `convert_and_check' when checking for + overflow in case labels. + * cp-parse.y (simple-stmt): Similar change, but use `convert' instead; + this leaves the behavior unchanged for C++. A C++ expert should look + into this. + + * tree.h (TREE_OVERFLOW): New macro. + * c-common.c (constant_expression_warning, overflow_warning, + convert_and_check): Distinguish between TREE_OVERFLOW, which is just + for warnings, and TREE_CONSTANT_OVERFLOW, which is for required + pedantic diagnostics. + * c-typeck.c (c_sizeof, build_c_cast): Set TREE_OVERFLOW in addition + to TREE_CONSTANT_OVERFLOW. + (store_init_value): STRIP_TYPE_NOPS is required before + constant_expression_warning. + * fold-const.c: (const_binop, fold_convert, fold): + Set TREE_OVERFLOW in addition to TREE_CONSTANT_OVERFLOW. + + Thu Jul 1 20:55:27 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * reload1.c (eliminate_regs): Fix typo in BYTE_LOADS_ZERO_EXTEND. + + Thu Jul 1 20:00:00 1993 DJ Delorie (dj@ctron.com) + + * gcc.c (choose_temp_base): Try multiple variables. Don't + assume that the variable points to a valid directory. + + * gcc.c (pexecute): Handle the MS-DOS return codes correctly. + Add .exe to file name when appropriate. + + * configure.bat: Make gcc use its own obstack.o. + + * objc/makefile.dos: New file for building with djgpp. + + Thu Jul 1 18:15:17 1993 Paul Eggert (eggert@twinsun.com) + + * fixincludes, fixinc.svr4: Don't create absolute symbolic links; + make them relative instead. + * fixincludes: Remove special case for IRIX 4.0.1 that was + superseded by a more general fix to fixincludes. + + * fixinc.svr4: Remove everything after #endif, instead of trying + to turn it into comments, which loses inside comments. + * fixincludes: Likewise. Remove #endif workarounds for Ultrix 4.[12] + and SunOS 4.1, which are no longer needed because of this bug fix. + + Thu Jul 1 14:56:56 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * pa.h (OVERRIDE_OPTIONS): Define. Give a warning if -fpic or + -fPIC was specified on the command line. + + * configure (hppa1.0-hp-hpux8.02): New target. + (hppa1.1-hp-hpux8.02): Accept "--gas" in this configuration. + * pa-oldas.h: New target for 1.0 machines running HPUX 8.02. + * pa.c (output_arg_descriptor): Reverse polarity of test for + HP_FP_ARG_DESCRIPTOR_REVERSED. + * pa.h (ASM_DOUBLE_ARG_DESCRIPTORS): Likewise. + * pa-hpux7.h (HP_FP_ARG_DESCRIPTOR_REVERSED): Define. + * pa1-oldas.h (HP_FP_ARG_DESCRIPTOR_REVERSED): Define. + (TARGET_DEFAULT): Clear useless bits in TARGET_DEFAULT. + * pa-utahmach.h (HP_FP_ARG_DESCRIPTOR_REVERSED): Do not define here. + * pa1-utahmach.h (HP_FP_ARG_DESCRIPTOR_REVERSED): Likewise. + * pa1-ghpux.h (HP_FP_ARG_DESCRIPTOR_REVERSED): Likewise. + * pa1-hpux.h (HP_FP_ARG_DESCRIPTOR_REVERSED): Likewise. + + Thu Jul 1 09:48:23 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * fold-const.c (fold, case GE_EXPR, LT_EXPR): Don't assume + result of comparison is integer_type_node. + + Thu Jul 1 00:23:16 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * config/i386/mach.h (SIZE_TYPE): Definition deleted. + + Wed Jun 30 16:16:20 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * config/m68k/sun3.h (SIZE_TYPE): Definition deleted. + + Wed Jun 30 16:55:25 1993 John F Carr (jfc@Athena.mit.edu) + + * mips.c (gen_int_relational): For test with constant result, + copy const0_rtx or const_true_rtx to result register instead + of allocating a new pseudo-register. + + Wed Jun 30 15:19:42 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * config.sub: Recognize `gnu' as a valid operating system. Sheesh. + + Wed Jun 30 13:43:45 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * pa.c (output_function_prologue): Emit SAVE_SP flag if a frame + pointer is needed. + + Wed Jun 30 00:52:25 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * collect2.c (main): Don't look for `gld' or `TARGET-gld'. + + * fixincludes (stdtypes.h): Verify that size_t etc. follow whitespace. + + * expr.c (expand_expr, case PLUS_EXPR): In the special case + to return sym+integer as an expression, limit it to when + the non-CONST_INT arg is at least a constant. + (expand_increment): Do preinc with single insn if there's such an insn. + + * stmt.c (expand_end_case): Pass 1 as UNSIGNEDP to emit_cmp_insn + when handling wide values. + Save original minval in orig_minval and use for making the table. + + Tue Jun 29 22:28:06 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * pa.c (singlemove_string): Use zdepi and ldil to load constants + into registers when appropriate. + + Tue Jun 29 11:26:35 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * config.sub: Recognize -sysv* after -sysvr4. + + * config/vax/vax.h (GO_IF_NONINDEXED_ADDRESS): Declare reg_equiv_mem. + + Mon Jun 28 20:12:04 1993 Steve Chamberlain (sac@apple-gunkies.gnu.ai.mit.edu) + + * config/sh/*: Major rework. + + Mon Jun 28 02:46:47 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * fixincludes (file): When changing VA_LIST to DUMMY_VA_LIST, + preserve _NEED___VA_LIST. + + * config/ns32k/ns32k.c (output_move_double): + Handle reg[n,n+1] = mem[reg[n] + reg[n+1]]. + * config/ns32k/ns32k.md (movdf, movdi): Delete `&' from constraint. + + * config/sparc/sparc.c (output_move_double): Use new local var + highest_first to make sure addreg1 gets handled in the overlap case. + In 2-reg-overlap case, really use proper reg in new address. + + * config/i860/i860.c (output_move_double): + Handle reg[n,n+1] = mem[reg[n] + reg[n+1]]. Use new local var + highest_first to make sure addreg1 gets handled in the overlap case. + * config/i860/i860.md (movdf, movdi): Delete `&' from load constraint. + + * config/sparc/sol2.h (CPP_SPEC): For -compat-bsd, put the ucbinclude + dirs before, not after. + + * expr.c (store_field): Store unaligned field with bit field methods. + + * config/vax/vax.h (GO_IF_NONINDEXED_ADDRESS): If reload_in_progress, + check a REG's reg_equiv_mem the way we would check a MEM. + + * reload.c (find_reloads_address): Be selective about what inner + addresses to allow in an indirect mem ref. + + Sun Jun 27 16:40:59 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * emit-rtl.c (copy_rtx_if_shared): Don't try to copy a 0-length vector. + + * config/m68k/x-apollo68 (TAROUTOPTS): New definition. + + * config.sub: Canonicalize -sco4 and -sco3.2.4 to -sco3.2v4. + + * gcc.c (DEFAULT_WORD_SWITCH_TAKES_ARG): Check for -iwithprefixbefore. + (option_map): Add --include-with-prefix-before and + --include-with-prefix-after. + + Sun Jun 27 16:04:52 1993 Holger Teutsch (holger@hotbso.rhein-main.de) + + * va-clipper.h: Use and define Macro __GNUC_VA_LIST. Define struct + __gnuc_va_list. + + Sun Jun 27 08:32:19 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * machmode.h (INTEGRAL_MODE_P, FLOAT_MODE_P): New macros. + * cse.c (simplify_*_operation, fold_rtx, record_jump_cond, cse_insn): + Use them. + * combine.c (subst, apply_distributive_law): Likewise. + (reversible_comparison_p): Likewise. + Can reverse if MODE_COMPLEX_INT or MODE_PARTIAL_INT. + + * function.c (fixup_stack_1): Handle + current_function_internal_arg_pointer. + + * stor-layout.c: Add prototypes for layout_record and layout_union. + (smallest_mode_for_size): New function. + (variable_size): Allow variable sizes if global_bindings_p returns a + negative value. + (mode_for_size): Fix incorrect comment. + (layout_decl): If DECL has a size already, don't copy from type. + (layout_type, case INTEGER_TYPE, ENUMERAL_TYPE): Use smallest + integer mode that fits, whether or not it fits exactly. + + * emit-rtl.c (restore_emit_status): Clear LAST_LABEL_NUM. + + * calls.c (expand_call): If function hasn't been used before, + call assemble_external. + + * expr.c (store_constructor): Treat QUAL_UNION_TYPE just + like UNION_TYPE. + (safe_from_p, case ADDR_EXPR): EXP is safe from X it is is static or + if the object whose address is being taken is safe from X. + (expand_expr): Fix misplaced comment from last change. + (expand_expr, case *_DECL): If not already used, assemble external. + (expand_expr, case EXIT_EXPR): Simplify. + (expand_expr, TRUTH_{AND,OR}IF_EXPR): Properly handle IGNORE case. + + * tree.c (array_type_nelts): Tighten up code and make more general. + (build_function_type): Allow function to return array. + (decl_function_context): Treat QUAL_UNION_TYPE like UNION_TYPE. + + * fold-const.c (fold, case TRUTH_XOR_EXPR): End with `return', + not `break'. + + * dwarfout.c (output_compile_unit_die): Add support for Ada. + + * c-iterate.c (collect_iterators, case SAVE_EXPR): Simplify code + added in previous change. + + * expr.c: Fix typo: was ARGS_GROW_DOWNARD. + + * combine.c (subst, case IF_THEN_ELSE): Install correct version of + last change. + + Sat Jun 26 15:38:33 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * cccp.c (main): For -iwithprefix, if no include_prefix, + make a default from GCC_INCLUDE_DIR. + Support -iwithprefixbefore. + + * reload.c (find_reloads): When merging reloads again after they have + been changed, do check reload_reg_class and reload_nocombine. + + * config/sparc/sparc.md (movdf recognizer): Remove & from + constraint for loading mem to cpu reg. + + * expr.c (expand_assignment): If FROM is scalar function call, + expand_expr FROM before TO. + + * gcc.c (translate_options): `*' inhibits warning of extraneous arg. + + Sat Jun 26 11:07:23 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * reload1.c (reload): Use reg_equiv_address for invalid addresses + of the form (mem (reg)). + + * config/*/xm-*.h: Remove line that #define's alloca + to __builtin_alloca. + + * fold-const.c (fold, case PLUS_EXPR, MINUS_EXPR): Apply + distributive law to multiplication. + (fold, case *_DIV_EXPR): Replace code to handle (A*C1)/C2 with + more general code to handle addition as well. + (fold, case *_MOD_EXPR): Add simplified version of above code. + + * integrate.c (function_cannot_inline_p): Can now inline nested + functions. + (expand_inline_function): Set up static chain if needed. + (output_inline_function): Don't switch to temporary allocation + here. + * toplev.c (compile_file): Switch to temporary allocation when + writing out inline function. + * cp-decl2.c (write_vtable_entries, finish_file): Likewise. + * c-decl.c, cp-decl.c (poplevel): Start new function context + when writing inline function. + + * c-decl.c (init_decl_processing): When making SIZETYPE, + start with name in SIZE_TYPE. If -traditional, use a + signed version of that type, if it is unsigned. + + * fold-const.c: Add prototypes for static functions. + ({l,r}{shift,rotate}_double): COUNT arg is HOST_WIDE_INT, PREC is int. + (all_ones_mask): Remove __inline__. + (range_test): Make static; not used elsewhere. + * tree.h: Add more decls for functions in fold-const.c. + + * calls.c (expand_calls): Fix typo: ALLOCATE_OUTGOING_ARGS + should be ACCUMULATE_OUTGOING_ARGS. + + * tree.def (TRUTH_{AND,OR,XOR}_EXPR): Make code class be 'e' like + the rest of the truth operations. + * fold-const.c (fold_truthop): Treat a BIT_AND_EXPR with a constant of + one as if it were surrounded with an NE_EXPR. + (fold): Don't move operation into conditional if it + is BIT_{AND,OR}_EXPR with the constant 1; change it to TRUTH_*_EXPR + instead. + When moving things inside conditions, move comparisons as well as + binary operations. + Don't make a SAVE_EXPR when moving things inside conditionals unless + the value would really have been used twice. + + * expr.c (do_store_flag): When computing via a shift, allow for + an inner RSHIFT_EXPR in BITNUM. + Sometimes do the operations as signed. + + * combine.c (subst): apply_distributive_law can also handle AND. + (subst, case IF_THEN_ELSE): Make a shift when appropriate. + (simplify_shift_const): If we have an outer operation and made + a shift, see if it can be simplified. + + Sat Jun 26 03:25:35 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * configure (i370-*-mvs*): New configuration. + * config/i370/i370.md, mvs370.c, tm-mvs.h, xm-mvs.h + + * final.c, varasm.c: Include ctype.h. + * c-lex.c: Include ctype.h. + (isalnum, isdigit): Macros deleted. + + * config/sparc/sparc.c (output_move_double): Handle + reg[n,n+1] = mem[reg[n] + reg[n+1]]. + * config/sparc/sparc.md (movdi): Delete the earlyclobber in load case. + + Sat Jun 26 03:15:38 1993 Doug Evans (dje@wookumz.gnu.ai.mit.edu) + + * gcc.c (option_map): Add missing comma. + + Sat Jun 26 02:17:28 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * config/we32k/we32k.c: Clean up formatting. + + * calls.c (calls_function_1): Add declaration. + + * config/m68k/m68k.md (fix_truncdfsi2, fix_truncdfhi2, fix_truncdfqi2): + Require TARGET_68881 as well as TARGET_68040. + + Fri Jun 25 20:13:51 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * calls.c (calls_function): Don't scan a single save_expr twice. + (calls_function_1): New subroutine for the actual recursion. + + * c-parse.in (all_iter_stmt_simple): Add missing `else'. + + Fri Jun 25 15:53:59 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + Cygnus<->FSF merge. + Fri Jun 25 10:00:34 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl.c: Delete some #if 0'd code that has been there forever. + + * cp-type2.c (my_friendly_abort): Update count of aborts (added by + emit_base_init rewrite). + + Make default copy constructors work properly. + * cp-lex.c (cons_up_default_function): Mark the generated ctor with + RID_INLINE, so it won't get emitted unless it's needed. + * cp-decl.c (grok_ctor_properties): If CTYPE has virtual base + classes, make sure we don't pay attention to the int that we + magically added to the ctor decl. + * cp-ptree.c (print_lang_type): Note a const copy ctor vs a normal + copy ctor. Say if TYPE_HAS_DEFAULT_CONSTRUCTOR. + * cp-tree.h (cons_up_default_function): Modify prototype. + * cp-class.c (finish_struct): Also check TYPE_HAS_CONSTRUCTOR, so + we don't generate a default ctor if they already declared one + (taking whatever arg types). + + Wed Feb 3 17:41:02 1993 Chip Salzenberg (chip@tct.com) + + * cp-class.c (needs_const_ctor): Eliminate as meaningless. + (finish_struct) Always generate default functions. + Generate exactly one copy constructor: either "X(X&)" or + "X(const X&)", but not both. + * cp-lex.c (cons_up_default_function): Take list of fields + as a new parameter. Use default_copy_constructor_body. + Set TREE_PUBLIC and DECL_EXTERNAL correctly for usage with + #pragma interface. + (default_copy_constructor_body): New function (uses obstacks). + + Thu Jun 24 12:41:16 1993 Mike Stump (mrs@rtl.cygnus.com) + + * cp-call.c (build_scoped_method_call, build_method_call): Remove + maybe_adjust argument to build_delete as it is unneeded and remove all + support for the magic cookie key in the area just before the data + allocated by new []. + * cp-decl.c (finish_function, maybe_build_cleanup, + push_exception_cleanup): Likewise. + * cp-decl2.c (delete_sanity, finish_file): Likewise. + * cp-init.c (init_init_processing, build_new, + maybe_adjust_addr_for_delete, build_delete, build_vbase_delete, + build_vec_delete): Likewise. + * cp-tree.c (build_cplus_new): Likewise. + * cp-tree.h (build_delete): Likewise. + + Wed Jun 23 17:18:41 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl.c (init_decl_processing): Also catch SIGBUS. + (sigsegv): Rename to signal_catch; also reset SIGBUS. + + * cp-typeck.c (pointer_diff): Error if op1 is a pointer to an + incomplete type. + + Wed Jun 23 16:17:43 1993 Mike Stump (mrs@rtl.cygnus.com) + + * cp-search.c (dfs_get_vbase_types, get_vbase_types): Conform to ARM + 12.6.2 with respect to virtual bases. Virtual bases are now + initialized in dfs order. + + Wed Jun 23 16:04:17 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-tree.c (layout_basetypes): Disable the warning relating to a + non-virtual dtor. + + Tue Jun 22 20:03:59 1993 Mike Stump (mrs@cygnus.com) + + * cp-lex.c (reinit_parse_for_block): Detect EOFs inside templates. + + Tue Jun 22 16:10:46 1993 Mike Stump (mrs@cygnus.com) + + * cp-class.c (finish_struct): Set TYPE_NONCOPIED_PARTS now that the + right vtable can be found, so that the vtable pointers are set + correctly when implementing default copy constructors. + * cp-typeck.c (build_modify_expr): Use TYPE_NONCOPIED_PARTS in the + same way the backend uses it when implementing default copy + constructors. + + Tue Jun 22 10:50:56 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl.c (grokdeclarator): Don't try to mangle the name of a fn + that has C linkage. + + * cp-init.c (xref_friends): Deleted fn, since it's the same as + xref_friend. + (xref_friend): Make it static. + (do_friend): Change call to xref_friend. + * cp-tree.h (xref_friend, xref_friends): Delete extern decls. + + * cp-tree.h (lang_type): Delete `dynamic' bit. + * gplus.gperf (dynamic): Delete reserved word. + * cp-hash.h: Generated a new version. + * cp-lex.c (init_lex): Delete doing an unset of `dynamic'. + * cp-parse.y (DYNAMIC): Delete token and setting it to %right. + (new, aggr): Delete DYNAMIC rules. + * cp-spew.c (init_spew, struct toks_follow_types): Delete DYNAMIC. + + * cp-typeck.c (convert_for_assignment): There's no standard + conversion from a pointer to member to a `void *'. + + * cp-decl.c (init_decl_processing): Add builtins for + __builtin_apply_args, __builtin_apply, and __builtin_return. + + Mon Jun 21 12:05:28 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl2.c (grok_x_components): New function. Adjust the code that + handles ENUMERAL_TYPEs and UNION_TYPEs to make more sense. + * cp-parse.y (component_decl): Move a lot of code into that fn. + * cp-tree.h (grok_x_components): Add extern decl. + + * cp-parse.y (component_decl_list): Don't warn about a semicolon + after a component_decl_list. + + * cp-search.c (lookup_field): Be careful to handle operators + properly when complaining about ambiguities &c. + + * cp-search.c (dfs_pushdecls): Make sure we have a context before + seeing if it derives from TYPE. + + Fri Jun 18 08:14:11 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl2.c (finish_anon_union): Use simple_cst_equal to find the + member that can hold all the values, instead of just doing a compare + between the DECL_SIZEs. + + Wed Jun 16 10:57:37 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-typeck.c (build_unary_op): Make sure it's the global fn `main' + before complaining about taking the address of it. + + * cp-decl.c (grokdeclarator): Also forbid `operator ()' as a + non-member fn. + + * cp-decl.c (grok_reference_init): Don't allow an initializer list + as the initializer for a reference. + + * cp-method.c (dump_init): Handle a NON_LVALUE_EXPR. + + Sun Jun 13 12:55:22 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl.c (grokvardecl): Don't complain about duplicate + definitions of `extern "C"' declarations (parallelize it with how + regular `extern' decls are handled). + + * cp-decl.c (start_function): Avoid a null-reference on CTYPE. + + * cp-cvt.c (build_default_binary_type_conversion): Look deeper into + what ARG1 and ARG2 are if they're POINTER_TYPEs. + + Thu Jun 10 12:09:17 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl.c (grokdeclarator): Make the warning about opr-eq being a + member function be a pedwarn. + + Thu Jun 10 00:30:08 1993 Mike Stump (mrs@cygnus.com) + + * cp-tree.h: (previous_class_type): Add external declaration. + * cp-class.c (prev_class_type): Rename to previous_class_type. + * cp-decl.c (struct saved_scope): Add previous_class_type slot. + * cp-decl.c (push_to_top_level, pop_from_top_level): Track + previous_class_type value. The only trick is that we have to call + popclass(-1) when we have a previous_class_type that we are about to + destroy, to keep things in sync. + + Tue Jun 8 16:48:49 1993 Mike Stump (mrs@cygnus.com) + + * cp-cvt.c (build_thunk, convert_fn_ptr): New routines to handle + thunks. + * cp-cvt.c (cp_convert_to_pointer): Use convert_fn_ptr when + converting non-static pointer to members. + + Tue Jun 8 16:41:59 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-lex.c (reinit_parse_for_block): Make sure not to try to use + consume_string on an escaped double-quote. + + Tue Jun 8 16:25:43 1993 Mike Stump (mrs@cygnus.com) + + * cp-call.c (build_method_call): Don't search hidden functions from + base classes, as this violates chapter 10. + + Mon Jun 7 18:46:01 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-init.c (emit_base_init): Rewrite, merging the two paths into + one for member initialization. Now members will be initialized in + order of declaration, not in the order of the mem-initializer list. + (perform_member_init, sort_member_init): New functions. + + Mon Jun 7 18:01:31 1993 Mike Stump (mrs@cygnus.com) + + * cp-search.c (is_subobject_of_p, lookup_field, lookup_fnfields): + Because virtual bases don't necessarily share the same binfo, use + the binfo hierarchy of TYPE_BINFO of any virtual bases, when + performing hiding checks. Fixes problem introduced on Thu Mar 25 + 23:09:27 1993. The symptom is the compiler reports non ambiguous + members as being ambiguous. + + Sun Jun 6 11:45:44 1993 Michael Tiemann (tiemann@rtl.cygnus.com) + + * cp-call.c (EVIL,TRIVIAL): New macros. + (convert_harshness): Use these macros. + + Sat Jun 5 19:06:13 1993 Michael Tiemann (tiemann@rtl.cygnus.com) + + * cp-init.c (emit_base_init): Make clearing BINFO_BASEINIT_MARKED + symmetric with its setting. Fixes p2825. + + Thu Jun 3 16:24:30 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-parse.y (component_declarator, component_declarator0): + Allow attribute after nameless field. + + * cp-lex.c (real_yylex): Take care to expand token_buffer before + storing each character. + + * cp-lex.c (real_yylex): If an integer value overflows so the high + word is negative, it's of unsigned long long type. Integer constant + is unsigned for purposes of int_fits_type_p so that it compares huge + constants properly. Warn about integers so large that they are + unsigned. + + * cp-cvt.c (convert_from_reference): Do an or-equals on setting + TREE_SIDE_EFFECTS for NVAL. + * cp-tree.c (lvalue_p): For a SAVE_EXPR, check its first argument. + + Thu Jun 3 11:34:35 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl2.c (grok_alignof): New function. + * cp-parse.y (unary_expr, ALIGNOF unary_expr rule): Move the code + into the new function, to reduce the size of the parser. + * cp-tree.h (grok_alignof): Add prototype. + + * cp-decl.c (grokdeclarator): Allow function-call notation for + initialization of scalars as well as aggregates. + + * cp-decl.c (pushdecl): Don't pay attention to friends when noting a + missing `static' decl. Disable this code for now. + + Wed Jun 2 12:23:05 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl.c (duplicate_decls): Do a regular error if the line number + on NEWDECL hasn't been set yet (e.g., before finish_struct). + + * cp-class.c (finish_struct): Remove warning about a bit-field + having a bad type in ANSI C++, it's not appropriate given the + warning immediately above. + + * cp-typeck.c (require_instantiated_type): Don't allow an + initializer list in an argument list. + + * cp-decl.c (pushdecl): Change shadowing of a param in outermost + block of the fn from a pedwarn to an error, since it's a + redeclaration. + + * cp-class.c (finish_struct): Say anonymous classes and structs are + useless, not just classes. + + * cp-lex.c (real_yylex): Warn if catch, throw, or try are used as + identifier names. + + * cp-decl.c (pushdecl): Make sure we have a CURRENT_FUNCTION_DECL + before setting its public flag. + + * cp-decl.c (expand_static_init): Only complain about multiple + initializations of a static variable if we actually have an + initializer. + (finish_decl): Likewise for const. + + * cp-search.c (build_mi_matrix): Fix off-by-one error in + clearing of MI_MATRIX. + (get_base_distance): Init NEW_BINFO to 0. + + * cp-pt.c (instantiate_member_templates): Initialize XXX to 0. + + * cp-call.c (build_method_call): Zero out candidates. + (build_overload_call_real): Likewise. + + Wed Jun 2 11:53:24 1993 Mike Stump (mrs@cygnus.com) + + * cp-search.c (lookup_fnfields_here): Use TYPE_MAIN_VARIANT on + context types before comparing. Fixes const member functions not + being found in templates. + + Tue Jun 1 18:26:18 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-parse.y (structsp): Avoid a null-ref on ID. + (left_curly): Likewise. + + Tue Jun 1 13:49:20 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl.c (pushdecl): Communicate a `static' decl of a prototype + into its definition, if they forget to take care of it. + + * cp-init.c (emit_base_init): Make error message more useful about + insufficient initializers for a member of a class w/o a ctor. + + Sun May 30 09:45:06 1993 Michael Tiemann (tiemann@rtl.cygnus.com) + + * cp-call.c (compute_conversion_costs): Penalise each argument that + matches an ellipsis, not just the ellipsis itself. + (build_method_call): Don't consider a candidate an easy match if + cp->ellipsis is non-zero (fixes p2778). + + Sat May 29 09:34:57 1993 Michael Tiemann (tiemann@rtl.cygnus.com) + + * cp-cvt.c (convert_to_reference): Match ARM rules more closely by: + (1) not converting between types of different signedness, and + (2) converting between types of different varieties if a const& + suggests we can use a temporary (fixes p2780). + + * cp-decl.c (decls_match): Handle pseudo-match of parameter lists + according to p308 of the ARM. + (push_overloaded_decl): Ditto. + * cp-typeck.c (comptypes): Rest of change (closes p2779). + + * cp-call.c (compute_conversion_costs): Count ellipses when we see + them. + (ideal_candidate): Gracefully handle arg lists that have ellipses + (Fixes p2777). + + * cp-call.c (build_method_call): Delete some #ifdefs that are + obsoleted by ANSI. + + Fri May 28 12:15:21 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl.c (finish_decl): Don't allow overloaded operators to have + default arguments. + + * cp-cvt.c (convert): If it's an anonymous enum, say so instead of + giving the cryptic `._123' as the enum type. + + Thu May 27 10:52:49 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl.c (grokdeclarator): Return 0 instead of doing a 155 abort, + so we'll get the right error message later. + + * cp-type2.c (readonly_error): Give a more useful error when the arg + is a RESULT_DECL. + + * cp-init.c (build_new): Set LOOKUP_COMPLAIN on the flags, so we'll + pay attention to the visibility of the constructor we're trying to + call. + + * toplev.c (lang_options): Add warning about ctor/dtor privacy. + * cp-decl2.c (lang_decode_option): Grok it. Make -Wall effect it. + (warn_ctor_dtor_privacy): New variable, default being on. + * cp-tree.h (warn_ctor_dtor_privacy): Add extern decl. + * cp-class.c (finish_struct_methods): Make the ctor warning + conditionalized on the flag. + (finish_struct): Likewise for ctors. + * invoke.texi (Option Summary, Warning Options): Add it. + (Options to Request or Suppress Warnings): Explain it. + + * cp-decl.c (grokdeclarator): Use a pedwarn on extern inline. + + Tue May 25 13:55:48 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-init.c (build_delete): Don't pass the size as an argument to + builtin delete for a non-aggregate type. Only pass it for a class + when we'll be using its own operator delete(). (complies w/ $12.5) + (build_x_delete): Don't pass the size down to builtin delete. + + * cp-decl2.c (delete_sanity): If it's a pointer to a type that has + no destructor, then build a regular delete expression, instead of a + vector one (since we didn't push any info into the BI_header_type + area). + + * cp-decl2.c (grok_array_decl): Add a pedwarn if they do `5[a]'. + + * cp-typeck.c (comptypes): Don't warn about t2 being an + error_mark_node. + + * cp-decl.c (finish_decl): If type is laid out, but decl is not, + call layout_decl. + + Mon May 17 10:35:55 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-tree.h (error_not_base_type): Add prototype. + + Fri May 14 17:16:55 1993 Mike Stump (mrs@poseidon.cygnus.com) + + * cp-class.c (finish_struct): Use get_binfo instead of binfo_value + to find vfields. Cures compiler_error. + + Thu May 13 14:57:51 1993 Mike Stump (mrs@cygnus.com) + + * cp-tree.c (binfo_value): If type is the main binfo for elem, + return it. + + Wed May 12 13:10:07 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-typeck.c (c_expand_return): Pedwarn on using return without a + value in a function that requires one. Clear + CURRENT_FUNCTION_RETURNS_NULL, so we don't get a bogus warning about + reaching the end of a non-void function. + + Tue May 11 17:51:16 1993 Mike Stump (mrs@poseidon.cygnus.com) + + * cp-decl.c (start_decl): Allow -fexternal-templates compiled code to + fall back to old strategy of generating static copies for templates + that are not under the control of #pragma interface/implementation, + but warn if this happens. + * cp-decl2.c (warn_if_unknown_interface): Likewise. + * cp-lex.c (reinit_parse_for_method, cons_up_default_function): + Likewise. + * cp-pt.c (end_template_decl, instantiate_member_templates, + instantiate_template): Likewise. + * cp-tree.h (warn_if_unknown_interface): Likewise. + + Sat May 8 05:53:17 1993 Michael Tiemann (tiemann@cygnus.com) + + * cp-decl.c (finish_decl): TOPLEV should be set non-zero also if we + are at the pseudo-global level. Use TOPLEV instead of testing + CURRENT_BINDING_LEVEL. + + Fri May 7 12:42:46 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-decl2.c (grok_array_decl): New function. + * cp-parse.y (primary): Use it instead of lots of code in the + parser. + * cp-tree.h (grok_array_decl): Add prototype. + + * cp-parse.y (component_decl): Disable change about TYPE_DECLs going + into the TYPE_FIELDS list for now. + * cp-type2.c (store_init_value): Disable checks for now. + + Thu May 6 16:59:19 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-lex.c (check_newline): Use a while instead of a do-while to + avoid reading the line after the #pragma if we're at a newline. + + Wed May 5 16:38:06 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * Makefile.in (stamp-cp-parse): Update reduce/reduce count to 13. + + * cp-decl2.c (delete_sanity): New function. + * cp-parse.y (unary_expr): Call it, getting rid of a lot of + repeated code in the parser. + * cp-tree.h (delete_sanity): Add prototype. + + * cp-init.c (emit_base_init): Don't try to do anything with a member + that lacks a DECL_NAME (e.g., types we added in component_decl from + the parser). + + Wed May 5 12:57:33 1993 Jim Wilson (wilson@sphagnum.cygnus.com) + + * cp-parse.y (get_current_declspecs): Obsolete, deleted. + + Tue May 4 13:46:09 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-type2.c (process_init_constructor): Don't check for private or + protected members; we do that in store_init_value now. + + * cp-parse.y (simple_stmt): Use expr_no_commas instead of expr for + case labels. + + * cp-typeck.c (build_binary_op_nodefault): Add 'right' and 'left' to + shift count warnings to distinguish them from each other. + + * cp-decl.c (finish_decl, grokdeclarator): Report overflows in + storage sizes. + (build_enumerator): Report overflows on enumerators. + * cp-decl2.c (grokbitfield): Likewise. + * cp-parse.y (unary_expr): Warn about overflows in parser-built + unary expressions. + * cp-typeck.c (c_sizeof): Call force_fit_type only for INTEGER_CST. + (build_c_cast): Ignore any integer overflow caused by a cast. + (convert_for_assignment): Warn if source had overflow in folding. + (build_conditional_expr): Check conversions in if-then-else + expressions. + * cp-tree.h (convert_and_check, overflow_warning, + unsigned_conversion_warning): Add prototypes for fns in c-common.c. + + * cp-decl.c (init_decl_processing): Make the arrays 200 long to + leave enough room for most names. + + * cp-decl.c (lookup_label): Return a NULL_TREE if not within a + function. + * cp-parse.y (unary_expr, ANDAND identifier): Handle lookup_label + returning a NULL_TREE. + + * cp-method.c (dump_init): Grok a FIELD_DECL as well. + + * cp-decl.c (finish_function): Move setting of the DECL_RESULT's + context and calling setjmp_protect after poplevel, so we have a + valid DECL_INITIAL for the fndecl (not an error_mark_node). + + Mon Jan 25 11:04:23 1993 Niklas Hallqvist (niklas at della.appli.se) + + * cp-parse.y (component_decl): Handle anonymous unions as static + class members. + * cp-decl.c (grokdeclarator): Ditto. + + * cp-decl.c (shadow_tag): Emit error message if static or extern + is specified as per ARM 7.1.1. + + * cp-decl2.c (finish_anon_union): Issue error if a global + anonymous union is not declared static, remove old funny error + about some optimizer failing. + + * cp-class.c (finish_struct): Corrected error message concerning + anonymous classes. + + * cp-lex.c (check_for_missing_semicolon): Allow trailing storage + specifiers. + + Fri Jan 29 09:39:17 1993 Niklas Hallqvist (niklas at della) + + * cp-parse.y (component_decl): Nested unions, enums and structs + should have their TYPE_DECLs in the TYPE_FIELDS slot of the + containing type so the access flags eventually will get correctly + set. + + * cp-type2.c (store_init_value): Check for the aggregate conditions + described in ARM 8.4.1. + + Mon May 3 19:10:28 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-lex.c (real_yylex): Don't warn about floating point out of + range if target floating-point format is IEEE. + + * cp-class.c (finish_struct): Promote unsigned bitfields to signed + int if the field isn't as wide as an int. + + * cp-search.c (dfs_pushdecls): Use warning_with_decl, so we give the + line number of the offending method declaration, rather than the + line number of the curly-brace that ends the class definition. + + Mon May 3 18:04:15 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-cvt.c (convert): When doing int->enum conversions, always call + pedwarn, even if we didn't give `-pedantic'. + + * cp-decl.c (start_function): Add extern decl of + `flag_external_templates'. + + * cp-lex.c (check_newline): Warn if there's anything after a + `#pragma interface'. + + Mon May 3 12:39:49 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-class.c (finish_struct_methods): Use `warning' on a class w/ a + private dtor and no friends, so the line number comes out right. Also + only emit this warning when `extra_warnings' is true. + + * cp-type2.c (process_init_constructor): Don't allow use of an + initializer list for a class with private or protected members. + + Sat May 1 15:07:24 1993 Mike Stump (mrs@poseidon.cygnus.com) + + * cp-decl.c (start_decl, start_function): Add a new flag + -fexternal-templates. Use flag_external_templates to determine when + template definitions should be made externally visible and + accessible. This permits non-exponential growth in object files + that use templates. + * cp-decl2.c (lang_f_options): Likewise. + * cp-lex.c (reinit_parse_for_method, cons_up_default_function): + Likewise. + * cp-parse.y (template_instantiate_once): Likewise. + * cp-pt.c (end_template_decl, instantiate_member_templates, + instantiate_template, end_template_instantiation): Likewise. + * toplev.c (lang_options): Likewise. + + Fri Apr 30 18:50:00 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * cp-spew.c (arbitrate_lookup): If the next character is a '[', then + have the compiler assume it's an expression instead of a type. + + Fri Apr 30 14:39:28 1993 Mike Stump (mrs@poseidon.cygnus.com) + + * cp-class.c (maybe_fixup_vptrs): Use the VF_NORMAL_VALUE of the + vfields to get the binfo to get the vtable, so that we may pick up + the most derived version of the vtable. + + * cp-class.c (finish_base_struct): Always set the VF_NORMAL_VALUE so + that maybe_fixup_vptrs can get the most derived vtable. + + Fri Jun 25 14:00:17 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * config.sub: Convert ...-sysvr4 into ...-sysv4. + + * config/m68k/news.h (CPP_PREDEFINES): Have two alternatives, + one for motorola and one for not motorola. + + * config/m68k/tower-as.h, mot3300.h, m68kv4.h, hp320.h, amix.h: + * config/m68k/3b1.h, crds.h (CPP_PREDEFINES): Add __motorola__. + + * expr.c (store_expr): If TARGET is volatile mem ref, return it. + + * toplev.c (lang_options): Add -fdollars-in-identifiers. + * c-decl.c (c_decode_option): Handle -fdollars-in-identifiers. + + Fri Jun 25 13:33:39 1993 Jeffrey A. Law (law@snake.cs.utah.edu) + + * pa-hpux.h (LINK_SPEC): Search shared libraries by default; turn + off shared library searching of -static is specified. + * pa-ghpux.h (LINK_SPEC): Likewise. + + * pa.h (TARGET_SHARED_LIBS): Delete switch and all references to + the switch. + * pa.c: References to TARGET_SHARED_LIBS deleted. + * pa.md: Likewise. + + * pa-utahmach.h (TARGET_DEFAULT): Allow indexing on Mach ports. + * pa1-utahmach.h (TARGET_DEFAULT): Likewise. + * pa.h (TARGET_DISABLE_INDEXING): Clean up comments. + + Fri Jun 25 00:50:48 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * expr.c (store_expr): Ignore SUGGEST_REG if target is volatile. + + * config/mips/mips.md (negdi2, negdi2_internal): Renamed from negdi3... + + Thu Jun 24 00:31:27 1993 Richard Stallman (rms@wookumz.gnu.ai.mit.edu) + + * gcc.c (option_map): Make --version alias for -dumpversion. + + Wed Jun 23 07:50:21 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * romp.c (output_prologue): Delete unused var, INSN. + (output_encoded_offset): New function. + (output_epilogue): Minor changes to traceback table; call + new output_encoded_offset. + (romp_debugger_{auto,arg}_correction): New functions. + * romp.h (DBX_REGPARM_STABS_LETTER, DEBUGGER_{AUTO,ARG}_OFFSET): + New macros. + + * reorg.c (fill_slots_from_thread): When replacing a use of a + register with what it was set to, don't do it when either the + destination or source of the copy is set in the insn. + + * jump.c (jump_optimize): Properly make jump into store-flag + sequence when the jump can't be reversed but the TRUE branch + is const0_rtx. + + * expr.c (expand_expr): Set IGNORE if target is const0_rtx or + result type is VOID. + Move most IGNORE processing to one place to avoid expanding things + that don't need to be expanded. + (expand_expr, case CONSTRUCTOR, case COND_EXPR): If IGNORE, don't + expand anything we don't have to. + (expand_expr, case CONVERT_EXPR): Don't deal with IGNORE here. + + Wed Jun 23 07:47:32 1993 John F Carr (jfc@Athena.mit.edu) + + * regs.h (scratch_list, scratch_block, scratch_list_length): New vars. + * reload1.c (mark_scratch_live): New function. + (reload): Call it on each SCRATCH. + Free scratch list and block. + (spill_hard_reg): Reallocate any SCRATCH whose register we want to + spill. + * local-alloc.c (scratch_block, scratch_list{,_length}, scratch_index): + New variables. + (local_alloc): Allocate and initialize them. + (alloc_qty_for_scratch): Can allocate likely-spilled register + classes for SCRATCH. + (block_alloc): Likewise for regs in small register classes. + Only allocate a SCRATCH if it can fit in the block we make. + Don't mark regs used in SCRATCH live here; instead, make entry in + new tables. + + Tue Jun 22 19:52:08 1993 Richard Stallman (rms@wookumz.gnu.ai.mit.edu) + + * emit-rtl.c (copy_rtx_if_shared): In `E' case, get the length + before copying, and don't get it again after. + + Tue Jun 22 10:50:56 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * toplev.c (report_error_function): Change format of the + included-file stack to be more readable. + * cccp.c (print_containing_files): Likewise. + + Mon Jun 21 19:21:18 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * rs6000.c (print_operand, case 'J'): Write out shift count + of 0, not 32 for bit 31 of CCR. + + See ChangeLog.7 for earlier changes. diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/ChangeLog.7 gcc-2.5.0/ChangeLog.7 *** gcc-2.4.5/ChangeLog.7 Sun Jun 20 19:43:26 1993 --- gcc-2.5.0/ChangeLog.7 Mon Jul 26 17:49:20 1993 *************** *** 1,11 **** - Sun Jun 20 18:09:50 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) - - * calls.c (expand_call): In last change, preserve the temp slot. - Sun Jun 20 13:37:00 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) * c-common.c (decl_attributes): If first_arg_num is 0, no error for it. * Makefile.in (extraclean): Delete *.gz, and other diff and tar files. Sat Jun 19 19:55:43 PDT 1993 Ron Guilmette (rfg@netcom.com) --- 1,13 ---- Sun Jun 20 13:37:00 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + * Version 2.4.5 released. + * c-common.c (decl_attributes): If first_arg_num is 0, no error for it. * Makefile.in (extraclean): Delete *.gz, and other diff and tar files. + + Sun Jun 20 18:09:50 1993 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * calls.c (expand_call): In last change, preserve the temp slot. Sat Jun 19 19:55:43 PDT 1993 Ron Guilmette (rfg@netcom.com) diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/INSTALL gcc-2.5.0/INSTALL *** gcc-2.4.5/INSTALL Sun Jun 20 19:48:48 1993 --- gcc-2.5.0/INSTALL Thu Oct 21 22:34:07 1993 *************** *** 24,34 **** If you are building a compiler to produce code for the machine it ! runs on, specify just one machine type. Use the `--target' option; the host type will default to be the same as the target. (For information on building a cross-compiler, see *Note ! Cross-Compiler::.) The command looks like this: configure --target=sparc-sun-sunos4.1 A configuration name may be canonical or it may be more or less abbreviated. --- 24,40 ---- If you are building a compiler to produce code for the machine it ! runs on, specify just one machine type, with the `--target' option; the host type will default to be the same as the target. (For information on building a cross-compiler, see *Note ! Cross-Compiler::.) Here is an example: configure --target=sparc-sun-sunos4.1 + If you run `configure' without specifying configuration arguments, + `configure' tries to guess the type of host you are on, and uses + that configuration type for both host and target. So you don't + need to specify a configuration, for building a native compiler, + unless `configure' cannot figure out what your configuration is. + A configuration name may be canonical or it may be more or less abbreviated. *************** *** 55,60 **** a29k, alpha, arm, cN, clipper, elxsi, h8300, hppa1.0, hppa1.1, ! i386, i860, i960, m68000, m68k, m88k, mips, ns32k, pyramid, ! romp, rs6000, sh, sparc, sparclite, vax, we32k. Here are the recognized company names. As you can see, customary --- 61,67 ---- a29k, alpha, arm, cN, clipper, elxsi, h8300, hppa1.0, hppa1.1, ! i370, i386, i486, i860, i960, m68000, m68k, m88k, mips, ! ns32k, pyramid, romp, rs6000, sh, sparc, sparclite, vax, ! we32k. Here are the recognized company names. As you can see, customary *************** *** 74,79 **** aix, acis, aos, bsd, clix, ctix, dgux, dynix, genix, hpux, ! isc, linux, luna, mach, minix, newsos, osf, osfrose, riscos, ! sco, solaris, sunos, sysv, ultrix, unos, vms. You can omit the system type; then `configure' guesses the --- 81,86 ---- aix, acis, aos, bsd, clix, ctix, dgux, dynix, genix, hpux, ! isc, linux, luna, lynxos, mach, minix, newsos, osf, osfrose, ! riscos, sco, solaris, sunos, sysv, ultrix, unos, vms. You can omit the system type; then `configure' guesses the *************** *** 124,128 **** The systems where it makes a difference whether you use GAS ! are `i386-ANYTHING-sysv', `i860-ANYTHING-bsd', `m68k-hp-hpux', `m68k-sony-bsd', `m68k-altos-sysv', `m68000-hp-hpux', `m68000-att-sysv', and `mips-ANY'). On any --- 131,136 ---- The systems where it makes a difference whether you use GAS ! are `hppa1.0-ANYTHING-ANYTHING', `hppa1.1-ANYTHING-ANYTHING', ! `i386-ANYTHING-sysv', `i860-ANYTHING-bsd', `m68k-bull-sysv', `m68k-hp-hpux', `m68k-sony-bsd', `m68k-altos-sysv', `m68000-hp-hpux', `m68000-att-sysv', and `mips-ANY'). On any *************** *** 129,134 **** other system, `--with-gnu-as' has no effect. ! On the systems listed above, if you use GAS, you should also ! use the GNU linker (and specify `--with-gnu-ld'). `--with-gnu-ld' --- 137,143 ---- other system, `--with-gnu-as' has no effect. ! On the systems listed above (except for the HP-PA), if you ! use GAS, you should also use the GNU linker (and specify ! `--with-gnu-ld'). `--with-gnu-ld' *************** *** 143,152 **** `--with-stabs' ! On MIPS based systems, you must specify whether you want GNU ! CC to create the normal ECOFF debugging format, or to use ! BSD-style stabs passed through the ECOFF symbol table. The ! normal ECOFF debug format cannot fully handle languages other ! than C. BSD stabs format can handle other languages, but it ! only works with the GNU debugger GDB. Normally, GNU CC uses the ECOFF debugging format by default; --- 152,161 ---- `--with-stabs' ! On MIPS based systems and on Alphas, you must specify whether ! you want GNU CC to create the normal ECOFF debugging format, ! or to use BSD-style stabs passed through the ECOFF symbol ! table. The normal ECOFF debug format cannot fully handle ! languages other than C. BSD stabs format can handle other ! languages, but it only works with the GNU debugger GDB. Normally, GNU CC uses the ECOFF debugging format by default; *************** *** 197,202 **** being able to represent a word on the target in an integral value on the host cannot be performed. Building ! cross-compilers for 32-bit machines that run on the Alpha has ! not been tested and may not work properly. `a29k' --- 206,237 ---- being able to represent a word on the target in an integral value on the host cannot be performed. Building ! cross-compilers on the Alpha for 32-bit machines has only ! been tested in a few cases and may not work properly. ! ! `make compare' may fail on some versions of OSF/1 unless you ! add `-save-temps' to `BOOT_CFLAGS'. This forces a fixed name ! to be used for the assembler input file instead of a random ! name in `/tmp'. The name of the assembler input file is ! stored in the object file and will cause miscompared if it ! differs between the `stage1' and `stage2' compilations. ! ! GNU CC now supports both the native (ECOFF) debugging format ! used by DBX and GDB and an encapsulated STABS format for use ! only with GDB. See the discussion of the `--with-stabs' ! option of `configure' above for more information on these ! formats and how to select them. ! ! There is a bug in DEC's assembler that produces incorrect ! line numbers for ECOFF format when the `.align' directive is ! used. To work around this problem, GNU CC will not emit such ! alignment directives even if optimization is being performed ! if it is writing ECOFF format debugging information. ! Unfortunately, this has the very undesirable side-effect that ! code addresses when `-O' is specified are different depending ! on whether or not `-g' is also specified. ! ! To avoid this behavior, specify `-gstabs+' and use GDB ! instead of DBX. DEC is now aware of this problem with the ! assembler and hopes to provide a fix shortly. `a29k' *************** *** 218,221 **** --- 253,261 ---- more details. + `hppa*-*-*' + Using GAS is highly recommended for all HP-PA configurations. + See *Note PA Install:: for the special procedures needed to + compile GNU CC for the HP-PA. + `i386-*-sco' Compilation with RCC is recommended. Also, it may be a good *************** *** 223,226 **** --- 263,269 ---- with the system. + `i386-*-sco3.2.4' + Use this configuration for SCO release 3.2 version 4. + `i386-*-isc' It may be good idea to link with GNU malloc instead of the *************** *** 264,267 **** --- 307,320 ---- file `README.ALTOS'. + `m68k-bull-sysv' + Bull DPX/2 series 200 and 300 with BOS-2.00.45 up to + BOS-2.01. GNU CC works either with native assembler or GNU + assembler. You can use GNU assembler with native coff + generation by providing `--gas' to the configure script or + use GNU assembler with dbx-in-coff encapsulation by providing + `--gas --stabs'. For any problem with native assembler or for + availability of the DPX/2 port of GAS, contact + `F.Pierresteguy@frcl.bull.fr'. + `m68k-hp-hpux' HP 9000 series 300 or 400 running HP-UX. HP-UX version 8.0 *************** *** 368,371 **** --- 421,432 ---- default when compiling `libgcc2.c'. + The PowerPC and POWER2 architectures are now supported, but + have not been extensively tested due to lack of appropriate + systems. Only AIX is supported on the PowerPC. + + XLC version 1.3.0.0 will miscompile `jump.c'. XLC version + 1.3.0.1 or later fixes this problem. We do not yet have a + PTF number for this fix. + `vax-dec-ultrix' Don't try compiling with Vax C (`vcc'). It produces *************** *** 571,575 **** names to be used in both stages; then you can do the comparison. ! 13. Install the compiler driver, the compiler's passes and run-time support with `make install'. Use the same value for `CC', `CFLAGS' and `LANGUAGES' that you used when compiling the files --- 632,641 ---- names to be used in both stages; then you can do the comparison. ! 13. Build the Objective C library (if you have built the Objective C ! compiler). Here is the command to do this: ! ! make objc-runtime CC="stage2/xgcc -Bstage2/" CFLAGS="-g -O" ! ! 14. Install the compiler driver, the compiler's passes and run-time support with `make install'. Use the same value for `CC', `CFLAGS' and `LANGUAGES' that you used when compiling the files *************** *** 610,619 **** some other compiler.) ! 14. Install the Objective C library (if you have built the Objective C ! compiler). Here is the command to do this: make install-libobjc CC="stage2/xgcc -Bstage2/" CFLAGS="-g -O" ! 15. If you're going to use C++, it's likely that you need to also install the libg++ distribution. It should be available from the same place where you got the GNU C distribution. Just as GNU C --- 676,685 ---- some other compiler.) ! 15. Install the Objective C library (if you are installing the ! Objective C compiler). Here is the command to do this: make install-libobjc CC="stage2/xgcc -Bstage2/" CFLAGS="-g -O" ! 16. If you're going to use C++, it's likely that you need to also install the libg++ distribution. It should be available from the same place where you got the GNU C distribution. Just as GNU C *************** *** 672,682 **** all. ! * Cross-compilers for the Mips as target currently do not work ! because the auxiliary programs `mips-tdump.c' and `mips-tfile.c' ! can't be compiled on anything but a Mips. ! ! * Cross-compilers to or from the Vax probably don't work completely ! because the Vax uses an incompatible floating point format (not ! IEEE format). Since GNU CC generates assembler code, you probably need a --- 738,754 ---- all. ! * Cross-compilers for the Mips as target using the Mips assembler ! currently do not work, because the auxiliary programs ! `mips-tdump.c' and `mips-tfile.c' can't be compiled on anything ! but a Mips. It does work to cross compile for a Mips if you use ! the GNU assembler and linker. ! ! * Cross-compilers between machines with different floating point ! formats have not all been made to work. GNU CC now has a floating ! point emulator with which these can work, but each target machine ! description needs to be updated to take advantage of it. ! ! * Cross-compilation between machines of different word sizes has not ! really been addressed yet. Since GNU CC generates assembler code, you probably need a *************** *** 686,689 **** --- 758,789 ---- for the target machine that you can install on the host machine. + Steps of Cross-Compilation + -------------------------- + + To compile and run a program using a cross-compiler involves several + steps: + + * Run the cross-compiler on the host machine to produce assembler + files for the target machine. This requires header files for the + target machine. + + * Assemble the files produced by the cross-compiler. You can do this + either with an assembler on the target machine, or with a + cross-assembler on the host machine. + + * Link those files to make an executable. You can do this either + with a linker on the target machine, or with a cross-linker on the + host machine. Whichever machine you use, you need libraries and + certain startup files (typically `crt....o') for the target + machine. + + It is most convenient to do all of these steps on the same host + machine, since then you can do it all with a single invocation of GNU + CC. This requires a suitable cross-assembler and cross-linker. For + some targets, the GNU assembler and linker are available. + + Configuring a Cross-Compiler + ---------------------------- + To build GNU CC as a cross-compiler, you start out by running `configure'. You must specify two different configurations, the host *************** *** 695,727 **** configure --target=m68k-hp-bsd4.3 --host=i386-bozotheclone-bsd4.3 ! Next you should install the cross-assembler and cross-linker (and ! `ar' and `ranlib'). Put them in the directory `/usr/local/TARGET/bin'. ! The installation of GNU CC will find them there and copy or link them ! to the proper place to find them when you run the cross-compiler later. ! ! If you want to install any additional libraries to use with the ! cross-compiler, put them in the directory `/usr/local/TARGET/lib'; all ! files in that subdirectory will be installed in the proper place when ! you install the cross-compiler. Likewise, put the header files for the ! target machine in `/usr/local/TARGET/include'. ! ! You must now produce a substitute for `libgcc1.a'. Normally this ! file is compiled with the "native compiler" for the target machine; ! compiling it with GNU CC does not work. But compiling it with the host ! machine's compiler also doesn't work--that produces a file that would ! run on the host, and you need it to run on the target. ! ! We can't give you any automatic way to produce this substitute. For ! some targets, the subroutines in `libgcc1.c' are not actually used. ! You need not provide the ones that won't be used. The ones that most ! commonly are used are the multiplication, division and remainder ! routines--many RISC machines rely on the library for this. One way to ! make them work is to define the appropriate `perform_...' macros for ! the subroutines that you need. If these definitions do not use the C ! arithmetic operators that they are meant to implement, you might be ! able to compile them with the cross-compiler you are building. To do ! this, specify `LIBGCC1=libgcc1.a OLDCC=./xgcc' when building the compiler. Now you can proceed just as for compiling a single-machine compiler through the step of building stage 1. If you have not provided some --- 795,996 ---- configure --target=m68k-hp-bsd4.3 --host=i386-bozotheclone-bsd4.3 ! Tools and Libraries for a Cross-Compiler ! ---------------------------------------- ! ! If you have a cross-assembler and cross-linker available, you should ! install them now. Put them in the directory `/usr/local/TARGET/bin'. ! Here is a table of the tools you should put in this directory: ! ! `as' ! This should be the cross-assembler. ! ! `ld' ! This should be the cross-linker. ! ! `ar' ! This should be the cross-archiver: a program which can manipulate ! archive files (linker libraries) in the target machine's format. ! ! `ranlib' ! This should be a program to construct a symbol table in an archive ! file. ! ! The installation of GNU CC will find these programs in that ! directory, and copy or link them to the proper place to for the ! cross-compiler to find them when run later. ! ! The easiest way to provide these files is to build the Binutils ! package and GAS. Configure them with the same `--host' and `--target' ! options that you use for configuring GNU CC, then build and install ! them. They install their executables automatically into the proper ! directory. Alas, they do not support all the targets that GNU CC ! supports. ! ! If you want to install libraries to use with the cross-compiler, ! such as a standard C library, put them in the directory ! `/usr/local/TARGET/lib'; installation of GNU CC copies all all the ! files in that subdirectory into the proper place for GNU CC to find ! them and link with them. Here's an example of copying some libraries ! from a target machine: ! ! ftp TARGET-MACHINE ! lcd /usr/local/TARGET/lib ! cd /lib ! get libc.a ! cd /usr/lib ! get libg.a ! get libm.a ! quit ! ! The precise set of libraries you'll need, and their locations on the ! target machine, vary depending on its operating system. ! ! Many targets require "start files" such as `crt0.o' and `crtn.o' ! which are linked into each executable; these too should be placed in ! `/usr/local/TARGET/lib'. There may be several alternatives for ! `crt0.o', for use with profiling or other compilation options. Check ! your target's definition of `STARTFILE_SPEC' to find out what start ! files it uses. Here's an example of copying these files from a target ! machine: ! ! ftp TARGET-MACHINE ! lcd /usr/local/TARGET/lib ! prompt ! cd /lib ! mget *crt*.o ! cd /usr/lib ! mget *crt*.o ! quit ! ! `libgcc.a' and Cross-Compilers ! ------------------------------ ! ! Code compiled by GNU CC uses certain runtime support functions ! implicitly. Some of these functions can be compiled successfully with ! GNU CC itself, but a few cannot be. These problem functions are in the ! source file `libgcc1.c'; the library made from them is called ! `libgcc1.a'. ! ! When you build a native compiler, these functions are compiled with ! some other compiler-the one that you use for bootstrapping GNU CC. ! Presumably it knows how to open code these operations, or else knows how ! to call the run-time emulation facilities that the machine comes with. ! But this approach doesn't work for building a cross-compiler. The ! compiler that you use for building knows about the host system, not the ! target system. ! ! So, when you build a cross-compiler you have to supply a suitable ! library `libgcc1.a' that does the job it is expected to do. ! ! To compile `libgcc1.c' with the cross-compiler itself does not work. ! The functions in this file are supposed to implement arithmetic ! operations that GNU CC does not know how to open code, for your target ! machine. If these functions are compiled with GNU CC itself, they will ! compile into infinite recursion. ! ! On any given target, most of these functions are not needed. If GNU ! CC can open code an arithmetic operation, it will not call these ! functions to perform the operation. It is possible that on your target ! machine, none of these functions is needed. If so, you can supply an ! empty library as `libgcc1.a'. ! ! Many targets need library support only for multiplication and ! division. If you are linking with a library that contains functions for ! multiplication and division, you can tell GNU CC to call them directly ! by defining the macros `MULSI3_LIBCALL', and the like. These macros ! need to be defined in the target description macro file. For some ! targets, they are defined already. This may be sufficient to avoid the ! need for libgcc1.a; if so, you can supply an empty library. ! ! Some targets do not have floating point instructions; they need other ! functions in `libgcc1.a', which do floating arithmetic. Recent ! versions of GNU CC have a file which emulates floating point. With a ! certain amount of work, you should be able to construct a floating ! point emulator that can be used as `libgcc1.a'. Perhaps future ! versions will contain code to do this automatically and conveniently. ! That depends on whether someone wants to implement it. ! ! If your target system has another C compiler, you can configure GNU ! CC as a native compiler on that machine, build just `libgcc1.a' with ! `make libgcc1.a' on that machine, and use the resulting file with the ! cross-compiler. To do this, execute the following on the target ! machine: ! ! cd TARGET-BUILD-DIR ! configure --host=sparc --target=sun3 ! make libgcc1.a ! ! And then this on the host machine: ! ! ftp TARGET-MACHINE ! binary ! cd TARGET-BUILD-DIR ! get libgcc1.a ! quit ! ! Another way to provide the functions you need in `libgcc1.a' is to ! define the appropriate `perform_...' macros for those functions. If ! these definitions do not use the C arithmetic operators that they are ! meant to implement, you should be able to compile them with the ! cross-compiler you are building. (If these definitions already exist ! for your target file, then you are all set.) ! ! To build `libgcc1.a' using the perform macros, use ! `LIBGCC1=libgcc1.a OLDCC=./xgcc' when building the compiler. ! Otherwise, you should place your replacement library under the name ! `libgcc1.a' in the directory in which you will build the ! cross-compiler, before you run `make'. ! ! Cross-Compilers and Header Files ! -------------------------------- ! ! If you are cross-compiling a standalone program or a program for an ! embedded system, then you may not need any header files except the few ! that are part of GNU CC (and those of your program). However, if you ! intend to link your program with a standard C library such as `libc.a', ! then you probably need to compile with the header files that go with ! the library you use. ! ! The GNU C compiler does not come with these files, because (1) they ! are system-specific, and (2) they belong in a C library, not in a compiler. + If the GNU C library supports your target machine, then you can get + the header files from there (assuming you actually use the GNU library + when you link your program). + + If your target machine comes with a C compiler, it probably comes + with suitable header files also. If you make these files accessible + from the host machine, the cross-compiler can use them also. + + Otherwise, you're on your own in finding header files to use when + cross-compiling. + + When you have found suitable header files, put them in + `/usr/local/TARGET/include', before building the cross compiler. Then + installation will run fixincludes properly and install the corrected + versions of the header files where the compiler will use them. + + Provide the header files before you build the cross-compiler, because + the build stage actually runs the cross-compiler to produce parts of + `libgcc.a'. (These are the parts that *can* be compiled with GNU CC.) + Some of them need suitable header files. + + Here's an example showing how to copy the header files from a target + machine. On the target machine, do this: + + (cd /usr/include; tar cf - .) > tarfile + + Then, on the host machine, do this: + + ftp TARGET-MACHINE + lcd /usr/local/TARGET/include + get tarfile + quit + tar xf tarfile + + Actually Building the Cross-Compiler + ------------------------------------ + Now you can proceed just as for compiling a single-machine compiler through the step of building stage 1. If you have not provided some *************** *** 733,743 **** `libgcc1.a' are available. ! When you are using a cross-compiler configuration, building stage 1 ! does not compile all of GNU CC. This is because one part of building, ! the compilation of `libgcc2.c', requires use of the cross-compiler. ! ! However, when you type `make install' to install the bulk of the ! cross-compiler, that will also compile `libgcc2.c' and install the ! resulting `libgcc.a'. Do not try to build stage 2 for a cross-compiler. It doesn't work to --- 1002,1013 ---- `libgcc1.a' are available. ! If you are making a cross-compiler for an embedded system, and there ! is no `stdio.h' header for it, then the compilation of `enquire' will ! probably fail. The job of `enquire' is to run on the target machine ! and figure out by experiment the nature of its floating point ! representation. `enquire' records its findings in the header file ! `float.h'. If you can't produce this file by running `enquire' on the ! target machine, then you will need to come up with a suitable `float.h' ! in some other way (or else, avoid using it in your programs). Do not try to build stage 2 for a cross-compiler. It doesn't work to *************** *** 751,754 **** --- 1021,1026 ---- must specify a 68030 as the host when you configure it. + To install the cross-compiler, use `make install', as usual. + Installing on the HP Precision Architecture =========================================== *************** *** 817,820 **** --- 1089,1102 ---- pains. + The GNU compiler does not really support the Super SPARC processor + that is used in SPARC Station 10 and similar class machines. You can + get code that runs by specifying `sparc' as the cpu type; however, its + performance is not very good, and may vary widely according to the + compiler version and optimization options used. This is because the + instruction scheduling parameters designed for the Sparc are not correct + for the Super SPARC. Implementing scheduling parameters for the Super + SPARC might be a good project for someone who is willing to learn a + great deal about instruction scheduling in GNU CC. + 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 *************** *** 1114,1118 **** mv /lib/cpp /lib/cpp.att cp cpp /lib/cpp.gnu ! echo "/lib/cpp.gnu -traditional $*" > /lib/cpp chmod +x /lib/cpp --- 1396,1400 ---- mv /lib/cpp /lib/cpp.att cp cpp /lib/cpp.gnu ! echo '/lib/cpp.gnu -traditional ${1+"$@"}' > /lib/cpp chmod +x /lib/cpp *************** *** 1233,1237 **** that you specify with `-B'. ! Cross compilers search a little differently: * `gld' in the compiler's search directories. --- 1515,1519 ---- that you specify with `-B'. ! Cross-compilers search a little differently: * `gld' in the compiler's search directories. *************** *** 1265,1267 **** --- 1547,1577 ---- (In a future version, we will probably change `collect2' to avoid any reinvocation of a file from which any parent `collect2' was run.) + + Standard Header File Directories + ================================ + + `GCC_INCLUDE_DIR' means the same thing for native and cross. It is + where GNU CC stores its private include files, and also where GNU CC + stores the fixed include files. A cross compiled GNU CC runs + `fixincludes' on the header files in `$(tooldir)/include'. (If the + cross compilation header files need to be fixed, they must be installed + before GNU CC is built. If the cross compilation header files are + already suitable for ANSI C and GNU CC, nothing special need be done). + + `GPLUS_INCLUDE_DIR' means the same thing for native and cross. It + is where `g++' looks first for header files. `libg++' installs only + target independent header files in that directory. + + `LOCAL_INCLUDE_DIR' is used only for a native compiler. It is + normally `/usr/local/include'. GNU CC searches this directory so that + users can install header files in `/usr/local/include'. + + `CROSS_INCLUDE_DIR' is used only for a cross compiler. GNU CC + doesn't install anything there. + + `TOOL_INCLUDE_DIR' is used for both native and cross compilers. It + is the place for other packages to install header files that GNU CC will + use. For a cross-compiler, this is the equivalent of `/usr/include'. + When you build a cross-compiler, `fixincludes' processes any header + files in this directory. diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/Makefile.in gcc-2.5.0/Makefile.in *** gcc-2.4.5/Makefile.in Sun Jun 20 19:43:50 1993 --- gcc-2.5.0/Makefile.in Thu Oct 21 14:40:47 1993 *************** *** 122,125 **** --- 122,128 ---- SYSTEM_HEADER_DIR = /usr/include + # Control whether to run fixproto. + STMP_FIXPROTO = stmp-fixproto + # There may be a premade insn-attrtab.c for this machine. # (You could rebuild it with genattrtab as usual, but it takes a long time.) *************** *** 176,179 **** --- 179,187 ---- OBSTACK=obstack.o + # Specify the rule for actually making libgcc.a, + LIBGCC = libgcc.a + # and the rule for installing it. + INSTALL_LIBGCC = install-libgcc + # Specify the rule for actually making libgcc1.a. # The value may be empty; that means to do absolutely nothing *************** *** 181,184 **** --- 189,196 ---- LIBGCC1 = libgcc1.a + # Specify the rule for making libgcc1.a for a cross-compiler. + # The default rule assumes that libgcc1.a is supplied by the user. + CROSS_LIBGCC1 = libgcc1.cross + # Specify the rule for actually making libgcc2.a. LIBGCC2 = libgcc2.a *************** *** 198,201 **** --- 210,220 ---- LIBGCC2_DEPS = + # Enquire target (This is a variable so that a target can choose not to + # build it.) + ENQUIRE = enquire + + # Cross-test target (must also be overridable for a target) + CROSS_TEST = cross-test + # List of extra executables that should be compiled for this target machine # that are used for compiling from source code to object code. *************** *** 261,265 **** # List of things which should already be built whenever we try to use xgcc # to link anything. ! GCC_PARTS=$(GCC_PASSES) libgcc.a $(EXTRA_PROGRAMS) $(USE_COLLECT2) $(EXTRA_PARTS) # Directory to link to, when using the target `maketest'. --- 280,284 ---- # List of things which should already be built whenever we try to use xgcc # to link anything. ! GCC_PARTS=$(GCC_PASSES) $(LIBGCC) $(EXTRA_PROGRAMS) $(USE_COLLECT2) $(EXTRA_PARTS) # Directory to link to, when using the target `maketest'. *************** *** 266,269 **** --- 285,291 ---- DIR = ../gcc + # Guaranteed to not exist when not passing md through cpp. + MD_FILE = md-cpp-not-used + # Flags to use when cross-building GCC. # Prefix to apply to names of object files when using them *************** *** 386,391 **** cp-class.o cp-init.o cp-method.o cp-except.o \ cp-expr.o cp-pt.o cp-edsel.o cp-xref.o \ ! $(CPLUS_INPUT) cp-spew.o c-common.o # Language-independent object files. OBJS = toplev.o version.o tree.o print-tree.o stor-layout.o fold-const.o \ --- 408,416 ---- cp-class.o cp-init.o cp-method.o cp-except.o \ cp-expr.o cp-pt.o cp-edsel.o cp-xref.o \ ! $(CPLUS_INPUT) cp-spew.o c-common.o cp-error.o cp-errfn.o + # Files specific to the C interpreter bytecode compiler(s). + BC_OBJS = bc-emit.o bc-optab.o + # Language-independent object files. OBJS = toplev.o version.o tree.o print-tree.o stor-layout.o fold-const.o \ *************** *** 413,417 **** genemit genoutput genrecog genextract genflags gencodes genconfig genpeep \ genattrtab genattr genopinit \ ! $(GCC_PASSES) $(EXTRA_PARTS) $(EXTRA_PROGRAMS) gcc-cross cccp \ cc1plus cc1obj enquire protoize unprotoize specs collect2 $(USE_COLLECT2) --- 438,445 ---- genemit genoutput genrecog genextract genflags gencodes genconfig genpeep \ genattrtab genattr genopinit \ ! bc-arity.h bc-opcode.h bc-opname.h \ ! stamp-bcarity stamp-bcopcode stamp-bcopname \ ! bi-arity bi-opcode bi-opname \ ! $(GCC_PASSES) $(EXTRA_PARTS) $(EXTRA_PROGRAMS) gcc-cross cccp g++ g++-cross \ cc1plus cc1obj enquire protoize unprotoize specs collect2 $(USE_COLLECT2) *************** *** 431,434 **** --- 459,463 ---- _fixunsdfsi _fixunssfsi _fixunsdfdi _fixdfdi _fixunssfdi _fixsfdi \ _fixxfdi _fixunsxfdi _floatdixf _fixunsxfsi \ + _fixtfdi _fixunstfdi _floatditf \ __gcc_bcmp _varargs _eprintf _op_new _new_handler _op_delete \ _bb _shtab _clear_cache _trampoline __main _exit _ctors *************** *** 436,440 **** # Header files that are made available under the same name # to programs compiled with GCC. ! USER_H = va-alpha.h va-i860.h va-i960.h va-mips.h va-m88k.h \ va-pa.h va-pyr.h va-sparc.h va-clipper.h va-spur.h proto.h $(EXTRA_HEADERS) --- 465,469 ---- # Header files that are made available under the same name # to programs compiled with GCC. ! USER_H = va-alpha.h va-h8300.h va-i860.h va-i960.h va-mips.h va-m88k.h \ va-pa.h va-pyr.h va-sparc.h va-clipper.h va-spur.h proto.h $(EXTRA_HEADERS) *************** *** 450,453 **** --- 479,483 ---- TREE_H = tree.h real.h tree.def machmode.h machmode.def CPLUS_TREE_H = $(TREE_H) cp-tree.h cp-tree.def + BYTECODE_H = bytecode.h bc-emit.h bc-optab.h # Avoid a lot of time thinking about remaking Makefile.in and *.def. *************** *** 462,474 **** # Note that we can compile enquire using the cross-compiler just build, # although we can't run it on this machine. ! all.cross: native gcc-cross specs libgcc.a stmp-headers cross-test enquire $(EXTRA_PARTS) # This is what to compile if making gcc with a cross-compiler. ! all.build: native xgcc $(EXTRA_PARTS) # This is what must be made before installing GCC and converting libraries. ! start.encap: native xgcc specs $(LIBGCC1) xlimits.h # Use this to make a GCC that will be used only to recompile GCC. ! for-bootstrap: start.encap libgcc.a # These can't be made, with COFF encapsulation, until after GCC can run. ! rest.encap: libgcc.a stmp-headers $(EXTRA_PARTS) # This is what is made with the host's compiler # whether making a cross compiler or not. --- 492,504 ---- # Note that we can compile enquire using the cross-compiler just build, # although we can't run it on this machine. ! all.cross: native gcc-cross g++-cross specs $(LIBGCC) stmp-headers $(STMP_FIXPROTO) $(CROSS_TEST) $(ENQUIRE) $(EXTRA_PARTS) # This is what to compile if making gcc with a cross-compiler. ! all.build: native xgcc g++ $(EXTRA_PARTS) # This is what must be made before installing GCC and converting libraries. ! start.encap: native xgcc g++ specs $(LIBGCC1) xlimits.h # Use this to make a GCC that will be used only to recompile GCC. ! for-bootstrap: start.encap $(LIBGCC) # These can't be made, with COFF encapsulation, until after GCC can run. ! rest.encap: $(LIBGCC) stmp-headers $(STMP_FIXPROTO) $(EXTRA_PARTS) # This is what is made with the host's compiler # whether making a cross compiler or not. *************** *** 496,504 **** # On the target machine, finish building a cross compiler. # This does the things that can't be done on the host machine. ! rest.cross: libgcc.a gfloat.h specs # Verify that it works to compile and link cross-test. # If it does, then there are sufficient replacements for libgcc1.a. ! cross-test: cross-test.o native gcc-cross libgcc.a $(GCC_PARTS) $(GCC_FOR_TARGET) $(GCC_CFLAGS) cross-test.o -o $@ cross-test.o: cross-test.c native gcc-cross --- 526,534 ---- # On the target machine, finish building a cross compiler. # This does the things that can't be done on the host machine. ! rest.cross: $(LIBGCC) gfloat.h specs # Verify that it works to compile and link cross-test. # If it does, then there are sufficient replacements for libgcc1.a. ! cross-test: cross-test.o native gcc-cross $(LIBGCC) $(GCC_PARTS) $(GCC_FOR_TARGET) $(GCC_CFLAGS) cross-test.o -o $@ cross-test.o: cross-test.c native gcc-cross *************** *** 519,522 **** --- 549,556 ---- $(GCC_FOR_TARGET) -dumpspecs > specs + # Create the compiler driver for g++. + g++: g++.o $(LIBDEPS) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o g++ g++.o $(LIBS) + # We do want to create an executable named `xgcc', so we can use it to # compile libgcc2.a. *************** *** 525,537 **** cp xgcc gcc-cross ! cc1:$(P) $(C_OBJS) $(OBJS) $(LIBDEPS) ! $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o cc1 $(C_OBJS) $(OBJS) $(LIBS) ! cc1plus:$(P) $(CPLUS_OBJS) $(OBJS) $(LIBDEPS) ! $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o cc1plus $(CPLUS_OBJS) $(OBJS) $(LIBS) ! cc1obj:$(P) $(OBJC_OBJS) $(OBJS) $(LIBDEPS) ! $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o cc1obj $(OBJC_OBJS) $(OBJS) $(LIBS) # Copy float.h from its source. gfloat.h: $(FLOAT_H) --- 559,576 ---- cp xgcc gcc-cross ! # Create a version of the g++ driver which calls the cross-compiler. ! g++-cross: $(srcdir)/g++.c ! $(CC) $(ALL_CFLAGS) $(INCLUDES) $(LDFLAGS) -o g++-cross \ ! -DGCC_NAME=\"$(target)-gcc\" $(srcdir)/g++.c version.o $(LIBS) ! cc1: $(P) $(C_OBJS) $(OBJS) $(BC_OBJS) $(LIBDEPS) ! $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o cc1 $(C_OBJS) $(OBJS) $(BC_OBJS) $(LIBS) ! cc1plus: $(P) $(CPLUS_OBJS) $(OBJS) $(BC_OBJS) $(LIBDEPS) ! $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o cc1plus $(CPLUS_OBJS) $(BC_OBJS) $(OBJS) $(LIBS) + cc1obj: $(P) $(OBJC_OBJS) $(OBJS) $(BC_OBJS) $(LIBDEPS) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o cc1obj $(OBJC_OBJS) $(OBJS) $(BC_OBJS) $(LIBS) + # Copy float.h from its source. gfloat.h: $(FLOAT_H) *************** *** 601,605 **** # -e causes any failing command to make this rule fail. # -e doesn't work in certain shells, so we test $$? as well. ! set -e; \ for name in $(LIB1FUNCS); \ do \ --- 640,647 ---- # -e causes any failing command to make this rule fail. # -e doesn't work in certain shells, so we test $$? as well. ! # lynx has a broken ar, it always complains when the initial library is ! # empty, thus this command works only if we don't do -e ! # There is a trailing backslash (\) deleted from the following line. ! # set -e; for name in $(LIB1FUNCS); \ do \ *************** *** 653,657 **** # -e causes any failing command to make this rule fail. # -e doesn't work in certain shells, so we test $$? as well. ! set -e; \ for name in $(LIB2FUNCS); \ do \ --- 695,702 ---- # -e causes any failing command to make this rule fail. # -e doesn't work in certain shells, so we test $$? as well. ! # lynx has a broken ar, it always complains when the initial library is ! # empty, thus this command works only if we don't do -e ! # There is a trailing backslash (\) deleted from the following line. ! # set -e; for name in $(LIB2FUNCS); \ do \ *************** *** 699,702 **** --- 744,752 ---- else true; \ fi + # Some versions of ar (specifically the one in RISC/os 5.x), create an + # unwritable table of contents file, and then print an error message when + # the second ar command tries to overwrite this file. To avoid the error + # message from ar, we make sure all files are writable. + (cd tmpcopy; chmod +w * > /dev/null 2>&1) (cd tmpcopy; $(AR) x ../$(LIBGCC2)) (cd tmpcopy; $(AR) $(AR_FLAGS) ../tmplibgcc.a *.o) *************** *** 737,745 **** crtbegin.o: crtstuff.c $(GCC_PASSES) $(CONFIG_H) gbl-ctors.h $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) -DCRT_BEGIN \ ! -finhibit-size-directive -g0 -c $(srcdir)/crtstuff.c -o crtbegin.o crtend.o: crtstuff.c $(GCC_PASSES) $(CONFIG_H) gbl-ctors.h $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) -DCRT_END \ ! -finhibit-size-directive -g0 -c $(srcdir)/crtstuff.c -o crtend.o # Compiling object files from source files. --- 787,797 ---- crtbegin.o: crtstuff.c $(GCC_PASSES) $(CONFIG_H) gbl-ctors.h $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) -DCRT_BEGIN \ ! -finhibit-size-directive -fno-inline-functions \ ! -g0 -c $(srcdir)/crtstuff.c -o crtbegin.o crtend.o: crtstuff.c $(GCC_PASSES) $(CONFIG_H) gbl-ctors.h $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) -DCRT_END \ ! -finhibit-size-directive -fno-inline-functions \ ! -g0 -c $(srcdir)/crtstuff.c -o crtend.o # Compiling object files from source files. *************** *** 780,784 **** $(srcdir)/cp-parse.c $(srcdir)/cp-parse.h : $(srcdir)/cp-parse.y ! @echo expect 29 shift/reduce conflicts and 14 reduce/reduce conflicts cd $(srcdir); $(BISON) $(BISONFLAGS) -d -o cp-parse.c cp-parse.y cd $(srcdir); grep '^#define[ ]*YYEMPTY' cp-parse.c >>cp-parse.h --- 832,836 ---- $(srcdir)/cp-parse.c $(srcdir)/cp-parse.h : $(srcdir)/cp-parse.y ! @echo expect 29 shift/reduce conflicts and 13 reduce/reduce conflicts cd $(srcdir); $(BISON) $(BISONFLAGS) -d -o cp-parse.c cp-parse.y cd $(srcdir); grep '^#define[ ]*YYEMPTY' cp-parse.c >>cp-parse.h *************** *** 809,812 **** --- 861,866 ---- cp-xref.o : cp-xref.c $(CONFIG_H) $(CPLUS_TREE_H) input.h cp-pt.o : cp-pt.c $(CONFIG_H) $(CPLUS_TREE_H) cp-decl.h cp-parse.h + cp-error.o : cp-error.c $(CONFIG_H) $(CPLUS_TREE_H) + cp-errfn.o : cp-errfn.c $(CONFIG_H) $(CPLUS_TREE_H) # To make a configuration always use collect2, set USE_COLLECT2 to ld. *************** *** 878,890 **** rtlanal.o : rtlanal.c $(CONFIG_H) $(RTL_H) varasm.o : varasm.c $(CONFIG_H) $(TREE_H) $(RTL_H) flags.h function.h \ ! defaults.h insn-codes.h expr.h hard-reg-set.h regs.h xcoffout.h function.o : function.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h function.h \ insn-flags.h insn-codes.h expr.h regs.h hard-reg-set.h insn-config.h \ ! recog.h output.h stmt.o : stmt.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h function.h \ ! insn-flags.h insn-config.h insn-codes.h hard-reg-set.h expr.h loop.h recog.h expr.o : expr.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h function.h \ ! insn-flags.h insn-codes.h expr.h insn-config.h recog.h output.h typeclass.h calls.o : calls.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h expr.h insn-codes.h \ insn-flags.h gvarargs.h --- 932,949 ---- rtlanal.o : rtlanal.c $(CONFIG_H) $(RTL_H) + toplev.o: bytecode.h bc-emit.h varasm.o : varasm.c $(CONFIG_H) $(TREE_H) $(RTL_H) flags.h function.h \ ! defaults.h insn-codes.h expr.h hard-reg-set.h regs.h xcoffout.h bytecode.h function.o : function.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h function.h \ insn-flags.h insn-codes.h expr.h regs.h hard-reg-set.h insn-config.h \ ! recog.h output.h bytecode.h stmt.o : stmt.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h function.h \ ! insn-flags.h insn-config.h insn-codes.h hard-reg-set.h expr.h loop.h \ ! recog.h bytecode.h bc-typecd.h bc-typecd.def bc-opcode.h bc-optab.h \ ! bc-emit.h expr.o : expr.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h function.h \ ! insn-flags.h insn-codes.h expr.h insn-config.h recog.h output.h \ ! typeclass.h bytecode.h bc-opcode.h bc-typecd.h bc-typecd.def bc-optab.h \ ! bc-emit.h modemap.def calls.o : calls.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h expr.h insn-codes.h \ insn-flags.h gvarargs.h *************** *** 903,907 **** xcoffout.o : xcoffout.c $(CONFIG_H) $(TREE_H) $(RTL_H) xcoffout.h flags.h emit-rtl.o : emit-rtl.c $(CONFIG_H) $(RTL_H) flags.h gvarargs.h function.h \ ! regs.h insn-config.h insn-codes.h real.h expr.h real.o : real.c $(CONFIG_H) $(TREE_H) getpwd.o : getpwd.c $(CONFIG_H) --- 962,967 ---- xcoffout.o : xcoffout.c $(CONFIG_H) $(TREE_H) $(RTL_H) xcoffout.h flags.h emit-rtl.o : emit-rtl.c $(CONFIG_H) $(RTL_H) flags.h gvarargs.h function.h \ ! regs.h insn-config.h insn-codes.h real.h expr.h bytecode.h bc-opcode.h \ ! bc-typecd.h bc-typecd.def bc-optab.h bc-emit.h bc-opname.h real.o : real.c $(CONFIG_H) $(TREE_H) getpwd.o : getpwd.c $(CONFIG_H) *************** *** 908,912 **** integrate.o : integrate.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h integrate.h \ ! insn-flags.h insn-config.h insn-codes.h expr.h real.h function.h jump.o : jump.c $(CONFIG_H) $(RTL_H) flags.h hard-reg-set.h regs.h \ --- 968,973 ---- integrate.o : integrate.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h integrate.h \ ! insn-flags.h insn-config.h insn-codes.h expr.h real.h function.h \ ! bytecode.h jump.o : jump.c $(CONFIG_H) $(RTL_H) flags.h hard-reg-set.h regs.h \ *************** *** 926,930 **** basic-block.h recog.h real.h hard-reg-set.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 reload.h real.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 output.h --- 987,991 ---- basic-block.h recog.h real.h hard-reg-set.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 reload.h real.h bytecode.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 output.h *************** *** 944,948 **** sched.o : sched.c $(CONFIG_H) $(RTL_H) basic-block.h regs.h hard-reg-set.h \ flags.h insn-config.h insn-attr.h ! final.o : final.c $(CONFIG_H) $(RTL_H) gvarargs.h flags.h regs.h \ recog.h conditions.h insn-config.h insn-attr.h real.h output.h \ hard-reg-set.h insn-flags.h insn-codes.h gstab.h xcoffout.h defaults.h --- 1005,1009 ---- sched.o : sched.c $(CONFIG_H) $(RTL_H) basic-block.h regs.h hard-reg-set.h \ flags.h insn-config.h insn-attr.h ! final.o : final.c $(CONFIG_H) $(RTL_H) $(TREE_H) gvarargs.h flags.h regs.h \ recog.h conditions.h insn-config.h insn-attr.h real.h output.h \ hard-reg-set.h insn-flags.h insn-codes.h gstab.h xcoffout.h defaults.h *************** *** 957,960 **** --- 1018,1032 ---- insn-flags.h output.h insn-attr.h insn-codes.h + # Build auxiliary files that support ecoff format. + mips-tfile: mips-tfile.o version.o $(LIBDEPS) + $(CC) $(CFLAGS) $(LDFLAGS) -o mips-tfile mips-tfile.o version.o $(LIBS) + + mips-tfile.o : mips-tfile.c $(CONFIG_H) $(RTL_H) + + mips-tdump: mips-tdump.o version.o $(LIBDEPS) + $(CC) $(CFLAGS) $(LDFLAGS) -o mips-tdump mips-tdump.o version.o $(LIBS) + + mips-tdump.o : mips-tdump.c $(CONFIG_H) $(RTL_H) + # Normally this target is not used; but it is used if you # define ALLOCA=alloca.o. In that case, you must get a suitable alloca.c *************** *** 1100,1103 **** --- 1172,1182 ---- # since that describes the host machine. + # Pass the md file through cpp if the target requests it. + $(MD_FILE): $(CPP_MD) + -if [ -f md.pre-cpp ]; then \ + rm -f md ; ./cpp $(CPP_MD_FLAGS) md.pre-cpp | sed 's/^# /; /g' > md ; \ + else true ; \ + fi + genconfig : genconfig.o $(HOST_RTL) $(HOST_LIBDEPS) $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o genconfig \ *************** *** 1216,1219 **** --- 1295,1376 ---- touch $(HOST_PREFIX_1) + # Remake bytecode files. + # BI_ALL=bi-run.o + BI_ALL= + BC_ALL=bc-opname.h bc-opcode.h bc-arity.h + BI_OBJ=bi-parser.o bi-lexer.o bi-reverse.o + + + bc-emit.o : bc-emit.c $(CONFIG_H) $(RTL_H) real.h $(BYTECODE_H) \ + bc-arity.h bc-opcode.h bc-typecd.h bc-typecd.def bi-run.h bytetypes.h + bc-optab.o : bc-optab.c $(CONFIG_H) $(REAL_H) $(BYTECODE_H) \ + bc-opcode.h bc-typecd.h bc-typecd.def + + + bytecode: $(BI_ALL) $(BC_ALL) + + bi-arity: bi-arity.o $(BI_OBJ) $(HOST_LIBDEPS) + $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o bi-arity \ + bi-arity.o $(BI_OBJ) $(HOST_LIBS) + bi-opcode: bi-opcode.o $(BI_OBJ) $(HOST_LIBDEPS) + $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o bi-opcode \ + bi-opcode.o $(BI_OBJ) $(HOST_LIBS) + bi-opname: bi-opname.o $(BI_OBJ) $(HOST_LIBDEPS) + $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o bi-opname \ + bi-opname.o $(BI_OBJ) $(HOST_LIBS) + + bi-run.o: $(srcdir)/bi-run.c $(srcdir)/bi-run.h $(srcdir)/bc-typecd.h \ + bc-opname.h bc-arity.h bc-opcode.h + $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c $(srcdir)/bi-run.c + $(srcdir)/bi-parser.c $(srcdir)/bi-parser.h: $(srcdir)/bi-parser.y + cd $(srcdir); $(BISON) $(BISONFLAGS) -d bi-parser.y -o bi-parser.c + bi-parser.o: $(srcdir)/bi-parser.c $(srcdir)/bi-defs.h hconfig.h + $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \ + $(srcdir)/bi-parser.c + bi-lexer.o: $(srcdir)/bi-lexer.c $(srcdir)/bi-parser.h hconfig.h + $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \ + $(srcdir)/bi-lexer.c + bi-arity.o: bi-arity.c $(srcdir)/bi-defs.h hconfig.h + $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \ + $(srcdir)/bi-arity.c + bi-opcode.o: bi-opcode.c $(srcdir)/bi-defs.h hconfig.h + $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \ + $(srcdir)/bi-opcode.c + bi-opname.o: bi-opname.c $(srcdir)/bi-defs.h hconfig.h + $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \ + $(srcdir)/bi-opname.c + bi-reverse.o: bi-reverse.c $(srcdir)/bi-defs.h + $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \ + $(srcdir)/bi-reverse.c + + + bc-arity.h: stamp-bcarity ; @true + stamp-bcarity : $(srcdir)/bytecode.def bi-arity $(srcdir)/move-if-change + ./bi-arity < $(srcdir)/bytecode.def >tmp-bc-arity.h + $(srcdir)/move-if-change tmp-bc-arity.h bc-arity.h + touch stamp-bcarity + + bc-opcode.h: stamp-bcopcode ; @true + stamp-bcopcode : $(srcdir)/bytecode.def bi-opcode $(srcdir)/move-if-change + ./bi-opcode < $(srcdir)/bytecode.def >tmp-bcopcd.h + $(srcdir)/move-if-change tmp-bcopcd.h bc-opcode.h + touch stamp-bcopcode + + bc-opname.h: stamp-bcopname ; @true + stamp-bcopname : $(srcdir)/bytecode.def bi-opname $(srcdir)/move-if-change + ./bi-opname < $(srcdir)/bytecode.def >tmp-bcopnm.h + $(srcdir)/move-if-change tmp-bcopnm.h bc-opname.h + touch stamp-bcopname + + bytecode.mostlyclean: + -rm -f bc-arity.h bc-opcode.h bc-opname.h + + bytecode.distclean bytecode.clean: bytecode.mostlyclean + -rm -f bi-arity bi-opcode bi-opname bi-lexer + + bytecode.realclean: bytecode.clean + -rm -f bi-parser.c bi-parser.h + + # Remake cpp and protoize. *************** *** 1288,1291 **** --- 1445,1449 ---- -rm -f SYSCALLS.c tmp-SYSCALLS.s + test-protoize-simple: ./protoize ./unprotoize $(GCC_PASSES) -rm -f tmp-proto.[cso] *************** *** 1358,1363 **** touch stmp-headers # Build fixed copies of system files. ! stmp-fixinc: $(srcdir)/$(FIXINCLUDES) gsyslimits.h rm -rf include mkdir include --- 1516,1532 ---- touch stmp-headers + # Running fixincludes requires making sure that xgcc and cpp have been + # compiled (they are used to get the value of __SIZE_TYPE__). + # But recompiling xgcc should not force the the header files to be + # fixed again. If you want to do that, delete stmp-fixinc. + fixinc.ready: xgcc cpp + -if [ -f fixinc.ready ] ; then \ + true; \ + else \ + touch fixinc.ready; \ + fi + # Build fixed copies of system files. ! stmp-fixinc: $(srcdir)/$(FIXINCLUDES) gsyslimits.h fixinc.ready rm -rf include mkdir include *************** *** 1367,1371 **** if [ -d $$dir ]; \ then \ ! $(srcdir)/$(FIXINCLUDES) include $$dir $(srcdir); \ else true; fi; \ done; \ --- 1536,1540 ---- if [ -d $$dir ]; \ then \ ! $(srcdir)/$(FIXINCLUDES) include $$dir $(srcdir) "`pwd`/xgcc -B`pwd`/"; \ else true; fi; \ done; \ *************** *** 1382,1386 **** # copy objc header files into build directory ! objc-headers: if [ -d objc ]; then true; else mkdir objc; fi thisdir1=`pwd`; \ --- 1551,1555 ---- # copy objc header files into build directory ! objc-headers: stmp-fixinc if [ -d objc ]; then true; else mkdir objc; fi thisdir1=`pwd`; \ *************** *** 1392,1395 **** --- 1561,1593 ---- GCC_CFLAGS="$(GCC_CFLAGS)" incinstalldir=$${thisdir1}/include touch objc-headers + + # Files related to the fixproto script. + + deduced.h: $(srcdir)/scan-types.sh + CC="$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(ALL_CPPFLAGS) -Iinclude -I${SYSTEM_HEADER_DIR}"; \ + export CC; \ + $(srcdir)/scan-types.sh >tmp-deduced.h + mv tmp-deduced.h deduced.h + + gen-protos: gen-protos.o scan.o + ${HOST_CC} -o gen-protos gen-protos.o scan.o + + xsys-protos.h: $(srcdir)/sys-protos.h deduced.h gen-protos Makefile + cat deduced.h $(srcdir)/sys-protos.h > fixtmp.c + $(GCC_FOR_TARGET) fixtmp.c -E \ + | sed -e 's/ / /g' -e 's/ *(/ (/g' -e 's/ [ ]*/ /g' -e 's/( )/()/' \ + | ./gen-protos >xsys-protos.h + rm -rf fixtmp.c + + patch-header: patch-header.o scan-decls.o scan.o xsys-protos.h $(HOST_OBSTACK) + $(HOST_CC) -o patch-header patch-header.o scan-decls.o scan.o $(HOST_OBSTACK) + + patch-header.o: xsys-protos.h + + # stmp-headers is to make sure fixincludes has already finished. + stmp-fixproto: patch-header xsys-protos.h fixproto stmp-headers + CPP="$(GCC_FOR_TARGET) -E"; export CPP; \ + ${srcdir}/fixproto include include $(SYSTEM_HEADER_DIR) + touch stmp-fixproto # Remake the info files. *************** *** 1420,1424 **** $(srcdir)/INSTALL: install1.texi install.texi ! $(MAKEINFO) -D INSTALLONLY --no-header `echo $(srcdir)/install1.texi | sed 's,^\./,,'` # Deletion of files made during compilation. --- 1618,1623 ---- $(srcdir)/INSTALL: install1.texi install.texi ! $(MAKEINFO) -D INSTALLONLY --no-header --no-split \ ! `echo $(srcdir)/install1.texi | sed 's,^\./,,'` # Deletion of files made during compilation. *************** *** 1433,1437 **** ! mostlyclean: -rm -f $(STAGESTUFF) # Clean the objc subdir if we created one. --- 1632,1636 ---- ! mostlyclean: bytecode.mostlyclean -rm -f $(STAGESTUFF) # Clean the objc subdir if we created one. *************** *** 1459,1462 **** --- 1658,1664 ---- -rm -f specs gfloat.h float.h-* enquire SYSCALLS.c.X SYSCALLS.c -rm -f collect collect2 ld mips-tfile mips-tdump alloca.s + # Delete files generated for fixproto + -rm -rf patch-header xsys-protos.h deduced.h tmp-deduced.h \ + gen-protos fixproto.list fixtmp.* # Delete unwanted output files from TeX. -rm -f *.toc *.log *.vr *.fn *.cp *.tp *.ky *.pg *************** *** 1468,1472 **** # Delete all files made by compilation # that don't exist in the distribution. ! clean: mostlyclean # It may not be quite desirable to delete unprotoize.c here, # but the spec for `make clean' requires it. --- 1670,1674 ---- # Delete all files made by compilation # that don't exist in the distribution. ! clean: mostlyclean bytecode.clean # It may not be quite desirable to delete unprotoize.c here, # but the spec for `make clean' requires it. *************** *** 1475,1485 **** -rm -f libgcc.a libgcc1.a libgcc2.a libgcc2.ready libgcc1.null -rm -f *.dvi # Delete the include directory. ! -rm -rf stmp-* include objc-headers # Delete all files that users would normally create # while building and installing GCC. ! distclean: clean ! -rm -f tm.h aux-output.c config.h md config.status tconfig.h hconfig.h -rm -f Makefile *.oaux -rm -fr stage1 stage2 stage3 stage4 --- 1677,1691 ---- -rm -f libgcc.a libgcc1.a libgcc2.a libgcc2.ready libgcc1.null -rm -f *.dvi + -if [ -f md.pre-cpp ]; then \ + rm -f md ; \ + fi # Delete the include directory. ! -rm -rf stmp-* fixinc.ready include objc-headers # Delete all files that users would normally create # while building and installing GCC. ! distclean: clean bytecode.distclean ! -rm -f tm.h aux-output.c config.h config.status tconfig.h hconfig.h ! -rm -f md md.pre-cpp -rm -f Makefile *.oaux -rm -fr stage1 stage2 stage3 stage4 *************** *** 1501,1508 **** -rm -f *lose config/*lose config/*/*lose -rm -f *.s *.s[0-9] *.i install1.texi config/ChangeLog # Get rid of every file that's generated from some other file. # Most of these files ARE PRESENT in the GCC distribution. ! realclean: distclean -rm -f c-parse.y objc-parse.y -rm -f cp-parse.c cp-parse.h cp-parse.output --- 1707,1715 ---- -rm -f *lose config/*lose config/*/*lose -rm -f *.s *.s[0-9] *.i install1.texi config/ChangeLog + -rm -f djefoo # Get rid of every file that's generated from some other file. # Most of these files ARE PRESENT in the GCC distribution. ! realclean: distclean bytecode.realclean -rm -f c-parse.y objc-parse.y -rm -f cp-parse.c cp-parse.h cp-parse.output *************** *** 1523,1528 **** # Copy the compiler files into directories where they will be run. ! install-normal: install-common $(INSTALL_HEADERS) install-libgcc install-man \ ! install-info # Do nothing while making gcc with a cross-compiler. The person who --- 1730,1735 ---- # Copy the compiler files into directories where they will be run. ! install-normal: install-common $(INSTALL_HEADERS) $(INSTALL_LIBGCC) \ ! install-man install-info # Do nothing while making gcc with a cross-compiler. The person who *************** *** 1538,1542 **** # Install float.h for cross compiler. # Run this on the target machine! ! install-float-h-cross: # if [ -f enquire ] ; then true; else false; fi # Note: don't use -. We should fail right away if enquire was not made. --- 1745,1749 ---- # Install float.h for cross compiler. # Run this on the target machine! ! install-float-h-cross: install-dir # if [ -f enquire ] ; then true; else false; fi # Note: don't use -. We should fail right away if enquire was not made. *************** *** 1551,1555 **** -if [ -d $(libdir) ] ; then true ; else mkdir $(libdir) ; fi -if [ -d $(libdir)/gcc-lib ] ; then true ; else mkdir $(libdir)/gcc-lib ; fi ! # This dir isn't curretly searched by cpp. # -if [ -d $(libdir)/gcc-lib/include ] ; then true ; else mkdir $(libdir)/gcc-lib/include ; fi -if [ -d $(libdir)/gcc-lib/$(target) ] ; then true ; else mkdir $(libdir)/gcc-lib/$(target) ; fi --- 1758,1762 ---- -if [ -d $(libdir) ] ; then true ; else mkdir $(libdir) ; fi -if [ -d $(libdir)/gcc-lib ] ; then true ; else mkdir $(libdir)/gcc-lib ; fi ! # This dir isn't currently searched by cpp. # -if [ -d $(libdir)/gcc-lib/include ] ; then true ; else mkdir $(libdir)/gcc-lib/include ; fi -if [ -d $(libdir)/gcc-lib/$(target) ] ; then true ; else mkdir $(libdir)/gcc-lib/$(target) ; fi *************** *** 1569,1574 **** # Install the compiler executables built during cross compilation. - # Deps on $(srcdir)/g++ $(srcdir)/c++ would be natural here, - # but the latter would get confused with the target `c++'. install-common: native install-dir xgcc $(EXTRA_PARTS) for file in $(COMPILERS); do \ --- 1776,1779 ---- *************** *** 1599,1602 **** --- 1804,1814 ---- $(INSTALL_PROGRAM) gcc-cross $(tooldir)/bin/gcc; \ else true; fi; \ + if [ -f cc1plus ] ; then \ + rm -f $(bindir)/$(target)-g++; \ + $(INSTALL_PROGRAM) g++-cross $(bindir)/$(target)-g++; \ + chmod a+x $(bindir)/$(target)-g++; \ + rm -f $(bindir)/$(target)-c++; \ + ln $(bindir)/$(target)-g++ $(bindir)/$(target)-c++; \ + fi ; \ else \ rm -f $(bindir)/gcc; \ *************** *** 1605,1608 **** --- 1817,1827 ---- ln $(bindir)/gcc $(bindir)/$(target)-gcc-1; \ mv $(bindir)/$(target)-gcc-1 $(bindir)/$(target)-gcc; \ + if [ -f cc1plus ] ; then \ + rm -f $(bindir)/g++; \ + $(INSTALL_PROGRAM) g++ $(bindir)/g++; \ + chmod a+x $(bindir)/g++; \ + rm -f $(bindir)/c++; \ + ln $(bindir)/g++ $(bindir)/c++; \ + fi ; \ fi # Install protoize if it was compiled. *************** *** 1617,1626 **** chmod a-x $(libsubdir)/SYSCALLS.c.X; \ fi - -if [ -f cc1plus ] ; then \ - rm -f $(bindir)/c++ ; \ - $(INSTALL_PROGRAM) $(srcdir)/c++ $(bindir)/c++ ; \ - rm -f $(bindir)/g++ ; \ - $(INSTALL_PROGRAM) $(srcdir)/g++ $(bindir)/g++ ; \ - fi -rm -f $(libsubdir)/cpp $(INSTALL_PROGRAM) cpp $(libsubdir)/cpp --- 1836,1839 ---- *************** *** 1627,1631 **** # Install the info files. ! install-info: doc -rm -f $(infodir)/cpp.info* $(infodir)/gcc.info* cd $(srcdir); for f in cpp.info* gcc.info*; \ --- 1840,1844 ---- # Install the info files. ! install-info: doc install-dir -rm -f $(infodir)/cpp.info* $(infodir)/gcc.info* cd $(srcdir); for f in cpp.info* gcc.info*; \ *************** *** 1687,1695 **** # Install the include directory using tar. ! install-headers-tar: stmp-headers install-include-dir ! cd include; tar cf - . | (cd $(libsubdir)/include; tar $(TAROUTOPTS) - ) # Install the include directory using cpio. ! install-headers-cpio: stmp-headers install-include-dir cd include; find . -print | cpio -pdum $(libsubdir)/include --- 1900,1912 ---- # Install the include directory using tar. ! install-headers-tar: stmp-headers $(STMP_FIXPROTO) install-include-dir ! cd include; \ ! (tar cf - .; exit 0) | (cd $(libsubdir)/include; tar $(TAROUTOPTS) - ) ! # /bin/sh on some systems returns the status of the first tar, ! # and that can lose with GNU tar which always writes a full block. ! # So use `exit 0' to ignore its exit status. # Install the include directory using cpio. ! install-headers-cpio: stmp-headers $(STMP_FIXPROTO) install-include-dir cd include; find . -print | cpio -pdum $(libsubdir)/include *************** *** 1718,1722 **** # Use this target to install the program `collect2' under the name `ld'. ! install-collect2: collect2 $(INSTALL_PROGRAM) collect2 $(libsubdir)/ld # Install the driver program as $(libsubdir)/gcc for collect2. --- 1935,1939 ---- # Use this target to install the program `collect2' under the name `ld'. ! install-collect2: collect2 install-dir $(INSTALL_PROGRAM) collect2 $(libsubdir)/ld # Install the driver program as $(libsubdir)/gcc for collect2. *************** *** 1852,1858 **** # stage2 directory. compare: force for file in *.o; do \ ! tail +16c $$file > tmp-foo1; \ tail +16c stage2/$$file > tmp-foo2 2>/dev/null \ && (cmp tmp-foo1 tmp-foo2 || echo $$file differs); \ --- 2069,2076 ---- # stage2 directory. + # ./ avoids bug in some versions of tail. compare: force for file in *.o; do \ ! tail +16c ./$$file > tmp-foo1; \ tail +16c stage2/$$file > tmp-foo2 2>/dev/null \ && (cmp tmp-foo1 tmp-foo2 || echo $$file differs); \ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/NEWS gcc-2.5.0/NEWS *** gcc-2.4.5/NEWS Sat Jun 12 21:19:34 1993 --- gcc-2.5.0/NEWS Thu Oct 21 21:46:51 1993 *************** *** 1,2 **** --- 1,101 ---- + Noteworthy GCC changes in version 2.5: + + * There is now support for the IBM 370 architecture as a target. + Currently the only operating system supported is MVS; GCC does not run + on MVS, so you must produce .s files using GCC as a cross compiler, + then transfer them to MVS to assemble them. + + * The power pc is now supported. + + * Basic block profiling has been enhanced to record the function the basic + block comes from, and if the module was compiled for debugging, the line number + and filename. A default version of the basic block support module has been + added to libgcc2 that appends the basic block information to a text file + 'bb.out'. Machine descriptions can now override the basic block support module + in the target macro file. + + * In C, initializers for static and global variables are now processed + an element at a time, so that they don't need a lot of storage. + + * The C syntax for specifying which structure field comes next in an + initializer is now `.FIELDNAME='. The corresponding syntax for + array initializers is now `[INDEX]='. For example, + + char whitespace[256] + = { [' '] = 1, ['\t'] = 1, ['\n'] = 1 }; + + This was changed to accord with the syntax proposed by the Numerical + C Extensions Group (NCEG). + + * Complex numbers are now supported in C. Use the keyword __complex__ + to declare complex data types. See the manual for details. + + * GCC now supports `long double' meaningfully on the Sparc (128-bit + floating point) and on the 386 (96-bit floating point). The Sparc + support works reliably only in Solaris 2.x; earlier versions (Sun OS 4) + have bugs in the emulation. + + * All targets now have assertions for cpu, machine and system. So you + can now use assertions to distinguish among all supported targets. + + * Nested functions in C may now be inline. Just declare them inline + in the usual way. + + * Packed structure members are now supported fully; it should be possible + to access them on any supported target, no matter how little alignment + they have. + + * To declare a function volatile or const, you must now write + something like this: + + typedef void voidfn (); + + volatile voidfn fatal; + + It used to be possible to do so by writing this: + + volatile void fatal (); + + but it turns out that ANSI C requires that to mean something + else (which is useless). + + * The new option -iwithprefixbefore specifies a directory to add to + the search path for include files in the same position where -I would + put it, but uses the specified prefix just like -iwithprefix. + + New features in g++: + + * The new flag `-fansi-overloading' for C++. Use a newly implemented + scheme of argument matching for C++. It makes g++ more accurately + obey the rules set down in Chapter 13 of the Annotated C++ Reference + Manual (the ARM). This option will be turned on by default in a + future release. + + * The -finline-debug flag is now gone (it was never really used by the + compiler). + + * Recognizing the syntax for pointers to members, e.g., "foo::*bar", has been + dramatically improved. You should not get any syntax errors or incorrect + runtime results while using pointers to members correctly; if you do, it's + a definite bug. + + * Forward declaration of an enum is now flagged as an error. + + * Class-local typedefs are now working properly. + + * Nested class support has been significantly improved. The compiler + will now (in theory) support up to 240 nested classes before hitting + other system limits (like memory size). + + * There is a new C version of the `g++' driver, to replace the old + shell script. This should significantly improve the performance of + executing g++ on a system where a user's PATH environment variable + references many NFS-mounted filesystems. This driver also works + under MS-DOS and OS/2. + + * The ANSI committee working on the C++ standard has adopted a new + keyword `mutable'. This will allow you to make a specific member be + modifiable in an otherwise const class. + Noteworthy GCC changes in version 2.4.4: *************** *** 102,106 **** `make CC=gcc' to avoid mismatches in the definition of `size_t'. - Newly documented compiler options: --- 201,204 ---- *************** *** 140,141 **** --- 238,240 ---- Control how C++ virtual function definitions are used (like cfront 1.x). + diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/README gcc-2.5.0/README *** gcc-2.4.5/README Sun Jun 20 19:49:02 1993 --- gcc-2.5.0/README Thu Oct 21 22:34:22 1993 *************** *** 1,3 **** ! This directory contains the version 2.4.5 release of the GNU C compiler. It includes all of the support for compiling C++ and Objective C, including a run-time library for Objective C. --- 1,3 ---- ! This directory contains the version 2.5.0 release of the GNU C compiler. It includes all of the support for compiling C++ and Objective C, including a run-time library for Objective C. diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/README.RS6000 gcc-2.5.0/README.RS6000 *** gcc-2.4.5/README.RS6000 Tue May 4 16:54:15 1993 --- gcc-2.5.0/README.RS6000 Tue Oct 19 20:33:08 1993 *************** *** 44,45 **** --- 44,49 ---- If you have this problem, set the LANG environment variable to "C" or "En_US". + + XLC version 1.3.0.0 will miscompile jump.c. XLC version 1.3.0.1 or + later fixes this problem. We do not yet have a PTF number for this + fix. diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/SERVICE gcc-2.5.0/SERVICE *** gcc-2.4.5/SERVICE Sun Jun 20 19:49:19 1993 --- gcc-2.5.0/SERVICE Thu Oct 21 22:34:46 1993 *************** *** 44,49 **** +1 415 285 9088 ! Former FSF staffmember. Performed X11 implementation of Emacs version ! 19 and worked on WYSIWYG Emacs. Installed and administered FSF network. Maintainer of GNU indent. 10 years experience with Unix systems, from writing ROM monitors to UI design. --- 44,49 ---- +1 415 285 9088 ! Former FSF staffmember. Performed X11 implementation of Emacs version ! 19 and worked on WYSIWYG Emacs. Installed and administered FSF network. Maintainer of GNU indent. 10 years experience with Unix systems, from writing ROM monitors to UI design. *************** *** 223,229 **** Graefestr. 76 1000 Berlin 61, Germany ! phone: (+49 30) 694 69 07 ! modems: (+49 30) 694 {61 82 | 67 49 | 68 09} ! email: internet: scuzzy.contrib.de [192.109.39.1] --- 223,229 ---- Graefestr. 76 1000 Berlin 61, Germany ! phone: (+49 30) 694 69 07 ! modems: (+49 30) 694 {61 82 | 67 49 | 68 09} ! email: internet: scuzzy.contrib.de [192.109.39.1] *************** *** 234,237 **** --- 234,260 ---- Entered: 10 Jul 92  + Stuart Cracraft + The MSM Company + Unix & PC Consulting Services + 25682 Cresta Loma + Laguna Niguel, Ca. + 92677 + GNUline: 714-347-8106 + GNUbeeper: 714-509-3133 (leave number for callback) + + Rate: based on your ability to afford. + + Programs supported: all GNU programs. + + Method: telephone line support, call-in via modem to your site, + or direct visit. + + Experience: supporting GNU since the mid-1980's, coordinator + of GNU Chess (original author), GNU Shogi, GNU Go. Ported GNU Emacs + to Solaris (System V Release 4). Expertise in C, Emacs Lisp, and Perl. + Customized programming also available. + + Entered: 1 Jul 93 +  Cygnus Support 1937 Landings Drive ...uunet!cygint!info *************** *** 265,282 **** Updated: 16 Feb 93  - Bradley N. Davis - 3242 South 540 West - Bountiful, UT 84010 - (801) 298-6345 - - Will work on most GNU software. Especially GNU Emacs, GCC and a - little X11 and G++. Experienced with PCs and 386s. - - Services offered: Installation, porting, customizing, troubleshooting. - - Fee: $20 to $50 / hour depending on job - - Updated: 6/11/91 -  DePalma SoftCraft Contact: Mauro DePalma 2923 Cohansey Drive Voice: (408) 259-4789 --- 288,291 ---- *************** *** 297,307 **** Heimatring 19 6000 Frankfurt/Main 70 ! phone: (+49 69) 6312083 ! modems: (+49 69) 6312934 | 6311235 | 634588 ! email: We distribute, install and/or port, teach, support free software and offer regular consulting. We accept software development contracts for ! any (unix) software as long as you will release it into free software. Rates are DM 200,-- plus VAT per hour. 25 % will be donated to the --- 306,316 ---- Heimatring 19 6000 Frankfurt/Main 70 ! phone: (+49 69) 6312083 ! modems: (+49 69) 6312934 | 6311235 | 634588 ! email: We distribute, install and/or port, teach, support free software and offer regular consulting. We accept software development contracts for ! any (unix) software as long as you will release it into free software. Rates are DM 200,-- plus VAT per hour. 25 % will be donated to the *************** *** 709,713 **** make free software as easy to install and use as shrink wrapped programs. ! - Warranty protection. - Customization and porting. - Subscriptions to new versions which we will send monthly or with --- 718,722 ---- make free software as easy to install and use as shrink wrapped programs. ! - Warranty protection. - Customization and porting. - Subscriptions to new versions which we will send monthly or with *************** *** 807,810 **** --- 816,836 ---- Entered: 10 Feb 92  + Julian H. Stacey + Holz Strasse 27d, Munich, 80469, Germany. + +49 89 268616 + + For Symmetric Computer Systems Model 375 owners: + Free Binaries & sources on SCS/375's TEAC 50/60M Cassette, for: + GCC-1.40, UUCP-1.4, Ghostscript 2.3, Tar-1.08, Gzip-1.2.2 etc. + (Native SCS compiler can't compile GCC on this NSC32016 based BSD4.2) + Commercial Freelance Consultancy: + Custom designs, provision & support of Unix, C, FSF tools, X Windows, + 386BSD, own tools, systems engineering, hardware, multi lingual systems + (inc. Cyrillic etc), real time etc. Resume on request. No Emacs work. + Rate: 140 DM/hour + FSF sources: on 1/4" QIC tape (60M/150M/525M) ~170 DM, to inc. an FSF contrib. + + Updated: 9 Aug 93 +  Richard M. Stallman UUCP: {mit-eddie,ucbvax,uunet,harvard,uw-beaver}!ai.mit.edu!rms *************** *** 902,929 **** Entered: 12 Feb 92  - Watchmaker Computing - P.O.Box 163, Kendall Square - Cambridge, MA 02142 - email: support@watch.com - - Emacs: We'll do GNUEmacs support, porting, bug fixing, and customizing. - We also have specific expertise in: - packages: GCC, G++, X11, Xt, InterViews, PERL, TeX, Epoch - languages: C, C++, Lisp, most others; we learn quickly! - Extensive experience coding for portability under UNIX. - Typical rates $35-$150/hour; will telecommute (Internet or phone) - - Entered: 1/16/91 -  Joe Wells ! c/o: Boston University Computer Science Department 111 Cummington Street, Room 138 Boston, Massachusetts 02215 ! Work: (617)353-3381; Home: (617)352-7508 Finger "jbw@cs.bu.edu" for up-to-date contact information. Experience: ! I have B.A. and M.A. degrees in Computer Science and am ! all-but-dissertation for a Ph.D. in C.S. My primary programming languages are Emacs Lisp, Perl, and Bourne shell. I have written numerous Emacs Lisp packages. I started the USENET "List of --- 928,941 ---- Entered: 12 Feb 92  Joe Wells ! care of: Boston University Computer Science Department 111 Cummington Street, Room 138 Boston, Massachusetts 02215 ! Work: (617) 353-3381; Home: (617) 352-7508 (until mid-May 1994) Finger "jbw@cs.bu.edu" for up-to-date contact information. Experience: ! I have B.A. and M.A. degrees in Computer Science and have completed ! all but the dissertation for a Ph.D. in C.S. My primary programming languages are Emacs Lisp, Perl, and Bourne shell. I have written numerous Emacs Lisp packages. I started the USENET "List of *************** *** 933,951 **** Programs supported: ! GNU Emacs: installation, training, customization, bug fixing, ! troubleshooting, extension, development, or answering any ! kind of question. ! Any other GNU program: installation and answering questions. Working conditions: ! I can do part-time (less than 20 hours/week) work for a long term and ! full-time work for a short term (a month or two). I can either work ! in or near Boston or via the Internet. My schedule is fairly ! flexible. I prefer that any Emacs Lisp package I write have the GNU ! GPL copying conditions. ! ! Rates: $45/hour, provided I don't have to travel far. ! Entered: 18Feb93  Chris Welty --- 945,967 ---- Programs supported: ! GNU Emacs and Taylor UUCP: ! Installation, training, customization, bug fixing, troubleshooting, ! extension, development, porting, or answering any kind of question. ! Any other GNU program: ! The same things, but I don't necessarily have huge amounts of ! experience with the particular program. Working conditions: ! I can do part-time (less than 20 hours per week including travel) ! work. I can either work in or near Boston or via the Internet or via ! telephone. My schedule is fairly flexible. Any programs I write will ! normally have the copying conditions of the GNU General Public ! License. ! ! Rates: $60/hour as an independent contractor. ! travel and telephone expenses. ! higher rates if extensive travel is required. ! Updated: 21Sep93  Chris Welty *************** *** 1029,1031 **** --- 1045,1050 ---- Updated: 7/11/92  + For a current copy of this directory, or to have yourself listed, ask: + gnu@prep.ai.mit.edu + ** Please keep this file alphabetical ** diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/alloca.c gcc-2.5.0/alloca.c *** gcc-2.4.5/alloca.c Sun Jun 20 19:49:20 1993 --- gcc-2.5.0/alloca.c Thu Oct 21 22:34:50 1993 *************** *** 23,30 **** #ifdef HAVE_CONFIG_H #include "config.h" #endif ! /* If compiling with GCC, this file's not needed. */ #ifndef alloca --- 23,38 ---- #ifdef HAVE_CONFIG_H + #if defined (emacs) || defined (CONFIG_BROKETS) + #include + #else #include "config.h" #endif + #endif + + /* If compiling with GCC 2, this file's not needed. */ + #if !defined (__GNUC__) || __GNUC__ < 2 ! /* If someone has defined alloca as a macro, ! there must be some other way alloca is supposed to work. */ #ifndef alloca *************** *** 46,50 **** provide an "address metric" ADDRESS_FUNCTION macro. */ ! #ifdef CRAY long i00afunc (); #define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg)) --- 54,58 ---- provide an "address metric" ADDRESS_FUNCTION macro. */ ! #if defined (CRAY) && defined (CRAY_STACKSEG_END) long i00afunc (); #define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg)) *************** *** 73,78 **** #ifndef emacs #define malloc xmalloc - extern pointer xmalloc (); #endif /* Define STACK_DIRECTION if you know the direction of stack --- 81,86 ---- #ifndef emacs #define malloc xmalloc #endif + extern pointer malloc (); /* Define STACK_DIRECTION if you know the direction of stack *************** *** 205,209 **** } ! #ifdef CRAY #ifdef DEBUG_I00AFUNC --- 213,217 ---- } ! #if defined (CRAY) && defined (CRAY_STACKSEG_END) #ifdef DEBUG_I00AFUNC *************** *** 474,475 **** --- 482,484 ---- #endif /* no alloca */ + #endif /* not GCC version 2 */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/basic-block.h gcc-2.5.0/basic-block.h *** gcc-2.4.5/basic-block.h Sat Apr 17 17:40:35 1993 --- gcc-2.5.0/basic-block.h Sat Jul 10 15:25:07 1993 *************** *** 27,31 **** hard registers is the same format as a HARD_REG_SET. */ ! #define REGSET_ELT_TYPE HOST_WIDE_INT /* Define the type for a pointer to a set with a bit for each --- 27,31 ---- hard registers is the same format as a HARD_REG_SET. */ ! #define REGSET_ELT_TYPE unsigned HOST_WIDE_INT /* Define the type for a pointer to a set with a bit for each diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/bc-emit.c gcc-2.5.0/bc-emit.c *** gcc-2.4.5/bc-emit.c --- gcc-2.5.0/bc-emit.c Tue Oct 12 20:16:34 1993 *************** *** 0 **** --- 1,987 ---- + /* Output bytecodes for GNU C-compiler. + Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + + #include "config.h" + #include "gvarargs.h" + #include "machmode.h" + #include "rtl.h" + #include "real.h" + #include "obstack.h" + #include "bytecode.h" + #ifdef __GNUC__ + #include "bytetypes.h" + #endif + #include "bc-emit.h" + #include "bc-opcode.h" + #include "bc-typecd.h" + #include "bi-run.h" + + #include + + extern char *xmalloc (), *xrealloc (); + extern void free (); + + extern struct obstack *rtl_obstack; + + /* Indexed by mode class, gives the narrowest mode for each class. */ + + enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS]; + + /* Commonly used modes. */ + /* Mode whose width is BITS_PER_UNIT */ + enum machine_mode byte_mode; + + /* Mode whose width is BITS_PER_WORD */ + enum machine_mode word_mode; + + /* Vector indexed by opcode giving info about the args for each opcode. */ + static struct arityvec arityvec[] = { + #include "bc-arity.h" + }; + + /* How to print a symbol name for the assembler. */ + static void + prsym (file, s) + FILE *file; + char *s; + { + if (*s == '*') + fprintf (file, "%s", s + 1); + else + + #ifdef NAMES_HAVE_UNDERSCORES + fprintf (file, "_%s", s); + #else + fprintf (file, "%s", s); + #endif + + } + + /* Maintain a bucket hash table for symbol names. */ + + #define HASH_BITS 32 + #define HASH_SIZE 509 + + static struct bc_sym *hashtab[HASH_SIZE]; + + static unsigned int + hash (name) + char *name; + { + unsigned int hash = 0; + + while (*name) + { + hash = hash << 3 | hash >> HASH_BITS - 3; + hash += *name++; + } + + return hash % HASH_SIZE; + } + + + /* Look up the named symbol, creating it if it doesn't exist. */ + struct bc_sym * + sym_lookup (name) + char *name; + { + int i; + struct bc_sym *s; + + i = hash (name); + for (s = hashtab[i]; s; s = s->next) + if (!strcmp (s->name, name)) + return s; + + s = (struct bc_sym *) xmalloc (sizeof (struct bc_sym)); + s->name = xmalloc (strlen (name) + 1); + strcpy (s->name, name); + s->defined = s->global = s->common = 0; + s->val = 0; + s->next = hashtab[i]; + hashtab[i] = s; + return s; + } + + + /* Write out .globl and common symbols to the named file. */ + static void + bc_sym_write (file) + FILE *file; + { + int i; + struct bc_sym *s; + + for (i = 0; i < HASH_SIZE; ++i) + for (s = hashtab[i]; s; s = s->next) + { + if (s->global) + { + fprintf (file, "\n\t.globl "); + prsym (file, s->name); + putc ('\n', file); + if (s->common) + { + fprintf (file, "\n\t.comm "); + prsym (file, s->name); + fprintf (file, ", %d\n", s->val); + } + } + else if (s->common) + { + fprintf (file, "\n\t.lcomm "); + prsym (file, s->name); + fprintf (file, ", %d\n", s->val); + } + } + } + + + + + /* Create and initialize a new segment. */ + static struct bc_seg * + seg_create () + { + struct bc_seg *result; + + result = (struct bc_seg *) xmalloc (sizeof (struct bc_seg)); + result->alloc = 256; + result->data = xmalloc (result->alloc); + result->size = 0; + result->syms = 0; + result->relocs = 0; + return result; + } + + + /* Advance the segment index to the next alignment boundary. */ + static void + seg_align (seg, log) + struct bc_seg *seg; + int log; + { + unsigned int oldsize = seg->size; + + seg->size = seg->size + (1 << log) - 1 & ~((1 << log) - 1); + if (seg->size > seg->alloc) + { + while (seg->size > seg->alloc) + seg->alloc *= 2; + seg->data = xrealloc (seg->data, seg->alloc); + } + bzero (seg->data + oldsize, seg->size - oldsize); + } + + + /* Append the given data to the given segment. */ + static void + seg_data (seg, data, size) + struct bc_seg *seg; + char *data; + unsigned int size; + { + if (seg->size + size > seg->alloc) + { + while (seg->size + size > seg->alloc) + seg->alloc *= 2; + seg->data = xrealloc (seg->data, seg->alloc); + } + + bcopy (data, seg->data + seg->size, size); + seg->size += size; + } + + + /* Append a zero-filled skip to the given segment. */ + static void + seg_skip (seg, size) + struct bc_seg *seg; + unsigned int size; + { + if (seg->size + size > seg->alloc) + { + while (seg->size + size > seg->alloc) + seg->alloc *= 2; + seg->data = xrealloc (seg->data, seg->alloc); + } + + memset (seg->data + seg->size, 0, size); + seg->size += size; + } + + + /* Define the given name as the current offset in the given segment. It + is an error if the name is already defined. Return 0 or 1 indicating + failure or success respectively. */ + static int + seg_defsym (seg, name) + struct bc_seg *seg; + char *name; + { + struct bc_sym *sym; + struct bc_segsym *segsym; + + sym = sym_lookup (name); + if (sym->defined) + return 0; + + sym->defined = 1; + sym->val = seg->size; + segsym = (struct bc_segsym *) xmalloc (sizeof (struct bc_segsym)); + segsym->sym = sym; + segsym->next = seg->syms; + seg->syms = segsym; + return 1; + } + + + /* Generate in seg's data a reference to the given sym, adjusted by + the given offset. */ + static void + seg_refsym (seg, name, offset) + struct bc_seg *seg; + char *name; + int offset; + { + struct bc_sym *sym; + struct bc_segreloc *segreloc; + + sym = sym_lookup (name); + segreloc = (struct bc_segreloc *) xmalloc (sizeof (struct bc_segreloc)); + segreloc->offset = seg->size; + segreloc->sym = sym; + segreloc->next = seg->relocs; + seg->relocs = segreloc; + seg_data (seg, (char *) &offset, sizeof offset); + } + + + /* Concatenate the contents of given segments into the first argument. */ + static void + seg_concat (result, seg) + struct bc_seg *result, *seg; + { + unsigned int fix; + struct bc_segsym *segsym; + struct bc_segreloc *segreloc; + + seg_align (result, MACHINE_SEG_ALIGN); + fix = result->size; + seg_data (result, seg->data, seg->size); + free (seg->data); + + /* Go through the symbols and relocs of SEG, adjusting their offsets + for their new location in RESULT. */ + if (seg->syms) + { + segsym = seg->syms; + do + segsym->sym->val += fix; + while (segsym->next && (segsym = segsym->next)); + segsym->next = result->syms; + result->syms = seg->syms; + } + if (seg->relocs) + { + segreloc = seg->relocs; + do + segreloc->offset += fix; + while (segreloc->next && (segreloc = segreloc->next)); + segreloc->next = result->relocs; + result->relocs = seg->relocs; + } + + free ((char *) seg); + } + + /* Write a segment to a file. */ + static void + bc_seg_write (seg, file) + struct bc_seg *seg; + FILE *file; + { + struct bc_segsym *segsym, *nsegsym, *psegsym; + struct bc_segreloc *segreloc, *nsegreloc, *psegreloc; + int i, offset, flag; + + /* Reverse the list of symbols. */ + for (psegsym = 0, segsym = seg->syms; segsym; segsym = nsegsym) + { + nsegsym = segsym->next; + segsym->next = psegsym; + psegsym = segsym; + } + seg->syms = psegsym; + + /* Reverse the list of relocs. */ + for (psegreloc = 0, segreloc = seg->relocs; segreloc; segreloc = nsegreloc) + { + nsegreloc = segreloc->next; + segreloc->next = psegreloc; + psegreloc = segreloc; + } + seg->relocs = psegreloc; + + /* Output each byte of the segment. */ + for (i = 0, segsym = seg->syms, segreloc = seg->relocs; i < seg->size; ++i) + { + while (segsym && segsym->sym->val == i) + { + if (i % 8 != 0) + putc ('\n', file); + + BC_WRITE_SEGSYM (segsym, file); + segsym = segsym->next; + flag = 1; + } + if (segreloc && segreloc->offset == i) + { + if (i % 8 != 0) + putc ('\n', file); + + offset = *(int *) (seg->data + i); + i += sizeof (int) - 1; + + BC_WRITE_RELOC_ENTRY (segreloc, file, offset); + segreloc = segreloc->next; + flag = 1; + } + else + { + if (i % 8 == 0 || flag) + BC_START_BYTECODE_LINE (file); + + BC_WRITE_BYTECODE (i % 8 == 0 || flag ? ' ' : ',', + seg->data[i] & 0xFF, + file); + flag = 0; + if (i % 8 == 7) + putc ('\n', file); + } + } + + /* Paranoia check--we should have visited all syms and relocs during + the output pass. */ + + if (segsym || segreloc) + abort (); + } + + + + /* Text and data segments of the object file in making. */ + static struct bc_seg *bc_text_seg; + static struct bc_seg *bc_data_seg; + + /* Called before anything else in this module. */ + void + bc_initialize () + { + int min_class_size[(int) MAX_MODE_CLASS]; + enum machine_mode mode; + int i; + + bc_init_mode_to_code_map (); + + bc_text_seg = seg_create (); + bc_data_seg = seg_create (); + + dconst0 = REAL_VALUE_ATOF ("0", DFmode); + dconst1 = REAL_VALUE_ATOF ("1", DFmode); + dconst2 = REAL_VALUE_ATOF ("2", DFmode); + dconstm1 = REAL_VALUE_ATOF ("-1", DFmode); + + /* Find the narrowest mode for each class and compute the word and byte + modes. */ + + for (i = 0; i < (int) MAX_MODE_CLASS; i++) + min_class_size[i] = 1000; + + for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE; + mode = (enum machine_mode) ((int) mode + 1)) + { + if (GET_MODE_SIZE (mode) < min_class_size[(int) GET_MODE_CLASS (mode)]) + { + class_narrowest_mode[(int) GET_MODE_CLASS (mode)] = mode; + min_class_size[(int) GET_MODE_CLASS (mode)] = GET_MODE_SIZE (mode); + } + if (GET_MODE_CLASS (mode) == MODE_INT + && GET_MODE_BITSIZE (mode) == BITS_PER_UNIT) + byte_mode = mode; + + if (GET_MODE_CLASS (mode) == MODE_INT + && GET_MODE_BITSIZE (mode) == BITS_PER_WORD) + word_mode = mode; + } + } + + + /* External addresses referenced in a function. Rather than trying to + work relocatable address directly into bytecoded functions (which would + require us to provide hairy location info and possibly obey alignment + rules imposed by the architecture) we build an auxilary table of + pointer constants, and encode just offsets into this table into the + actual bytecode. */ + static struct bc_seg *ptrconsts; + + /* Trampoline code for the function entry. */ + struct bc_seg *trampoline; + + /* Actual byte code of the function. */ + struct bc_seg *bytecode; + + /* List of labels defined in the function. */ + struct bc_label *labels; + + /* List of label references in the function. */ + struct bc_labelref *labelrefs; + + + /* Add symbol to pointer table. Return offset into table where + pointer was stored. The offset usually goes into the bytecode + stream as a constP literal. */ + int + bc_define_pointer (p) + char *p; + { + int offset = ptrconsts->size; + + seg_refsym (ptrconsts, p, 0); + return offset; + } + + + /* Begin a bytecoded function. */ + int + bc_begin_function (name) + char *name; + { + ptrconsts = seg_create (); + trampoline = seg_create (); + bytecode = seg_create (); + return seg_defsym (trampoline, name); + } + + + /* Force alignment in inline bytecode. */ + void + bc_align_bytecode (align) + int align; + { + seg_align (bytecode, align); + } + + + /* Emit data inline into bytecode. */ + void + bc_emit_bytecode_const (data, size) + char *data; + unsigned int size; + { + if (bytecode) + seg_data (bytecode, data, size); + } + + + /* Create a new "bytecode label", to have its value defined later. + Bytecode labels have nothing to do with the object file symbol table, + and are purely local to a given bytecoded function. */ + struct bc_label * + bc_get_bytecode_label () + { + struct bc_label *result; + + result = (struct bc_label *) xmalloc (sizeof (struct bc_label)); + result->defined = 0; + result->next = labels; + result->uid = 0; + labels = result; + return result; + } + + + /* Define the given label with the current location counter. */ + int + bc_emit_bytecode_labeldef (label) + struct bc_label *label; + { + extern int bc_new_uid (); + + if (!label || label->defined) + return 0; + + label->offset = bytecode->size; + label->defined = 1; + label->uid = bc_new_uid (); + + #ifdef DEBUG_PRINT_CODE + fprintf (stderr, "$%lx:\n", label); + #endif + + return 1; + } + + + /* Generate a location-relative reference to the given bytecode label. + It need not be defined yet; label references will be backpatched later. */ + void + bc_emit_bytecode_labelref (label) + struct bc_label *label; + { + struct bc_labelref *labelref; + static int zero; + + labelref = (struct bc_labelref *) xmalloc (sizeof (struct bc_labelref)); + labelref->label = label; + labelref->offset = bytecode->size; + labelref->next = labelrefs; + labelrefs = labelref; + + #ifdef DEBUG_PRINT_CODE + fprintf (stderr, " $%lx", label); + #endif + + seg_data (bytecode, (char *) &zero, sizeof zero); + } + + + /* Emit a reference to an external address; generate the reference in the + ptrconst area, and emit an offset in the bytecode. */ + void + bc_emit_code_labelref (name, offset) + char *name; + int offset; + { + int ptroff; + + ptroff = ptrconsts->size / sizeof (char *); + seg_data (bytecode, (char *) &ptroff, sizeof ptroff); + seg_refsym (ptrconsts, name, offset); + + #ifdef DEBUG_PRINT_CODE + fprintf (stderr, " [external <%x> %s]", ptroff, name); + #endif + } + + + /* Backpatch label references in the byte code, and concatenate the bytecode + and pointer constant segments to the cumulative text for the object file. + Return a label name for the pointer constants region. */ + char * + bc_end_function () + { + int addr; + struct bc_label *label, *next; + struct bc_labelref *ref, *nextref; + char ptrconsts_label[20]; + static int nlab; + + /* Backpatch bytecode label references. */ + for (ref = labelrefs; ref; ref = ref->next) + if (ref->label->defined) + { + addr = ref->label->offset; + bcopy (&addr, bytecode->data + ref->offset, sizeof addr); + } + + /* Free the chains of labelrefs and labeldefs. */ + for (ref = labelrefs; ref; ref = nextref) + { + nextref = ref->next; + free ((char *) ref); + } + + for (label = labels; label; label = next) + { + next = label->next; + free ((char *) label); + } + + seg_concat (trampoline, bytecode); + seg_align (trampoline, MACHINE_SEG_ALIGN); + sprintf (ptrconsts_label, "*LP%d", nlab++); + seg_defsym (trampoline, ptrconsts_label); + seg_concat (trampoline, ptrconsts); + seg_concat (bc_text_seg, trampoline); + + labels = 0; + labelrefs = 0; + trampoline = 0; + bytecode = 0; + ptrconsts = 0; + + return sym_lookup (ptrconsts_label)->name; + } + + /* Force alignment in const data. */ + void + bc_align_const (align) + int align; + { + seg_align (bc_text_seg, align); + } + + /* Emit const data. */ + void + bc_emit_const (data, size) + char *data; + unsigned int size; + { + seg_data (bc_text_seg, data, size); + } + + /* Emit a zero-filled constant skip. */ + void + bc_emit_const_skip (size) + unsigned int size; + { + seg_skip (bc_text_seg, size); + } + + /* Emit a label definition in const data. */ + int + bc_emit_const_labeldef (name) + char *name; + { + return seg_defsym (bc_text_seg, name); + } + + /* Emit a label reference in const data. */ + void + bc_emit_const_labelref (name, offset) + char *name; + int offset; + { + seg_refsym (bc_text_seg, name, offset); + } + + /* Force alignment in data. */ + void + bc_align_data (align) + int align; + { + seg_align (bc_data_seg, align); + } + + /* Emit data. */ + void + bc_emit_data (data, size) + char *data; + unsigned int size; + { + seg_data (bc_data_seg, data, size); + } + + /* Emit a zero-filled data skip. */ + void + bc_emit_data_skip (size) + unsigned int size; + { + seg_skip (bc_data_seg, size); + } + + /* Emit label definition in data. */ + int + bc_emit_data_labeldef (name) + char *name; + { + return seg_defsym (bc_data_seg, name); + } + + /* Emit label reference in data. */ + void + bc_emit_data_labelref (name, offset) + char *name; + int offset; + { + seg_refsym (bc_data_seg, name, offset); + } + + /* Emit a common block of the given name and size. Note that + when the .o file is actually written non-global "common" + blocks will have to be turned into space in the data section. */ + int + bc_emit_common (name, size) + char *name; + unsigned int size; + { + struct bc_sym *sym; + + sym = sym_lookup (name); + if (sym->defined) + return 0; + + sym->defined = 1; + sym->common = 1; + sym->val = size; + return 1; + } + + /* Globalize the given label. */ + void + bc_globalize_label (name) + char *name; + { + struct bc_sym *sym; + + sym = sym_lookup (name); + sym->global = 1; + } + + static enum { in_text, in_data } section = in_text; + + void + bc_text () + { + section = in_text; + } + + void + bc_data () + { + section = in_data; + } + + void + bc_align (align) + int align; + { + if (section == in_text) + bc_align_const (align); + else + bc_align_data (align); + } + + void + bc_emit (data, size) + char *data; + unsigned int size; + { + if (section == in_text) + bc_emit_const (data, size); + else + bc_emit_data (data, size); + } + + void + bc_emit_skip (size) + unsigned int size; + { + if (section == in_text) + bc_emit_const_skip (size); + else + bc_emit_data_skip (size); + } + + int + bc_emit_labeldef (name) + char *name; + { + if (section == in_text) + return bc_emit_const_labeldef (name); + else + return bc_emit_data_labeldef (name); + } + + void + bc_emit_labelref (name, offset) + char *name; + int offset; + { + if (section == in_text) + bc_emit_const_labelref (name, offset); + else + bc_emit_data_labelref (name, offset); + } + + void + bc_write_file (file) + FILE *file; + { + BC_WRITE_FILE (file); + } + + + /* Allocate a new bytecode rtx. + If you supply a null BC_LABEL, we generate one. */ + + rtx + bc_gen_rtx (label, offset, bc_label) + char *label; + int offset; + struct bc_label *bc_label; + { + rtx r; + + if (bc_label == 0) + bc_label = (struct bc_label *) xmalloc (sizeof (struct bc_label)); + + r = gen_rtx (CODE_LABEL, VOIDmode, label, bc_label); + bc_label->offset = offset; + + return r; + } + + + /* Print bytecode rtx */ + void + bc_print_rtl (fp, r) + FILE *fp; + rtx r; + { + #if 0 /* This needs to get fixed to really work again. */ + /* BC_WRITE_RTL has a definition + that doesn't even make sense for this use. */ + BC_WRITE_RTL (r, fp); + #endif + } + + + /* Emit a bytecode, keeping a running tally of the stack depth. */ + void + bc_emit_bytecode (bytecode) + enum bytecode_opcode bytecode; + { + char byte; + int npushes = arityvec[(int) bytecode].noutputs - arityvec[(int) bytecode].ninputs; + static int prev_lineno = -1; + + byte = bytecode; + + #ifdef BCDEBUG_PRINT_CODE + if (lineno != prev_lineno) + { + fprintf (stderr, "\n", lineno); + prev_lineno = lineno; + } + + fputs (opcode_name[(unsigned int) bytecode], stderr); + #endif + + /* Due to errors we are often requested to output bytecodes that + will cause an interpreter stack undeflow when executed. Instead of + dumping core on such occasions, we omit the bytecode. Erroneous code + should not be executed, regardless. This makes life much easier, since + we don't have to deceive ourselves about the known stack depth. */ + + bc_emit_bytecode_const (&byte, 1); + + if ((stack_depth -= arityvec[(int) bytecode].ninputs) >= 0) + { + if ((stack_depth += arityvec[(int) bytecode].noutputs) > max_stack_depth) + max_stack_depth = stack_depth; + } + + #ifdef VALIDATE_STACK_FOR_BC + VALIDATE_STACK_FOR_BC (); + #endif + } + + + #ifdef BCDEBUG_PRINT_CODE + #define PRLIT(TYPE, PTR) fprintf (stderr, " [%x]", *(TYPE *) PTR) + #else + #define PRLIT(X,Y) + #endif + + /* Emit a complete bytecode instruction, expecting the correct number + of literal values in the call. First argument is the instruction, the + remaining arguments are literals of size HOST_WIDE_INT or smaller. */ + void + bc_emit_instruction (va_alist) + va_dcl + { + va_list arguments; + enum bytecode_opcode opcode; + int nliteral, instruction; + + + va_start (arguments); + + /* Emit instruction bytecode */ + opcode = va_arg (arguments, enum bytecode_opcode); + bc_emit_bytecode (opcode); + instruction = (int) opcode; + + /* Loop literals and emit as bytecode constants */ + for (nliteral = 0; nliteral < arityvec[instruction].nliterals; nliteral++) + { + HOST_WIDE_INT literal; + + switch (arityvec[instruction].literals[nliteral]) + { + /* This conditional is a kludge, but it's necessary + because TYPE might be long long. */ + #ifdef __GNUC__ + /* Expand definitions into case statements */ + #define DEFTYPECODE(CODE, NAME, MODE, TYPE) \ + case CODE: \ + { \ + TYPE temp = va_arg (arguments, TYPE); \ + bc_emit_bytecode_const ((void *) &temp, sizeof temp); \ + PRLIT (TYPE, &temp); } \ + break; + + #include "bc-typecd.def" + + #undef DEFTYPECODE + #endif /* __GNUC__ */ + + default: + abort (); + } + } + + #ifdef BCDEBUG_PRINT_CODE + fputc ('\n', stderr); + #endif + } + + /* Emit the machine-code interface trampoline at the beginning of a byte + coded function. The argument is a label name of the interpreter + bytecode callinfo structure; the return value is a label name for + the beginning of the actual bytecode. */ + char * + bc_emit_trampoline (callinfo) + char *callinfo; + { + char mylab[20]; + static int n; + + sprintf (mylab, "*LB%d", n++); + + BC_EMIT_TRAMPOLINE (trampoline, callinfo); + + seg_defsym (bytecode, mylab); + return sym_lookup (mylab)->name; + } + + + /* Simple strdup */ + char * + bc_xstrdup (str) + char *str; + { + char *tmp = xmalloc (strlen (str) + 1); + + strcpy (tmp, str); + return tmp; + } diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/bc-emit.h gcc-2.5.0/bc-emit.h *** gcc-2.4.5/bc-emit.h --- gcc-2.5.0/bc-emit.h Wed Sep 22 10:45:51 1993 *************** *** 0 **** --- 1,133 ---- + /* bc-emit.h - declare entry points for producing object files of bytecodes. */ + + /* Internal format of symbol table for the object file. */ + struct bc_sym + { + /* Private copy separately malloc'd. */ + char *name; + + /* Symbol has a defined value. */ + unsigned int defined:1; + + /* Symbol has been globalized. */ + unsigned int global:1; + + /* Symbol is common. */ + unsigned int common:1; + + /* Value if defined. */ + unsigned long int val; + + /* Used in internal symbol table structure. */ + struct bc_sym *next; + }; + + + /* List of symbols defined in a particular segment. */ + struct bc_segsym + { + struct bc_sym *sym; + struct bc_segsym *next; + }; + + + /* List of relocations needed in a particular segment. */ + struct bc_segreloc + { + /* Offset of datum to be relocated. */ + unsigned int offset; + + /* Symbol to be relocated by. */ + struct bc_sym *sym; + + struct bc_segreloc *next; + }; + + + /* Segment of an object file. */ + struct bc_seg + { + /* Size allocated to contents. */ + unsigned int alloc; + + /* Pointer to base of contents. */ + char *data; + + /* Actual size of contents. */ + unsigned int size; + + /* List of symbols defined in this segment. */ + struct bc_segsym *syms; + + /* List of relocations for this segment. */ + struct bc_segreloc *relocs; + }; + + + /* Anonymous bytecode label within a single function. */ + struct bc_label + { + /* Offset of label from start of segment. */ + unsigned int offset; + + /* True when offset is valid. */ + unsigned int defined:1; + + /* Unique bytecode ID, used to determine innermost + block containment */ + int uid; + + /* Next node in list */ + struct bc_label *next; + }; + + + /* Reference to a bc_label; a list of all such references is kept for + the function, then when it is finished they are backpatched to + contain the correct values. */ + + struct bc_labelref + { + /* Label referenced. */ + struct bc_label *label; + + /* Code offset of reference. */ + unsigned int offset; + + /* Next labelref in list */ + struct bc_labelref *next; + }; + + + + extern void bc_initialize(); + extern int bc_begin_function(); + extern char *bc_emit_trampoline(); + extern void bc_emit_bytecode(); + extern void bc_emit_bytecode_const(); + extern struct bc_label *bc_get_bytecode_label(); + extern int bc_emit_bytecode_labeldef(); + extern void bc_emit_bytecode_labelref(); + extern void bc_emit_code_labelref(); + extern char *bc_end_function(); + extern void bc_align_const(); + extern void bc_emit_const(); + extern void bc_emit_const_skip(); + extern int bc_emit_const_labeldef(); + extern void bc_emit_const_labelref(); + extern void bc_align_data(); + extern void bc_emit_data(); + extern void bc_emit_data_skip(); + extern int bc_emit_data_labeldef(); + extern void bc_emit_data_labelref(); + extern int bc_define_pointer (); + extern int bc_emit_common(); + extern void bc_globalize_label(); + extern void bc_text(); + extern void bc_data(); + extern void bc_align(); + extern void bc_emit(); + extern void bc_emit_skip(); + extern int bc_emit_labeldef(); + extern void bc_emit_labelref(); + extern void bc_write_file(); diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/bc-optab.c gcc-2.5.0/bc-optab.c *** gcc-2.4.5/bc-optab.c --- gcc-2.5.0/bc-optab.c Mon Oct 4 17:59:20 1993 *************** *** 0 **** --- 1,788 ---- + /* Bytecode conversion definitions for GNU C-compiler. + Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + + #include "config.h" + #include "tree.h" + #include "rtl.h" + #include "machmode.h" + #include "obstack.h" + #include "bytecode.h" + #include "bc-typecd.h" + #include "bc-opcode.h" + #include "bc-optab.h" + + #define obstack_chunk_alloc xmalloc + #define obstack_chunk_free free + + extern char *xmalloc (); + extern void free (); + + /* Table relating interpreter typecodes to machine modes. */ + #define GET_TYPECODE_MODE(CODE) (typecode_mode[((int) CODE)]) + enum machine_mode typecode_mode[] = { + #define DEFTYPECODE(CODE, NAME, MODE, TYPE) MODE, + #include "bc-typecd.def" + #undef DEFTYPECODE + }; + + /* Machine mode to type code map */ + static enum typecode signed_mode_to_code_map[MAX_MACHINE_MODE+1]; + static enum typecode unsigned_mode_to_code_map[MAX_MACHINE_MODE+1]; + + #define GET_TYPECODE_SIZE(CODE) GET_MODE_SIZE (GET_TYPECODE_MODE (CODE)) + + #define BIG_ARBITRARY_NUMBER 100000 + + /* Table of recipes for conversions among scalar types, to be filled + in as needed at run time. */ + static struct conversion_recipe + { + unsigned char *opcodes; /* Bytecodes to emit in order. */ + int nopcodes; /* Count of bytecodes. */ + int cost; /* A rather arbitrary cost function. */ + } conversion_recipe[NUM_TYPECODES][NUM_TYPECODES]; + + /* Binary operator tables. */ + struct binary_operator optab_plus_expr[] = { + { addSI, SIcode, SIcode, SIcode }, + { addDI, DIcode, DIcode, DIcode }, + { addSF, SFcode, SFcode, SFcode }, + { addDF, DFcode, DFcode, DFcode }, + { addXF, XFcode, XFcode, XFcode }, + { addPSI, Pcode, Pcode, SIcode }, + { -1, -1, -1, -1 }, + }; + + struct binary_operator optab_minus_expr[] = { + { subSI, SIcode, SIcode, SIcode }, + { subDI, DIcode, DIcode, DIcode }, + { subSF, SFcode, SFcode, SFcode }, + { subDF, DFcode, DFcode, DFcode }, + { subXF, XFcode, XFcode, XFcode }, + { subPP, SIcode, Pcode, Pcode }, + { -1, -1, -1, -1 }, + }; + + /* The ordering of the tables for multiplicative operators + is such that unsigned operations will be preferred to signed + operations when one argument is unsigned. */ + + struct binary_operator optab_mult_expr[] = { + { mulSU, SUcode, SUcode, SUcode }, + { mulDU, DUcode, DUcode, DUcode }, + { mulSI, SIcode, SIcode, SIcode }, + { mulDI, DIcode, DIcode, DIcode }, + { mulSF, SFcode, SFcode, SFcode }, + { mulDF, DFcode, DFcode, DFcode }, + { mulXF, XFcode, XFcode, XFcode }, + { -1, -1, -1, -1 }, + }; + + struct binary_operator optab_trunc_div_expr[] = { + { divSU, SUcode, SUcode, SUcode }, + { divDU, DUcode, DUcode, DUcode }, + { divSI, SIcode, SIcode, SIcode }, + { divDI, DIcode, DIcode, DIcode }, + { -1, -1, -1, -1 }, + }; + + struct binary_operator optab_trunc_mod_expr[] = { + { modSU, SUcode, SUcode, SUcode }, + { modDU, DUcode, DUcode, DUcode }, + { modSI, SIcode, SIcode, SIcode }, + { modDI, DIcode, DIcode, DIcode }, + { -1, -1, -1, -1 }, + }; + + struct binary_operator optab_rdiv_expr[] = { + { divSF, SFcode, SFcode, SFcode }, + { divDF, DFcode, DFcode, DFcode }, + { divXF, XFcode, XFcode, XFcode }, + { -1, -1, -1, -1 }, + }; + + struct binary_operator optab_bit_and_expr[] = { + { andSI, SIcode, SIcode, SIcode }, + { andDI, DIcode, DIcode, DIcode }, + { -1, -1, -1, -1 }, + }; + + struct binary_operator optab_bit_ior_expr[] = { + { iorSI, SIcode, SIcode, SIcode }, + { iorDI, DIcode, DIcode, DIcode }, + { -1, -1, -1, -1 }, + }; + + struct binary_operator optab_bit_xor_expr[] = { + { xorSI, SIcode, SIcode, SIcode }, + { xorDI, DIcode, DIcode, DIcode }, + { -1, -1, -1, -1 }, + }; + + struct binary_operator optab_lshift_expr[] = { + { lshiftSI, SIcode, SIcode, SIcode }, + { lshiftSU, SUcode, SUcode, SIcode }, + { lshiftDI, DIcode, DIcode, SIcode }, + { lshiftDU, DUcode, DUcode, SIcode }, + { -1, -1, -1, -1 }, + }; + + struct binary_operator optab_rshift_expr[] = { + { rshiftSI, SIcode, SIcode, SIcode }, + { rshiftSU, SUcode, SUcode, SIcode }, + { rshiftDI, DIcode, DIcode, SIcode }, + { rshiftDU, DUcode, DUcode, SIcode }, + { -1, -1, -1, -1 }, + }; + + struct binary_operator optab_truth_and_expr[] = { + { andSI, SIcode, Tcode, Tcode }, + { -1, -1, -1, -1 }, + }; + + struct binary_operator optab_truth_or_expr[] = { + { iorSI, SIcode, Tcode, Tcode }, + { -1, -1, -1, -1 }, + }; + + struct binary_operator optab_lt_expr[] = { + { ltSI, Tcode, SIcode, SIcode }, + { ltSU, Tcode, SUcode, SUcode }, + { ltDI, Tcode, DIcode, DIcode }, + { ltDU, Tcode, DUcode, DUcode }, + { ltSF, Tcode, SFcode, SFcode }, + { ltDF, Tcode, DFcode, DFcode }, + { ltXF, Tcode, XFcode, XFcode }, + { ltP, Tcode, Pcode, Pcode }, + { -1, -1, -1, -1 }, + }; + + struct binary_operator optab_le_expr[] = { + { leSI, Tcode, SIcode, SIcode }, + { leSU, Tcode, SUcode, SUcode }, + { leDI, Tcode, DIcode, DIcode }, + { leDU, Tcode, DUcode, DUcode }, + { leSF, Tcode, SFcode, SFcode }, + { leDF, Tcode, DFcode, DFcode }, + { leXF, Tcode, XFcode, XFcode }, + { leP, Tcode, Pcode, Pcode }, + { -1, -1, -1, -1 }, + }; + + struct binary_operator optab_ge_expr[] = { + { geSI, Tcode, SIcode, SIcode }, + { geSU, Tcode, SUcode, SUcode }, + { geDI, Tcode, DIcode, DIcode }, + { geDU, Tcode, DUcode, DUcode }, + { geSF, Tcode, SFcode, SFcode }, + { geDF, Tcode, DFcode, DFcode }, + { geXF, Tcode, XFcode, XFcode }, + { geP, Tcode, Pcode, Pcode }, + { -1, -1, -1, -1 }, + }; + + struct binary_operator optab_gt_expr[] = { + { gtSI, Tcode, SIcode, SIcode }, + { gtSU, Tcode, SUcode, SUcode }, + { gtDI, Tcode, DIcode, DIcode }, + { gtDU, Tcode, DUcode, DUcode }, + { gtSF, Tcode, SFcode, SFcode }, + { gtDF, Tcode, DFcode, DFcode }, + { gtXF, Tcode, XFcode, XFcode }, + { gtP, Tcode, Pcode, Pcode }, + { -1, -1, -1, -1 }, + }; + + struct binary_operator optab_eq_expr[] = { + { eqSI, Tcode, SIcode, SIcode }, + { eqDI, Tcode, DIcode, DIcode }, + { eqSF, Tcode, SFcode, SFcode }, + { eqDF, Tcode, DFcode, DFcode }, + { eqXF, Tcode, XFcode, XFcode }, + { eqP, Tcode, Pcode, Pcode }, + { -1, -1, -1, -1 }, + }; + + struct binary_operator optab_ne_expr[] = { + { neSI, Tcode, SIcode, SIcode }, + { neDI, Tcode, DIcode, DIcode }, + { neSF, Tcode, SFcode, SFcode }, + { neDF, Tcode, DFcode, DFcode }, + { neXF, Tcode, XFcode, XFcode }, + { neP, Tcode, Pcode, Pcode }, + { -1, -1, -1, -1 }, + }; + + /* Unary operator tables. */ + struct unary_operator optab_negate_expr[] = { + { negSI, SIcode, SIcode }, + { negDI, DIcode, DIcode }, + { negSF, SFcode, SFcode }, + { negDF, DFcode, DFcode }, + { negXF, XFcode, XFcode }, + { -1, -1, -1 }, + }; + + struct unary_operator optab_bit_not_expr[] = { + { notSI, SIcode, SIcode }, + { notDI, DIcode, DIcode }, + { -1, -1, -1 }, + }; + + struct unary_operator optab_truth_not_expr[] = { + { notT, SIcode, SIcode }, + { -1, -1, -1 }, + }; + + /* Increment operator tables. */ + struct increment_operator optab_predecrement_expr[] = { + { predecQI, QIcode }, + { predecQI, QUcode }, + { predecHI, HIcode }, + { predecHI, HUcode }, + { predecSI, SIcode }, + { predecSI, SUcode }, + { predecDI, DIcode }, + { predecDI, DUcode }, + { predecP, Pcode }, + { predecSF, SFcode }, + { predecDF, DFcode }, + { predecXF, XFcode }, + { -1, -1 }, + }; + + struct increment_operator optab_preincrement_expr[] = { + { preincQI, QIcode }, + { preincQI, QUcode }, + { preincHI, HIcode }, + { preincHI, HUcode }, + { preincSI, SIcode }, + { preincSI, SUcode }, + { preincDI, DIcode }, + { preincDI, DUcode }, + { preincP, Pcode }, + { preincSF, SFcode }, + { preincDF, DFcode }, + { preincXF, XFcode }, + { -1, -1 }, + }; + + struct increment_operator optab_postdecrement_expr[] = { + { postdecQI, QIcode }, + { postdecQI, QUcode }, + { postdecHI, HIcode }, + { postdecHI, HUcode }, + { postdecSI, SIcode }, + { postdecSI, SUcode }, + { postdecDI, DIcode }, + { postdecDI, DUcode }, + { postdecP, Pcode }, + { postdecSF, SFcode }, + { postdecDF, DFcode }, + { postdecXF, XFcode }, + { -1, -1 }, + }; + + struct increment_operator optab_postincrement_expr[] = { + { postincQI, QIcode }, + { postincQI, QUcode }, + { postincHI, HIcode }, + { postincHI, HUcode }, + { postincSI, SIcode }, + { postincSI, SUcode }, + { postincDI, DIcode }, + { postincDI, DUcode }, + { postincP, Pcode }, + { postincSF, SFcode }, + { postincDF, DFcode }, + { postincXF, XFcode }, + { -1, -1 }, + }; + + /* Table of conversions supported by the interpreter. */ + static struct conversion_info + { + enum bytecode_opcode opcode; /* here indicates the conversion needs no opcode. */ + enum typecode from; + enum typecode to; + int cost; /* 1 for no-op conversions, 2 for widening conversions, + 4 for int/float conversions, 8 for narrowing conversions. */ + } conversion_info[] = { + { -1, QIcode, QUcode, 1 }, + { -1, HIcode, HUcode, 1 }, + { -1, SIcode, SUcode, 1 }, + { -1, DIcode, DUcode, 1 }, + { -1, QUcode, QIcode, 1 }, + { -1, HUcode, HIcode, 1 }, + { -1, SUcode, SIcode, 1 }, + { -1, DUcode, DIcode, 1 }, + { -1, Tcode, SIcode, 1 }, + { convertQIHI, QIcode, HIcode, 2 }, + { convertQUHU, QUcode, HUcode, 2 }, + { convertQUSU, QUcode, SUcode, 2 }, + { convertHISI, HIcode, SIcode, 2 }, + { convertHUSU, HUcode, SUcode, 2 }, + { convertSIDI, SIcode, DIcode, 2 }, + { convertSUDU, SUcode, DUcode, 2 }, + { convertSFDF, SFcode, DFcode, 2 }, + { convertDFXF, DFcode, XFcode, 2 }, + { convertHIQI, HIcode, QIcode, 8 }, + { convertSIQI, SIcode, QIcode, 8 }, + { convertSIHI, SIcode, HIcode, 8 }, + { convertSUQU, SUcode, QUcode, 8 }, + { convertDISI, DIcode, SIcode, 8 }, + { convertDFSF, DFcode, SFcode, 8 }, + { convertXFDF, XFcode, DFcode, 8 }, + { convertPSI, Pcode, SIcode, 2 }, + { convertSIP, SIcode, Pcode, 2 }, + { convertSIT, SIcode, Tcode, 2 }, + { convertDIT, DIcode, Tcode, 2 }, + { convertSFT, SFcode, Tcode, 2 }, + { convertDFT, DFcode, Tcode, 2 }, + { convertXFT, XFcode, Tcode, 2 }, + { convertQISI, QIcode, SIcode, 2 }, + { convertPT, Pcode, Tcode, 2 }, + { convertSISF, SIcode, SFcode, 4 }, + { convertSIDF, SIcode, DFcode, 4 }, + { convertSIXF, SIcode, XFcode, 4 }, + { convertSUSF, SUcode, SFcode, 4 }, + { convertSUDF, SUcode, DFcode, 4 }, + { convertSUXF, SUcode, XFcode, 4 }, + { convertDISF, DIcode, SFcode, 4 }, + { convertDIDF, DIcode, DFcode, 4 }, + { convertDIXF, DIcode, XFcode, 4 }, + { convertDUSF, DUcode, SFcode, 4 }, + { convertDUDF, DUcode, DFcode, 4 }, + { convertDUXF, DUcode, XFcode, 4 }, + { convertSFSI, SFcode, SIcode, 4 }, + { convertDFSI, DFcode, SIcode, 4 }, + { convertXFSI, XFcode, SIcode, 4 }, + { convertSFSU, SFcode, SUcode, 4 }, + { convertDFSU, DFcode, SUcode, 4 }, + { convertXFSU, XFcode, SUcode, 4 }, + { convertSFDI, SFcode, DIcode, 4 }, + { convertDFDI, DFcode, DIcode, 4 }, + { convertXFDI, XFcode, DIcode, 4 }, + { convertSFDU, SFcode, DUcode, 4 }, + { convertDFDU, DFcode, DUcode, 4 }, + { convertXFDU, XFcode, DUcode, 4 }, + { convertSIQI, SIcode, QIcode, 8 }, + }; + + #define NUM_CONVERSIONS (sizeof conversion_info / sizeof (struct conversion_info)) + + /* List form of a conversion recipe. */ + struct conversion_list + { + enum bytecode_opcode opcode; + enum typecode to; + int cost; + struct conversion_list *prev; + }; + + /* Determine if it is "reasonable" to add a given conversion to + a given list of conversions. The following criteria define + "reasonable" conversion lists: + * No typecode appears more than once in the sequence (no loops). + * At most one conversion from integer to float or vice versa is present. + * Either sign extensions or zero extensions may be present, but not both. + * No widening conversions occur after a signed/unsigned conversion. + * The sequence of sizes must be strict nonincreasing or nondecreasing. */ + static int + conversion_reasonable_p (conversion, list) + struct conversion_info *conversion; + struct conversion_list *list; + { + struct conversion_list *curr; + int curr_size, prev_size; + int has_int_float, has_float_int; + int has_sign_extend, has_zero_extend; + int has_signed_unsigned, has_unsigned_signed; + + has_int_float = 0; + has_float_int = 0; + has_sign_extend = 0; + has_zero_extend = 0; + has_signed_unsigned = 0; + has_unsigned_signed = 0; + + /* Make sure the destination typecode doesn't already appear in + the list. */ + for (curr = list; curr; curr = curr->prev) + if (conversion->to == curr->to) + return 0; + + /* Check for certain kinds of conversions. */ + if (TYPECODE_INTEGER_P (conversion->from) + && TYPECODE_FLOAT_P (conversion->to)) + has_int_float = 1; + if (TYPECODE_FLOAT_P (conversion->from) + && TYPECODE_INTEGER_P (conversion->to)) + has_float_int = 1; + if (TYPECODE_SIGNED_P (conversion->from) + && TYPECODE_SIGNED_P (conversion->to) + && GET_TYPECODE_SIZE (conversion->from) + < GET_TYPECODE_SIZE (conversion->to)) + has_sign_extend = 1; + if (TYPECODE_UNSIGNED_P (conversion->from) + && TYPECODE_UNSIGNED_P (conversion->to) + && GET_TYPECODE_SIZE (conversion->from) + < GET_TYPECODE_SIZE (conversion->to)) + has_zero_extend = 1; + + for (curr = list; curr && curr->prev; curr = curr->prev) + { + if (TYPECODE_INTEGER_P (curr->prev->to) + && TYPECODE_FLOAT_P (curr->to)) + has_int_float = 1; + if (TYPECODE_FLOAT_P (curr->prev->to) + && TYPECODE_INTEGER_P (curr->to)) + has_float_int = 1; + if (TYPECODE_SIGNED_P (curr->prev->to) + && TYPECODE_SIGNED_P (curr->to) + && GET_TYPECODE_SIZE (curr->prev->to) + < GET_TYPECODE_SIZE (curr->to)) + has_sign_extend = 1; + if (TYPECODE_UNSIGNED_P (curr->prev->to) + && TYPECODE_UNSIGNED_P (curr->to) + && GET_TYPECODE_SIZE (curr->prev->to) + < GET_TYPECODE_SIZE (curr->to)) + has_zero_extend = 1; + if (TYPECODE_SIGNED_P (curr->prev->to) + && TYPECODE_UNSIGNED_P (curr->to)) + has_signed_unsigned = 1; + if (TYPECODE_UNSIGNED_P (curr->prev->to) + && TYPECODE_SIGNED_P (curr->to)) + has_unsigned_signed = 1; + } + + if (TYPECODE_INTEGER_P (conversion->from) + && TYPECODE_INTEGER_P (conversion->to) + && GET_TYPECODE_SIZE (conversion->to) + > GET_TYPECODE_SIZE (conversion->from) + && (has_signed_unsigned || has_unsigned_signed)) + return 0; + + if (has_float_int && has_int_float || has_sign_extend && has_zero_extend) + return 0; + + /* Make sure the sequence of destination typecode sizes is + strictly nondecreasing or strictly nonincreasing. */ + prev_size = GET_TYPECODE_SIZE (conversion->to); + for (curr = list; curr; curr = curr->prev) + { + curr_size = GET_TYPECODE_SIZE (curr->to); + if (curr_size != prev_size) + break; + } + if (!curr) + return 1; + + if (curr_size < prev_size) + for (prev_size = curr_size; curr; curr = curr->prev) + { + curr_size = GET_TYPECODE_SIZE (curr->to); + if (curr_size > prev_size) + return 0; + prev_size = curr_size; + } + else + for (prev_size = curr_size; curr; curr = curr->prev) + { + curr_size = GET_TYPECODE_SIZE (curr->to); + if (curr_size < prev_size) + return 0; + prev_size = curr_size; + } + return 1; + } + + + /* Exhaustively search all reasonable conversions to find one to + convert the given types. */ + static struct conversion_recipe + deduce_conversion (from, to) + enum typecode from, to; + { + struct rl + { + struct conversion_list *list; + struct rl *next; + } *prev, curr, *good, *temp; + struct conversion_list *conv, *best; + int i, cost, bestcost; + struct conversion_recipe result; + struct obstack recipe_obstack; + + + obstack_init (&recipe_obstack); + curr.next = (struct rl *) obstack_alloc (&recipe_obstack, sizeof (struct rl)); + curr.next->list = + (struct conversion_list *) obstack_alloc (&recipe_obstack, + sizeof (struct conversion_list)); + curr.next->list->opcode = -1; + curr.next->list->to = from; + curr.next->list->cost = 0; + curr.next->list->prev = 0; + curr.next->next = 0; + good = 0; + + while (curr.next) + { + /* Remove successful conversions from further consideration. */ + for (prev = &curr; prev; prev = prev->next) + if (prev->next && prev->next->list->to == to) + { + temp = prev->next->next; + prev->next->next = good; + good = prev->next; + prev->next = temp; + } + + /* Go through each of the pending conversion chains, trying + all possible candidate conversions on them. */ + for (prev = curr.next, curr.next = 0; prev; prev = prev->next) + for (i = 0; i < NUM_CONVERSIONS; ++i) + if (conversion_info[i].from == prev->list->to + && conversion_reasonable_p (&conversion_info[i], prev->list)) + { + temp = (struct rl *) obstack_alloc (&recipe_obstack, + sizeof (struct rl)); + temp->list = (struct conversion_list *) + obstack_alloc (&recipe_obstack, + sizeof (struct conversion_list)); + temp->list->opcode = conversion_info[i].opcode; + temp->list->to = conversion_info[i].to; + temp->list->cost = conversion_info[i].cost; + temp->list->prev = prev->list; + temp->next = curr.next; + curr.next = temp; + } + } + + bestcost = BIG_ARBITRARY_NUMBER; + best = 0; + for (temp = good; temp; temp = temp->next) + { + for (conv = temp->list, cost = 0; conv; conv = conv->prev) + cost += conv->cost; + if (cost < bestcost) + { + bestcost = cost; + best = temp->list; + } + } + + if (!best) + abort (); + + for (i = 0, conv = best; conv; conv = conv->prev) + if (conv->opcode != -1) + ++i; + + result.opcodes = (unsigned char *) xmalloc (i); + result.nopcodes = i; + for (conv = best; conv; conv = conv->prev) + if (conv->opcode != -1) + result.opcodes[--i] = conv->opcode; + result.cost = bestcost; + obstack_free (&recipe_obstack, 0); + return result; + } + + #define DEDUCE_CONVERSION(FROM, TO) \ + (conversion_recipe[(int) FROM][(int) TO].opcodes ? 0 \ + : (conversion_recipe[(int) FROM][(int) TO] \ + = deduce_conversion (FROM, TO), 0)) + + + /* Emit a conversion between the given scalar types. */ + void + emit_typecode_conversion (from, to) + enum typecode from, to; + { + int i; + + DEDUCE_CONVERSION (from, to); + for (i = 0; i < conversion_recipe[(int) from][(int) to].nopcodes; ++i) + bc_emit_instruction (conversion_recipe[(int) from][(int) to].opcodes[i]); + } + + + /* Initialize mode_to_code_map[] */ + void + bc_init_mode_to_code_map () + { + int mode; + + for (mode = 0; mode < MAX_MACHINE_MODE + 1; mode++) + { + signed_mode_to_code_map[mode] = + unsigned_mode_to_code_map[mode] = + LAST_AND_UNUSED_TYPECODE; + } + + #define DEF_MODEMAP(SYM, CODE, UCODE, CONST, LOAD, STORE) \ + { signed_mode_to_code_map[(int) SYM] = CODE; \ + unsigned_mode_to_code_map[(int) SYM] = UCODE; } + #include "modemap.def" + #undef DEF_MODEMAP + + /* Initialize opcode maps for const, load, and store */ + bc_init_mode_to_opcode_maps (); + } + + /* Given a machine mode return the preferred typecode. */ + enum typecode + preferred_typecode (mode, unsignedp) + enum machine_mode mode; + int unsignedp; + { + enum typecode code = (unsignedp + ? unsigned_mode_to_code_map + : signed_mode_to_code_map) [MIN ((int) mode, + (int) MAX_MACHINE_MODE)]; + + if (code == LAST_AND_UNUSED_TYPECODE) + abort (); + + return code; + } + + + /* Expand a conversion between the given types. */ + void + bc_expand_conversion (from, to) + tree from, to; + { + enum typecode fcode, tcode; + + fcode = preferred_typecode (TYPE_MODE (from), TREE_UNSIGNED (from)); + tcode = preferred_typecode (TYPE_MODE (to), TREE_UNSIGNED (to)); + + emit_typecode_conversion (fcode, tcode); + } + + /* Expand a conversion of the given type to a truth value. */ + void + bc_expand_truth_conversion (from) + tree from; + { + enum typecode fcode; + + fcode = preferred_typecode (TYPE_MODE (from), TREE_UNSIGNED (from)); + emit_typecode_conversion (fcode, Tcode); + } + + /* Emit an appropriate binary operation. */ + void + bc_expand_binary_operation (optab, resulttype, arg0, arg1) + struct binary_operator optab[]; + tree resulttype, arg0, arg1; + { + int i, besti, cost, bestcost; + enum typecode resultcode, arg0code, arg1code; + + resultcode = preferred_typecode (TYPE_MODE (resulttype), TREE_UNSIGNED (resulttype)); + arg0code = preferred_typecode (TYPE_MODE (TREE_TYPE (arg0)), TREE_UNSIGNED (resulttype)); + arg1code = preferred_typecode (TYPE_MODE (TREE_TYPE (arg1)), TREE_UNSIGNED (resulttype)); + + besti = -1; + bestcost = BIG_ARBITRARY_NUMBER; + + for (i = 0; optab[i].opcode != -1; ++i) + { + cost = 0; + DEDUCE_CONVERSION (arg0code, optab[i].arg0); + cost += conversion_recipe[(int) arg0code][(int) optab[i].arg0].cost; + DEDUCE_CONVERSION (arg1code, optab[i].arg1); + cost += conversion_recipe[(int) arg1code][(int) optab[i].arg1].cost; + if (cost < bestcost) + { + besti = i; + bestcost = cost; + } + } + + if (besti == -1) + abort (); + + expand_expr (arg1); + emit_typecode_conversion (arg1code, optab[besti].arg1); + expand_expr (arg0); + emit_typecode_conversion (arg0code, optab[besti].arg0); + bc_emit_instruction (optab[besti].opcode); + emit_typecode_conversion (optab[besti].result, resultcode); + } + + /* Emit an appropriate unary operation. */ + void + bc_expand_unary_operation (optab, resulttype, arg0) + struct unary_operator optab[]; + tree resulttype, arg0; + { + int i, besti, cost, bestcost; + enum typecode resultcode, arg0code; + + resultcode = preferred_typecode (TYPE_MODE (resulttype), TREE_UNSIGNED (resulttype)); + arg0code = preferred_typecode (TYPE_MODE (TREE_TYPE (arg0)), TREE_UNSIGNED (TREE_TYPE (arg0))); + + besti = -1; + bestcost = BIG_ARBITRARY_NUMBER; + + for (i = 0; optab[i].opcode != -1; ++i) + { + DEDUCE_CONVERSION (arg0code, optab[i].arg0); + cost = conversion_recipe[(int) arg0code][(int) optab[i].arg0].cost; + if (cost < bestcost) + { + besti = i; + bestcost = cost; + } + } + + if (besti == -1) + abort (); + + expand_expr (arg0); + emit_typecode_conversion (arg0code, optab[besti].arg0); + bc_emit_instruction (optab[besti].opcode); + emit_typecode_conversion (optab[besti].result, resultcode); + } + + + /* Emit an appropriate increment. */ + void + bc_expand_increment (optab, type) + struct increment_operator optab[]; + tree type; + { + enum typecode code; + int i; + + code = preferred_typecode (TYPE_MODE (type), TREE_UNSIGNED (type)); + for (i = 0; (int) optab[i].opcode >= 0; ++i) + if (code == optab[i].arg) + { + bc_emit_instruction (optab[i].opcode); + return; + } + abort (); + } diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/bc-optab.h gcc-2.5.0/bc-optab.h *** gcc-2.4.5/bc-optab.h --- gcc-2.5.0/bc-optab.h Wed Sep 22 13:44:30 1993 *************** *** 0 **** --- 1,74 ---- + /* Bytecode token definitions for GNU C-compiler. + Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + + extern void bc_expand_conversion (); + extern void bc_expand_truth_conversion (); + extern void bc_expand_binary_operation (); + extern void bc_expand_unary_operation (); + + struct binary_operator + { + enum bytecode_opcode opcode; + enum typecode result; + enum typecode arg0; + enum typecode arg1; + }; + + extern struct binary_operator optab_plus_expr[]; + extern struct binary_operator optab_minus_expr[]; + extern struct binary_operator optab_mult_expr[]; + extern struct binary_operator optab_trunc_div_expr[]; + extern struct binary_operator optab_trunc_mod_expr[]; + extern struct binary_operator optab_rdiv_expr[]; + extern struct binary_operator optab_bit_and_expr[]; + extern struct binary_operator optab_bit_ior_expr[]; + extern struct binary_operator optab_bit_xor_expr[]; + extern struct binary_operator optab_lshift_expr[]; + extern struct binary_operator optab_rshift_expr[]; + extern struct binary_operator optab_truth_and_expr[]; + extern struct binary_operator optab_truth_or_expr[]; + extern struct binary_operator optab_lt_expr[]; + extern struct binary_operator optab_le_expr[]; + extern struct binary_operator optab_ge_expr[]; + extern struct binary_operator optab_gt_expr[]; + extern struct binary_operator optab_eq_expr[]; + extern struct binary_operator optab_ne_expr[]; + + struct unary_operator + { + enum bytecode_opcode opcode; + enum typecode result; + enum typecode arg0; + }; + + extern struct unary_operator optab_negate_expr[]; + extern struct unary_operator optab_bit_not_expr[]; + extern struct unary_operator optab_truth_not_expr[]; + + struct increment_operator + { + enum bytecode_opcode opcode; + enum typecode arg; + }; + + extern struct increment_operator optab_predecrement_expr[]; + extern struct increment_operator optab_preincrement_expr[]; + extern struct increment_operator optab_postdecrement_expr[]; + extern struct increment_operator optab_postincrement_expr[]; diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/bc-typecd.def gcc-2.5.0/bc-typecd.def *** gcc-2.4.5/bc-typecd.def --- gcc-2.5.0/bc-typecd.def Wed Sep 22 13:44:20 1993 *************** *** 0 **** --- 1,21 ---- + /* Typecodes used by the interpreter and their related + machine modes and types. + + The last argument is used for retrieving the given + type from a varargs list. Due to a bug in varargs, + the type has to be the generic machine type of + larger. */ + + DEFTYPECODE (QIcode, "QI", QImode, SItype) + DEFTYPECODE (QUcode, "QU", QImode, SUtype) + DEFTYPECODE (HIcode, "HI", HImode, SItype) + DEFTYPECODE (HUcode, "HU", HImode, SUtype) + DEFTYPECODE (SIcode, "SI", SImode, SItype) + DEFTYPECODE (SUcode, "SU", SImode, SUtype) + DEFTYPECODE (DIcode, "DI", DImode, DItype) + DEFTYPECODE (DUcode, "DU", DImode, DUtype) + DEFTYPECODE (SFcode, "SF", SFmode, SFtype) + DEFTYPECODE (DFcode, "DF", DFmode, DFtype) + DEFTYPECODE (XFcode, "XF", XFmode, XFtype) + DEFTYPECODE (Pcode, "P", PSImode, Ptype) + DEFTYPECODE (Tcode, "T", SImode, SItype) diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/bc-typecd.h gcc-2.5.0/bc-typecd.h *** gcc-2.4.5/bc-typecd.h --- gcc-2.5.0/bc-typecd.h Mon Oct 4 17:59:24 1993 *************** *** 0 **** --- 1,53 ---- + /* Typecode definitions for Bytecode Interpreter. + Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + #ifndef TYPECODE_H + #define TYPECODE_H + + enum typecode + { + #define DEFTYPECODE(CODE, NAME, MACHMODE, TYPE) CODE, + #include "bc-typecd.def" + #undef DEFTYPECODE + + LAST_AND_UNUSED_TYPECODE + }; + + /* Determine if a given type is integer. */ + #define TYPECODE_INTEGER_P(TYPECODE) ((int) (TYPECODE) < (int) SFcode) + + /* Determine if a given type is unsigned. */ + #define TYPECODE_UNSIGNED_P(TYPECODE) \ + (TYPECODE_INTEGER_P(TYPECODE) && (int) (TYPECODE) & 1) + + /* Determine if a given type is signed. */ + #define TYPECODE_SIGNED_P(TYPECODE) \ + (TYPECODE_INTEGER_P(TYPECODE) && !((int) (TYPECODE) & 1)) + + /* Determine if a given type is floating. */ + #define TYPECODE_FLOAT_P(TYPECODE) \ + ((int) (TYPECODE) < (int) Pcode && !TYPECODE_INTEGER_P(TYPECODE)) + + /* Determine if the given type is arithmetic. */ + #define TYPECODE_ARITH_P(TYPECODE) \ + (TYPECODE_INTEGER_P(TYPECODE) || TYPECODE_FLOAT_P(TYPECODE)) + + #define NUM_TYPECODES ((int) LAST_AND_UNUSED_TYPECODE) + + #endif diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/bi-arity.c gcc-2.5.0/bi-arity.c *** gcc-2.4.5/bi-arity.c --- gcc-2.5.0/bi-arity.c Tue Oct 5 15:46:36 1993 *************** *** 0 **** --- 1,75 ---- + /* Bytecode Interpreter utility to generate arity table. + Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + + #include + #include "hconfig.h" + #include "bi-defs.h" + + int + length (n) + struct node *n; + { + int k; + + for (k = 0; n; n = n->next) + ++k; + return k; + } + + int + main () + { + struct def *d; + struct variation *v; + struct node *n; + + yyparse (); + reverse (); + + for (d = defs; d; d = d->next) + for (v = d->variations; v; v = v->next) + { + printf ("{ %d, %d, %d, {", length (v->inputs), + length (v->outputs), length (v->literals)); + for (n = v->literals; n; n = n->next) + printf ("%scode, ", n->text); + if (v->literals == 0) + printf ("0"); + printf ("}},\n"); + } + return 0; + } + + /* Safely allocate NBYTES bytes of memory. Returns pointer to block of + memory. */ + char * + xmalloc (nbytes) + int nbytes; + { + char *tmp = (char *) malloc (nbytes); + + if (!tmp) + { + fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n", nbytes); + exit (1); + } + + return tmp; + } diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/bi-defs.h gcc-2.5.0/bi-defs.h *** gcc-2.4.5/bi-defs.h --- gcc-2.5.0/bi-defs.h Wed Sep 22 11:43:42 1993 *************** *** 0 **** --- 1,47 ---- + /* Definitions for Bytecode Interpreter. + Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + + struct node + { + char *text; + struct node *next; + }; + + struct variation + { + char *name; + int code; + struct node *inputs; + struct node *outputs; + struct node *literals; + struct variation *next; + }; + + struct def + { + char *basename; + char *template; + struct variation *variations; + struct def *next; + }; + + extern struct def *defs; + extern int ndefs; + extern void reverse(); diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/bi-lexer.c gcc-2.5.0/bi-lexer.c *** gcc-2.4.5/bi-lexer.c --- gcc-2.5.0/bi-lexer.c Wed Oct 6 18:53:39 1993 *************** *** 0 **** --- 1,170 ---- + /* Lexer for scanner of bytecode definition file. + Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + #include + #include "hconfig.h" + #include "bi-parser.h" + + /* Current read buffer and point */ + static char *buffer = NULL; + static char *inpoint = NULL; + + + /* Safely allocate NBYTES bytes of memory. Reuturns pointer to block of + memory. */ + + static char * + xmalloc (nbytes) + int nbytes; + { + char *tmp = (char *) malloc (nbytes); + + if (!tmp) + { + fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n", nbytes); + exit (1); + } + + return tmp; + } + + + /* Safely reallocate BLOCK so its size becomes NBYTES. + The block returned may be different from the one supplied. */ + + static char * + xrealloc (block, nbytes) + char *block; + int nbytes; + { + char *tmp = (block + ? (char *) realloc (block, nbytes) + : (char *) malloc (nbytes)); + + if (!tmp) + { + fprintf (stderr, "can't reallocate %d bytes (out of virtual memory)\n", nbytes); + exit (1); + } + + return tmp; + } + + + /* Scan for string token on standard input. A string is, for our + purposes here, a sequence of characters that starts with the regexp + ``[^ #\t\n(),]'' and is then followed by the regexp ``[^#(),]*''. Any + character is accepted if preceded by a backslash, "\\". It is assumed + that the first character has already been checked by the main loop. */ + + static char * + scan_string () + { + char *buffer = NULL; + char *point = NULL; + int buffer_size = 0; + int c; + + while ((c = getc (stdin)) != EOF + && c != '#' && c != '(' && c != ')' && c != ',') + { + /* Extend buffer, if necessary (minus two so there's room for the NUL + trailer as well as another character if this one is a backslash). */ + if (!buffer_size || (point - buffer >= buffer_size-2)) + { + int previous_point_index = point - buffer; + + buffer_size = (!buffer_size ? 32 : buffer_size * 2); + if (!buffer) + buffer = xmalloc (buffer_size); + else + buffer = xrealloc (buffer, buffer_size); + + point = buffer + previous_point_index; + } + *point++ = c & 0xff; + + if (c == '\\') + { + c = getc (stdin); + + /* Catch special case: backslash at end of file */ + if (c == EOF) + break; + + *point++ = c; + } + } + *point = 0; + + if (c != EOF) + ungetc (c, stdin); + + return buffer; + } + + + int + yylex () + { + int c; + char *token; + + + /* First char determines what token we're looking at */ + for (;;) + { + c = getc (stdin); + + switch (c) + { + case EOF: + return 0; + + case ' ': + case '\t': + case '\n': + /* Ignore whitespace */ + continue; + + case '#': + /* Comments advance to next line */ + while ((c = getc (stdin)) != '\n' && c != EOF); + continue; + + default: + if (c != '(' && c != ')' && c != '\\' && c != ',') + { + ungetc (c, stdin); + yylval.string = scan_string (); + + /* Check if string is "define_operator"; if so, return + a DEFOP token instead. */ + if (!strcmp (yylval.string, "define_operator")) + { + free (yylval.string); + yylval.string = 0; + return DEFOP; + } + return STRING; + } + return c & 0xff; + } + } + } diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/bi-opcode.c gcc-2.5.0/bi-opcode.c *** gcc-2.4.5/bi-opcode.c --- gcc-2.5.0/bi-opcode.c Wed Oct 6 12:10:02 1993 *************** *** 0 **** --- 1,71 ---- + /* Utility to generate opcode list from bytecode definition. + Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + #include + #include "hconfig.h" + #include "bi-defs.h" + + int + main(argc, argv) + int argc; + char **argv; + { + struct def *d; + struct variation *v; + int i; + + yyparse(); + reverse(); + + + puts ("/* This file is automatically generated from bytecode.def, do not make\n\ + any changes here. Instead edit bytecode.def and type ``make''. */\n\ + enum bytecode_opcode\n{"); + + i = 0; + for (d = defs; d; d = d->next) + for (v = d->variations; v; v = v->next) + printf (" %s%s,\n", d->basename, v->name, i++); + + puts (" LAST_AND_UNUSED_OPCODE\n};"); + + if (i > 256) + fprintf (stderr, "%s: warning, number of opcodes is %d\n", *argv, i); + else + fprintf (stderr, "(Number of opcodes is %d)\n", i); + + return 0; + } + + /* Safely allocate NBYTES bytes of memory. Returns pointer to block of + memory. */ + char * + xmalloc (nbytes) + int nbytes; + { + char *tmp = (char *) malloc (nbytes); + + if (!tmp) + { + fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n", nbytes); + exit (1); + } + + return tmp; + } diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/bi-opname.c gcc-2.5.0/bi-opname.c *** gcc-2.4.5/bi-opname.c --- gcc-2.5.0/bi-opname.c Tue Oct 5 15:46:42 1993 *************** *** 0 **** --- 1,54 ---- + /* Utility to generate opcode name list from bytecode definition file. + Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + #include + #include "hconfig.h" + #include "bi-defs.h" + + int + main() + { + struct def *d; + struct variation *v; + + yyparse(); + reverse(); + + for (d = defs; d; d = d->next) + for (v = d->variations; v; v = v->next) + printf("\"%s%s\",\n", d->basename, v->name); + return 0; + } + + /* Safely allocate NBYTES bytes of memory. Returns pointer to block of + memory. */ + char * + xmalloc (nbytes) + int nbytes; + { + char *tmp = (char *) malloc (nbytes); + + if (!tmp) + { + fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n", nbytes); + exit (1); + } + + return tmp; + } diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/bi-parser.c gcc-2.5.0/bi-parser.c *** gcc-2.4.5/bi-parser.c --- gcc-2.5.0/bi-parser.c Wed Oct 6 16:33:40 1993 *************** *** 0 **** --- 1,918 ---- + + /* A Bison parser, made from bi-parser.y */ + + #define YYBISON 1 /* Identify Bison output. */ + + #define DEFOP 258 + #define STRING 259 + + #line 21 "bi-parser.y" + + + #include + #include "hconfig.h" + #include "bi-defs.h" + + extern char yytext[]; + extern int yyleng; + + + /* Chain of all defs built by the parser. */ + struct def *defs; + int ndefs; + + static struct node *makenode (); + static struct variation *makevar (); + static struct def *makedef (); + + void yyerror (); + + + #line 43 "bi-parser.y" + typedef union + { + char *string; + struct def *def; + struct variation *variation; + struct node *node; + } YYSTYPE; + + #ifndef YYLTYPE + typedef + struct yyltype + { + int timestamp; + int first_line; + int first_column; + int last_line; + int last_column; + char *text; + } + yyltype; + + #define YYLTYPE yyltype + #endif + + #include + + #ifndef __STDC__ + #define const + #endif + + + + #define YYFINAL 39 + #define YYFLAG -32768 + #define YYNTBASE 8 + + #define YYTRANSLATE(x) ((unsigned)(x) <= 259 ? yytranslate[x] : 17) + + static const char yytranslate[] = { 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, + 7, 2, 2, 6, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 1, 2, 3, 4 + }; + + static const short yyprhs[] = { 0, + 0, 2, 4, 7, 18, 20, 24, 28, 34, 42, + 52, 53, 55, 59, 60, 62, 66 + }; + + static const short yyrhs[] = { 9, + 0, 10, 0, 9, 10, 0, 3, 5, 4, 6, + 13, 6, 5, 11, 7, 7, 0, 12, 0, 11, + 6, 12, 0, 5, 13, 7, 0, 5, 13, 6, + 14, 7, 0, 5, 13, 6, 14, 6, 14, 7, + 0, 5, 13, 6, 14, 6, 14, 6, 14, 7, + 0, 0, 4, 0, 5, 15, 7, 0, 0, 16, + 0, 16, 6, 15, 0, 4, 0 + }; + + #if YYDEBUG != 0 + static const short yyrline[] = { 0, + 59, 64, 66, 70, 75, 77, 81, 84, 86, 88, + 92, 94, 97, 100, 104, 107, 111 + }; + + static const char * const yytname[] = { "$","error","$illegal.","DEFOP","STRING", + "'('","','","')'","top","defs","def","variations","variation","opt_string","list", + "items","item","" + }; + #endif + + static const short yyr1[] = { 0, + 8, 9, 9, 10, 11, 11, 12, 12, 12, 12, + 13, 13, 14, 14, 15, 15, 16 + }; + + static const short yyr2[] = { 0, + 1, 1, 2, 10, 1, 3, 3, 5, 7, 9, + 0, 1, 3, 0, 1, 3, 1 + }; + + static const short yydefact[] = { 0, + 0, 1, 2, 0, 3, 0, 11, 12, 0, 0, + 0, 11, 0, 5, 0, 0, 0, 14, 7, 6, + 4, 0, 0, 17, 0, 15, 14, 8, 13, 0, + 0, 16, 14, 9, 0, 10, 0, 0, 0 + }; + + static const short yydefgoto[] = { 37, + 2, 3, 13, 14, 9, 23, 25, 26 + }; + + static const short yypact[] = { 2, + 6, 2,-32768, 8,-32768, 7, 10,-32768, 9, 11, + 12, 10, -5,-32768, -3, 12, 13, 14,-32768,-32768, + -32768, 17, 1,-32768, 15, 18, 14,-32768,-32768, 17, + 3,-32768, 14,-32768, 16,-32768, 25, 26,-32768 + }; + + static const short yypgoto[] = {-32768, + -32768, 27,-32768, 19, 20, -27, -12,-32768 + }; + + + #define YYLAST 35 + + + static const short yytable[] = { 31, + 16, 17, 18, 19, 1, 35, 27, 28, 33, 34, + 4, 6, 7, 8, 10, 11, 12, 32, 22, 21, + 24, 29, 36, 30, 38, 39, 0, 0, 5, 0, + 0, 15, 0, 0, 20 + }; + + static const short yycheck[] = { 27, + 6, 7, 6, 7, 3, 33, 6, 7, 6, 7, + 5, 4, 6, 4, 6, 5, 5, 30, 5, 7, + 4, 7, 7, 6, 0, 0, -1, -1, 2, -1, + -1, 12, -1, -1, 16 + }; + /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ + #line 3 "bison.simple" + + /* Skeleton output parser for bison, + Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman + + This program 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. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + + + #ifndef alloca + #ifdef __GNUC__ + #define alloca __builtin_alloca + #else /* not GNU C. */ + #if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) + #include + #else /* not sparc */ + #if defined (MSDOS) && !defined (__TURBOC__) + #include + #else /* not MSDOS, or __TURBOC__ */ + #if defined(_AIX) + #include + #pragma alloca + #endif /* not _AIX */ + #endif /* not MSDOS, or __TURBOC__ */ + #endif /* not sparc. */ + #endif /* not GNU C. */ + #endif /* alloca not defined. */ + + /* This is the parser code that is written into each bison parser + when the %semantic_parser declaration is not specified in the grammar. + It was written by Richard Stallman by simplifying the hairy parser + used when %semantic_parser is specified. */ + + /* Note: there must be only one dollar sign in this file. + It is replaced by the list of actions, each action + as one case of the switch. */ + + #define yyerrok (yyerrstatus = 0) + #define yyclearin (yychar = YYEMPTY) + #define YYEMPTY -2 + #define YYEOF 0 + #define YYACCEPT return(0) + #define YYABORT return(1) + #define YYERROR goto yyerrlab1 + /* Like YYERROR except do call yyerror. + This remains here temporarily to ease the + transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + #define YYFAIL goto yyerrlab + #define YYRECOVERING() (!!yyerrstatus) + #define YYBACKUP(token, value) \ + do \ + if (yychar == YYEMPTY && yylen == 1) \ + { yychar = (token), yylval = (value); \ + yychar1 = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { yyerror ("syntax error: cannot back up"); YYERROR; } \ + while (0) + + #define YYTERROR 1 + #define YYERRCODE 256 + + #ifndef YYPURE + #define YYLEX yylex() + #endif + + #ifdef YYPURE + #ifdef YYLSP_NEEDED + #define YYLEX yylex(&yylval, &yylloc) + #else + #define YYLEX yylex(&yylval) + #endif + #endif + + /* If nonreentrant, generate the variables here */ + + #ifndef YYPURE + + int yychar; /* the lookahead symbol */ + YYSTYPE yylval; /* the semantic value of the */ + /* lookahead symbol */ + + #ifdef YYLSP_NEEDED + YYLTYPE yylloc; /* location data for the lookahead */ + /* symbol */ + #endif + + int yynerrs; /* number of parse errors so far */ + #endif /* not YYPURE */ + + #if YYDEBUG != 0 + int yydebug; /* nonzero means print parse trace */ + /* Since this is uninitialized, it does not stop multiple parsers + from coexisting. */ + #endif + + /* YYINITDEPTH indicates the initial size of the parser's stacks */ + + #ifndef YYINITDEPTH + #define YYINITDEPTH 200 + #endif + + /* YYMAXDEPTH is the maximum size the stacks can grow to + (effective only if the built-in stack extension method is used). */ + + #if YYMAXDEPTH == 0 + #undef YYMAXDEPTH + #endif + + #ifndef YYMAXDEPTH + #define YYMAXDEPTH 10000 + #endif + + #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ + #define __yy_bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) + #else /* not GNU C or C++ */ + #ifndef __cplusplus + + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void + __yy_bcopy (from, to, count) + char *from; + char *to; + int count; + { + register char *f = from; + register char *t = to; + register int i = count; + + while (i-- > 0) + *t++ = *f++; + } + + #else /* __cplusplus */ + + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void + __yy_bcopy (char *from, char *to, int count) + { + register char *f = from; + register char *t = to; + register int i = count; + + while (i-- > 0) + *t++ = *f++; + } + + #endif + #endif + + #line 169 "bison.simple" + int + yyparse() + { + register int yystate; + register int yyn; + register short *yyssp; + register YYSTYPE *yyvsp; + int yyerrstatus; /* number of tokens to shift before error messages enabled */ + int yychar1; /* lookahead token as an internal (translated) token number */ + + short yyssa[YYINITDEPTH]; /* the state stack */ + YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ + + short *yyss = yyssa; /* refer to the stacks thru separate pointers */ + YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ + + #ifdef YYLSP_NEEDED + YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ + YYLTYPE *yyls = yylsa; + YYLTYPE *yylsp; + + #define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) + #else + #define YYPOPSTACK (yyvsp--, yyssp--) + #endif + + int yystacksize = YYINITDEPTH; + + #ifdef YYPURE + int yychar; + YYSTYPE yylval; + int yynerrs; + #ifdef YYLSP_NEEDED + YYLTYPE yylloc; + #endif + #endif + + YYSTYPE yyval; /* the variable used to return */ + /* semantic values from the action */ + /* routines */ + + int yylen; + + #if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Starting parse\n"); + #endif + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. */ + + yyssp = yyss - 1; + yyvsp = yyvs; + #ifdef YYLSP_NEEDED + yylsp = yyls; + #endif + + /* Push a new state, which is found in yystate . */ + /* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. */ + yynewstate: + + *++yyssp = yystate; + + if (yyssp >= yyss + yystacksize - 1) + { + /* Give user a chance to reallocate the stack */ + /* Use copies of these so that the &'s don't force the real ones into memory. */ + YYSTYPE *yyvs1 = yyvs; + short *yyss1 = yyss; + #ifdef YYLSP_NEEDED + YYLTYPE *yyls1 = yyls; + #endif + + /* Get the current used size of the three stacks, in elements. */ + int size = yyssp - yyss + 1; + + #ifdef yyoverflow + /* Each stack pointer address is followed by the size of + the data in use in that stack, in bytes. */ + yyoverflow("parser stack overflow", + &yyss1, size * sizeof (*yyssp), + &yyvs1, size * sizeof (*yyvsp), + #ifdef YYLSP_NEEDED + &yyls1, size * sizeof (*yylsp), + #endif + &yystacksize); + + yyss = yyss1; yyvs = yyvs1; + #ifdef YYLSP_NEEDED + yyls = yyls1; + #endif + #else /* no yyoverflow */ + /* Extend the stack our own way. */ + if (yystacksize >= YYMAXDEPTH) + { + yyerror("parser stack overflow"); + return 2; + } + yystacksize *= 2; + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); + __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); + __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); + #ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); + __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); + #endif + #endif /* no yyoverflow */ + + yyssp = yyss + size - 1; + yyvsp = yyvs + size - 1; + #ifdef YYLSP_NEEDED + yylsp = yyls + size - 1; + #endif + + #if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Stack size increased to %d\n", yystacksize); + #endif + + if (yyssp >= yyss + yystacksize - 1) + YYABORT; + } + + #if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Entering state %d\n", yystate); + #endif + + yybackup: + + /* Do appropriate processing given the current state. */ + /* Read a lookahead token if we need one and don't already have one. */ + /* yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* yychar is either YYEMPTY or YYEOF + or a valid token in external form. */ + + if (yychar == YYEMPTY) + { + #if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Reading a token: "); + #endif + yychar = YYLEX; + } + + /* Convert token to internal form (in yychar1) for indexing tables with */ + + if (yychar <= 0) /* This means end of input. */ + { + yychar1 = 0; + yychar = YYEOF; /* Don't call YYLEX any more */ + + #if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Now at end of input.\n"); + #endif + } + else + { + yychar1 = YYTRANSLATE(yychar); + + #if YYDEBUG != 0 + if (yydebug) + { + fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); + /* Give the individual parser a way to print the precise meaning + of a token, for further debugging info. */ + #ifdef YYPRINT + YYPRINT (stderr, yychar, yylval); + #endif + fprintf (stderr, ")\n"); + } + #endif + } + + yyn += yychar1; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) + goto yydefault; + + yyn = yytable[yyn]; + + /* yyn is what to do for this token type in this state. + Negative => reduce, -yyn is rule number. + Positive => shift, yyn is new state. + New state is final state => don't bother to shift, + just return success. + 0, or most negative number => error. */ + + if (yyn < 0) + { + if (yyn == YYFLAG) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + else if (yyn == 0) + goto yyerrlab; + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + + #if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); + #endif + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; + #ifdef YYLSP_NEEDED + *++yylsp = yylloc; + #endif + + /* count tokens shifted since error; after three, turn off error status. */ + if (yyerrstatus) yyerrstatus--; + + yystate = yyn; + goto yynewstate; + + /* Do the default action for the current state. */ + yydefault: + + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + + /* Do a reduction. yyn is the number of a rule to reduce with. */ + yyreduce: + yylen = yyr2[yyn]; + yyval = yyvsp[1-yylen]; /* implement default value of the action */ + + #if YYDEBUG != 0 + if (yydebug) + { + int i; + + fprintf (stderr, "Reducing via rule %d (line %d), ", + yyn, yyrline[yyn]); + + /* Print the symboles being reduced, and their result. */ + for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) + fprintf (stderr, "%s ", yytname[yyrhs[i]]); + fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); + } + #endif + + + switch (yyn) { + + case 1: + #line 61 "bi-parser.y" + { defs = yyvsp[0].def; ; + break;} + case 3: + #line 67 "bi-parser.y" + { yyvsp[0].def->next = yyvsp[-1].def; yyval.def = yyvsp[0].def; ; + break;} + case 4: + #line 72 "bi-parser.y" + { yyval.def = makedef (yyvsp[-7].string, yyvsp[-5].string, yyvsp[-2].variation); ; + break;} + case 6: + #line 78 "bi-parser.y" + { yyvsp[0].variation->next = yyvsp[-2].variation; yyval.variation = yyvsp[0].variation; ; + break;} + case 7: + #line 83 "bi-parser.y" + { yyval.variation = makevar (yyvsp[-1].string, (struct node *) NULL, (struct node *) NULL, (struct node *) NULL); ; + break;} + case 8: + #line 85 "bi-parser.y" + { yyval.variation = makevar (yyvsp[-3].string, yyvsp[-1].node, (struct node *) NULL, (struct node *) NULL); ; + break;} + case 9: + #line 87 "bi-parser.y" + { yyval.variation = makevar (yyvsp[-5].string, yyvsp[-3].node, yyvsp[-1].node, (struct node *) NULL); ; + break;} + case 10: + #line 89 "bi-parser.y" + { yyval.variation = makevar (yyvsp[-7].string, yyvsp[-5].node, yyvsp[-3].node, yyvsp[-1].node); ; + break;} + case 11: + #line 93 "bi-parser.y" + { yyval.string = ""; ; + break;} + case 12: + #line 94 "bi-parser.y" + { yyval.string = yyvsp[0].string; ; + break;} + case 13: + #line 99 "bi-parser.y" + { yyval.node = yyvsp[-1].node; ; + break;} + case 14: + #line 101 "bi-parser.y" + { yyval.node = NULL; ; + break;} + case 16: + #line 108 "bi-parser.y" + { yyvsp[-2].node->next = yyvsp[0].node; yyval.node = yyvsp[-2].node; ; + break;} + case 17: + #line 113 "bi-parser.y" + { yyval.node = makenode (yyvsp[0].string); ; + break;} + } + /* the action file gets copied in in place of this dollarsign */ + #line 440 "bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; + #ifdef YYLSP_NEEDED + yylsp -= yylen; + #endif + + #if YYDEBUG != 0 + if (yydebug) + { + short *ssp1 = yyss - 1; + fprintf (stderr, "state stack now"); + while (ssp1 != yyssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } + #endif + + *++yyvsp = yyval; + + #ifdef YYLSP_NEEDED + yylsp++; + if (yylen == 0) + { + yylsp->first_line = yylloc.first_line; + yylsp->first_column = yylloc.first_column; + yylsp->last_line = (yylsp-1)->last_line; + yylsp->last_column = (yylsp-1)->last_column; + yylsp->text = 0; + } + else + { + yylsp->last_line = (yylsp+yylen-1)->last_line; + yylsp->last_column = (yylsp+yylen-1)->last_column; + } + #endif + + /* Now "shift" the result of the reduction. + Determine what state that goes to, + based on the state we popped back to + and the rule number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTBASE] + *yyssp; + if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTBASE]; + + goto yynewstate; + + yyerrlab: /* here on detecting error */ + + if (! yyerrstatus) + /* If not already recovering from an error, report this error. */ + { + ++yynerrs; + + #ifdef YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (yyn > YYFLAG && yyn < YYLAST) + { + int size = 0; + char *msg; + int x, count; + + count = 0; + for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++) + if (yycheck[x + yyn] == x) + size += strlen(yytname[x]) + 15, count++; + msg = (char *) malloc(size + 15); + if (msg != 0) + { + strcpy(msg, "parse error"); + + if (count < 5) + { + count = 0; + for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++) + if (yycheck[x + yyn] == x) + { + strcat(msg, count == 0 ? ", expecting `" : " or `"); + strcat(msg, yytname[x]); + strcat(msg, "'"); + count++; + } + } + yyerror(msg); + free(msg); + } + else + yyerror ("parse error; also virtual memory exceeded"); + } + else + #endif /* YYERROR_VERBOSE */ + yyerror("parse error"); + } + + yyerrlab1: /* here on error raised explicitly by an action */ + + if (yyerrstatus == 3) + { + /* if just tried and failed to reuse lookahead token after an error, discard it. */ + + /* return failure if at end of input */ + if (yychar == YYEOF) + YYABORT; + + #if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); + #endif + + yychar = YYEMPTY; + } + + /* Else will try to reuse lookahead token + after shifting the error token. */ + + yyerrstatus = 3; /* Each real token shifted decrements this */ + + goto yyerrhandle; + + yyerrdefault: /* current state does not do anything special for the error token. */ + + #if 0 + /* This is wrong; only states that explicitly want error tokens + should shift them. */ + yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ + if (yyn) goto yydefault; + #endif + + yyerrpop: /* pop the current state because it cannot handle the error token */ + + if (yyssp == yyss) YYABORT; + yyvsp--; + yystate = *--yyssp; + #ifdef YYLSP_NEEDED + yylsp--; + #endif + + #if YYDEBUG != 0 + if (yydebug) + { + short *ssp1 = yyss - 1; + fprintf (stderr, "Error: state stack now"); + while (ssp1 != yyssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } + #endif + + yyerrhandle: + + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yyerrdefault; + + yyn += YYTERROR; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) + goto yyerrdefault; + + yyn = yytable[yyn]; + if (yyn < 0) + { + if (yyn == YYFLAG) + goto yyerrpop; + yyn = -yyn; + goto yyreduce; + } + else if (yyn == 0) + goto yyerrpop; + + if (yyn == YYFINAL) + YYACCEPT; + + #if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Shifting error token, "); + #endif + + *++yyvsp = yylval; + #ifdef YYLSP_NEEDED + *++yylsp = yylloc; + #endif + + yystate = yyn; + goto yynewstate; + } + #line 116 "bi-parser.y" + + + static struct node * + makenode (s) + char *s; + { + struct node *n; + + n = (struct node *) malloc (sizeof (struct node)); + n->text = s; + n->next = NULL; + return n; + } + + static struct variation * + makevar (name, inputs, outputs, literals) + char *name; + struct node *inputs, *outputs, *literals; + { + struct variation *v; + + v = (struct variation *) malloc (sizeof (struct variation)); + v->name = name; + v->code = ndefs++; + v->inputs = inputs; + v->outputs = outputs; + v->literals = literals; + v->next = NULL; + return v; + } + + static struct def * + makedef (name, template, vars) + char *name, *template; + struct variation *vars; + { + struct def *d; + + d = (struct def *) malloc (sizeof (struct def)); + d->basename = name; + d->template = template; + d->variations = vars; + d->next = NULL; + return d; + } + + void + yyerror (s) + char *s; + { + fprintf (stderr, "syntax error in input\n"); + exit (1); + } diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/bi-parser.h gcc-2.5.0/bi-parser.h *** gcc-2.4.5/bi-parser.h --- gcc-2.5.0/bi-parser.h Wed Oct 6 16:33:40 1993 *************** *** 0 **** --- 1,12 ---- + typedef union + { + char *string; + struct def *def; + struct variation *variation; + struct node *node; + } YYSTYPE; + #define DEFOP 258 + #define STRING 259 + + + extern YYSTYPE yylval; diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/bi-parser.y gcc-2.5.0/bi-parser.y *** gcc-2.4.5/bi-parser.y --- gcc-2.5.0/bi-parser.y Wed Oct 6 12:10:06 1993 *************** *** 0 **** --- 1,168 ---- + /* Bytecode definition file parser. + Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + + %{ + + #include + #include "hconfig.h" + #include "bi-defs.h" + + extern char yytext[]; + extern int yyleng; + + + /* Chain of all defs built by the parser. */ + struct def *defs; + int ndefs; + + static struct node *makenode (); + static struct variation *makevar (); + static struct def *makedef (); + + void yyerror (); + + %} + + %union + { + char *string; + struct def *def; + struct variation *variation; + struct node *node; + } + + %token DEFOP STRING + %type opt_string + %type defs def + %type variations variation + %type list items item + + %% + + top: + defs + { defs = $1; } + ; + + defs: + def + | defs def + { $2->next = $1; $$ = $2; } + ; + + def: + DEFOP '(' STRING ',' opt_string ',' '(' variations ')' ')' + { $$ = makedef ($3, $5, $8); } + ; + + variations: + variation + | variations ',' variation + { $3->next = $1; $$ = $3; } + ; + + variation: + '(' opt_string ')' + { $$ = makevar ($2, (struct node *) NULL, (struct node *) NULL, (struct node *) NULL); } + | '(' opt_string ',' list ')' + { $$ = makevar ($2, $4, (struct node *) NULL, (struct node *) NULL); } + | '(' opt_string ',' list ',' list ')' + { $$ = makevar ($2, $4, $6, (struct node *) NULL); } + | '(' opt_string ',' list ',' list ',' list ')' + { $$ = makevar ($2, $4, $6, $8); } + ; + + opt_string: + /* empty */ { $$ = ""; } + | STRING { $$ = $1; } + ; + + list: + '(' items ')' + { $$ = $2; } + | /* empty */ + { $$ = NULL; } + ; + + items: + item + /* Note right recursion. */ + | item ',' items + { $1->next = $3; $$ = $1; } + ; + + item: + STRING + { $$ = makenode ($1); } + ; + + %% + + static struct node * + makenode (s) + char *s; + { + struct node *n; + + n = (struct node *) malloc (sizeof (struct node)); + n->text = s; + n->next = NULL; + return n; + } + + static struct variation * + makevar (name, inputs, outputs, literals) + char *name; + struct node *inputs, *outputs, *literals; + { + struct variation *v; + + v = (struct variation *) malloc (sizeof (struct variation)); + v->name = name; + v->code = ndefs++; + v->inputs = inputs; + v->outputs = outputs; + v->literals = literals; + v->next = NULL; + return v; + } + + static struct def * + makedef (name, template, vars) + char *name, *template; + struct variation *vars; + { + struct def *d; + + d = (struct def *) malloc (sizeof (struct def)); + d->basename = name; + d->template = template; + d->variations = vars; + d->next = NULL; + return d; + } + + void + yyerror (s) + char *s; + { + fprintf (stderr, "syntax error in input\n"); + exit (1); + } diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/bi-reverse.c gcc-2.5.0/bi-reverse.c *** gcc-2.4.5/bi-reverse.c --- gcc-2.5.0/bi-reverse.c Wed Oct 13 11:55:58 1993 *************** *** 0 **** --- 1,60 ---- + /* Reverse order of definitions obtained from bytecode definition file. + Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + + #include "hconfig.h" + #include "bi-defs.h" + + void + reverse() + { + struct def *dp, *d, *dn; + struct variation *vp, *v, *vn; + + dp = defs; + if (dp) + { + vp = dp->variations; + if (vp) + { + for (v = vp->next, vp->next = 0; v; vp = v, v = vn) + { + vn = v->next; + v->next = vp; + } + dp->variations = vp; + } + for (d = dp->next, dp->next = 0; d; dp = d, d = dn) + { + vp = d->variations; + if (vp) + { + for (v = vp->next, vp->next = 0; v; vp = v, v = vn) + { + vn = v->next; + v->next = vp; + } + d->variations = vp; + } + dn = d->next; + d->next = dp; + } + defs = dp; + } + } diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/bi-run.h gcc-2.5.0/bi-run.h *** gcc-2.4.5/bi-run.h --- gcc-2.5.0/bi-run.h Wed Sep 22 16:27:46 1993 *************** *** 0 **** --- 1,165 ---- + /* Definitions for Bytecode Interpreter. + Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + #define MAXLITERALS 5 + + struct arityvec + { + char ninputs; + char noutputs; + char nliterals; + char literals[MAXLITERALS]; + }; + + struct argtype + { + int modealign; /* Argument mode:alignment */ + int size; /* Argument size, in bytes */ + }; + + struct callinfo + { + int nargs; /* Number of arguments in call */ + struct argtype retvaltype; /* Type of return value */ + struct argtype argtypes[1]; /* Argument types */ + }; + + /* Structure describing a bytecode function. If this changes, we also + need to change expand_function_end () in bc-trans.c */ + struct bytecode + { + int stacksize; /* Depth required of evaluation stack. */ + int localsize; /* Size in bytes of local variables. */ + unsigned char *pc0; /* Initial program counter. */ + void **ptrlit; /* Vector of (relocatable) pointer literals. */ + struct callinfo *callinfo; /* Vector of procedure call type info. */ + }; + + + #define INTERP_BPC 8 /* Bits per char */ + #define INTERP_BPI \ + (sizeof (int) * INTERP_BPC) /* Bits per int */ + + + #ifndef min + #define min(L, R) ((L) < (R) ? (L) : (R)) + #endif + + + /* bit field operations. */ + + /* Low (high) mask: int with low (high) N bits set */ + + #define LM(N) ((1 << (N)) - 1) + #define HM(N) ((~LM (INTERP_BPI - (N)))) + + + /* Sign-extend SIZE low bits of VALUE to integer (typeof VALUE) + Signed bitfields are loaded from memory by the sxloadBI instruction, + which first retrieves the bitfield with XFIELD and then sign extends + it to an SItype. */ + + #define EXTEND(SIZE, VALUE) \ + ({ SUtype value = (SUtype) (VALUE); \ + (value & (1 << ((SIZE) - 1)) ? value | ~LM (SIZE) : value); }) + + + /* Given OFFSET:SIZE for a bitfield, calculate: + + [1] BYTE_OFFSET = the byte offset of the bit field. + [2] BIT_OFFSET = the bit offset of the bit field (less than INTERP_BPC). + [3] NBYTES = the number of integral bytes in the bit field. + [4] TRAILING_BITS= the number of trailing bits (less than INTERP_BPC). + + + , , , , , (memory bytes) + ---------------- (bitfield) + | | || | | (divisions) + ^ ^ ^ ^ + | | | |__ [4] (bits) + | | |_________ [3] (bytes) + | |_________________ [2] (bits) + |___________________________ [1] (bytes) + + + The above applies to BYTE_LOW_ENDIAN machines. In BYTE_BIG_ENDIAN machines, the + bit numbering is reversed (i.e. bit 0 is the sign bit). + + (Alright, so I drew this to keep my tongue in cheek while writing the code below, + not because I'm into ASCII art.) */ + + + #define BI_PARAMS(OFFSET, SIZE, BYTE_OFFSET, BIT_OFFSET, NBYTES, TRAILING_BITS) \ + { BYTE_OFFSET = (OFFSET) / (INTERP_BPC); \ + BIT_OFFSET = (OFFSET) % (INTERP_BPC); \ + NBYTES = ((SIZE) - (INTERP_BPC - (BIT_OFFSET))) / INTERP_BPC; \ + if ((NBYTES) < 0 || ((NBYTES) > 64)) \ + NBYTES = 0; \ + if ((SIZE) + (BIT_OFFSET) <= INTERP_BPC) \ + TRAILING_BITS = 0; \ + else \ + TRAILING_BITS = ((SIZE) - (INTERP_BPC - (BIT_OFFSET))) % INTERP_BPC; } + + + /* SHIFT_IN_BITS retrieves NBITS bits from SOURCE and shifts into + DEST. The bit field starts OFFSET bits into SOURCE. + + OR_IN_BITS copies the NBITS low bits from VALUE into a the bitfield in + DEST offset by OFFSET bits. */ + + + #ifdef BYTES_BIG_ENDIAN + + #define SHIFT_IN_BITS(DEST, SOURCE, OFFSET, NBITS) \ + (DEST = ((DEST) << (NBITS)) \ + | (LM ((NBITS)) \ + & ((SOURCE) >> (INTERP_BPC - (OFFSET) - (NBITS))))) + + #define OR_IN_BITS(DEST, VALUE, OFFSET, NBITS) \ + (DEST = ((DEST) & ~(LM ((NBITS)) << (INTERP_BPC - (OFFSET) - (NBITS)))) \ + | (((VALUE) & LM ((NBITS))) << (INTERP_BPC - (OFFSET) - (NBITS)))) + + #else + + #define SHIFT_IN_BITS(DEST, SOURCE, OFFSET, NBITS) \ + (DEST = ((DEST) << (NBITS)) \ + | (LM ((NBITS)) \ + & ((SOURCE) >> (OFFSET)))) + + #define OR_IN_BITS(DEST, VALUE, OFFSET, NBITS) \ + (DEST = ((DEST) & ~(LM ((NBITS)) << (OFFSET))) \ + | (((VALUE) & LM ((NBITS))) << (OFFSET))) + + #endif + + + /* Procedure call; arguments are a pointer to the function to be called, + a pointer to a place to store the return value, a pointer to a vector + describing the type of procedure call, and the interpreter's stack pointer, + which will point to the first of the arguments at this point. */ + + #define CALL(FUNC, CALLDESC, RETVAL, SP) __call(FUNC, CALLDESC, RETVAL, SP) + + + /* Procedure return; arguments are a pointer to the calldesc for this + function, and a pointer to the place where the value to be returned + may be found. Generally the MACHARGS above contain a machine dependent + cookie that is used to determine where to jump to. */ + + #define PROCRET(CALLDESC, RETVAL) return diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/bytecode.def gcc-2.5.0/bytecode.def *** gcc-2.4.5/bytecode.def --- gcc-2.5.0/bytecode.def Wed Sep 22 13:46:33 1993 *************** *** 0 **** --- 1,322 ---- + # -*- C -*- + # bytecode.def - definitions of bytecodes for the stack machine. + + # The production of the bytecode interpreter and compiler is + # heavily automated by using this file creatively. + + # Various elementary data types are understood by the bytecode interpreter. + # Q[IU] - quarter word (byte) signed and unsigned integers (char). + # H[IU] - half word signed and unsigned integers (short int, maybe int). + # S[IU] - single word signed and unsigned integers (maybe int, long int). + # D[IU] - double word signed and unsigned integers (long long int). + # SF - single precision floating point (float). + # DF - double precision floating point (double). + # XF - extended precision floating point (long double). + # P - pointer type for address arithmetic and other purposes. + + # The bytecode specification consists of a series of define_operator + # forms, that are parsed by preprocessors to automatically build + # various switch statements. + # define_operator(name, + # , + # ) + # The is self explanatory. + # The consists of a (parenthesized list) of + # variation items, each of which is in itself a list. A variation + # item consists of a name suffix, the types of the input arguments + # expected on the stack (shallowest item first) and (optionally) the + # types of the output arguments (similarly ordered). Finally, the + # types of the literal arguments (if any) may appear. + + # Substitution in the C prototype code is as follows: + # Substitution happens only after a dollar sign. To get a literal + # dollar sign (why would you ever want one anyway?) use $$. + # $R1 means "result 1" $TR1 means "type name of result one" + # $S1 means "source 1" and similarly with $TS1. + # $L1 means "literal (inline) argument 1" and $TL1 means type thereof. + # + + # Notice that the number following $R doesn't affect the push order; + # it's used only for clarity and orthogonality, although it's checked + # to make sure it doesn't exceed the number of outputs. A $R reference + # results in a push, and represents the result lvalue. E.g. + + # $R1 = 2\, $R2 = 17 + # will expand to: + # INTERP_PUSH($TR1) = 2, INTERP_PUSH($TR2) = 17 + # + + # Opcode 0 should never happen. + define_operator(neverneverland, abort\(\), (())) + + # Stack manipulations. + define_operator(drop, 0, ((, (SI)))) + define_operator(dup, 0, ((, (SI), (SI, SI)))) + define_operator(over, 0, ((, (SI), (SI, SI)))) + + # Adjust stack pointer + + define_operator(setstack, 0, ((SI,,,(SI)))) + define_operator(adjstack, 0, ((SI,,,(SI)))) + + # Constants, loads, and stores. + define_operator(const, + $R1 = $L1, + ((QI,, (QI), (QI)), (HI,, (HI), (HI)), + (SI,, (SI), (SI)), (DI,, (DI), (DI)), + (SF,, (SF), (SF)), (DF,, (DF), (DF)), + (XF,, (XF), (XF)), (P,, (P), (P)))) + define_operator(load, + $R1 = *\($TR1 *\) $S1, + ((QI, (P), (QI)), (HI, (P), (HI)), + (SI, (P), (SI)), (DI, (P), (DI)), + (SF, (P), (SF)), (DF, (P), (DF)), + (XF, (P), (XF)), (P, (P), (P)))) + define_operator(store, + *\($TS2 *\) $S1 = $S2, + ((QI, (P, QI)), (HI, (P, HI)), + (SI, (P, SI)), (DI, (P, DI)), + (SF, (P, SF)), (DF, (P, DF)), + (XF, (P, XF)), (P, (P, P)), + (BLK, (SI, BLK, BLK)))) + + # Clear memory block + + define_operator(clear, $S1 + $S2, ((BLK, (SI, BLK)))) + + + # Advance pointer by SI constant + + define_operator(addconst, $R1 = $S1, ((PSI, (P), (P), (SI)))) + + + # newlocalSI is used for creating variable-sized storage during function + # initialization. + + # Create local space, return pointer to block + + define_operator(newlocal, $R1 = $S1, ((SI, (SI), (P)))) + + + # Push the address of a local variable. + define_operator(local, $R1 = locals + $L1, ((P,, (P), (SI)))) + + # Push the address of an argument variable. + define_operator(arg, $R1 = args + $L1, ((P,, (P), (SI)))) + + # Arithmetic conversions. + define_operator(convert, + $R1 = \($TR1\) $S1, + (# Signed integral promotions (sign extensions). + (QIHI, (QI), (HI)), (HISI, (HI), (SI)), (SIDI, (SI), (DI)), + (QISI, (QI), (SI)), + # Unsigned integral promotions (zero extensions). + (QUHU, (QU), (HU)), (HUSU, (HU), (SU)), (SUDU, (SU), (DU)), + (QUSU, (QU), (SU)), + # Floating promotions. + (SFDF, (SF), (DF)), (DFXF, (DF), (XF)), + # Integral truncation. + (HIQI, (HI), (QI)), (SIHI, (SI), (HI)), (DISI, (DI), (SI)), + (SIQI, (SI), (QI)), + # Unsigned truncation. + (SUQU, (SU), (QU)), + # Floating truncation. + (DFSF, (DF), (SF)), (XFDF, (XF), (DF)), + # Integral conversions to floating types. + (SISF, (SI), (SF)), (SIDF, (SI), (DF)), (SIXF, (SI), (XF)), + (SUSF, (SU), (SF)), (SUDF, (SU), (DF)), (SUXF, (SU), (XF)), + (DISF, (DI), (SF)), (DIDF, (DI), (DF)), (DIXF, (DI), (XF)), + (DUSF, (DU), (SF)), (DUDF, (DU), (DF)), (DUXF, (DU), (XF)), + # Floating conversions to integral types. + (SFSI, (SF), (SI)), (DFSI, (DF), (SI)), (XFSI, (XF), (SI)), + (SFSU, (SF), (SU)), (DFSU, (DF), (SU)), (XFSU, (XF), (SU)), + (SFDI, (SF), (DI)), (DFDI, (DF), (DI)), (XFDI, (XF), (DI)), + (SFDU, (SF), (DU)), (DFDU, (DF), (DU)), (XFDU, (XF), (DU)), + # Pointer/integer conversions. + (PSI, (P), (SI)), (SIP, (SI), (P)))) + + # Truth value conversion. These are necessary because conversions of, e.g., + # floating types to integers may not function correctly for large values. + define_operator(convert, + $R1 = !!$S1, + ((SIT, (SI), (T)), (DIT, (DI), (T)), + (SFT, (SF), (T)), (DFT, (DF), (T)), + (XFT, (XF), (T)), (PT, (P), (T)))) + + # Bit field load/store. + + # Load and zero-extend bitfield + + define_operator(zxload, $R1 = $S1, ((BI, (SU, SU, P), (SU)))) + + # Load and sign-extend bitfield + + define_operator(sxload, $R1 = $S1, ((BI, (SU, SU, P), (SI)))) + + # Store integer in bitfield + + define_operator(sstore, $R1 = $S1, ((BI, (SU, SU, P, SI)))) + + + # Binary operations. + define_operator(add, + $R1 = $S1 + $S2, + ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)), + (SF, (SF, SF), (SF)), (DF, (DF, DF), (DF)), + (XF, (XF, XF), (XF)), + (PSI, (P, SI), (P)))) + define_operator(sub, + $R1 = $S1 - $S2, + ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)), + (SF, (SF, SF), (SF)), (DF, (DF, DF), (DF)), + (XF, (XF, XF), (XF)), + (PP, (P, P), (SI)))) + define_operator(mul, + $R1 = $S1 * $S2, + ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)), + (SU, (SU, SU), (SU)), (DU, (DU, DU), (DU)), + (SF, (SF, SF), (SF)), (DF, (DF, DF), (DF)), + (XF, (XF, XF), (XF)))) + define_operator(div, + $R1 = $S1 / $S2, + ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)), + (SU, (SU, SU), (SU)), (DU, (DU, DU), (DU)), + (SF, (SF, SF), (SF)), (DF, (DF, DF), (DF)), + (XF, (XF, XF), (XF)))) + define_operator(mod, + $R1 = $S1 % $S2, + ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)), + (SU, (SU, SU), (SU)), (DU, (DU, DU), (DU)))) + define_operator(and, + $R1 = $S1 & $S2, + ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)))) + define_operator(ior, + $R1 = $S1 | $S2, + ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)))) + define_operator(xor, + $R1 = $S1 ^ $S2, + ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)))) + define_operator(lshift, + $R1 = $S1 << $S2, + ((SI, (SI, SI), (SI)), (SU, (SU, SI), (SU)), + (DI, (DI, SI), (DI)), (DU, (DU, SI), (DU)))) + define_operator(rshift, + $R1 = $S1 >> $S2, + ((SI, (SI, SI), (SI)), (SU, (SU, SI), (SU)), + (DI, (DI, SI), (DI)), (DU, (DU, SI), (DU)))) + define_operator(lt, + $R1 = $S1 < $S2, + ((SI, (SI, SI), (T)), (SU, (SU, SU), (T)), + (DI, (DI, DI), (T)), (DU, (DU, DU), (T)), + (SF, (SF, SF), (T)), (DF, (DF, DF), (T)), + (XF, (XF, XF), (T)), (P, (P, P), (T)))) + define_operator(le, + $R1 = $S1 <= $S2, + ((SI, (SI, SI), (T)), (SU, (SU, SU), (T)), + (DI, (DI, DI), (T)), (DU, (DU, DU), (T)), + (SF, (SF, SF), (T)), (DF, (DF, DF), (T)), + (XF, (XF, XF), (T)), (P, (P, P), (T)))) + define_operator(ge, + $R1 = $S1 >= $S2, + ((SI, (SI, SI), (T)), (SU, (SU, SU), (T)), + (DI, (DI, DI), (T)), (DU, (DU, DU), (T)), + (SF, (SF, SF), (T)), (DF, (DF, DF), (T)), + (XF, (XF, XF), (T)), (P, (P, P), (T)))) + define_operator(gt, + $R1 = $S1 > $S2, + ((SI, (SI, SI), (T)), (SU, (SU, SU), (T)), + (DI, (DI, DI), (T)), (DU, (DU, DU), (T)), + (SF, (SF, SF), (T)), (DF, (DF, DF), (T)), + (XF, (XF, XF), (T)), (P, (P, P), (T)))) + define_operator(eq, + $R1 = $S1 == $S2, + ((SI, (SI, SI), (T)), (DI, (DI, DI), (T)), + (SF, (SF, SF), (T)), (DF, (DF, DF), (T)), + (XF, (XF, XF), (T)), (P, (P, P), (T)))) + define_operator(ne, + $R1 = $S1 != $S2, + ((SI, (SI, SI), (T)), (DI, (DI, DI), (T)), + (SF, (SF, SF), (T)), (DF, (DF, DF), (T)), + (XF, (XF, XF), (T)), (P, (P, P), (T)))) + + # Unary operations. + define_operator(neg, + $R1 = -$S1, + ((SI, (SI), (SI)), (DI, (DI), (DI)), + (SF, (SF), (SF)), (DF, (DF), (DF)), + (XF, (XF), (XF)))) + define_operator(not, + $R1 = ~$S1, + ((SI, (SI), (SI)), (DI, (DI), (DI)))) + define_operator(not, + $R1 = !$S1, + ((T, (SI), (SI)))) + + # Increment operations. + define_operator(predec, + $R1 = *\($TR1 *\) $S1 -= $S2, + ((QI, (P, QI), (QI)), (HI, (P, HI), (HI)), + (SI, (P, SI), (SI)), (DI, (P, DI), (DI)), + (P, (P, SI), (P)), (SF, (P, SF), (SF)), + (DF, (P, DF), (DF)), (XF, (P, XF), (XF)), + (BI, (SU, SU, P, SI), (SI)))) + + define_operator(preinc, + $R1 = *\($TR1 *\) $S1 += $S2, + ((QI, (P, QI), (QI)), (HI, (P, HI), (HI)), + (SI, (P, SI), (SI)), (DI, (P, DI), (DI)), + (P, (P, SI), (P)), (SF, (P, SF), (SF)), + (DF, (P, DF), (DF)), (XF, (P, XF), (XF)), + (BI, (SU, SU, P, SI), (SI)))) + + define_operator(postdec, + $R1 = *\($TR1 *\) $S1\, *\($TR1 *\) $S1 -= $S2, + ((QI, (P, QI), (QI)), (HI, (P, HI), (HI)), + (SI, (P, SI), (SI)), (DI, (P, DI), (DI)), + (P, (P, SI), (P)), (SF, (P, SF), (SF)), + (DF, (P, DF), (DF)), (XF, (P, XF), (XF)), + (BI, (SU, SU, P, SI), (SI)))) + + define_operator(postinc, + $R1 = *\($TR1 *\) $S1\, *\($TR1 *\) $S1 += $S2, + ((QI, (P, QI), (QI)), (HI, (P, HI), (HI)), + (SI, (P, SI), (SI)), (DI, (P, DI), (DI)), + (P, (P, SI), (P)), (SF, (P, SF), (SF)), + (DF, (P, DF), (DF)), (XF, (P, XF), (XF)), + (BI, (SU, SU, P, SI), (SI)))) + + # Jumps. + define_operator(xjumpif, if \($S1\) pc = code->pc0 + $L1, ((, (T),, (SI)))) + define_operator(xjumpifnot, if \(! $S1\) pc = code->pc0 + $L1, ((, (T),, (SI)))) + define_operator(jump, pc = code->pc0 + $L1, ((,,,(SI)))) + + # This is for GCC2. It jumps to the address on the stack. + define_operator(jump, pc = \(void *\) $S1, ((P,,))) + + # Switches. In order to (eventually) support ranges we provide four different + # varieties of switches. Arguments are the switch index from the stack, the + # bytecode offset of the switch table, the size of the switch table, and + # the default label. + define_operator(caseSI, CASESI\($S1\, $L1\, $L2\, $L3\), ((, (SI),, (SI, SI, SI)))) + define_operator(caseSU, CASESU\($S1\, $L1\, $L2\, $L3\), ((, (SU),, (SI, SI, SI)))) + define_operator(caseDI, CASEDI\($S1\, $L1\, $L2\, $L3\), ((, (DI),, (SI, SI, SI)))) + define_operator(caseDU, CASEDU\($S1\, $L1\, $L2\, $L3\), ((, (DU),, (SI, SI, SI)))) + + # Procedure call. + # Stack arguments are (deepest first): + # procedure arguments in reverse order. + # pointer to the place to hold the return value. + # address of the call description vector. + # pointer to the procedure to be called. + define_operator(call, CALL\($S1\, $S2\, $S3\, sp\), ((, (P, P, P)))) + + # Procedure return. + # Pushes on interpreter stack: + # value of retptr (pointer to return value storage slot) + define_operator(return, $R1 = retptr, ((P,,(P)))) + + # Really return. + define_operator(ret, return, (())) + + # Print an obnoxious line number. + define_operator(linenote, fprintf\(stderr\, "%d\\n"\, $L1\), ((,,,(SI)))) diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/bytecode.h gcc-2.5.0/bytecode.h *** gcc-2.4.5/bytecode.h --- gcc-2.5.0/bytecode.h Wed Sep 22 16:16:32 1993 *************** *** 0 **** --- 1,91 ---- + /* Bytecode definitions for GNU C-compiler. + Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + + extern int output_bytecode; + extern int stack_depth; + extern int max_stack_depth; + + /* Emit DI constant according to target machine word ordering */ + + #ifdef WORD_HIGH_ENDIAN + + #define bc_emit_bytecode_DI_const(CST) \ + { int opcode; \ + opcode = TREE_INT_CST_HIGH (CST); \ + bc_emit_bytecode_const ((char *) &opcode, sizeof opcode); \ + opcode = TREE_INT_CST_LOW (CST); \ + bc_emit_bytecode_const ((char *) &opcode, sizeof opcode); \ + } + + #else + + #define bc_emit_bytecode_DI_const(CST) \ + { int opcode; \ + opcode = TREE_INT_CST_LOW (CST); \ + bc_emit_bytecode_const ((char *) &opcode, sizeof opcode); \ + opcode = TREE_INT_CST_HIGH (CST); \ + bc_emit_bytecode_const ((char *) &opcode, sizeof opcode); \ + } + + #endif + + + extern void bc_expand_expr (); + extern void bc_output_data_constructor (); + extern void bc_store_field (); + extern void bc_load_bit_field (); + extern void bc_store_bit_field (); + extern void bc_push_offset_and_size (); + extern void bc_init_mode_to_code_map (); + + /* These are just stubs, so the compiler will compile for targets + that aren't yet supported by the bytecode generator. */ + + #ifndef TARGET_SUPPORTS_BYTECODE + + #define MACHINE_SEG_ALIGN 1 + #define INT_ALIGN 1 + #define PTR_ALIGN 1 + #define NAMES_HAVE_UNDERSCORES + #define BC_NOP (0) + #define BC_GLOBALIZE_LABEL(FP, NAME) BC_NOP + #define BC_OUTPUT_COMMON(FP, NAME, SIZE, ROUNDED) BC_NOP + #define BC_OUTPUT_LOCAL(FP, NAME, SIZE, ROUNDED) BC_NOP + #define BC_OUTPUT_ALIGN(FP, ALIGN) BC_NOP + #define BC_OUTPUT_LABEL(FP, NAME) BC_NOP + #define BC_OUTPUT_SKIP(FP, SIZE) BC_NOP + #define BC_OUTPUT_LABELREF(FP, NAME) BC_NOP + #define BC_OUTPUT_FLOAT(FP, VAL) BC_NOP + #define BC_OUTPUT_DOUBLE(FP, VAL) BC_NOP + #define BC_OUTPUT_BYTE(FP, VAL) BC_NOP + #define BC_OUTPUT_FILE ASM_OUTPUT_FILE + #define BC_OUTPUT_ASCII ASM_OUTPUT_ASCII + #define BC_OUTPUT_IDENT ASM_OUTPUT_IDENT + #define BCXSTR(RTX) ((RTX)->bc_label) + #define BC_WRITE_FILE(FP) BC_NOP + #define BC_WRITE_SEGSYM(SEGSYM, FP) BC_NOP + #define BC_WRITE_RELOC_ENTRY(SEGRELOC, FP, OFFSET) BC_NOP + #define BC_START_BYTECODE_LINE(FP) BC_NOP + #define BC_WRITE_BYTECODE(SEP, VAL, FP) BC_NOP + #define BC_WRITE_RTL(R, FP) BC_NOP + #define BC_EMIT_TRAMPOLINE(TRAMPSEG, CALLINFO) BC_NOP + #define VALIDATE_STACK BC_NOP + + #endif /* !TARGET_SUPPORTS_BYTECODE */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/bytetypes.h gcc-2.5.0/bytetypes.h *** gcc-2.4.5/bytetypes.h --- gcc-2.5.0/bytetypes.h Tue Sep 28 20:19:16 1993 *************** *** 0 **** --- 1,35 ---- + /* These should come from genemit */ + + /* Use __signed__ in case compiling with -traditional. */ + + typedef __signed__ char QItype; + typedef unsigned char QUtype; + typedef __signed__ short int HItype; + typedef unsigned short int HUtype; + typedef __signed__ long int SItype; + typedef unsigned long int SUtype; + typedef __signed__ long long int DItype; + typedef unsigned long long int DUtype; + typedef float SFtype; + typedef double DFtype; + typedef long double XFtype; + typedef char *Ptype; + typedef int Ttype; + + + typedef union stacktype + { + QItype QIval; + QUtype QUval; + HItype HIval; + HUtype HUval; + SItype SIval; + SUtype SUval; + DItype DIval; + DUtype DUval; + SFtype SFval; + DFtype DFval; + XFtype XFval; + Ptype Pval; + Ttype Tval; + } stacktype; Only in gcc-2.4.5: c++ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/c-common.c gcc-2.5.0/c-common.c *** gcc-2.4.5/c-common.c Sun Jun 20 13:36:55 1993 --- gcc-2.5.0/c-common.c Wed Oct 20 21:43:23 1993 *************** *** 1,4 **** /* Subroutines shared by all languages that are variants of C. ! Copyright (C) 1992 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,4 ---- /* Subroutines shared by all languages that are variants of C. ! Copyright (C) 1992, 1993 Free Software Foundation, Inc. This file is part of GNU CC. *************** *** 25,31 **** --- 25,34 ---- #include "obstack.h" #include + #include extern struct obstack permanent_obstack; + static void declare_hidden_char_array PROTO((char *, char *)); + /* Make bindings for __FUNCTION__ and __PRETTY_FUNCTION__. */ *************** *** 33,39 **** declare_function_name () { - tree decl, type, init; char *name, *printable_name; - int len; if (current_function_decl == NULL) --- 36,40 ---- *************** *** 55,94 **** } ! /* If the default size of char arrays isn't big enough for the name, ! make a bigger one. */ ! len = strlen (name) + 1; ! type = char_array_type_node; ! if (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TREE_TYPE (char_array_type_node))) ! < len) ! type = build_array_type (char_type_node, ! build_index_type (build_int_2 (len, 0))); ! push_obstacks_nochange (); ! decl = build_decl (VAR_DECL, get_identifier ("__FUNCTION__"), type); ! TREE_STATIC (decl) = 1; ! TREE_READONLY (decl) = 1; ! DECL_SOURCE_LINE (decl) = 0; ! DECL_IN_SYSTEM_HEADER (decl) = 1; ! DECL_IGNORED_P (decl) = 1; ! init = build_string (len, name); ! TREE_TYPE (init) = type; ! DECL_INITIAL (decl) = init; ! finish_decl (pushdecl (decl), init, NULL_TREE); ! len = strlen (printable_name) + 1; type = char_array_type_node; ! if (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TREE_TYPE (char_array_type_node))) ! < len) type = build_array_type (char_type_node, ! build_index_type (build_int_2 (len, 0))); push_obstacks_nochange (); ! decl = build_decl (VAR_DECL, get_identifier ("__PRETTY_FUNCTION__"), type); TREE_STATIC (decl) = 1; TREE_READONLY (decl) = 1; DECL_SOURCE_LINE (decl) = 0; DECL_IN_SYSTEM_HEADER (decl) = 1; DECL_IGNORED_P (decl) = 1; ! init = build_string (len, printable_name); TREE_TYPE (init) = type; DECL_INITIAL (decl) = init; --- 56,87 ---- } ! declare_hidden_char_array ("__FUNCTION__", name); ! declare_hidden_char_array ("__PRETTY_FUNCTION__", printable_name); ! } ! static void ! declare_hidden_char_array (name, value) ! char *name, *value; ! { ! tree decl, type, init; ! int vlen; ! /* If the default size of char arrays isn't big enough for the name, ! make a bigger one. */ ! vlen = strlen (value) + 1; type = char_array_type_node; ! if (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TREE_TYPE (type))) < vlen) type = build_array_type (char_type_node, ! build_index_type (build_int_2 (vlen, 0))); push_obstacks_nochange (); ! decl = build_decl (VAR_DECL, get_identifier (name), type); TREE_STATIC (decl) = 1; TREE_READONLY (decl) = 1; + TREE_ASM_WRITTEN (decl) = 1; DECL_SOURCE_LINE (decl) = 0; DECL_IN_SYSTEM_HEADER (decl) = 1; DECL_IGNORED_P (decl) = 1; ! init = build_string (vlen, value); TREE_TYPE (init) = type; DECL_INITIAL (decl) = init; *************** *** 223,226 **** --- 216,230 ---- used for DECL_REGISTER. It wouldn't mean anything anyway. */ } + else if (TREE_VALUE (a) == get_identifier ("noreturn") + || TREE_VALUE (a) == get_identifier ("volatile")) + { + if (TREE_CODE (decl) == FUNCTION_DECL) + TREE_THIS_VOLATILE (decl) = 1; + } + else if (TREE_VALUE (a) == get_identifier ("const")) + { + if (TREE_CODE (decl) == FUNCTION_DECL) + TREE_READONLY (decl) = 1; + } else if (TREE_VALUE (a) != 0 && TREE_CODE (TREE_VALUE (a)) == TREE_LIST *************** *** 333,342 **** } } ! ! record_format_info (DECL_NAME (decl), is_scan, format_num, ! first_arg_num); } } /* Print a warning if a constant expression had overflow in folding. Invoke this function on every expression that the language --- 337,949 ---- } } ! ! record_function_format (DECL_NAME (decl), DECL_ASSEMBLER_NAME (decl), ! is_scan, format_num, first_arg_num); } } + /* Check a printf/fprintf/sprintf/scanf/fscanf/sscanf format against + a parameter list. */ + + #define T_I &integer_type_node + #define T_L &long_integer_type_node + #define T_S &short_integer_type_node + #define T_UI &unsigned_type_node + #define T_UL &long_unsigned_type_node + #define T_US &short_unsigned_type_node + #define T_F &float_type_node + #define T_D &double_type_node + #define T_LD &long_double_type_node + #define T_C &char_type_node + #define T_V &void_type_node + #define T_W &wchar_type_node + + typedef struct { + char *format_chars; + int pointer_count; + /* Type of argument if no length modifier is used. */ + tree *nolen; + /* Type of argument if length modifier for shortening is used. + If NULL, then this modifier is not allowed. */ + tree *hlen; + /* Type of argument if length modifier `l' is used. + If NULL, then this modifier is not allowed. */ + tree *llen; + /* Type of argument if length modifier `L' is used. + If NULL, then this modifier is not allowed. */ + tree *bigllen; + /* List of other modifier characters allowed with these options. */ + char *flag_chars; + } format_char_info; + + static format_char_info print_char_table[] = { + { "di", 0, T_I, T_I, T_L, NULL, "-wp0 +" }, + { "oxX", 0, T_UI, T_UI, T_UL, NULL, "-wp0#" }, + { "u", 0, T_UI, T_UI, T_UL, NULL, "-wp0" }, + { "feEgG", 0, T_D, NULL, NULL, T_LD, "-wp0 +#" }, + { "c", 0, T_I, NULL, T_W, NULL, "-w" }, + { "C", 0, T_W, NULL, NULL, NULL, "-w" }, + { "s", 1, T_C, NULL, T_W, NULL, "-wp" }, + { "S", 1, T_W, NULL, NULL, NULL, "-wp" }, + { "p", 1, T_V, NULL, NULL, NULL, "-w" }, + { "n", 1, T_I, T_S, T_L, NULL, "" }, + { NULL } + }; + + static format_char_info scan_char_table[] = { + { "di", 1, T_I, T_S, T_L, NULL, "*" }, + { "ouxX", 1, T_UI, T_US, T_UL, NULL, "*" }, + { "efgEG", 1, T_F, NULL, T_D, T_LD, "*" }, + { "sc", 1, T_C, NULL, T_W, NULL, "*" }, + { "[", 1, T_C, NULL, NULL, NULL, "*" }, + { "C", 1, T_W, NULL, NULL, NULL, "*" }, + { "S", 1, T_W, NULL, NULL, NULL, "*" }, + { "p", 2, T_V, NULL, NULL, NULL, "*" }, + { "n", 1, T_I, T_S, T_L, NULL, "" }, + { NULL } + }; + + typedef struct function_format_info { + struct function_format_info *next; /* next structure on the list */ + tree name; /* identifier such as "printf" */ + tree assembler_name; /* optional mangled identifier (for C++) */ + int is_scan; /* TRUE if *scanf */ + int format_num; /* number of format argument */ + int first_arg_num; /* number of first arg (zero for varargs) */ + } function_format_info; + + static function_format_info *function_format_list = NULL; + + static void check_format_info PROTO((function_format_info *, tree)); + + /* Initialize the table of functions to perform format checking on. + The ANSI functions are always checked (whether is + included or not), since it is common to call printf without + including . There shouldn't be a problem with this, + since ANSI reserves these function names whether you include the + header file or not. In any case, the checking is harmless. */ + + void + init_function_format_info () + { + record_function_format (get_identifier ("printf"), NULL_TREE, 0, 1, 2); + record_function_format (get_identifier ("fprintf"), NULL_TREE, 0, 2, 3); + record_function_format (get_identifier ("sprintf"), NULL_TREE, 0, 2, 3); + record_function_format (get_identifier ("scanf"), NULL_TREE, 1, 1, 2); + record_function_format (get_identifier ("fscanf"), NULL_TREE, 1, 2, 3); + record_function_format (get_identifier ("sscanf"), NULL_TREE, 1, 2, 3); + record_function_format (get_identifier ("vprintf"), NULL_TREE, 0, 1, 0); + record_function_format (get_identifier ("vfprintf"), NULL_TREE, 0, 2, 0); + record_function_format (get_identifier ("vsprintf"), NULL_TREE, 0, 2, 0); + } + + /* Record information for argument format checking. FUNCTION_IDENT is + the identifier node for the name of the function to check (its decl + need not exist yet). IS_SCAN is true for scanf-type format checking; + false indicates printf-style format checking. FORMAT_NUM is the number + of the argument which is the format control string (starting from 1). + FIRST_ARG_NUM is the number of the first actual argument to check + against teh format string, or zero if no checking is not be done + (e.g. for varargs such as vfprintf). */ + + void + record_function_format (name, assembler_name, is_scan, + format_num, first_arg_num) + tree name; + tree assembler_name; + int is_scan; + int format_num; + int first_arg_num; + { + function_format_info *info; + + /* Re-use existing structure if it's there. */ + + for (info = function_format_list; info; info = info->next) + { + if (info->name == name && info->assembler_name == assembler_name) + break; + } + if (! info) + { + info = (function_format_info *) xmalloc (sizeof (function_format_info)); + info->next = function_format_list; + function_format_list = info; + + info->name = name; + info->assembler_name = assembler_name; + } + + info->is_scan = is_scan; + info->format_num = format_num; + info->first_arg_num = first_arg_num; + } + + static char tfaff[] = "too few arguments for format"; + + /* Check the argument list of a call to printf, scanf, etc. + NAME is the function identifier. + ASSEMBLER_NAME is the function's assembler identifier. + (Either NAME or ASSEMBLER_NAME, but not both, may be NULL_TREE.) + PARAMS is the list of argument values. */ + + void + check_function_format (name, assembler_name, params) + tree name; + tree assembler_name; + tree params; + { + function_format_info *info; + + /* See if this function is a format function. */ + for (info = function_format_list; info; info = info->next) + { + if (info->assembler_name + ? (info->assembler_name == assembler_name) + : (info->name == name)) + { + /* Yup; check it. */ + check_format_info (info, params); + break; + } + } + } + + /* Check the argument list of a call to printf, scanf, etc. + INFO points to the function_format_info structure. + PARAMS is the list of argument values. */ + + static void + check_format_info (info, params) + function_format_info *info; + tree params; + { + int i; + int arg_num; + int suppressed, wide, precise; + int length_char; + int format_char; + int format_length; + tree format_tree; + tree cur_param; + tree cur_type; + tree wanted_type; + tree first_fillin_param; + char *format_chars; + format_char_info *fci; + static char message[132]; + char flag_chars[8]; + int has_operand_number = 0; + + /* Skip to format argument. If the argument isn't available, there's + no work for us to do; prototype checking will catch the problem. */ + for (arg_num = 1; ; ++arg_num) + { + if (params == 0) + return; + if (arg_num == info->format_num) + break; + params = TREE_CHAIN (params); + } + format_tree = TREE_VALUE (params); + params = TREE_CHAIN (params); + if (format_tree == 0) + return; + /* We can only check the format if it's a string constant. */ + while (TREE_CODE (format_tree) == NOP_EXPR) + format_tree = TREE_OPERAND (format_tree, 0); /* strip coercion */ + if (format_tree == null_pointer_node) + { + warning ("null format string"); + return; + } + if (TREE_CODE (format_tree) != ADDR_EXPR) + return; + format_tree = TREE_OPERAND (format_tree, 0); + if (TREE_CODE (format_tree) != STRING_CST) + return; + format_chars = TREE_STRING_POINTER (format_tree); + format_length = TREE_STRING_LENGTH (format_tree); + if (format_length <= 1) + warning ("zero-length format string"); + if (format_chars[--format_length] != 0) + { + warning ("unterminated format string"); + return; + } + /* Skip to first argument to check. */ + while (arg_num + 1 < info->first_arg_num) + { + if (params == 0) + return; + params = TREE_CHAIN (params); + ++arg_num; + } + + first_fillin_param = params; + while (1) + { + if (*format_chars == 0) + { + if (format_chars - TREE_STRING_POINTER (format_tree) != format_length) + warning ("embedded `\\0' in format"); + if (info->first_arg_num != 0 && params != 0 && ! has_operand_number) + warning ("too many arguments for format"); + return; + } + if (*format_chars++ != '%') + continue; + if (*format_chars == 0) + { + warning ("spurious trailing `%%' in format"); + continue; + } + if (*format_chars == '%') + { + ++format_chars; + continue; + } + flag_chars[0] = 0; + suppressed = wide = precise = FALSE; + if (info->is_scan) + { + suppressed = *format_chars == '*'; + if (suppressed) + ++format_chars; + while (isdigit (*format_chars)) + ++format_chars; + } + else + { + /* See if we have a number followed by a dollar sign. If we do, + it is an operand number, so set PARAMS to that operand. */ + if (*format_chars >= '0' && *format_chars <= '9') + { + char *p = format_chars; + + while (*p >= '0' && *p++ <= '9') + ; + + if (*p == '$') + { + int opnum = atoi (format_chars); + + params = first_fillin_param; + format_chars = p + 1; + has_operand_number = 1; + + for (i = 1; i < opnum && params != 0; i++) + params = TREE_CHAIN (params); + + if (opnum == 0 || params == 0) + { + warning ("operand number out of range in format"); + return; + } + } + } + + while (*format_chars != 0 && index (" +#0-", *format_chars) != 0) + { + if (index (flag_chars, *format_chars) != 0) + { + sprintf (message, "repeated `%c' flag in format", + *format_chars); + warning (message); + } + i = strlen (flag_chars); + flag_chars[i++] = *format_chars++; + flag_chars[i] = 0; + } + /* "If the space and + flags both appear, + the space flag will be ignored." */ + if (index (flag_chars, ' ') != 0 + && index (flag_chars, '+') != 0) + warning ("use of both ` ' and `+' flags in format"); + /* "If the 0 and - flags both appear, + the 0 flag will be ignored." */ + if (index (flag_chars, '0') != 0 + && index (flag_chars, '-') != 0) + warning ("use of both `0' and `-' flags in format"); + if (*format_chars == '*') + { + wide = TRUE; + /* "...a field width...may be indicated by an asterisk. + In this case, an int argument supplies the field width..." */ + ++format_chars; + if (params == 0) + { + warning (tfaff); + return; + } + if (info->first_arg_num != 0) + { + cur_param = TREE_VALUE (params); + params = TREE_CHAIN (params); + ++arg_num; + /* size_t is generally not valid here. + It will work on most machines, because size_t and int + have the same mode. But might as well warn anyway, + since it will fail on other machines. */ + if (TYPE_MAIN_VARIANT (TREE_TYPE (cur_param)) + != integer_type_node) + { + sprintf (message, + "field width is not type int (arg %d)", + arg_num); + warning (message); + } + } + } + else + { + while (isdigit (*format_chars)) + { + wide = TRUE; + ++format_chars; + } + } + if (*format_chars == '.') + { + precise = TRUE; + ++format_chars; + if (*format_chars != '*' && !isdigit (*format_chars)) + warning ("`.' not followed by `*' or digit in format"); + /* "...a...precision...may be indicated by an asterisk. + In this case, an int argument supplies the...precision." */ + if (*format_chars == '*') + { + if (info->first_arg_num != 0) + { + ++format_chars; + if (params == 0) + { + warning (tfaff); + return; + } + cur_param = TREE_VALUE (params); + params = TREE_CHAIN (params); + ++arg_num; + if (TYPE_MAIN_VARIANT (TREE_TYPE (cur_param)) + != integer_type_node) + { + sprintf (message, + "field width is not type int (arg %d)", + arg_num); + warning (message); + } + } + } + else + { + while (isdigit (*format_chars)) + ++format_chars; + } + } + } + if (*format_chars == 'h' || *format_chars == 'l' || *format_chars == 'L') + length_char = *format_chars++; + else + length_char = 0; + if (suppressed && length_char != 0) + { + sprintf (message, + "use of `*' and `%c' together in format", + length_char); + warning (message); + } + format_char = *format_chars; + if (format_char == 0) + { + warning ("conversion lacks type at end of format"); + continue; + } + format_chars++; + fci = info->is_scan ? scan_char_table : print_char_table; + while (fci->format_chars != 0 + && index (fci->format_chars, format_char) == 0) + ++fci; + if (fci->format_chars == 0) + { + if (format_char >= 040 && format_char < 0177) + sprintf (message, + "unknown conversion type character `%c' in format", + format_char); + else + sprintf (message, + "unknown conversion type character 0x%x in format", + format_char); + warning (message); + continue; + } + if (wide && index (fci->flag_chars, 'w') == 0) + { + sprintf (message, "width used with `%c' format", + format_char); + warning (message); + } + if (precise && index (fci->flag_chars, 'p') == 0) + { + sprintf (message, "precision used with `%c' format", + format_char); + warning (message); + } + if (info->is_scan && format_char == '[') + { + /* Skip over scan set, in case it happens to have '%' in it. */ + if (*format_chars == '^') + ++format_chars; + /* Find closing bracket; if one is hit immediately, then + it's part of the scan set rather than a terminator. */ + if (*format_chars == ']') + ++format_chars; + while (*format_chars && *format_chars != ']') + ++format_chars; + if (*format_chars != ']') + /* The end of the format string was reached. */ + warning ("no closing `]' for `%%[' format"); + } + if (suppressed) + { + if (index (fci->flag_chars, '*') == 0) + { + sprintf (message, + "suppression of `%c' conversion in format", + format_char); + warning (message); + } + continue; + } + for (i = 0; flag_chars[i] != 0; ++i) + { + if (index (fci->flag_chars, flag_chars[i]) == 0) + { + sprintf (message, "flag `%c' used with type `%c'", + flag_chars[i], format_char); + warning (message); + } + } + if (precise && index (flag_chars, '0') != 0 + && (format_char == 'd' || format_char == 'i' + || format_char == 'o' || format_char == 'u' + || format_char == 'x' || format_char == 'x')) + { + sprintf (message, + "precision and `0' flag not both allowed with `%c' format", + format_char); + warning (message); + } + switch (length_char) + { + default: wanted_type = fci->nolen ? *(fci->nolen) : 0; break; + case 'h': wanted_type = fci->hlen ? *(fci->hlen) : 0; break; + case 'l': wanted_type = fci->llen ? *(fci->llen) : 0; break; + case 'L': wanted_type = fci->bigllen ? *(fci->bigllen) : 0; break; + } + if (wanted_type == 0) + { + sprintf (message, + "use of `%c' length character with `%c' type character", + length_char, format_char); + warning (message); + } + + /* + ** XXX -- should kvetch about stuff such as + ** { + ** const int i; + ** + ** scanf ("%d", &i); + ** } + */ + + /* Finally. . .check type of argument against desired type! */ + if (info->first_arg_num == 0) + continue; + if (params == 0) + { + warning (tfaff); + return; + } + cur_param = TREE_VALUE (params); + params = TREE_CHAIN (params); + ++arg_num; + cur_type = TREE_TYPE (cur_param); + + /* Check the types of any additional pointer arguments + that precede the "real" argument. */ + for (i = 0; i < fci->pointer_count; ++i) + { + if (TREE_CODE (cur_type) == POINTER_TYPE) + { + cur_type = TREE_TYPE (cur_type); + continue; + } + sprintf (message, + "format argument is not a %s (arg %d)", + ((fci->pointer_count == 1) ? "pointer" : "pointer to a pointer"), + arg_num); + warning (message); + break; + } + + /* Check the type of the "real" argument, if there's a type we want. */ + if (i == fci->pointer_count && wanted_type != 0 + && wanted_type != TYPE_MAIN_VARIANT (cur_type) + /* If we want `void *', allow any pointer type. + (Anything else would already have got a warning.) */ + && ! (wanted_type == void_type_node + && fci->pointer_count > 0) + /* Don't warn about differences merely in signedness. */ + && !(TREE_CODE (wanted_type) == INTEGER_TYPE + && TREE_CODE (cur_type) == INTEGER_TYPE + && (TREE_UNSIGNED (wanted_type) + ? wanted_type == unsigned_type (cur_type) + : wanted_type == signed_type (cur_type))) + /* Likewise, "signed char", "unsigned char" and "char" are + equivalent but the above test won't consider them equivalent. */ + && ! (wanted_type == char_type_node + && (cur_type == signed_char_type_node + || cur_type == unsigned_char_type_node))) + { + register char *this; + register char *that; + + this = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (wanted_type))); + that = 0; + if (TREE_CODE (cur_type) != ERROR_MARK + && TYPE_NAME (cur_type) != 0 + && TREE_CODE (cur_type) != INTEGER_TYPE + && !(TREE_CODE (cur_type) == POINTER_TYPE + && TREE_CODE (TREE_TYPE (cur_type)) == INTEGER_TYPE)) + { + if (TREE_CODE (TYPE_NAME (cur_type)) == TYPE_DECL + && DECL_NAME (TYPE_NAME (cur_type)) != 0) + that = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (cur_type))); + else + that = IDENTIFIER_POINTER (TYPE_NAME (cur_type)); + } + + /* A nameless type can't possibly match what the format wants. + So there will be a warning for it. + Make up a string to describe vaguely what it is. */ + if (that == 0) + { + if (TREE_CODE (cur_type) == POINTER_TYPE) + that = "pointer"; + else + that = "different type"; + } + + if (strcmp (this, that) != 0) + { + sprintf (message, "%s format, %s arg (arg %d)", + this, that, arg_num); + warning (message); + } + } + } + } + /* Print a warning if a constant expression had overflow in folding. Invoke this function on every expression that the language *************** *** 350,362 **** { if (TREE_CODE (value) == INTEGER_CST && TREE_CONSTANT_OVERFLOW (value)) ! { ! /* ??? This is a warning, not a pedwarn, in 2.4, ! because it happens in contexts that are not ! "constant expressions" in ANSI C. ! Fix the problem differently in 2.5. */ ! warning ("overflow in constant expression"); ! /* Suppress duplicate warnings. */ ! TREE_CONSTANT_OVERFLOW (value) = 0; ! } } --- 957,962 ---- { if (TREE_CODE (value) == INTEGER_CST && TREE_CONSTANT_OVERFLOW (value)) ! if (pedantic) ! pedwarn ("overflow in constant expression"); } *************** *** 372,383 **** tree value; { ! if (TREE_CODE (value) == INTEGER_CST && TREE_CONSTANT_OVERFLOW (value)) { ! /* ??? This is a warning, not a pedwarn, in 2.4, ! because it happens in contexts that are not ! "constant expressions" in ANSI C. ! Fix the problem differently in 2.5. */ warning ("integer overflow in expression"); - TREE_CONSTANT_OVERFLOW (value) = 0; } } --- 972,979 ---- tree value; { ! if (TREE_CODE (value) == INTEGER_CST && TREE_OVERFLOW (value)) { ! TREE_OVERFLOW (value) = 0; warning ("integer overflow in expression"); } } *************** *** 399,405 **** if (!int_fits_type_p (operand, signed_type (TREE_TYPE (result)))) /* This detects cases like converting -129 or 256 to unsigned char. */ ! pedwarn ("large integer implicitly truncated to unsigned type"); else if (warn_conversion) ! pedwarn ("negative integer implicitly converted to unsigned type"); } } --- 995,1001 ---- if (!int_fits_type_p (operand, signed_type (TREE_TYPE (result)))) /* This detects cases like converting -129 or 256 to unsigned char. */ ! warning ("large integer implicitly truncated to unsigned type"); else if (warn_conversion) ! warning ("negative integer implicitly converted to unsigned type"); } } *************** *** 416,433 **** if (TREE_CODE (t) == INTEGER_CST) { ! if (TREE_UNSIGNED (TREE_TYPE (expr)) ! && !TREE_UNSIGNED (type) ! && TREE_CODE (TREE_TYPE (expr)) == INTEGER_TYPE ! && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (expr))) ! /* No warning for converting 0x80000000 to int. */ ! TREE_CONSTANT_OVERFLOW (t) = 0; ! else if (TREE_CONSTANT_OVERFLOW (t)) ! { ! /* ??? This is a warning, not a pedwarn, in 2.4, ! because it happens in contexts that are not ! "constant expressions" in ANSI C. ! Fix the problem differently in 2.5. */ ! warning ("overflow in implicit constant conversion"); ! TREE_CONSTANT_OVERFLOW (t) = 0; } else --- 1012,1024 ---- if (TREE_CODE (t) == INTEGER_CST) { ! if (TREE_OVERFLOW (t)) ! { ! TREE_OVERFLOW (t) = 0; ! ! /* No warning for converting 0x80000000 to int. */ ! if (!(TREE_UNSIGNED (type) < TREE_UNSIGNED (TREE_TYPE (expr)) ! && TREE_CODE (TREE_TYPE (expr)) == INTEGER_TYPE ! && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (expr)))) ! warning ("overflow in implicit constant conversion"); } else *************** *** 1040,1044 **** case COMPLEX_EXPR: return build_binary_op ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)) ! ? TRUTH_AND_EXPR : TRUTH_ANDIF_EXPR), truthvalue_conversion (TREE_OPERAND (expr, 0)), truthvalue_conversion (TREE_OPERAND (expr, 1)), --- 1631,1635 ---- case COMPLEX_EXPR: return build_binary_op ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)) ! ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR), truthvalue_conversion (TREE_OPERAND (expr, 0)), truthvalue_conversion (TREE_OPERAND (expr, 1)), *************** *** 1110,1114 **** return (build_binary_op ((TREE_SIDE_EFFECTS (expr) ! ? TRUTH_AND_EXPR : TRUTH_ANDIF_EXPR), truthvalue_conversion (build_unary_op (REALPART_EXPR, expr, 0)), truthvalue_conversion (build_unary_op (IMAGPART_EXPR, expr, 0)), --- 1701,1705 ---- return (build_binary_op ((TREE_SIDE_EFFECTS (expr) ! ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR), truthvalue_conversion (build_unary_op (REALPART_EXPR, expr, 0)), truthvalue_conversion (build_unary_op (IMAGPART_EXPR, expr, 0)), *************** *** 1208,1215 **** { tree real_main_variant = TYPE_MAIN_VARIANT (type); - int permanent = TREE_PERMANENT (type); ! if (permanent) ! push_obstacks (&permanent_obstack, &permanent_obstack); type = build_array_type (c_build_type_variant (TREE_TYPE (type), constp, volatilep), --- 1799,1804 ---- { tree real_main_variant = TYPE_MAIN_VARIANT (type); ! push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type)); type = build_array_type (c_build_type_variant (TREE_TYPE (type), constp, volatilep), *************** *** 1216,1221 **** TYPE_DOMAIN (type)); TYPE_MAIN_VARIANT (type) = real_main_variant; ! if (permanent) ! pop_obstacks (); } return build_type_variant (type, constp, volatilep); --- 1805,1809 ---- TYPE_DOMAIN (type)); TYPE_MAIN_VARIANT (type) = real_main_variant; ! pop_obstacks (); } return build_type_variant (type, constp, volatilep); diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/c-decl.c gcc-2.5.0/c-decl.c *** gcc-2.4.5/c-decl.c Sat Jun 19 18:43:09 1993 --- gcc-2.5.0/c-decl.c Mon Oct 18 23:18:16 1993 *************** *** 1,4 **** /* Process declarations and variables for C compiler. ! Copyright (C) 1988, 1992 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,4 ---- /* Process declarations and variables for C compiler. ! Copyright (C) 1988, 1992, 1993 Free Software Foundation, Inc. This file is part of GNU CC. *************** *** 209,213 **** /* While defining an enum type, this is 1 plus the last enumerator ! constant value. */ static tree enum_next_value; --- 209,216 ---- /* While defining an enum type, this is 1 plus the last enumerator ! constant value. Note that will do not have to save this or `enum_overflow' ! around nested function definition since such a definition could only ! occur in an enum value expression and we don't use these variables in ! that case. */ static tree enum_next_value; *************** *** 435,438 **** --- 438,445 ---- int flag_traditional; + /* Nonzero means to allow single precision math even if we're generally + being traditional. */ + int flag_allow_single_precision = 0; + /* Nonzero means to treat bitfields as signed unless they say `unsigned'. */ *************** *** 535,538 **** --- 542,547 ---- #endif } + else if (!strcmp (p, "-fallow-single-precision")) + flag_allow_single_precision = 1; else if (!strcmp (p, "-fnotraditional") || !strcmp (p, "-fno-traditional")) { *************** *** 541,544 **** --- 550,561 ---- dollars_in_ident = DOLLARS_IN_IDENTIFIERS > 1; } + else if (!strcmp (p, "-fdollars-in-identifiers")) + { + #if DOLLARS_IN_IDENTIFIERS > 0 + dollars_in_ident = 1; + #endif + } + else if (!strcmp (p, "-fnodollars-in-identifiers")) + dollars_in_ident = 0; else if (!strcmp (p, "-fsigned-char")) flag_signed_char = 1; *************** *** 689,693 **** void ! print_lang_decl () { } --- 706,713 ---- void ! print_lang_decl (file, node, indent) ! FILE *file; ! tree node; ! int indent; { } *************** *** 694,698 **** void ! print_lang_type () { } --- 714,721 ---- void ! print_lang_type (file, node, indent) ! FILE *file; ! tree node; ! int indent; { } *************** *** 924,928 **** TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1; else ! output_inline_function (decl); } --- 947,955 ---- TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1; else ! { ! push_function_context (); ! output_inline_function (decl); ! pop_function_context (); ! } } *************** *** 1096,1100 **** /* Insert BLOCK at the end of the list of subblocks of the current binding level. This is used when a BIND_EXPR is expanded, ! to handle the BLOCK node inside teh BIND_EXPR. */ void --- 1123,1127 ---- /* Insert BLOCK at the end of the list of subblocks of the current binding level. This is used when a BIND_EXPR is expanded, ! to handle the BLOCK node inside the BIND_EXPR. */ void *************** *** 1268,1283 **** { if (TREE_CODE (olddecl) == FUNCTION_DECL ! && DECL_BUILT_IN (olddecl)) { ! /* If you declare a built-in function name as static, the ! built-in definition is overridden, but optionally warn this was a bad choice of name. */ if (!TREE_PUBLIC (newdecl)) { ! if (warn_shadow) warning_with_decl (newdecl, "shadowing built-in function `%s'"); } /* Likewise, if the built-in is not ansi, then programs can override it even globally without an error. */ else if (DECL_BUILT_IN_NONANSI (olddecl)) warning_with_decl (newdecl, --- 1295,1319 ---- { if (TREE_CODE (olddecl) == FUNCTION_DECL ! && (DECL_BUILT_IN (olddecl) ! || DECL_BUILT_IN_NONANSI (olddecl))) { ! /* If you declare a built-in or predefined function name as static, ! the old definition is overridden, but optionally warn this was a bad choice of name. */ if (!TREE_PUBLIC (newdecl)) { ! if (!warn_shadow) ! ; ! else if (DECL_BUILT_IN (olddecl)) warning_with_decl (newdecl, "shadowing built-in function `%s'"); + else + warning_with_decl (newdecl, "shadowing library function `%s'"); } /* Likewise, if the built-in is not ansi, then programs can override it even globally without an error. */ + else if (! DECL_BUILT_IN (olddecl)) + warning_with_decl (newdecl, + "library function `%s' declared as non-function"); + else if (DECL_BUILT_IN_NONANSI (olddecl)) warning_with_decl (newdecl, *************** *** 1284,1304 **** "built-in function `%s' declared as non-function"); else - error_with_decl (newdecl, - "built-in function `%s' declared as non-function"); - } - else if (TREE_CODE (olddecl) == FUNCTION_DECL - && DECL_BUILT_IN_NONANSI (olddecl)) - { - /* If overriding decl is static, - optionally warn this was a bad choice of name. */ - if (!TREE_PUBLIC (newdecl)) - { - if (warn_shadow) - warning_with_decl (newdecl, "shadowing library function `%s'"); - } - /* Otherwise, always warn. */ - else warning_with_decl (newdecl, ! "library function `%s' declared as non-function"); } else --- 1320,1325 ---- "built-in function `%s' declared as non-function"); else warning_with_decl (newdecl, ! "built-in function `%s' declared as non-function"); } else *************** *** 1578,1582 **** followed by a definition. */ && !(TREE_CODE (newdecl) == FUNCTION_DECL && DECL_INITIAL (newdecl) != 0 ! && DECL_INITIAL (olddecl) == 0)) { warning_with_decl (newdecl, "redundant redeclaration of `%s' in same scope"); --- 1599,1605 ---- followed by a definition. */ && !(TREE_CODE (newdecl) == FUNCTION_DECL && DECL_INITIAL (newdecl) != 0 ! && DECL_INITIAL (olddecl) == 0) ! /* Don't warn about extern decl followed by (tentative) definition. */ ! && !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl))) { warning_with_decl (newdecl, "redundant redeclaration of `%s' in same scope"); *************** *** 1759,1763 **** if (warn_nested_externs && DECL_EXTERNAL (x) && b != global_binding_level ! && x != IDENTIFIER_IMPLICIT_DECL (name)) warning ("nested extern declaration of `%s'", IDENTIFIER_POINTER (name)); --- 1782,1788 ---- if (warn_nested_externs && DECL_EXTERNAL (x) && b != global_binding_level ! && x != IDENTIFIER_IMPLICIT_DECL (name) ! /* Don't print error messages for __FUNCTION__ and __PRETTY_FUNCTION__ */ ! && !DECL_IN_SYSTEM_HEADER (x)) warning ("nested extern declaration of `%s'", IDENTIFIER_POINTER (name)); *************** *** 2604,2607 **** --- 2629,2640 ---- long_unsigned_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)); + + 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)); + /* `unsigned long' is the standard type for sizeof. Traditionally, use a signed type. *************** *** 2608,2616 **** Note that stddef.h uses `unsigned long', and this must agree, even of long and int are the same size. */ ! if (flag_traditional) ! sizetype = long_integer_type_node; ! else ! sizetype ! = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))); ptrdiff_type_node --- 2641,2648 ---- Note that stddef.h uses `unsigned long', and this must agree, even of long and int are the same size. */ ! sizetype ! = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))); ! if (flag_traditional && TREE_UNSIGNED (sizetype)) ! sizetype = signed_type (sizetype); ptrdiff_type_node *************** *** 2622,2625 **** --- 2654,2659 ---- TREE_TYPE (TYPE_SIZE (long_unsigned_type_node)) = sizetype; TREE_TYPE (TYPE_SIZE (long_integer_type_node)) = sizetype; + TREE_TYPE (TYPE_SIZE (long_long_integer_type_node)) = sizetype; + TREE_TYPE (TYPE_SIZE (long_long_unsigned_type_node)) = sizetype; error_mark_node = make_node (ERROR_MARK); *************** *** 2630,2637 **** 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"), --- 2664,2667 ---- *************** *** 2638,2645 **** 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)); - /* Define both `signed char' and `unsigned char'. */ signed_char_type_node = make_signed_type (CHAR_TYPE_SIZE); --- 2668,2671 ---- *************** *** 2723,2728 **** = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (WCHAR_TYPE))); wchar_type_size = TYPE_PRECISION (wchar_type_node); ! signed_wchar_type_node = type_for_size (wchar_type_size, 0); ! unsigned_wchar_type_node = type_for_size (wchar_type_size, 1); integer_zero_node = build_int_2 (0, 0); --- 2749,2754 ---- = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (WCHAR_TYPE))); wchar_type_size = TYPE_PRECISION (wchar_type_node); ! signed_wchar_type_node = signed_type (wchar_type_node); ! unsigned_wchar_type_node = unsigned_type (wchar_type_node); integer_zero_node = build_int_2 (0, 0); *************** *** 3033,3037 **** start_identifier_warnings (); ! init_format_info_table (); init_iterators (); --- 3059,3064 ---- start_identifier_warnings (); ! /* Prepare to check format strings against argument lists. */ ! init_function_format_info (); init_iterators (); *************** *** 3441,3448 **** ? /* A static variable with an incomplete type ! is an error if it is initialized or `static'. Otherwise, let it through, but if it is not `extern' then it may cause an error message later. */ ! !TREE_PUBLIC (decl) || DECL_INITIAL (decl) : /* An automatic variable with an incomplete type --- 3468,3477 ---- ? /* A static variable with an incomplete type ! is an error if it is initialized. ! Also if it is not file scope. Otherwise, let it through, but if it is not `extern' then it may cause an error message later. */ ! (DECL_INITIAL (decl) != 0 ! || current_binding_level != global_binding_level) : /* An automatic variable with an incomplete type *************** *** 3532,3536 **** to have a copy of the top-level decl's DECL_INLINE. */ if (DECL_INITIAL (decl) != 0) ! DECL_INITIAL (decl) = error_mark_node; } --- 3561,3580 ---- to have a copy of the top-level decl's DECL_INLINE. */ if (DECL_INITIAL (decl) != 0) ! { ! /* If this is a static const variable, then preserve the ! initializer instead of discarding it so that we can optimize ! references to it. */ ! if (TREE_STATIC (decl) && TREE_READONLY (decl)) ! { ! preserve_initializer (); ! /* Hack? Set the permanent bit for something that is permanent, ! but not on the permenent obstack, so as to convince ! output_constant_def to make its rtl on the permanent ! obstack. */ ! TREE_PERMANENT (DECL_INITIAL (decl)) = 1; ! } ! else ! DECL_INITIAL (decl) = error_mark_node; ! } } *************** *** 3635,3645 **** int eltsize = int_size_in_bytes (TREE_TYPE (TREE_TYPE (initial_value))); ! maxindex = build_int_2 (TREE_STRING_LENGTH (initial_value) / eltsize - 1, 0); } else if (TREE_CODE (initial_value) == CONSTRUCTOR) { ! register int nelts ! = list_length (CONSTRUCTOR_ELTS (initial_value)); ! maxindex = build_int_2 (nelts - 1, - (nelts == 0)); } else --- 3679,3697 ---- int eltsize = int_size_in_bytes (TREE_TYPE (TREE_TYPE (initial_value))); ! maxindex = build_int_2 ((TREE_STRING_LENGTH (initial_value) ! / eltsize) - 1, 0); } else if (TREE_CODE (initial_value) == CONSTRUCTOR) { ! tree elts = CONSTRUCTOR_ELTS (initial_value); ! maxindex = size_binop (MINUS_EXPR, integer_zero_node, size_one_node); ! for (; elts; elts = TREE_CHAIN (elts)) ! { ! if (TREE_PURPOSE (elts)) ! maxindex = TREE_PURPOSE (elts); ! else ! maxindex = size_binop (PLUS_EXPR, maxindex, size_one_node); ! } ! maxindex = copy_node (maxindex); } else *************** *** 4288,4291 **** --- 4340,4350 ---- ? NULL_TREE : arg_types); #endif + /* ANSI seems to say that `const int foo ();' + does not make the function foo const. */ + if (constp || volatilep) + type = c_build_type_variant (type, constp, volatilep); + constp = 0; + volatilep = 0; + type = build_function_type (type, arg_types); declarator = TREE_OPERAND (declarator, 0); *************** *** 4406,4415 **** } ! /* `void' at top level (not within pointer) ! is allowed only in typedefs or type names. We don't complain about parms either, but that is because a better error message can be made later. */ ! if (TYPE_MAIN_VARIANT (type) == void_type_node && decl_context != PARM) { error ("variable or field `%s' declared void", --- 4465,4480 ---- } ! /* Aside from typedefs and type names (handle above), ! `void' at top level (not within pointer) ! is allowed only in public variables. We don't complain about parms either, but that is because a better error message can be made later. */ ! if (TYPE_MAIN_VARIANT (type) == void_type_node && decl_context != PARM ! && ! ((decl_context != FIELD && TREE_CODE (type) != FUNCTION_TYPE) ! && ((specbits & (1 << (int) RID_EXTERN)) ! || (current_binding_level == global_binding_level ! && !(specbits ! & ((1 << (int) RID_STATIC) | (1 << (int) RID_REGISTER))))))) { error ("variable or field `%s' declared void", *************** *** 4435,4440 **** { /* Transfer const-ness of array into that of type pointed to. */ ! type = build_pointer_type ! (c_build_type_variant (TREE_TYPE (type), constp, volatilep)); volatilep = constp = 0; size_varies = 0; --- 4500,4507 ---- { /* Transfer const-ness of array into that of type pointed to. */ ! type = TREE_TYPE (type); ! if (constp || volatilep) ! type = c_build_type_variant (type, constp, volatilep); ! type = build_pointer_type (type); volatilep = constp = 0; size_varies = 0; *************** *** 4444,4448 **** if (pedantic && (constp || volatilep)) pedwarn ("ANSI C forbids const or volatile function types"); ! type = build_pointer_type (c_build_type_variant (type, constp, volatilep)); volatilep = constp = 0; } --- 4511,4517 ---- if (pedantic && (constp || volatilep)) pedwarn ("ANSI C forbids const or volatile function types"); ! if (constp || volatilep) ! type = c_build_type_variant (type, constp, volatilep); ! type = build_pointer_type (type); volatilep = constp = 0; } *************** *** 4546,4549 **** --- 4615,4622 ---- pedwarn ("ANSI C forbids const or volatile functions"); + if (volatilep + && TREE_TYPE (TREE_TYPE (decl)) != void_type_node) + warning ("volatile function returns non-void value"); + if (extern_ref) DECL_EXTERNAL (decl) = 1; *************** *** 4844,4848 **** DECL_ARG_TYPE (decl) = type; #ifdef PROMOTE_PROTOTYPES ! if (TREE_CODE (type) == INTEGER_TYPE && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)) DECL_ARG_TYPE (decl) = integer_type_node; --- 4917,4922 ---- DECL_ARG_TYPE (decl) = type; #ifdef PROMOTE_PROTOTYPES ! if ((TREE_CODE (type) == INTEGER_TYPE ! || TREE_CODE (type) == ENUMERAL_TYPE) && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)) DECL_ARG_TYPE (decl) = integer_type_node; *************** *** 5136,5140 **** if (DECL_INITIAL (x) && pedantic && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != integer_type_node ! && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != unsigned_type_node) pedwarn_with_decl (x, "bit-field `%s' type invalid in ANSI C"); --- 5210,5218 ---- if (DECL_INITIAL (x) && pedantic && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != integer_type_node ! && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != unsigned_type_node ! /* Accept an enum that's equivalent to int or unsigned int. */ ! && !(TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE ! && (TYPE_PRECISION (TREE_TYPE (x)) ! == TYPE_PRECISION (integer_type_node)))) pedwarn_with_decl (x, "bit-field `%s' type invalid in ANSI C"); *************** *** 5492,5506 **** TREE_UNSIGNED (enumtype) = ! tree_int_cst_lt (minnode, integer_zero_node); ! /* If the enumerators might not fit in an int, change their type now. */ ! /* It seems more useful in the debugger to leave these as int ! unless the enumerator is wider than int. */ ! if (TYPE_PRECISION (enumtype) <= TYPE_PRECISION (integer_type_node)) ! for (pair = values; pair; pair = TREE_CHAIN (pair)) ! { ! TREE_TYPE (TREE_PURPOSE (pair)) = enumtype; ! DECL_SIZE (TREE_PURPOSE (pair)) = TYPE_SIZE (enumtype); ! if (TREE_CODE (TREE_PURPOSE (pair)) != FUNCTION_DECL) ! DECL_ALIGN (TREE_PURPOSE (pair)) = TYPE_ALIGN (enumtype); ! } /* Replace the decl nodes in VALUES with their names. */ --- 5570,5585 ---- TREE_UNSIGNED (enumtype) = ! tree_int_cst_lt (minnode, integer_zero_node); ! /* Change the type of the enumerators to be the enum type. ! Formerly this was done only for enums that fit in an int, ! but the comment said it was done only for enums wider than int. ! It seems necessary to do this for wide enums, ! and best not to change what's done for ordinary narrower ones. */ ! for (pair = values; pair; pair = TREE_CHAIN (pair)) ! { ! TREE_TYPE (TREE_PURPOSE (pair)) = enumtype; ! DECL_SIZE (TREE_PURPOSE (pair)) = TYPE_SIZE (enumtype); ! if (TREE_CODE (TREE_PURPOSE (pair)) != FUNCTION_DECL) ! DECL_ALIGN (TREE_PURPOSE (pair)) = TYPE_ALIGN (enumtype); ! } /* Replace the decl nodes in VALUES with their names. */ *************** *** 5541,5545 **** tree name, value; { ! register tree decl; /* Validate and default VALUE. */ --- 5620,5624 ---- tree name, value; { ! register tree decl, type; /* Validate and default VALUE. */ *************** *** 5552,5556 **** { if (TREE_CODE (value) == INTEGER_CST) ! constant_expression_warning (value); else { --- 5631,5638 ---- { if (TREE_CODE (value) == INTEGER_CST) ! { ! value = default_conversion (value); ! constant_expression_warning (value); ! } else { *************** *** 5583,5589 **** /* Now create a declaration for the enum value name. */ ! decl = build_decl (CONST_DECL, name, integer_type_node); DECL_INITIAL (decl) = value; ! TREE_TYPE (value) = integer_type_node; pushdecl (decl); --- 5665,5678 ---- /* Now create a declaration for the enum value name. */ ! type = TREE_TYPE (value); ! type = type_for_size (MAX (TYPE_PRECISION (type), ! TYPE_PRECISION (integer_type_node)), ! ((flag_traditional ! || TYPE_PRECISION (type) >= TYPE_PRECISION (integer_type_node)) ! && TREE_UNSIGNED (type))); ! ! decl = build_decl (CONST_DECL, name, type); DECL_INITIAL (decl) = value; ! TREE_TYPE (value) = type; pushdecl (decl); *************** *** 6051,6055 **** DECL_ARG_TYPE (parm) = TREE_TYPE (parm); #ifdef PROMOTE_PROTOTYPES ! if (TREE_CODE (TREE_TYPE (parm)) == INTEGER_TYPE && TYPE_PRECISION (TREE_TYPE (parm)) < TYPE_PRECISION (integer_type_node)) --- 6140,6145 ---- DECL_ARG_TYPE (parm) = TREE_TYPE (parm); #ifdef PROMOTE_PROTOTYPES ! if ((TREE_CODE (TREE_TYPE (parm)) == INTEGER_TYPE ! || TREE_CODE (TREE_TYPE (parm)) == ENUMERAL_TYPE) && TYPE_PRECISION (TREE_TYPE (parm)) < TYPE_PRECISION (integer_type_node)) *************** *** 6416,6420 **** { struct c_function *next; - tree enum_next_value; tree named_labels; tree shadowed_labels; --- 6506,6509 ---- *************** *** 6445,6449 **** c_function_chain = p; - p->enum_next_value = enum_next_value; p->named_labels = named_labels; p->shadowed_labels = shadowed_labels; --- 6534,6537 ---- *************** *** 6482,6486 **** c_function_chain = p->next; - enum_next_value = p->enum_next_value; named_labels = p->named_labels; shadowed_labels = p->shadowed_labels; --- 6570,6573 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/c-iterate.c gcc-2.5.0/c-iterate.c *** gcc-2.4.5/c-iterate.c Fri Jun 18 16:03:49 1993 --- gcc-2.5.0/c-iterate.c Wed Jul 28 15:33:13 1993 *************** *** 1,4 **** /* Build expressions with type checking for C compiler. ! Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,4 ---- /* Build expressions with type checking for C compiler. ! Copyright (C) 1987, 1988, 1989, 1992, 1993 Free Software Foundation, Inc. This file is part of GNU CC. *************** *** 210,219 **** case SAVE_EXPR: /* In each scan, scan a given save_expr only once. */ ! { ! tree tail; ! for (tail = save_exprs; tail; tail = TREE_CHAIN (tail)) ! if (TREE_VALUE (tail) == exp) ! return list; ! } save_exprs = tree_cons (NULL_TREE, exp, save_exprs); return collect_iterators (TREE_OPERAND (exp, 0), list); --- 210,216 ---- case SAVE_EXPR: /* In each scan, scan a given save_expr only once. */ ! if (value_member (exp, save_exprs)) ! return list; ! save_exprs = tree_cons (NULL_TREE, exp, save_exprs); return collect_iterators (TREE_OPERAND (exp, 0), list); *************** *** 282,288 **** rtx *start_note, *end_note; { /* Force the save_expr in DECL_INITIAL to be calculated if it hasn't been calculated yet. */ ! expand_expr (DECL_INITIAL (idecl), 0, VOIDmode, 0); if (DECL_RTL (idecl) == 0) --- 279,287 ---- rtx *start_note, *end_note; { + tree expr; + /* Force the save_expr in DECL_INITIAL to be calculated if it hasn't been calculated yet. */ ! expand_expr (DECL_INITIAL (idecl), const0_rtx, VOIDmode, 0); if (DECL_RTL (idecl) == 0) *************** *** 291,298 **** if (start_note) *start_note = emit_note (0, NOTE_INSN_DELETED); /* Initialize counter. */ ! expand_expr (build (MODIFY_EXPR, TREE_TYPE (idecl), ! idecl, integer_zero_node), ! 0, VOIDmode, 0); expand_start_loop_continue_elsewhere (1); --- 290,298 ---- if (start_note) *start_note = emit_note (0, NOTE_INSN_DELETED); + /* Initialize counter. */ ! expr = build (MODIFY_EXPR, TREE_TYPE (idecl), idecl, integer_zero_node); ! TREE_SIDE_EFFECTS (expr) = 1; ! expand_expr (expr, const0_rtx, VOIDmode, 0); expand_start_loop_continue_elsewhere (1); *************** *** 333,338 **** expand_loop_continue_here (); incr = build_binary_op (PLUS_EXPR, idecl, integer_one_node, 0); ! expand_expr (build (MODIFY_EXPR, TREE_TYPE (idecl), idecl, incr), ! 0, VOIDmode, 0); test = build_binary_op (LT_EXPR, idecl, DECL_INITIAL (idecl), 0); expand_exit_loop_if_false (0, test); --- 333,339 ---- expand_loop_continue_here (); incr = build_binary_op (PLUS_EXPR, idecl, integer_one_node, 0); ! incr = build (MODIFY_EXPR, TREE_TYPE (idecl), idecl, incr); ! TREE_SIDE_EFFECTS (incr) = 1; ! expand_expr (incr, const0_rtx, VOIDmode, 0); test = build_binary_op (LT_EXPR, idecl, DECL_INITIAL (idecl), 0); expand_exit_loop_if_false (0, test); diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/c-lex.c gcc-2.5.0/c-lex.c *** gcc-2.4.5/c-lex.c Wed May 26 02:17:58 1993 --- gcc-2.5.0/c-lex.c Wed Sep 29 01:42:10 1993 *************** *** 32,35 **** --- 32,37 ---- #include "c-parse.h" + #include + #ifdef MULTIBYTE_CHARS #include *************** *** 89,95 **** int check_newline (); - - /* Nonzero tells yylex to ignore \ in string constants. */ - static int ignore_escape_flag = 0; /* C code produced by gperf version 2.5 (GNU C++ version) */ --- 91,94 ---- *************** *** 715,722 **** /* More follows: it must be a string constant (filename). */ ! /* Read the string constant, but don't treat \ as special. */ ! ignore_escape_flag = 1; token = yylex (); - ignore_escape_flag = 0; if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) --- 714,719 ---- /* More follows: it must be a string constant (filename). */ ! /* Read the string constant. */ token = yylex (); if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) *************** *** 884,889 **** #endif /* HANDLE_SYSV_PRAGMA */ - #define isalnum(char) ((char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') || (char >= '0' && char <= '9')) - #define isdigit(char) (char >= '0' && char <= '9') #define ENDFILE -1 /* token that represents end-of-file */ --- 881,884 ---- *************** *** 1478,1522 **** else { set_float_handler (handler); ! /* The second argument, machine_mode, of REAL_VALUE_ATOF tells the ! desired precision of the binary result of decimal-to-binary conversion. */ ! /* Read the suffixes to choose a data type. */ ! switch (c) ! { ! case 'f': case 'F': ! type = float_type_node; ! value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type)); ! if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT ! && REAL_VALUE_ISINF (value) && pedantic) ! pedwarn ("floating point number exceeds range of `float'"); ! garbage_chars = -1; ! break; ! ! case 'l': case 'L': ! type = long_double_type_node; ! value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type)); ! if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT ! && REAL_VALUE_ISINF (value) && pedantic) ! pedwarn ( ! "floating point number exceeds range of `long double'"); ! garbage_chars = -1; ! break; ! ! case 'i': case 'I': ! if (imag) ! error ("more than one `i' or `j' in numeric constant"); ! imag = 1; ! garbage_chars = -1; ! break; ! default: ! value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type)); ! if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT ! && REAL_VALUE_ISINF (value) && pedantic) ! pedwarn ("floating point number exceeds range of `double'"); ! } ! set_float_handler (NULL_PTR); } #ifdef ERANGE --- 1473,1556 ---- else { + int fflag = 0, lflag = 0; + /* Copy token_buffer now, while it has just the number + and not the suffixes; once we add `f' or `i', + REAL_VALUE_ATOF may not work any more. */ + char *copy = (char *) alloca (p - token_buffer + 1); + bcopy (token_buffer, copy, p - token_buffer + 1); + set_float_handler (handler); ! while (1) ! { ! int lose = 0; ! /* Read the suffixes to choose a data type. */ ! switch (c) ! { ! case 'f': case 'F': ! if (fflag) ! error ("more than one `f' in numeric constant"); ! fflag = 1; ! break; ! ! case 'l': case 'L': ! if (lflag) ! error ("more than one `l' in numeric constant"); ! lflag = 1; ! break; ! ! case 'i': case 'I': ! if (imag) ! error ("more than one `i' or `j' in numeric constant"); ! imag = 1; ! break; ! default: ! lose = 1; ! } ! ! if (lose) ! break; ! ! if (p >= token_buffer + maxtoken - 3) ! p = extend_token_buffer (p); ! *p++ = c; ! *p = 0; ! c = getc (finput); ! } ! ! /* The second argument, machine_mode, of REAL_VALUE_ATOF ! tells the desired precision of the binary result ! of decimal-to-binary conversion. */ ! ! if (fflag) ! { ! if (lflag) ! error ("both `f' and `l' in floating constant"); ! ! type = float_type_node; ! value = REAL_VALUE_ATOF (copy, TYPE_MODE (type)); ! if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT ! && REAL_VALUE_ISINF (value) && pedantic) ! pedwarn ("floating point number exceeds range of `float'"); ! } ! else if (lflag) ! { ! type = long_double_type_node; ! value = REAL_VALUE_ATOF (copy, TYPE_MODE (type)); ! if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT ! && REAL_VALUE_ISINF (value) && pedantic) ! pedwarn ("floating point number exceeds range of `long double'"); ! } ! else ! { ! value = REAL_VALUE_ATOF (copy, TYPE_MODE (type)); ! if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT ! && REAL_VALUE_ISINF (value) && pedantic) ! pedwarn ("floating point number exceeds range of `double'"); ! } ! ! set_float_handler (NULL_PTR); } #ifdef ERANGE *************** *** 1534,1538 **** } #endif ! /* Note: garbage_chars is -1 if first char is *not* garbage. */ while (isalnum (c) || c == '.' || c == '_' || (!flag_traditional && (c == '+' || c == '-') --- 1568,1572 ---- } #endif ! garbage_chars = 0; while (isalnum (c) || c == '.' || c == '_' || (!flag_traditional && (c == '+' || c == '-') *************** *** 1900,1905 **** while (c != '"' && c >= 0) { ! /* ignore_escape_flag is set for reading the filename in #line. */ ! if (!ignore_escape_flag && c == '\\') { int ignore = 0; --- 1934,1938 ---- while (c != '"' && c >= 0) { ! if (c == '\\') { int ignore = 0; diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/c-parse.in gcc-2.5.0/c-parse.in *** gcc-2.4.5/c-parse.in Thu May 6 13:41:30 1993 --- gcc-2.5.0/c-parse.in Wed Oct 13 15:46:42 1993 *************** *** 177,181 **** %type SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual %type initdecls notype_initdecls initdcl notype_initdcl ! %type init initlist maybeasm %type asm_operands nonnull_asm_operands asm_operand asm_clobbers %type maybe_attribute attribute_list attrib --- 177,181 ---- %type SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual %type initdecls notype_initdecls initdcl notype_initdcl ! %type init maybeasm %type asm_operands nonnull_asm_operands asm_operand asm_clobbers %type maybe_attribute attribute_list attrib *************** *** 457,463 **** { tree type = groktypename ($2); $$ = build_c_cast (type, $4); } ! | '(' typename ')' '{' initlist maybecomma '}' %prec UNARY ! { tree type = groktypename ($2); ! char *name; if (pedantic) pedwarn ("ANSI C forbids constructor expressions"); --- 457,470 ---- { tree type = groktypename ($2); $$ = build_c_cast (type, $4); } ! | '(' typename ')' '{' ! { start_init (NULL_TREE, NULL, 0); ! $2 = groktypename ($2); ! really_start_incremental_init ($2); } ! initlist_maybe_comma '}' %prec UNARY ! { char *name; ! tree result = pop_init_level (0); ! tree type = $2; ! finish_init (); ! if (pedantic) pedwarn ("ANSI C forbids constructor expressions"); *************** *** 471,476 **** else name = ""; ! $$ = digest_init (type, build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($5)), ! NULL_PTR, 0, 0, name); if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0) { --- 478,482 ---- else name = ""; ! $$ = result; if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0) { *************** *** 728,738 **** TREE_SIDE_EFFECTS (rtl_exp) = 1; ! /* Make a BIND_EXPR for the BLOCK already made. */ ! $$ = build (BIND_EXPR, TREE_TYPE (rtl_exp), ! NULL_TREE, rtl_exp, $3); ! /* Remove the block from the tree at this point. ! It gets put back at the proper place ! when the BIND_EXPR is expanded. */ ! delete_block ($3); } | primary '(' exprlist ')' %prec '.' --- 734,749 ---- TREE_SIDE_EFFECTS (rtl_exp) = 1; ! if (TREE_CODE ($3) == BLOCK) ! { ! /* Make a BIND_EXPR for the BLOCK already made. */ ! $$ = build (BIND_EXPR, TREE_TYPE (rtl_exp), ! NULL_TREE, rtl_exp, $3); ! /* Remove the block from the tree at this point. ! It gets put back at the proper place ! when the BIND_EXPR is expanded. */ ! delete_block ($3); ! } ! else ! $$ = $3; } | primary '(' exprlist ')' %prec '.' *************** *** 1008,1015 **** initdcl: declarator maybeasm maybe_attribute '=' ! { $$ = start_decl ($1, current_declspecs, 1); } init /* Note how the declaration of the variable is in effect while its init is parsed! */ ! { decl_attributes ($5, $3); finish_decl ($5, $6, $2); } | declarator maybeasm maybe_attribute --- 1019,1029 ---- initdcl: declarator maybeasm maybe_attribute '=' ! { $$ = start_decl ($1, current_declspecs, 1); ! decl_attributes ($$, $3); ! start_init ($$, $2, global_bindings_p ()); } init /* Note how the declaration of the variable is in effect while its init is parsed! */ ! { finish_init (); ! decl_attributes ($5, $3); finish_decl ($5, $6, $2); } | declarator maybeasm maybe_attribute *************** *** 1021,1028 **** notype_initdcl: notype_declarator maybeasm maybe_attribute '=' ! { $$ = start_decl ($1, current_declspecs, 1); } init /* Note how the declaration of the variable is in effect while its init is parsed! */ ! { decl_attributes ($5, $3); finish_decl ($5, $6, $2); } | notype_declarator maybeasm maybe_attribute --- 1035,1045 ---- notype_initdcl: notype_declarator maybeasm maybe_attribute '=' ! { $$ = start_decl ($1, current_declspecs, 1); ! decl_attributes ($$, $3); ! start_init ($$, $2, global_bindings_p ()); } init /* Note how the declaration of the variable is in effect while its init is parsed! */ ! { finish_init (); ! decl_attributes ($5, $3); finish_decl ($5, $6, $2); } | notype_declarator maybeasm maybe_attribute *************** *** 1049,1056 **** attrib : IDENTIFIER ! { if (strcmp (IDENTIFIER_POINTER ($1), "packed")) warning ("`%s' attribute directive ignored", IDENTIFIER_POINTER ($1)); $$ = $1; } | IDENTIFIER '(' IDENTIFIER ')' { /* If not "mode (m)", then issue warning. */ --- 1066,1075 ---- attrib : IDENTIFIER ! { if (strcmp (IDENTIFIER_POINTER ($1), "packed") ! && strcmp (IDENTIFIER_POINTER ($1), "noreturn")) warning ("`%s' attribute directive ignored", IDENTIFIER_POINTER ($1)); $$ = $1; } + | TYPE_QUAL | IDENTIFIER '(' IDENTIFIER ')' { /* If not "mode (m)", then issue warning. */ *************** *** 1091,1116 **** NULL_TREE); } ; init: expr_no_commas ! | '{' '}' ! { $$ = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE); ! if (pedantic) ! pedwarn ("ANSI C forbids empty initializer braces"); } ! | '{' initlist '}' ! { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); } ! | '{' initlist ',' '}' ! { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); } | error ! { $$ = NULL_TREE; } ; ! /* This chain is built in reverse order, ! and put in forward order where initlist is used. */ ! initlist: ! init ! { $$ = build_tree_list (NULL_TREE, $1); } ! | initlist ',' init ! { $$ = tree_cons (NULL_TREE, $3, $1); } /* These are for labeled elements. The syntax for an array element initializer conflicts with the syntax for an Objective-C message, --- 1110,1158 ---- NULL_TREE); } ; + + /* Initializers. `init' is the entry point. */ init: expr_no_commas ! | '{' ! { really_start_incremental_init (NULL_TREE); ! /* Note that the call to clear_momentary ! is in process_init_element. */ ! push_momentary (); } ! initlist_maybe_comma '}' ! { $$ = pop_init_level (0); ! if ($$ == error_mark_node) ! pop_momentary (); ! else ! pop_momentary_nofree (); } ! | error ! { $$ = error_mark_node; ! pop_momentary (); } ; ! /* `initlist_maybe_comma' is the guts of an initializer in braces. */ ! initlist_maybe_comma: ! /* empty */ ! { if (pedantic) ! pedwarn ("ANSI C forbids empty initializer braces"); } ! | initlist1 maybecomma ! ; ! ! initlist1: ! initelt ! | initlist1 ',' initelt ! ; ! ! /* `initelt' is a single element of an initializer. ! It may use braces. */ ! initelt: ! expr_no_commas ! { process_init_element ($1); } ! | '{' ! { push_init_level (0); } ! initlist_maybe_comma '}' ! { process_init_element (pop_init_level (0)); } ! | error /* These are for labeled elements. The syntax for an array element initializer conflicts with the syntax for an Objective-C message, *************** *** 1117,1140 **** so don't include these productions in the Objective-C grammer. */ ifc ! | '[' expr_no_commas ELLIPSIS expr_no_commas ']' init ! { $$ = build_tree_list (tree_cons ($2, NULL_TREE, ! build_tree_list ($4, NULL_TREE)), ! $6); } ! | initlist ',' '[' expr_no_commas ELLIPSIS expr_no_commas ']' init ! { $$ = tree_cons (tree_cons ($4, NULL_TREE, ! build_tree_list ($6, NULL_TREE)), ! $8, ! $1); } ! | '[' expr_no_commas ']' init ! { $$ = build_tree_list ($2, $4); } ! | initlist ',' '[' expr_no_commas ']' init ! { $$ = tree_cons ($4, $6, $1); } end ifc ! | identifier ':' init ! { $$ = build_tree_list ($1, $3); } ! | initlist ',' identifier ':' init ! { $$ = tree_cons ($3, $5, $1); } ; ! nested_function: declarator --- 1159,1177 ---- so don't include these productions in the Objective-C grammer. */ ifc ! | '[' expr_no_commas ELLIPSIS expr_no_commas ']' '=' ! { set_init_index ($2, $4); } ! initelt ! | '[' expr_no_commas ']' '=' ! { set_init_index ($2, NULL_TREE); } ! initelt end ifc ! | identifier ':' ! { set_init_label ($1); } ! initelt ! | '.' identifier '=' ! { set_init_label ($2); } ! initelt ; ! nested_function: declarator *************** *** 1550,1554 **** { emit_line_note ($-1, $0); expand_start_cond (truthvalue_conversion ($3), 0); ! $1 = stmt_count; if_stmt_file = $-1; if_stmt_line = $0; --- 1587,1591 ---- { emit_line_note ($-1, $0); expand_start_cond (truthvalue_conversion ($3), 0); ! $$ = stmt_count; if_stmt_file = $-1; if_stmt_line = $0; *************** *** 1614,1617 **** --- 1651,1666 ---- { stmt_count++; emit_line_note ($-1, $0); + /* It appears that this should not be done--that a non-lvalue array + shouldn't get an error if the value isn't used. + Section 3.2.2.1 says that an array lvalue gets converted to a pointer + if it appears as a top-level expression, + but says nothing about non-lvalue arrays. */ + #if 0 + /* Call default_conversion to get an error + on referring to a register array if pedantic. */ + if (TREE_CODE (TREE_TYPE ($1)) == ARRAY_TYPE + || TREE_CODE (TREE_TYPE ($1)) == FUNCTION_TYPE) + $1 = default_conversion ($1); + #endif iterator_expand ($1); clear_momentary (); } *************** *** 1626,1629 **** --- 1675,1681 ---- | simple_if %prec IF { expand_end_cond (); + /* This warning is here instead of in simple_if, because we + do not want a warning if an empty if is followed by an + else statement. */ if (extra_warnings && stmt_count == $1) warning_with_file_and_line (if_stmt_file, if_stmt_line, *************** *** 1800,1804 **** if (TREE_CODE ($3) != VAR_DECL) error ("invalid `for (ITERATOR)' syntax"); ! if (! ITERATOR_P ($3)) error ("`%s' is not an iterator", IDENTIFIER_POINTER (DECL_NAME ($3))); --- 1852,1856 ---- if (TREE_CODE ($3) != VAR_DECL) error ("invalid `for (ITERATOR)' syntax"); ! else if (! ITERATOR_P ($3)) error ("`%s' is not an iterator", IDENTIFIER_POINTER (DECL_NAME ($3))); *************** *** 1854,1858 **** { tree duplicate; ! int success = pushcase (value, label, &duplicate); if (success == 1) error ("case label not within a switch statement"); --- 1906,1911 ---- { tree duplicate; ! int success = pushcase (value, convert_and_check, ! label, &duplicate); if (success == 1) error ("case label not within a switch statement"); *************** *** 1879,1883 **** { tree duplicate; ! int success = pushcase_range (value1, value2, label, &duplicate); if (success == 1) --- 1932,1937 ---- { tree duplicate; ! int success = pushcase_range (value1, value2, ! convert_and_check, label, &duplicate); if (success == 1) *************** *** 1901,1905 **** register tree label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); ! int success = pushcase (NULL_TREE, label, &duplicate); stmt_count++; if (success == 1) --- 1955,1959 ---- register tree label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); ! int success = pushcase (NULL_TREE, 0, label, &duplicate); stmt_count++; if (success == 1) diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/c-pragma.c gcc-2.5.0/c-pragma.c *** gcc-2.4.5/c-pragma.c Sat Aug 1 14:18:32 1992 --- gcc-2.5.0/c-pragma.c Sun Oct 10 19:18:57 1993 *************** *** 21,24 **** --- 21,25 ---- #include "config.h" #include "tree.h" + #include "function.h" #ifdef HANDLE_SYSV_PRAGMA *************** *** 29,32 **** --- 30,49 ---- #endif + /* See varasm.c for an identical definition. */ + enum pragma_state + { + ps_start, + ps_done, + ps_bad, + ps_weak, + ps_name, + ps_equals, + ps_value, + ps_pack, + ps_left, + ps_align, + ps_right + }; + /* When structure field packing is in effect, this variable is the number of bits to use as the maximum alignment. When packing is not *************** *** 46,63 **** tree token; { ! static enum pragma_state ! { ! ps_start, ! ps_done, ! ps_bad, ! ps_weak, ! ps_name, ! ps_equals, ! ps_value, ! ps_pack, ! ps_left, ! ps_align, ! ps_right ! } state = ps_start, type; static char *name; static char *value; --- 63,67 ---- tree token; { ! static enum pragma_state state = ps_start, type; static char *name; static char *value; *************** *** 77,98 **** #ifdef HANDLE_PRAGMA_WEAK if (HANDLE_PRAGMA_WEAK) ! { ! if (state == ps_name || state == ps_value) ! { ! fprintf (asm_out_file, "\t%s\t", WEAK_ASM_OP); ! ASM_OUTPUT_LABELREF (asm_out_file, name); ! fputc ('\n', asm_out_file); ! if (state == ps_value) ! { ! fprintf (asm_out_file, "\t%s\t", SET_ASM_OP); ! ASM_OUTPUT_LABELREF (asm_out_file, name); ! fputc (',', asm_out_file); ! ASM_OUTPUT_LABELREF (asm_out_file, value); ! fputc ('\n', asm_out_file); ! } ! } ! else if (! (state == ps_done || state == ps_start)) ! warning ("malformed `#pragma weak'"); ! } #endif /* HANDLE_PRAMA_WEAK */ } --- 81,86 ---- #ifdef HANDLE_PRAGMA_WEAK if (HANDLE_PRAGMA_WEAK) ! handle_pragma_weak (state, asm_out_file, name, value); ! #endif /* HANDLE_PRAMA_WEAK */ } diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/c-tree.h gcc-2.5.0/c-tree.h *** gcc-2.4.5/c-tree.h Fri Apr 9 19:01:03 1993 --- gcc-2.5.0/c-tree.h Tue Oct 5 15:09:42 1993 *************** *** 164,167 **** --- 164,172 ---- /* in c-common.c */ + extern void declare_function_name PROTO((void)); + extern void decl_attributes PROTO((tree, tree)); + extern void init_function_format_info PROTO((void)); + extern void record_function_format PROTO((tree, tree, int, int, int)); + extern void check_function_format PROTO((tree, tree, tree)); /* Print an error message for invalid operands to arith operation CODE. NOP_EXPR is used as a special case (see truthvalue_conversion). */ *************** *** 173,178 **** extern tree combine_strings PROTO((tree)); extern void constant_expression_warning PROTO((tree)); - extern void decl_attributes PROTO((tree, tree)); - extern void declare_function_name PROTO((void)); extern tree convert_and_check PROTO((tree, tree)); extern void overflow_warning PROTO((tree)); --- 178,181 ---- *************** *** 285,292 **** extern void pop_label_level PROTO((void)); extern tree poplevel PROTO((int, int, int)); ! extern void print_lang_decl PROTO((void)); extern void print_lang_identifier STDIO_PROTO((FILE *, tree, int)); ! extern void print_lang_type PROTO((void)); extern void push_c_function_context PROTO((void)); extern void push_label_level PROTO((void)); --- 288,297 ---- extern void pop_label_level PROTO((void)); extern tree poplevel PROTO((int, int, int)); ! extern void print_lang_decl STDIO_PROTO((FILE *, tree, ! int)); extern void print_lang_identifier STDIO_PROTO((FILE *, tree, int)); ! extern void print_lang_type STDIO_PROTO((FILE *, tree, ! int)); extern void push_c_function_context PROTO((void)); extern void push_label_level PROTO((void)); *************** *** 327,334 **** extern tree common_type PROTO((tree, tree)); extern tree default_conversion PROTO((tree)); - extern tree digest_init PROTO((tree, tree, tree *, int, int, char *)); extern tree parser_build_binary_op PROTO((enum tree_code, tree, tree)); extern tree require_complete_type PROTO((tree)); extern void store_init_value PROTO((tree, tree)); /* in c-iterate.c */ --- 332,346 ---- extern tree common_type PROTO((tree, tree)); extern tree default_conversion PROTO((tree)); extern tree parser_build_binary_op PROTO((enum tree_code, tree, tree)); extern tree require_complete_type PROTO((tree)); extern void store_init_value PROTO((tree, tree)); + extern void start_init PROTO((tree, tree, int)); + extern void finish_init PROTO((void)); + extern void really_start_incremental_init PROTO((tree)); + extern void push_init_level PROTO((int)); + extern tree pop_init_level PROTO((int)); + extern void set_init_index PROTO((tree, tree)); + extern void set_init_label PROTO((tree)); + extern void process_init_element PROTO((tree)); /* in c-iterate.c */ *************** *** 423,426 **** --- 435,442 ---- extern int flag_traditional; + + /* Nonzero means to allow single precision math even if we're generally + being traditional. */ + extern int flag_allow_single_precision; /* Nonzero means warn about suggesting putting in ()'s. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/c-typeck.c gcc-2.5.0/c-typeck.c *** gcc-2.4.5/c-typeck.c Sun Jun 20 13:53:48 1993 --- gcc-2.5.0/c-typeck.c Wed Oct 20 19:07:21 1993 *************** *** 1,4 **** /* Build expressions with type checking for C compiler. ! Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,4 ---- /* Build expressions with type checking for C compiler. ! Copyright (C) 1987, 1988, 1989, 1992, 1993 Free Software Foundation, Inc. This file is part of GNU CC. *************** *** 56,60 **** static tree convert_arguments (); static char *get_spelling (); ! tree digest_init (); static void pedantic_lvalue_warning (); tree truthvalue_conversion (); --- 56,60 ---- static tree convert_arguments (); static char *get_spelling (); ! static tree digest_init (); static void pedantic_lvalue_warning (); tree truthvalue_conversion (); *************** *** 63,66 **** --- 63,67 ---- static tree internal_build_compound_expr (); + void process_init_element (); /* Do `exp = require_complete_type (exp);' to make sure exp *************** *** 232,241 **** /* Same precision. Prefer longs to ints even when same size. */ ! if (t1 == long_unsigned_type_node ! || t2 == long_unsigned_type_node) return long_unsigned_type_node; ! if (t1 == long_integer_type_node ! || t2 == long_integer_type_node) { /* But preserve unsignedness from the other type, --- 233,242 ---- /* Same precision. Prefer longs to ints even when same size. */ ! if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node ! || TYPE_MAIN_VARIANT (t2) == long_unsigned_type_node) return long_unsigned_type_node; ! if (TYPE_MAIN_VARIANT (t1) == long_integer_type_node ! || TYPE_MAIN_VARIANT (t2) == long_integer_type_node) { /* But preserve unsignedness from the other type, *************** *** 762,767 **** size_int (TYPE_PRECISION (char_type_node))); /* size_binop does not put the constant in range, so do it now. */ ! if (TREE_CODE (t) == INTEGER_CST) ! TREE_CONSTANT_OVERFLOW (t) |= force_fit_type (t, 0); return t; } --- 763,768 ---- size_int (TYPE_PRECISION (char_type_node))); /* size_binop does not put the constant in range, so do it now. */ ! if (TREE_CODE (t) == INTEGER_CST && force_fit_type (t, 0)) ! TREE_CONSTANT_OVERFLOW (t) = TREE_OVERFLOW (t) = 1; return t; } *************** *** 944,948 **** type = type_for_size (MAX (TYPE_PRECISION (type), TYPE_PRECISION (integer_type_node)), ! (flag_traditional && TREE_UNSIGNED (type))); return convert (type, exp); } --- 945,951 ---- type = type_for_size (MAX (TYPE_PRECISION (type), TYPE_PRECISION (integer_type_node)), ! ((flag_traditional ! || TYPE_PRECISION (type) >= TYPE_PRECISION (integer_type_node)) ! && TREE_UNSIGNED (type))); return convert (type, exp); } *************** *** 958,962 **** return convert (integer_type_node, exp); } ! if (flag_traditional && TYPE_MAIN_VARIANT (type) == float_type_node) return convert (double_type_node, exp); if (code == VOID_TYPE) --- 961,966 ---- return convert (integer_type_node, exp); } ! if (flag_traditional && !flag_allow_single_precision ! && TYPE_MAIN_VARIANT (type) == float_type_node) return convert (double_type_node, exp); if (code == VOID_TYPE) *************** *** 974,978 **** --- 978,997 ---- tree restype = TREE_TYPE (type); tree ptrtype; + int constp = 0; + int volatilep = 0; + if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'r' + || TREE_CODE_CLASS (TREE_CODE (exp)) == 'd') + { + constp = TREE_READONLY (exp); + volatilep = TREE_THIS_VOLATILE (exp); + } + + if (TYPE_READONLY (type) || TYPE_VOLATILE (type) + || constp || volatilep) + restype = c_build_type_variant (restype, + TYPE_READONLY (type) || constp, + TYPE_VOLATILE (type) || volatilep); + if (TREE_CODE (exp) == INDIRECT_REF) return convert (TYPE_POINTER_TO (restype), *************** *** 993,1000 **** } - if (TYPE_READONLY (type) || TYPE_VOLATILE (type)) - restype = c_build_type_variant (restype, TYPE_READONLY (type), - TYPE_VOLATILE (type)); - ptrtype = build_pointer_type (restype); --- 1012,1015 ---- *************** *** 1020,1023 **** --- 1035,1133 ---- } + /* Look up component name in the structure type definition. + + If this component name is found indirectly within an anonymous union, + store in *INDIRECT the component which directly contains + that anonymous union. Otherwise, set *INDIRECT to 0. */ + + static tree + lookup_field (type, component, indirect) + tree type, component; + tree *indirect; + { + tree field; + + /* If TYPE_LANG_SPECIFIC is set, then it is a sorted array of pointers + to the field elements. Use a binary search on this array to quickly + find the element. Otherwise, do a linear search. TYPE_LANG_SPECIFIC + will always be set for structures which have many elements. */ + + if (TYPE_LANG_SPECIFIC (type)) + { + int bot, top, half; + tree *field_array = &TYPE_LANG_SPECIFIC (type)->elts[0]; + + field = TYPE_FIELDS (type); + bot = 0; + top = TYPE_LANG_SPECIFIC (type)->len; + while (top - bot > 1) + { + HOST_WIDE_INT cmp; + + half = (top - bot + 1) >> 1; + field = field_array[bot+half]; + + if (DECL_NAME (field) == NULL_TREE) + { + /* Step through all anon unions in linear fashion. */ + while (DECL_NAME (field_array[bot]) == NULL_TREE) + { + tree anon, junk; + + field = field_array[bot++]; + anon = lookup_field (TREE_TYPE (field), component, &junk); + if (anon != NULL_TREE) + { + *indirect = field; + return anon; + } + } + + /* Entire record is only anon unions. */ + if (bot > top) + return NULL_TREE; + + /* Restart the binary search, with new lower bound. */ + continue; + } + + cmp = (HOST_WIDE_INT) DECL_NAME (field) - (HOST_WIDE_INT) component; + if (cmp == 0) + break; + if (cmp < 0) + bot += half; + else + top = bot + half; + } + + if (DECL_NAME (field_array[bot]) == component) + field = field_array[bot]; + else if (DECL_NAME (field) != component) + field = 0; + } + else + { + for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + { + if (DECL_NAME (field) == NULL_TREE) + { + tree junk; + tree anon = lookup_field (TREE_TYPE (field), component, &junk); + if (anon != NULL_TREE) + { + *indirect = field; + return anon; + } + } + + if (DECL_NAME (field) == component) + break; + } + } + + *indirect = NULL_TREE; + return field; + } + /* Make an expression to refer to the COMPONENT field of structure or union value DATUM. COMPONENT is an IDENTIFIER_NODE. */ *************** *** 1053,1056 **** --- 1163,1168 ---- if (code == RECORD_TYPE || code == UNION_TYPE) { + tree indirect = 0; + if (TYPE_SIZE (type) == 0) { *************** *** 1059,1105 **** } ! /* Look up component name in the structure type definition. ! ! If TYPE_LANG_SPECIFIC is set, then it is a sorted array of pointers ! to the field elements. Use a binary search on this array to quickly ! find the element. Otherwise, do a linear search. TYPE_LANG_SPECIFIC ! will always be set for structures which have many elements. */ ! ! if (TYPE_LANG_SPECIFIC (type)) ! { ! int bot, top, half; ! tree *field_array = &TYPE_LANG_SPECIFIC (type)->elts[0]; ! ! field = TYPE_FIELDS (type); ! bot = 0; ! top = TYPE_LANG_SPECIFIC (type)->len; ! while (top - bot > 1) ! { ! int cmp; ! ! half = (top - bot + 1) >> 1; ! field = field_array[bot+half]; ! cmp = (long)DECL_NAME (field) - (long)component; ! if (cmp == 0) ! break; ! if (cmp < 0) ! bot += half; ! else ! top = bot + half; ! } ! ! if (DECL_NAME (field_array[bot]) == component) ! field = field_array[bot]; ! else if (DECL_NAME (field) != component) ! field = 0; ! } ! else ! { ! for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) ! { ! if (DECL_NAME (field) == component) ! break; ! } ! } if (!field) --- 1171,1175 ---- } ! field = lookup_field (type, component, &indirect); if (!field) *************** *** 1114,1117 **** --- 1184,1200 ---- return error_mark_node; + /* If FIELD was found buried within an anonymous union, + make one COMPONENT_REF to get that anonymous union, + then fall thru to make a second COMPONENT_REF to get FIELD. */ + if (indirect != 0) + { + ref = build (COMPONENT_REF, TREE_TYPE (indirect), datum, indirect); + if (TREE_READONLY (datum) || TREE_READONLY (indirect)) + TREE_READONLY (ref) = 1; + if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (indirect)) + TREE_THIS_VOLATILE (ref) = 1; + datum = ref; + } + ref = build (COMPONENT_REF, TREE_TYPE (field), datum, field); *************** *** 1173,1177 **** TREE_SIDE_EFFECTS (ref) = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer) || flag_volatile; ! TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t) || flag_volatile; return ref; } --- 1256,1260 ---- TREE_SIDE_EFFECTS (ref) = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer) || flag_volatile; ! TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t); return ref; } *************** *** 1241,1244 **** --- 1324,1338 ---- return error_mark_node; } + /* An array that is indexed by a constant value which is not within + the array bounds cannot be stored in a register either; because we + would get a crash in store_bit_field/extract_bit_field when trying + to access a non-existent part of the register. */ + if (TREE_CODE (index) == INTEGER_CST + && TYPE_VALUES (TREE_TYPE (array)) + && ! int_fits_type_p (index, TYPE_VALUES (TREE_TYPE (array)))) + { + if (mark_addressable (array) == 0) + return error_mark_node; + } if (pedantic && !lvalue_p (array)) *************** *** 1310,1832 **** } - /* Check a printf/fprintf/sprintf/scanf/fscanf/sscanf format against PARAMS. */ - - #define ISDIGIT(c) ((c) >= '0' && (c) <= '9') - - #define T_I &integer_type_node - #define T_L &long_integer_type_node - #define T_S &short_integer_type_node - #define T_UI &unsigned_type_node - #define T_UL &long_unsigned_type_node - #define T_US &short_unsigned_type_node - #define T_F &float_type_node - #define T_D &double_type_node - #define T_LD &long_double_type_node - #define T_C &char_type_node - #define T_V &void_type_node - #define T_W &wchar_type_node - - typedef struct - { - char *format_chars; - int pointer_count; - /* Type of argument if no length modifier is used. */ - tree *nolen; - /* Type of argument if length modifier for shortening is used. - If NULL, then this modifier is not allowed. */ - tree *hlen; - /* Type of argument if length modifier `l' is used. - If NULL, then this modifier is not allowed. */ - tree *llen; - /* Type of argument if length modifier `L' is used. - If NULL, then this modifier is not allowed. */ - tree *bigllen; - /* List of other modifier characters allowed with these options. */ - char *flag_chars; - } format_char_info; - - static format_char_info print_table[] - = { - { "di", 0, T_I, T_I, T_L, NULL, "-wp0 +" }, - { "oxX", 0, T_UI, T_UI, T_UL, NULL, "-wp0#" }, - { "u", 0, T_UI, T_UI, T_UL, NULL, "-wp0" }, - { "feEgG", 0, T_D, NULL, NULL, T_LD, "-wp0 +#" }, - { "c", 0, T_I, NULL, T_W, NULL, "-w" }, - { "C", 0, T_W, NULL, NULL, NULL, "-w" }, - { "s", 1, T_C, NULL, T_W, NULL, "-wp" }, - { "S", 1, T_W, NULL, NULL, NULL, "-wp" }, - { "p", 1, T_V, NULL, NULL, NULL, "-" }, - { "n", 1, T_I, T_S, T_L, NULL, "" }, - { NULL } - }; - - static format_char_info scan_table[] - = { - { "di", 1, T_I, T_S, T_L, NULL, "*" }, - { "ouxX", 1, T_UI, T_US, T_UL, NULL, "*" }, - { "efgEG", 1, T_F, NULL, T_D, T_LD, "*" }, - { "sc", 1, T_C, NULL, T_W, NULL, "*" }, - { "[", 1, T_C, NULL, NULL, NULL, "*" }, - { "C", 1, T_W, NULL, NULL, NULL, "*" }, - { "S", 1, T_W, NULL, NULL, NULL, "*" }, - { "p", 2, T_V, NULL, NULL, NULL, "*" }, - { "n", 1, T_I, T_S, T_L, NULL, "" }, - { NULL } - }; - - typedef struct - { - tree function_ident; /* identifier such as "printf" */ - int is_scan; /* TRUE if *scanf */ - int format_num; /* number of format argument */ - int first_arg_num; /* number of first arg (zero for varargs) */ - } function_info; - - static unsigned int function_info_entries = 0; - static function_info *function_info_table = NULL; - - /* Record information for argument format checking. FUNCTION_IDENT is - the identifier node for the name of the function to check (its decl - need not exist yet). IS_SCAN is true for scanf-type format checking; - false indicates printf-style format checking. FORMAT_NUM is the number - of the argument which is the format control string (starting from 1). - FIRST_ARG_NUM is the number of the first actual argument to check - against teh format string, or zero if no checking is not be done - (e.g. for varargs such as vfprintf). */ - - void - record_format_info (function_ident, is_scan, format_num, first_arg_num) - tree function_ident; - int is_scan; - int format_num; - int first_arg_num; - { - function_info *info; - - function_info_entries++; - if (function_info_table) - function_info_table - = (function_info *) xrealloc (function_info_table, - function_info_entries * sizeof (function_info)); - else - function_info_table = (function_info *) xmalloc (sizeof (function_info)); - - info = &function_info_table[function_info_entries - 1]; - - info->function_ident = function_ident; - info->is_scan = is_scan; - info->format_num = format_num; - info->first_arg_num = first_arg_num; - } - - /* Initialize the table of functions to perform format checking on. - The ANSI functions are always checked (whether is - included or not), since it is common to call printf without - including . There shouldn't be a problem with this, - since ANSI reserves these function names whether you include the - header file or not. In any case, the checking is harmless. */ - - void - init_format_info_table () - { - record_format_info (get_identifier ("printf"), 0, 1, 2); - record_format_info (get_identifier ("fprintf"), 0, 2, 3); - record_format_info (get_identifier ("sprintf"), 0, 2, 3); - record_format_info (get_identifier ("scanf"), 1, 1, 2); - record_format_info (get_identifier ("fscanf"), 1, 2, 3); - record_format_info (get_identifier ("sscanf"), 1, 2, 3); - record_format_info (get_identifier ("vprintf"), 0, 1, 0); - record_format_info (get_identifier ("vfprintf"), 0, 2, 0); - record_format_info (get_identifier ("vsprintf"), 0, 2, 0); - } - - static char tfaff[] = "too few arguments for format"; - - /* Check the argument list of a call to printf, scanf, etc. - INFO points to the element of function_info_table. - PARAMS is the list of argument values. */ - - static void - check_format (info, params) - function_info *info; - tree params; - { - int i; - int arg_num; - int suppressed, wide, precise; - int length_char; - int format_char; - int format_length; - tree format_tree; - tree cur_param; - tree cur_type; - tree wanted_type; - char *format_chars; - format_char_info *fci; - static char message[132]; - char flag_chars[8]; - - /* Skip to format argument. If the argument isn't available, there's - no work for us to do; prototype checking will catch the problem. */ - for (arg_num = 1; ; ++arg_num) - { - if (params == 0) - return; - if (arg_num == info->format_num) - break; - params = TREE_CHAIN (params); - } - format_tree = TREE_VALUE (params); - params = TREE_CHAIN (params); - if (format_tree == 0) - return; - /* We can only check the format if it's a string constant. */ - while (TREE_CODE (format_tree) == NOP_EXPR) - format_tree = TREE_OPERAND (format_tree, 0); /* strip coercion */ - if (format_tree == null_pointer_node) - { - warning ("null format string"); - return; - } - if (TREE_CODE (format_tree) != ADDR_EXPR) - return; - format_tree = TREE_OPERAND (format_tree, 0); - if (TREE_CODE (format_tree) != STRING_CST) - return; - format_chars = TREE_STRING_POINTER (format_tree); - format_length = TREE_STRING_LENGTH (format_tree); - if (format_length <= 1) - warning ("zero-length format string"); - if (format_chars[--format_length] != 0) - { - warning ("unterminated format string"); - return; - } - /* Skip to first argument to check. */ - while (arg_num + 1 < info->first_arg_num) - { - if (params == 0) - return; - params = TREE_CHAIN (params); - ++arg_num; - } - while (1) - { - if (*format_chars == 0) - { - if (format_chars - TREE_STRING_POINTER (format_tree) != format_length) - warning ("embedded `\\0' in format"); - if (info->first_arg_num != 0 && params != 0) - warning ("too many arguments for format"); - return; - } - if (*format_chars++ != '%') - continue; - if (*format_chars == 0) - { - warning ("spurious trailing `%%' in format"); - continue; - } - if (*format_chars == '%') - { - ++format_chars; - continue; - } - flag_chars[0] = 0; - suppressed = wide = precise = FALSE; - if (info->is_scan) - { - suppressed = *format_chars == '*'; - if (suppressed) - ++format_chars; - while (ISDIGIT (*format_chars)) - ++format_chars; - } - else - { - while (*format_chars != 0 && index (" +#0-", *format_chars) != 0) - { - if (index (flag_chars, *format_chars) != 0) - { - sprintf (message, "repeated `%c' flag in format", - *format_chars); - warning (message); - } - i = strlen (flag_chars); - flag_chars[i++] = *format_chars++; - flag_chars[i] = 0; - } - /* "If the space and + flags both appear, - the space flag will be ignored." */ - if (index (flag_chars, ' ') != 0 - && index (flag_chars, '+') != 0) - warning ("use of both ` ' and `+' flags in format"); - /* "If the 0 and - flags both appear, - the 0 flag will be ignored." */ - if (index (flag_chars, '0') != 0 - && index (flag_chars, '-') != 0) - warning ("use of both `0' and `-' flags in format"); - if (*format_chars == '*') - { - wide = TRUE; - /* "...a field width...may be indicated by an asterisk. - In this case, an int argument supplies the field width..." */ - ++format_chars; - if (params == 0) - { - warning (tfaff); - return; - } - if (info->first_arg_num != 0) - { - cur_param = TREE_VALUE (params); - params = TREE_CHAIN (params); - ++arg_num; - /* size_t is generally not valid here. - It will work on most machines, because size_t and int - have the same mode. But might as well warn anyway, - since it will fail on other machines. */ - if (TYPE_MAIN_VARIANT (TREE_TYPE (cur_param)) - != integer_type_node) - { - sprintf (message, - "field width is not type int (arg %d)", - arg_num); - warning (message); - } - } - } - else - { - while (ISDIGIT (*format_chars)) - { - wide = TRUE; - ++format_chars; - } - } - if (*format_chars == '.') - { - precise = TRUE; - ++format_chars; - if (*format_chars != '*' && !ISDIGIT (*format_chars)) - warning ("`.' not followed by `*' or digit in format"); - /* "...a...precision...may be indicated by an asterisk. - In this case, an int argument supplies the...precision." */ - if (*format_chars == '*') - { - if (info->first_arg_num != 0) - { - ++format_chars; - if (params == 0) - { - warning (tfaff); - return; - } - cur_param = TREE_VALUE (params); - params = TREE_CHAIN (params); - ++arg_num; - if (TYPE_MAIN_VARIANT (TREE_TYPE (cur_param)) - != integer_type_node) - { - sprintf (message, - "field width is not type int (arg %d)", - arg_num); - warning (message); - } - } - } - else - { - while (ISDIGIT (*format_chars)) - ++format_chars; - } - } - } - if (*format_chars == 'h' || *format_chars == 'l' || *format_chars == 'L') - length_char = *format_chars++; - else - length_char = 0; - if (suppressed && length_char != 0) - { - sprintf (message, - "use of `*' and `%c' together in format", - length_char); - warning (message); - } - format_char = *format_chars; - if (format_char == 0) - { - warning ("conversion lacks type at end of format"); - continue; - } - format_chars++; - fci = info->is_scan ? scan_table : print_table; - while (1) - { - if (fci->format_chars == 0 - || index (fci->format_chars, format_char) != 0) - break; - ++fci; - } - if (fci->format_chars == 0) - { - if (format_char >= 040 && format_char < 0177) - sprintf (message, - "unknown conversion type character `%c' in format", - format_char); - else - sprintf (message, - "unknown conversion type character 0x%x in format", - format_char); - warning (message); - continue; - } - if (wide && index (fci->flag_chars, 'w') == 0) - { - sprintf (message, "width used with `%c' format", - format_char); - warning (message); - } - if (precise && index (fci->flag_chars, 'p') == 0) - { - sprintf (message, "precision used with `%c' format", - format_char); - warning (message); - } - if (suppressed) - { - if (index (fci->flag_chars, '*') == 0) - { - sprintf (message, - "suppression of `%c' conversion in format", - format_char); - warning (message); - } - continue; - } - for (i = 0; flag_chars[i] != 0; ++i) - { - if (index (fci->flag_chars, flag_chars[i]) == 0) - { - sprintf (message, "flag `%c' used with type `%c'", - flag_chars[i], format_char); - warning (message); - } - } - if (precise && index (flag_chars, '0') != 0 - && (format_char == 'd' || format_char == 'i' - || format_char == 'o' || format_char == 'u' - || format_char == 'x' || format_char == 'x')) - { - sprintf (message, - "precision and `0' flag not both allowed with `%c' format", - format_char); - warning (message); - } - switch (length_char) - { - default: wanted_type = fci->nolen ? *(fci->nolen) : 0; break; - case 'h': wanted_type = fci->hlen ? *(fci->hlen) : 0; break; - case 'l': wanted_type = fci->llen ? *(fci->llen) : 0; break; - case 'L': wanted_type = fci->bigllen ? *(fci->bigllen) : 0; break; - } - if (wanted_type == 0) - { - sprintf (message, - "use of `%c' length character with `%c' type character", - length_char, format_char); - warning (message); - } - - /* - ** XXX -- should kvetch about stuff such as - ** { - ** const int i; - ** - ** scanf ("%d", &i); - ** } - */ - - /* Finally. . .check type of argument against desired type! */ - if (info->first_arg_num == 0) - continue; - if (params == 0) - { - warning (tfaff); - return; - } - cur_param = TREE_VALUE (params); - params = TREE_CHAIN (params); - ++arg_num; - cur_type = TREE_TYPE (cur_param); - - /* Check the types of any additional pointer arguments - that precede the "real" argument. */ - for (i = 0; i < fci->pointer_count; ++i) - { - if (TREE_CODE (cur_type) == POINTER_TYPE) - { - cur_type = TREE_TYPE (cur_type); - continue; - } - sprintf (message, - "format argument is not a %s (arg %d)", - ((fci->pointer_count == 1) ? "pointer" : "pointer to a pointer"), - arg_num); - warning (message); - break; - } - - /* Check the type of the "real" argument, if there's a type we want. */ - if (i == fci->pointer_count && wanted_type != 0 - && wanted_type != TYPE_MAIN_VARIANT (cur_type) - /* If we want `void *', allow any pointer type. - (Anything else would already have got a warning.) */ - && ! (wanted_type == void_type_node - && fci->pointer_count > 0) - /* Don't warn about differences merely in signedness. */ - && !(TREE_CODE (wanted_type) == INTEGER_TYPE - && TREE_CODE (cur_type) == INTEGER_TYPE - && TYPE_PRECISION (wanted_type) == TYPE_PRECISION (cur_type))) - { - register char *this; - register char *that; - - this = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (wanted_type))); - that = 0; - if (TREE_CODE (cur_type) != ERROR_MARK - && TYPE_NAME (cur_type) != 0 - && TREE_CODE (cur_type) != INTEGER_TYPE - && !(TREE_CODE (cur_type) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (cur_type)) == INTEGER_TYPE)) - { - if (TREE_CODE (TYPE_NAME (cur_type)) == TYPE_DECL - && DECL_NAME (TYPE_NAME (cur_type)) != 0) - that = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (cur_type))); - else - that = IDENTIFIER_POINTER (TYPE_NAME (cur_type)); - } - - /* A nameless type can't possibly match what the format wants. - So there will be a warning for it. - Make up a string to describe vaguely what it is. */ - if (that == 0) - { - if (TREE_CODE (cur_type) == POINTER_TYPE) - that = "pointer"; - else - that = "different type"; - } - - if (strcmp (this, that) != 0) - { - sprintf (message, "%s format, %s arg (arg %d)", - this, that, arg_num); - warning (message); - } - } - } - } - /* Build a function call to function FUNCTION with parameters PARAMS. PARAMS is a list--a chain of TREE_LIST nodes--in which the --- 1404,1407 ---- *************** *** 1840,1844 **** register tree fntype, fundecl; register tree coerced_params; ! tree name = NULL_TREE; /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue. */ --- 1415,1419 ---- register tree fntype, fundecl; register tree coerced_params; ! tree name = NULL_TREE, assembler_name = NULL_TREE; /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue. */ *************** *** 1849,1852 **** --- 1424,1429 ---- { name = DECL_NAME (function); + assembler_name = DECL_ASSEMBLER_NAME (function); + /* Differs from default_conversion by not setting TREE_ADDRESSABLE (because calling an inline function does not mean the function *************** *** 1883,1901 **** /* Check for errors in format strings. */ - if (warn_format && name != 0) - { - unsigned int i; - - /* See if this function is a format function. */ - for (i = 0; i < function_info_entries; i++) - if (function_info_table[i].function_ident == name) - { - register char *message; ! /* If so, check it. */ ! check_format (&function_info_table[i], coerced_params); ! break; ! } ! } /* Recognize certain built-in functions so we can make tree-codes --- 1460,1466 ---- /* Check for errors in format strings. */ ! if (warn_format && (name || assembler_name)) ! check_function_format (name, assembler_name, coerced_params); /* Recognize certain built-in functions so we can make tree-codes *************** *** 1999,2002 **** --- 1564,1568 ---- { tree parmname; + tree type0 = type; #ifdef PROMOTE_PROTOTYPES /* Rather than truncating and then reextending, *************** *** 2003,2007 **** 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; --- 1569,1574 ---- convert directly to int, if that's the type we will want. */ if (! flag_traditional ! && (TREE_CODE (type) == INTEGER_TYPE ! || TREE_CODE (type) == ENUMERAL_TYPE) && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))) type = integer_type_node; *************** *** 2074,2077 **** --- 1641,1650 ---- if a constant value is unaffected. */ ; + /* Likewise for a constant in a NOP_EXPR. */ + else if (TREE_CODE (val) == NOP_EXPR + && TREE_CODE (TREE_OPERAND (val, 0)) == INTEGER_CST + && int_fits_type_p (TREE_OPERAND (val, 0), type)) + ; + #if 0 /* We never get such tree structure here. */ else if (TREE_CODE (TREE_TYPE (val)) == ENUMERAL_TYPE && int_fits_type_p (TYPE_MIN_VALUE (TREE_TYPE (val)), type) *************** *** 2080,2083 **** --- 1653,1664 ---- if an enum value is unaffected. */ ; + #endif + /* If the value is extended from a narrower + unsigned type, it doesn't matter whether we + pass it as signed or unsigned; the value + certainly is the same either way. */ + else if (TYPE_PRECISION (TREE_TYPE (val)) < TYPE_PRECISION (type) + && TREE_UNSIGNED (TREE_TYPE (val))) + ; else if (TREE_UNSIGNED (type)) warn_for_assignment ("%s as unsigned due to prototype", (char *) 0, name, parmnum + 1); *************** *** 2092,2096 **** #ifdef PROMOTE_PROTOTYPES ! if (TREE_CODE (type) == INTEGER_TYPE && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))) parmval = default_conversion (parmval); --- 1673,1678 ---- #ifdef PROMOTE_PROTOTYPES ! if ((TREE_CODE (type) == INTEGER_TYPE ! || TREE_CODE (type) == ENUMERAL_TYPE) && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))) parmval = default_conversion (parmval); *************** *** 2214,2221 **** { int flag = TREE_CONSTANT (result); ! /* We use NOP_EXPR rather than NON_LVALUE_EXPR ! so that convert_for_assignment won't strip it. ! That way, we get warnings for things like p = (1 - 1). */ ! result = build1 (NOP_EXPR, TREE_TYPE (result), result); C_SET_EXP_ORIGINAL_CODE (result, code); TREE_CONSTANT (result) = flag; --- 1796,1804 ---- { int flag = TREE_CONSTANT (result); ! /* We used to use NOP_EXPR rather than NON_LVALUE_EXPR ! so that convert_for_assignment wouldn't strip it. ! That way, we got warnings for things like p = (1 - 1). ! But it turns out we should not get those warnings. */ ! result = build1 (NON_LVALUE_EXPR, TREE_TYPE (result), result); C_SET_EXP_ORIGINAL_CODE (result, code); TREE_CONSTANT (result) = flag; *************** *** 2361,2365 **** /* When dividing two signed integers, you have to promote to int. E.g. (short) -32868 / (short) -1 doesn't fit in a short. */ ! shorten = TREE_UNSIGNED (op0); common = 1; } --- 1944,1948 ---- /* When dividing two signed integers, you have to promote to int. E.g. (short) -32868 / (short) -1 doesn't fit in a short. */ ! shorten = TREE_UNSIGNED (orig_op0); common = 1; } *************** *** 2530,2534 **** register tree tt1 = TREE_TYPE (type1); /* Anything compares with void *. void * compares with anything. ! Otherwise, the targets must be the same. */ if (comp_target_types (type0, type1)) ; --- 2113,2118 ---- register tree tt1 = TREE_TYPE (type1); /* Anything compares with void *. void * compares with anything. ! Otherwise, the targets must be compatible ! and both must be object or both incomplete. */ if (comp_target_types (type0, type1)) ; *************** *** 2535,2539 **** else if (TYPE_MAIN_VARIANT (tt0) == void_type_node) { ! if (pedantic && !integer_zerop (op0) && TREE_CODE (tt1) == FUNCTION_TYPE) pedwarn ("ANSI C forbids comparison of `void *' with function pointer"); --- 2119,2125 ---- else if (TYPE_MAIN_VARIANT (tt0) == void_type_node) { ! /* op0 != orig_op0 detects the case of something ! whose value is 0 but which isn't a valid null ptr const. */ ! if (pedantic && (!integer_zerop (op0) || op0 != orig_op0) && TREE_CODE (tt1) == FUNCTION_TYPE) pedwarn ("ANSI C forbids comparison of `void *' with function pointer"); *************** *** 2541,2545 **** else if (TYPE_MAIN_VARIANT (tt1) == void_type_node) { ! if (pedantic && !integer_zerop (op1) && TREE_CODE (tt0) == FUNCTION_TYPE) pedwarn ("ANSI C forbids comparison of `void *' with function pointer"); --- 2127,2131 ---- else if (TYPE_MAIN_VARIANT (tt1) == void_type_node) { ! if (pedantic && (!integer_zerop (op1) || op1 != orig_op1) && TREE_CODE (tt0) == FUNCTION_TYPE) pedwarn ("ANSI C forbids comparison of `void *' with function pointer"); *************** *** 2603,2606 **** --- 2189,2195 ---- if (! comp_target_types (type0, type1)) pedwarn ("comparison of distinct pointer types lacks a cast"); + else if ((TYPE_SIZE (TREE_TYPE (type0)) != 0) + != (TYPE_SIZE (TREE_TYPE (type1)) != 0)) + pedwarn ("comparison of complete and incomplete pointers"); else if (pedantic && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE) *************** *** 3014,3018 **** case BIT_NOT_EXPR: ! if (typecode != INTEGER_TYPE) errstring = "wrong type argument to bit-complement"; else if (!noconvert) --- 2603,2613 ---- case BIT_NOT_EXPR: ! if (typecode == COMPLEX_TYPE) ! { ! code = CONJ_EXPR; ! if (!noconvert) ! arg = default_conversion (arg); ! } ! else if (typecode != INTEGER_TYPE) errstring = "wrong type argument to bit-complement"; else if (!noconvert) *************** *** 3028,3031 **** --- 2623,2635 ---- break; + case CONJ_EXPR: + /* Conjugating a real value is a no-op, but allow it anyway. */ + if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE + || typecode == COMPLEX_TYPE)) + errstring = "wrong type argument to conjugation"; + else if (!noconvert) + arg = default_conversion (arg); + break; + case TRUTH_NOT_EXPR: if (typecode != INTEGER_TYPE *************** *** 3561,3564 **** --- 3165,3169 ---- register enum tree_code code2; register tree result_type = NULL; + tree orig_op1 = op1, orig_op2 = op2; /* If second operand is omitted, it is the same as the first one; *************** *** 3584,3588 **** { if (TREE_CODE (ifexp) == INTEGER_CST) ! return (integer_zerop (ifexp) ? op2 : op1); return fold (build (COND_EXPR, TREE_TYPE (op1), ifexp, op1, op2)); --- 3189,3193 ---- { if (TREE_CODE (ifexp) == INTEGER_CST) ! return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1); return fold (build (COND_EXPR, TREE_TYPE (op1), ifexp, op1, op2)); *************** *** 3631,3637 **** if (comp_target_types (type1, type2)) result_type = common_type (type1, type2); ! else if (integer_zerop (op1) && TREE_TYPE (type1) == void_type_node) result_type = qualify_type (type2, type1); ! else if (integer_zerop (op2) && TREE_TYPE (type2) == void_type_node) result_type = qualify_type (type1, type2); else if (TYPE_MAIN_VARIANT (TREE_TYPE (type1)) == void_type_node) --- 3236,3244 ---- if (comp_target_types (type1, type2)) result_type = common_type (type1, type2); ! else if (integer_zerop (op1) && TREE_TYPE (type1) == void_type_node ! && TREE_CODE (orig_op1) != NOP_EXPR) result_type = qualify_type (type2, type1); ! else if (integer_zerop (op2) && TREE_TYPE (type2) == void_type_node ! && TREE_CODE (orig_op2) != NOP_EXPR) result_type = qualify_type (type1, type2); else if (TYPE_MAIN_VARIANT (TREE_TYPE (type1)) == void_type_node) *************** *** 3709,3713 **** result_type = TREE_TYPE (op1); if (TREE_CONSTANT (ifexp)) ! return (integer_zerop (ifexp) ? op2 : op1); if (TYPE_MODE (result_type) == BLKmode) --- 3316,3320 ---- result_type = TREE_TYPE (op1); if (TREE_CONSTANT (ifexp)) ! return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1); if (TYPE_MODE (result_type) == BLKmode) *************** *** 3742,3746 **** if (TREE_CODE (ifexp) == INTEGER_CST) ! return integer_zerop (ifexp) ? op2 : op1; return fold (build (COND_EXPR, result_type, ifexp, op1, op2)); --- 3349,3353 ---- if (TREE_CODE (ifexp) == INTEGER_CST) ! return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1); return fold (build (COND_EXPR, result_type, ifexp, op1, op2)); *************** *** 3841,3844 **** --- 3448,3455 ---- { tree field; + if (TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE + || TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE) + value = default_conversion (value); + for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (field)), *************** *** 3862,3868 **** else name = ""; ! return digest_init (type, build_nt (CONSTRUCTOR, NULL_TREE, ! build_tree_list (field, value)), ! NULL_PTR, 0, 0, name); } error ("cast to union type from type not present in union"); --- 3473,3479 ---- else name = ""; ! return digest_init (type, build (CONSTRUCTOR, type, NULL_TREE, ! build_tree_list (field, value)), ! 0, 0); } error ("cast to union type from type not present in union"); *************** *** 3871,3875 **** else { ! tree otype; /* If casting to void, avoid the error that would come --- 3482,3486 ---- else { ! tree otype, ovalue; /* If casting to void, avoid the error that would come *************** *** 3926,3929 **** --- 3537,3541 ---- warning ("cast to pointer from integer of different size"); + ovalue = value; value = convert (type, value); *************** *** 3930,3941 **** /* Ignore any integer overflow caused by the cast. */ if (TREE_CODE (value) == INTEGER_CST) ! TREE_CONSTANT_OVERFLOW (value) = 0; } if (value == expr && pedantic) ! { ! /* If pedantic, don't let a cast be an lvalue. */ ! return non_lvalue (value); ! } return value; } --- 3542,3561 ---- /* Ignore any integer overflow caused by the cast. */ if (TREE_CODE (value) == INTEGER_CST) ! { ! TREE_OVERFLOW (value) = TREE_OVERFLOW (ovalue); ! TREE_CONSTANT_OVERFLOW (value) = TREE_CONSTANT_OVERFLOW (ovalue); ! } } + /* Pedantically, don't ley (void *) (FOO *) 0 be a null pointer constant. */ + if (pedantic && TREE_CODE (value) == INTEGER_CST + && TREE_CODE (expr) == INTEGER_CST + && TREE_CODE (TREE_TYPE (expr)) != INTEGER_TYPE) + value = non_lvalue (value); + + /* If pedantic, don't let a cast be an lvalue. */ if (value == expr && pedantic) ! value = non_lvalue (value); ! return value; } *************** *** 3978,3986 **** case COMPOUND_EXPR: pedantic_lvalue_warning (COMPOUND_EXPR); return build (COMPOUND_EXPR, lhstype, ! TREE_OPERAND (lhs, 0), ! build_modify_expr (TREE_OPERAND (lhs, 1), ! modifycode, rhs)); ! /* Handle (a ? b : c) used as an "lvalue". */ case COND_EXPR: --- 3598,3608 ---- case COMPOUND_EXPR: pedantic_lvalue_warning (COMPOUND_EXPR); + newrhs = build_modify_expr (TREE_OPERAND (lhs, 1), + modifycode, rhs); + if (TREE_CODE (newrhs) == ERROR_MARK) + return error_mark_node; return build (COMPOUND_EXPR, lhstype, ! TREE_OPERAND (lhs, 0), newrhs); ! /* Handle (a ? b : c) used as an "lvalue". */ case COND_EXPR: *************** *** 3997,4000 **** --- 3619,3624 ---- build_modify_expr (TREE_OPERAND (lhs, 2), modifycode, rhs)); + if (TREE_CODE (cond) == ERROR_MARK) + return cond; /* Make sure the code to compute the rhs comes out before the split. */ *************** *** 4039,4042 **** --- 3663,3668 ---- convert (TREE_TYPE (inner_lhs), convert (lhstype, newrhs))); + if (TREE_CODE (result) == ERROR_MARK) + return result; pedantic_lvalue_warning (CONVERT_EXPR); return convert (TREE_TYPE (lhs), result); *************** *** 4161,4169 **** (coder == INTEGER_TYPE || coder == REAL_TYPE || coder == ENUMERAL_TYPE || codel == COMPLEX_TYPE)) ! /* Don't use convert_and_check here. If the input has type int ! and did not overflow, and we are converting it here to a short, ! we don't want an error. A warning would be okay, but it's too risky now ! to add an option to convert_and_check to get just warnings. */ ! return convert (type, rhs); /* Conversion to a union from its member types. */ else if (codel == UNION_TYPE) --- 3787,3791 ---- (coder == INTEGER_TYPE || coder == REAL_TYPE || coder == ENUMERAL_TYPE || codel == COMPLEX_TYPE)) ! return convert_and_check (type, rhs); /* Conversion to a union from its member types. */ else if (codel == UNION_TYPE) *************** *** 4238,4242 **** if (TYPE_MAIN_VARIANT (ttl) == void_type_node || TYPE_MAIN_VARIANT (ttr) == void_type_node ! || comp_target_types (type, rhstype)) { if (pedantic --- 3860,3866 ---- if (TYPE_MAIN_VARIANT (ttl) == void_type_node || TYPE_MAIN_VARIANT (ttr) == void_type_node ! || comp_target_types (type, rhstype) ! || (unsigned_type (TYPE_MAIN_VARIANT (ttl)) ! == unsigned_type (TYPE_MAIN_VARIANT (ttr)))) { if (pedantic *************** *** 4245,4249 **** || (TYPE_MAIN_VARIANT (ttr) == void_type_node ! && !integer_zerop (rhs) && TREE_CODE (ttl) == FUNCTION_TYPE))) warn_for_assignment ("ANSI forbids %s between function pointer and `void *'", --- 3869,3875 ---- || (TYPE_MAIN_VARIANT (ttr) == void_type_node ! /* Check TREE_CODE to catch cases like (void *) (char *) 0 ! which are not ANSI null ptr constants. */ ! && (!integer_zerop (rhs) || TREE_CODE (rhs) == NOP_EXPR) && TREE_CODE (ttl) == FUNCTION_TYPE))) warn_for_assignment ("ANSI forbids %s between function pointer and `void *'", *************** *** 4257,4263 **** warn_for_assignment ("%s discards `const' from pointer target type", get_spelling (errtype), funname, parmnum); ! if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr)) warn_for_assignment ("%s discards `volatile' from pointer target type", get_spelling (errtype), funname, parmnum); } else --- 3883,3899 ---- warn_for_assignment ("%s discards `const' from pointer target type", get_spelling (errtype), funname, parmnum); ! else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr)) warn_for_assignment ("%s discards `volatile' from pointer target type", get_spelling (errtype), funname, parmnum); + /* If this is not a case of ignoring a mismatch in signedness, + no warning. */ + else if (TYPE_MAIN_VARIANT (ttl) == void_type_node + || TYPE_MAIN_VARIANT (ttr) == void_type_node + || comp_target_types (type, rhstype)) + ; + /* If there is a mismatch, do warn. */ + else if (pedantic) + warn_for_assignment ("pointer targets in %s differ in signedness", + get_spelling (errtype), funname, parmnum); } else *************** *** 4275,4285 **** } } - else if (unsigned_type (TYPE_MAIN_VARIANT (ttl)) - == unsigned_type (TYPE_MAIN_VARIANT (ttr))) - { - if (pedantic) - warn_for_assignment ("pointer targets in %s differ in signedness", - get_spelling (errtype), funname, parmnum); - } else warn_for_assignment ("%s from incompatible pointer type", --- 3911,3914 ---- *************** *** 4290,4295 **** { /* An explicit constant 0 can convert to a pointer, ! but not a 0 that results from casting or folding. */ ! if (! (TREE_CODE (rhs) == INTEGER_CST && integer_zerop (rhs))) { warn_for_assignment ("%s makes pointer from integer without a cast", --- 3919,3930 ---- { /* An explicit constant 0 can convert to a pointer, ! or one that results from arithmetic, even including ! a cast to integer type. */ ! if (! (TREE_CODE (rhs) == INTEGER_CST && integer_zerop (rhs)) ! && ! ! (TREE_CODE (rhs) == NOP_EXPR ! && TREE_CODE (TREE_TYPE (rhs)) == INTEGER_TYPE ! && TREE_CODE (TREE_OPERAND (rhs, 0)) == INTEGER_CST ! && integer_zerop (TREE_OPERAND (rhs, 0)))) { warn_for_assignment ("%s makes pointer from integer without a cast", *************** *** 4481,4484 **** --- 4116,4145 ---- return 0; } + + /* If VALUE is a compound expr all of whose expressions are constant, then + return its value. Otherwise, return error_mark_node. + + This is for handling COMPOUND_EXPRs as initializer elements + which is allowed with a warning when -pedantic is specified. */ + + static tree + valid_compound_expr_initializer (value, endtype) + tree value; + tree endtype; + { + if (TREE_CODE (value) == COMPOUND_EXPR) + { + if (valid_compound_expr_initializer (TREE_OPERAND (value, 0), endtype) + == error_mark_node) + return error_mark_node; + return valid_compound_expr_initializer (TREE_OPERAND (value, 1), + endtype); + } + else if (! TREE_CONSTANT (value) + && ! initializer_constant_valid_p (value, endtype)) + return error_mark_node; + else + return value; + } /* Perform appropriate conversions on the initial value of a variable, *************** *** 4501,4507 **** /* Digest the specified initializer into an expression. */ ! value = digest_init (type, init, NULL_PTR, TREE_STATIC (decl), ! TREE_STATIC (decl) || pedantic, ! IDENTIFIER_POINTER (DECL_NAME (decl))); /* Store the expression if valid; else report error. */ --- 4162,4167 ---- /* Digest the specified initializer into an expression. */ ! value = digest_init (type, init, TREE_STATIC (decl), ! TREE_STATIC (decl) || pedantic); /* Store the expression if valid; else report error. */ *************** *** 4536,4543 **** #endif /* ANSI wants warnings about out-of-range constant initializers. */ constant_expression_warning (value); - - DECL_INITIAL (decl) = value; } --- 4196,4204 ---- #endif + DECL_INITIAL (decl) = value; + /* ANSI wants warnings about out-of-range constant initializers. */ + STRIP_TYPE_NOPS (value); constant_expression_warning (value); } *************** *** 4617,4623 **** static void ! push_member_name (string) ! char *string; { PUSH_SPELLING (SPELLING_MEMBER, string, u.s); } --- 4278,4287 ---- static void ! push_member_name (decl) ! tree decl; ! { + char *string + = DECL_NAME (decl) ? IDENTIFIER_POINTER (DECL_NAME (decl)) : ""; PUSH_SPELLING (SPELLING_MEMBER, string, u.s); } *************** *** 4763,4835 **** } - /* Keep a pointer to the last free TREE_LIST node as we digest an initializer, - so that we can reuse it. This is set in digest_init, and used in - process_init_constructor. - - We will never keep more than one free TREE_LIST node here. This is for - two main reasons. First, we take elements off the old list and add them - to the new list one at a time, thus there should never be more than - one free TREE_LIST at a time, and thus even if there is, we will never - need more than one. Secondly, to avoid dangling pointers to freed obstacks, - we want to always ensure that we have either a pointer to a valid TREE_LIST - within the current initializer, or else a pointer to null. */ - - static tree free_tree_list = NULL_TREE; - /* Digest the parser output INIT as an initializer for type TYPE. Return a C expression of type TYPE to represent the initial value. - If TAIL is nonzero, it points to a variable holding a list of elements - of which INIT is the first. We update the list stored there by - removing from the head all the elements that we use. - Normally this is only one; we use more than one element only if - TYPE is an aggregate and INIT is not a constructor. - The arguments REQUIRE_CONSTANT and CONSTRUCTOR_CONSTANT request errors if non-constant initializers or elements are seen. CONSTRUCTOR_CONSTANT ! applies only to elements of constructors. ! If OFWHAT is nonnull, it specifies what we are initializing, for error ! messages. Examples: variable name, variable.member, array[44]. ! If OFWHAT is null, the component name is stored on the spelling stack. ! (That is true for all nested calls to digest_init.) */ ! ! tree ! digest_init (type, init, tail, require_constant, constructor_constant, ofwhat) ! tree type, init, *tail; int require_constant, constructor_constant; - char *ofwhat; { enum tree_code code = TREE_CODE (type); - tree element = 0; - tree old_tail_contents; - /* Nonzero if INIT is a braced grouping, which comes in as a CONSTRUCTOR - tree node which has no TREE_TYPE. */ - int raw_constructor - = TREE_CODE (init) == CONSTRUCTOR && TREE_TYPE (init) == 0; tree inside_init = init; - /* Make sure there is just one "partially bracketed" message - per top-level initializer or constructor. */ - if (ofwhat != 0) - partial_bracket_mentioned = 0; - - /* By default, assume we use one element from a list. - We correct this later in the cases where it is not true. - - Thus, we update TAIL now to point to the next element, and save the - old value in OLD_TAIL_CONTENTS. If we didn't actually use the first - element, then we will reset TAIL before proceeding. FREE_TREE_LIST - is handled similarly. */ - - if (tail) - { - old_tail_contents = *tail; - *tail = TREE_CHAIN (*tail); - free_tree_list = old_tail_contents; - } - else - free_tree_list = 0; - if (init == error_mark_node) return init; --- 4427,4445 ---- } /* Digest the parser output INIT as an initializer for type TYPE. Return a C expression of type TYPE to represent the initial value. The arguments REQUIRE_CONSTANT and CONSTRUCTOR_CONSTANT request errors if non-constant initializers or elements are seen. CONSTRUCTOR_CONSTANT ! applies only to elements of constructors. */ ! static tree ! digest_init (type, init, require_constant, constructor_constant) ! tree type, init; int require_constant, constructor_constant; { enum tree_code code = TREE_CODE (type); tree inside_init = init; if (init == error_mark_node) return init; *************** *** 4841,4854 **** inside_init = TREE_OPERAND (init, 0); - if (inside_init && raw_constructor - && CONSTRUCTOR_ELTS (inside_init) != 0 - && TREE_CHAIN (CONSTRUCTOR_ELTS (inside_init)) == 0) - { - element = TREE_VALUE (CONSTRUCTOR_ELTS (inside_init)); - /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ - if (element && TREE_CODE (element) == NON_LVALUE_EXPR) - element = TREE_OPERAND (element, 0); - } - /* Initialization of an array of chars from a string constant optionally enclosed in braces. */ --- 4451,4454 ---- *************** *** 4862,4871 **** || typ1 == unsigned_wchar_type_node || typ1 == signed_wchar_type_node) ! && ((inside_init && TREE_CODE (inside_init) == STRING_CST) ! || (element && TREE_CODE (element) == STRING_CST))) { ! tree string = element ? element : inside_init; ! if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string))) != char_type_node) && TYPE_PRECISION (typ1) == TYPE_PRECISION (char_type_node)) --- 4462,4472 ---- || typ1 == unsigned_wchar_type_node || typ1 == signed_wchar_type_node) ! && ((inside_init && TREE_CODE (inside_init) == STRING_CST))) { ! if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)), ! TYPE_MAIN_VARIANT (type))) ! return inside_init; ! if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init))) != char_type_node) && TYPE_PRECISION (typ1) == TYPE_PRECISION (char_type_node)) *************** *** 4872,4879 **** { error_init ("char-array%s initialized from wide string", ! " `%s'", ofwhat); return error_mark_node; } ! if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string))) == char_type_node) && TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node)) --- 4473,4480 ---- { error_init ("char-array%s initialized from wide string", ! " `%s'", NULL); return error_mark_node; } ! if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init))) == char_type_node) && TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node)) *************** *** 4880,4888 **** { error_init ("int-array%s initialized from non-wide string", ! " `%s'", ofwhat); return error_mark_node; } ! TREE_TYPE (string) = type; if (TYPE_DOMAIN (type) != 0 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST) --- 4481,4489 ---- { error_init ("int-array%s initialized from non-wide string", ! " `%s'", NULL); return error_mark_node; } ! TREE_TYPE (inside_init) = type; if (TYPE_DOMAIN (type) != 0 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST) *************** *** 4893,4897 **** because it's ok to ignore the terminating null char that is counted in the length of the constant. */ ! if (size < TREE_STRING_LENGTH (string) - (TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node) ? TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT --- 4494,4498 ---- because it's ok to ignore the terminating null char that is counted in the length of the constant. */ ! if (size < TREE_STRING_LENGTH (inside_init) - (TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node) ? TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT *************** *** 4899,4915 **** pedwarn_init ( "initializer-string for array of chars%s is too long", ! " `%s'", ofwhat); } ! return string; } } ! /* Any type except an array can be initialized ! from an expression of the same type, optionally with braces. ! For an array, this is allowed only for a string constant. */ if (inside_init && TREE_TYPE (inside_init) != 0 ! && ((TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)) ! == TYPE_MAIN_VARIANT (type)) || (code == ARRAY_TYPE && comptypes (TREE_TYPE (inside_init), type)) --- 4500,4515 ---- pedwarn_init ( "initializer-string for array of chars%s is too long", ! " `%s'", NULL); } ! return inside_init; } } ! /* Any type can be initialized ! from an expression of the same type, optionally with braces. */ if (inside_init && TREE_TYPE (inside_init) != 0 ! && (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)), ! TYPE_MAIN_VARIANT (type)) || (code == ARRAY_TYPE && comptypes (TREE_TYPE (inside_init), type)) *************** *** 4924,4931 **** || TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE)) inside_init = default_conversion (inside_init); ! else if (code == ARRAY_TYPE && TREE_CODE (inside_init) != STRING_CST) { error_init ("array%s initialized from non-constant array expression", ! " `%s'", ofwhat); return error_mark_node; } --- 4524,4532 ---- || TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE)) inside_init = default_conversion (inside_init); ! else if (code == ARRAY_TYPE && TREE_CODE (inside_init) != STRING_CST ! && TREE_CODE (inside_init) != CONSTRUCTOR) { error_init ("array%s initialized from non-constant array expression", ! " `%s'", NULL); return error_mark_node; } *************** *** 4935,4942 **** inside_init = decl_constant_value (inside_init); ! if (require_constant && ! TREE_CONSTANT (inside_init)) { error_init ("initializer element%s is not constant", ! " for `%s'", ofwhat); inside_init = error_mark_node; } --- 4536,4561 ---- inside_init = decl_constant_value (inside_init); ! /* Compound expressions can only occur here if -pedantic or ! -pedantic-errors is specified. In the later case, we always want ! an error. In the former case, we simply want a warning. */ ! if (require_constant && pedantic ! && TREE_CODE (inside_init) == COMPOUND_EXPR) ! { ! inside_init ! = valid_compound_expr_initializer (inside_init, ! TREE_TYPE (inside_init)); ! if (inside_init == error_mark_node) ! error_init ("initializer element%s is not constant", ! " for `%s'", NULL); ! else ! pedwarn_init ("initializer element%s is not constant", ! " for `%s'", NULL); ! if (flag_pedantic_errors) ! inside_init = error_mark_node; ! } ! else if (require_constant && ! TREE_CONSTANT (inside_init)) { error_init ("initializer element%s is not constant", ! " for `%s'", NULL); inside_init = error_mark_node; } *************** *** 4945,4949 **** { error_init ("initializer element%s is not computable at load time", ! " for `%s'", ofwhat); inside_init = error_mark_node; } --- 4564,4568 ---- { error_init ("initializer element%s is not computable at load time", ! " for `%s'", NULL); inside_init = error_mark_node; } *************** *** 4952,5677 **** } ! if (element && (TREE_TYPE (element) == type ! || (code == ARRAY_TYPE && TREE_TYPE (element) ! && comptypes (TREE_TYPE (element), type)))) { ! if (code == ARRAY_TYPE) ! { ! error_init ("array%s initialized from non-constant array expression", ! " `%s'", ofwhat); ! return error_mark_node; ! } ! if (pedantic && (code == RECORD_TYPE || code == UNION_TYPE)) ! pedwarn ("single-expression nonscalar initializer has braces"); ! if (optimize && TREE_READONLY (element) && TREE_CODE (element) == VAR_DECL) ! element = decl_constant_value (element); ! if (require_constant && ! TREE_CONSTANT (element)) { error_init ("initializer element%s is not constant", ! " for `%s'", ofwhat); ! element = error_mark_node; } else if (require_constant ! && initializer_constant_valid_p (element, TREE_TYPE (element)) == 0) { error_init ("initializer element%s is not computable at load time", ! " for `%s'", ofwhat); ! element = error_mark_node; } ! return element; } ! /* Check for initializing a union by its first field. ! Such an initializer must use braces. */ ! if (code == UNION_TYPE) { ! tree result; ! tree field = TYPE_FIELDS (type); ! ! /* Find the first named field. ANSI decided in September 1990 ! that only named fields count here. */ ! while (field && DECL_NAME (field) == 0) ! field = TREE_CHAIN (field); ! if (field == 0) ! { ! error_init ("union%s with no named members cannot be initialized", ! " `%s'", ofwhat); ! return error_mark_node; } ! if (raw_constructor) ! result = process_init_constructor (type, inside_init, NULL_PTR, ! require_constant, ! constructor_constant, ofwhat); ! else if (tail != 0) ! { ! *tail = old_tail_contents; ! free_tree_list = NULL_TREE; ! result = process_init_constructor (type, NULL_TREE, tail, ! require_constant, ! constructor_constant, ofwhat); } else ! result = 0; ! if (result) ! return result; } ! /* Handle scalar types, including conversions. */ ! if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE ! || code == ENUMERAL_TYPE || code == COMPLEX_TYPE) { ! if (raw_constructor) { ! if (element == 0) ! { ! error_init ( ! "initializer for scalar%s requires one element", ! " `%s'", ofwhat); ! return error_mark_node; ! } ! else ! { ! /* Deal with extra levels of {...}. */ ! if (TREE_CODE (element) == CONSTRUCTOR ! && TREE_TYPE (element) == 0) ! { ! error_init ( ! "initializer for scalar%s requires one element", ! " `%s'", ofwhat); ! return error_mark_node; ! } ! inside_init = element; ! } } ! #if 0 /* A non-raw constructor is an actual expression. */ ! if (TREE_CODE (inside_init) == CONSTRUCTOR) { ! error_init ("initializer for scalar%s has extra braces", ! " `%s'", ofwhat); ! return error_mark_node; } #endif ! SAVE_SPELLING_DEPTH ! ({ ! if (ofwhat) ! push_string (ofwhat); ! if (!raw_constructor) ! inside_init = init; ! /* Note that convert_for_assignment calls default_conversion ! for arrays and functions. We must not call it in the ! case where inside_init is a null pointer constant. */ ! inside_init ! = convert_for_assignment (type, inside_init, ! &initialization_message, ! NULL_TREE, NULL_TREE, 0); ! }); ! if (require_constant && ! TREE_CONSTANT (inside_init)) { ! error_init ("initializer element%s is not constant", ! " for `%s'", ofwhat); ! inside_init = error_mark_node; } ! else if (require_constant ! && initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0) { ! error_init ("initializer element%s is not computable at load time", ! " for `%s'", ofwhat); ! inside_init = error_mark_node; } ! return inside_init; } ! /* Come here only for records and arrays. */ ! if (TYPE_SIZE (type) && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) { ! error_init ("variable-sized object%s may not be initialized", ! " `%s'", ofwhat); ! return error_mark_node; } ! if (code == ARRAY_TYPE || code == RECORD_TYPE) { ! if (raw_constructor) ! return process_init_constructor (type, inside_init, ! NULL_PTR, constructor_constant, ! constructor_constant, ofwhat); ! else if (tail != 0) ! { ! *tail = old_tail_contents; ! free_tree_list = NULL_TREE; ! return process_init_constructor (type, NULL_TREE, tail, ! constructor_constant, ! constructor_constant, ofwhat); ! } ! else if (flag_traditional) ! /* Traditionally one can say `char x[100] = 0;'. */ ! return process_init_constructor (type, ! build_nt (CONSTRUCTOR, NULL_TREE, ! tree_cons (NULL_TREE, ! inside_init, ! NULL_TREE)), ! NULL_PTR, constructor_constant, ! constructor_constant, ofwhat); ! } ! error_init ("invalid initializer%s", " for `%s'", ofwhat); ! return error_mark_node; } - - /* Process a constructor for a variable of type TYPE. - The constructor elements may be specified either with INIT or with ELTS, - only one of which should be non-null. - - If INIT is specified, it is a CONSTRUCTOR node which is specifically - and solely for initializing this datum. - - If ELTS is specified, it is the address of a variable containing - a list of expressions. We take as many elements as we need - from the head of the list and update the list. - - In the resulting constructor, TREE_CONSTANT is set if all elts are - constant, and TREE_STATIC is set if, in addition, all elts are simple enough - constants that the assembler and linker can compute them. - - The argument CONSTANT_VALUE says to print an error if either the - value or any element is not a constant. - - The argument CONSTANT_ELEMENT says to print an error if an element - of an aggregate is not constant. It does not apply to a value - which is not a constructor. - - OFWHAT is a character string describing the object being initialized, - for error messages. It might be "variable" or "variable.member" - or "variable[17].member[5]". ! If OFWHAT is null, the description string is stored on the spelling ! stack. That is always true for recursive calls. */ ! static tree ! process_init_constructor (type, init, elts, constant_value, constant_element, ! ofwhat) ! tree type, init, *elts; ! int constant_value, constant_element; ! char *ofwhat; { ! register tree tail; ! /* List of the elements of the result constructor, ! in reverse order. */ ! register tree members = NULL; ! tree result; ! int allconstant = 1; ! int allsimple = 1; ! int erroneous = 0; ! int depth = SPELLING_DEPTH (); ! ! if (ofwhat) ! push_string (ofwhat); ! ! /* Make TAIL be the list of elements to use for the initialization, ! no matter how the data was given to us. */ ! ! if (elts) ! { ! if (warn_missing_braces) ! { ! if (! partial_bracket_mentioned) ! warning ("aggregate has a partly bracketed initializer"); ! partial_bracket_mentioned = 1; ! } ! tail = *elts; } else ! tail = CONSTRUCTOR_ELTS (init); ! /* Gobble as many elements as needed, and make a constructor or initial value ! for each element of this aggregate. Chain them together in result. ! If there are too few, use 0 for each scalar ultimate component. */ ! if (TREE_CODE (type) == ARRAY_TYPE) { ! tree min_index, max_index; ! /* These are non-zero only within a range initializer. */ ! tree start_index = 0, end_index = 0; ! /* Within a range, this is the value for the elts in the range. */ ! tree range_val = 0; ! /* Do arithmetic using double integers, but don't use fold/build, ! because these allocate a new tree object everytime they are called, ! thus resulting in gcc using too much memory for large ! initializers. */ ! union tree_node current_index_node, members_index_node; ! tree current_index = ¤t_index_node; ! tree members_index = &members_index_node; ! TREE_TYPE (current_index) = integer_type_node; ! TREE_TYPE (members_index) = integer_type_node; ! ! /* If we have array bounds, set our bounds from that. Otherwise, ! we have a lower bound of zero and an unknown upper bound. */ ! if (TYPE_DOMAIN (type)) { ! min_index = TYPE_MIN_VALUE (TYPE_DOMAIN (type)); ! max_index = TYPE_MAX_VALUE (TYPE_DOMAIN (type)); } ! else { ! min_index = integer_zero_node; ! max_index = 0; ! } ! TREE_INT_CST_LOW (members_index) = TREE_INT_CST_LOW (min_index); ! TREE_INT_CST_HIGH (members_index) = TREE_INT_CST_HIGH (min_index); ! /* Don't leave the loop based on index if the next item has an explicit ! index value that will override it. */ ! for (TREE_INT_CST_LOW (current_index) = TREE_INT_CST_LOW (min_index), ! TREE_INT_CST_HIGH (current_index) = TREE_INT_CST_HIGH (min_index); ! tail != 0 || end_index; ! add_double (TREE_INT_CST_LOW (current_index), ! TREE_INT_CST_HIGH (current_index), 1, 0, ! &TREE_INT_CST_LOW (current_index), ! &TREE_INT_CST_HIGH (current_index))) { ! register tree next1 = 0; ! ! /* Handle the case where we are inside of a range. ! current_index increments through the range, ! so just keep reusing the same element of TAIL ! until the end of the range. */ ! if (end_index != 0) { ! next1 = range_val; ! if (!tree_int_cst_lt (current_index, end_index)) ! end_index = 0; } ! ! /* If this element specifies an index, ! move to that index before storing it in the new list. */ ! else if (TREE_PURPOSE (tail) != 0) { ! int win = 0; ! tree index = TREE_PURPOSE (tail); ! ! if (index && (TREE_CODE (index) == NON_LVALUE_EXPR ! || TREE_CODE (index) == NOP_EXPR)) ! index = TREE_OPERAND (index, 0); ! ! /* Begin a range. */ ! if (TREE_CODE (index) == TREE_LIST) { ! start_index = TREE_PURPOSE (index); ! end_index = TREE_PURPOSE (TREE_CHAIN (index)); ! ! /* Expose constants. It Doesn't matter if we change ! the mode.*/ ! if (end_index ! && (TREE_CODE (end_index) == NON_LVALUE_EXPR ! || TREE_CODE (end_index) == NOP_EXPR)) ! end_index = TREE_OPERAND (end_index, 0); ! if (start_index ! && (TREE_CODE (start_index) == NON_LVALUE_EXPR ! || TREE_CODE (start_index) == NOP_EXPR)) ! start_index = TREE_OPERAND (start_index, 0); ! ! constant_expression_warning (start_index); ! constant_expression_warning (end_index); ! ! if ((TREE_CODE (start_index) == IDENTIFIER_NODE) ! || (TREE_CODE (end_index) == IDENTIFIER_NODE)) ! error ("field name used as index in array initializer"); ! else if ((TREE_CODE (start_index) != INTEGER_CST) ! || (TREE_CODE (end_index) != INTEGER_CST)) ! error ("non-constant or non-integer array index in initializer"); ! else if (tree_int_cst_lt (start_index, min_index) ! || (max_index && tree_int_cst_lt (max_index, start_index)) ! || tree_int_cst_lt (end_index, min_index) ! || (max_index && tree_int_cst_lt (max_index, end_index))) ! error ("array index out of range in initializer"); ! else if (tree_int_cst_lt (end_index, start_index)) ! { ! /* If the range is empty, don't initialize any elements, ! but do reset current_index for the next initializer ! element. */ ! warning ("empty array initializer range"); ! tail = TREE_CHAIN (tail); ! TREE_INT_CST_LOW (current_index) ! = TREE_INT_CST_LOW (end_index); ! TREE_INT_CST_HIGH (current_index) ! = TREE_INT_CST_HIGH (end_index); ! continue; ! } ! else { ! TREE_INT_CST_LOW (current_index) ! = TREE_INT_CST_LOW (start_index); ! TREE_INT_CST_HIGH (current_index) ! = TREE_INT_CST_HIGH (start_index); ! win = 1; ! /* See if the first element is also the last. */ ! if (!tree_int_cst_lt (current_index, end_index)) ! end_index = 0; } } ! else if (TREE_CODE (index) == IDENTIFIER_NODE) ! error ("field name used as index in array initializer"); ! else if (TREE_CODE (index) != INTEGER_CST) ! error ("non-constant array index in initializer"); ! else if (tree_int_cst_lt (index, min_index) ! || (max_index && tree_int_cst_lt (max_index, index))) ! error ("array index out of range in initializer"); ! else ! { ! constant_expression_warning (index); ! TREE_INT_CST_LOW (current_index) = TREE_INT_CST_LOW (index); ! TREE_INT_CST_HIGH (current_index) ! = TREE_INT_CST_HIGH (index); ! win = 1; ! } ! if (!win) { ! /* If there was an error, end the current range. */ ! end_index = 0; ! TREE_VALUE (tail) = error_mark_node; } } ! if (max_index && tree_int_cst_lt (max_index, current_index)) ! break; /* Stop if we've indeed run out of elements. */ ! /* Now digest the value specified. */ ! if (next1 != 0) ! ; ! else if (TREE_VALUE (tail) != 0) ! { ! tree tail1 = tail; ! /* Build the element of this array, with "[]" notation. For ! error messages, we assume that the index fits within a ! host int. */ ! SAVE_SPELLING_DEPTH ! ({ ! push_array_bounds (TREE_INT_CST_LOW (current_index)); ! next1 = digest_init (TYPE_MAIN_VARIANT (TREE_TYPE (type)), ! TREE_VALUE (tail), &tail1, ! /* Both of these are the same because ! a value here is an elt overall. */ ! constant_element, constant_element, ! NULL_PTR); ! }); ! if (tail1 != 0 && TREE_CODE (tail1) != TREE_LIST) ! abort (); ! if (tail == tail1 && TYPE_DOMAIN (type) == 0) ! { ! error_init ( ! "non-empty initializer for array%s of empty elements", ! " `%s'", NULL_PTR); ! /* Just ignore what we were supposed to use. */ ! tail1 = 0; ! } ! tail = tail1; ! } ! else ! { ! next1 = error_mark_node; ! tail = TREE_CHAIN (tail); ! } ! if (end_index != 0) ! range_val = next1; ! if (next1 == error_mark_node) ! erroneous = 1; ! else if (!TREE_CONSTANT (next1)) ! allconstant = 0; ! else if (initializer_constant_valid_p (next1, TREE_TYPE (next1)) == 0) ! allsimple = 0; ! /* Now store NEXT1 in the list, I elements from the *end*. ! Make the list longer if necessary. */ ! while (! tree_int_cst_lt (current_index, members_index)) { ! if (free_tree_list) ! { ! TREE_CHAIN (free_tree_list) = members; ! TREE_PURPOSE (free_tree_list) = NULL_TREE; ! TREE_VALUE (free_tree_list) = NULL_TREE; ! members = free_tree_list; ! free_tree_list = NULL_TREE; ! } ! else ! members = tree_cons (NULL_TREE, NULL_TREE, members); ! add_double (TREE_INT_CST_LOW (members_index), ! TREE_INT_CST_HIGH (members_index), 1, 0, ! &TREE_INT_CST_LOW (members_index), ! &TREE_INT_CST_HIGH (members_index)); } ! { ! tree temp; ! union tree_node idx_node; ! tree idx = &idx_node; ! TREE_TYPE (idx) = integer_type_node; ! ! temp = members; ! for (add_double (TREE_INT_CST_LOW (members_index), ! TREE_INT_CST_HIGH (members_index), -1, -1, ! &TREE_INT_CST_LOW (idx), ! &TREE_INT_CST_HIGH (idx)); ! tree_int_cst_lt (current_index, idx); ! add_double (TREE_INT_CST_LOW (idx), ! TREE_INT_CST_HIGH (idx), -1, -1, ! &TREE_INT_CST_LOW (idx), ! &TREE_INT_CST_HIGH (idx))) ! temp = TREE_CHAIN (temp); ! TREE_VALUE (temp) = next1; ! } } } ! if (TREE_CODE (type) == RECORD_TYPE) { ! register tree field; ! int members_length = 0; ! int i; ! /* Don't leave the loop based on field just yet; see if next item ! overrides the expected field first. */ ! for (field = TYPE_FIELDS (type), i = 0; tail; ! field = TREE_CHAIN (field), i++) { ! register tree next1; ! /* If this element specifies a field, ! move to that field before storing it in the new list. */ ! if (TREE_PURPOSE (tail) != 0) { ! int win = 0; ! if (TREE_CODE (TREE_PURPOSE (tail)) != IDENTIFIER_NODE) ! error ("index value instead of field name in structure initializer"); ! else { ! tree temp; ! int j; ! for (temp = TYPE_FIELDS (type), j = 0; ! temp; ! temp = TREE_CHAIN (temp), j++) ! if (DECL_NAME (temp) == TREE_PURPOSE (tail)) ! break; ! if (temp) ! field = temp, i = j, win = 1; ! else ! error ("no field `%s' in structure being initialized", ! IDENTIFIER_POINTER (TREE_PURPOSE (tail))); } ! if (!win) ! TREE_VALUE (tail) = error_mark_node; } ! if (field == 0) ! break; /* No more fields to init. */ ! ! if (! DECL_NAME (field)) { ! next1 = integer_zero_node; } ! else if (TREE_VALUE (tail) != 0) { ! tree tail1 = tail; ! /* Build the name of this member, with a "." for membership. */ ! SAVE_SPELLING_DEPTH ! ({ ! push_member_name (IDENTIFIER_POINTER (DECL_NAME (field))); ! next1 = digest_init (TREE_TYPE (field), ! TREE_VALUE (tail), &tail1, ! constant_element, constant_element, ! NULL_PTR); ! }); ! if (tail1 != 0 && TREE_CODE (tail1) != TREE_LIST) ! abort (); ! tail = tail1; } ! else { ! next1 = error_mark_node; ! tail = TREE_CHAIN (tail); } ! if (next1 == error_mark_node) ! erroneous = 1; ! else if (!TREE_CONSTANT (next1)) ! allconstant = 0; ! else if (initializer_constant_valid_p (next1, TREE_TYPE (next1)) == 0) ! allsimple = 0; ! ! /* Now store NEXT1 in the list, I elements from the *end*. ! Make the list longer if necessary. */ ! while (i >= members_length) { ! if (free_tree_list) ! { ! TREE_CHAIN (free_tree_list) = members; ! TREE_PURPOSE (free_tree_list) = NULL_TREE; ! TREE_VALUE (free_tree_list) = NULL_TREE; ! members = free_tree_list; ! free_tree_list = NULL_TREE; ! } ! else ! members = tree_cons (NULL_TREE, NULL_TREE, members); ! members_length++; } - { - tree temp; - int j; - - temp = members; - for (j = members_length - 1; j > i; j--) - temp = TREE_CHAIN (temp); - TREE_VALUE (temp) = next1; - TREE_PURPOSE (temp) = field; - } - } - } - if (TREE_CODE (type) == UNION_TYPE) - { - register tree field = TYPE_FIELDS (type); - register tree next1; ! /* Find the first named field. ANSI decided in September 1990 ! that only named fields count here. */ ! while (field && DECL_NAME (field) == 0) ! field = TREE_CHAIN (field); ! /* For a union, get the initializer for 1 fld. */ ! if (tail == 0) ! { ! error ("empty initializer for union"); ! tail = build_tree_list (0, 0); } ! ! /* If this element specifies a field, initialize via that field. */ ! if (TREE_PURPOSE (tail) != 0) { ! int win = 0; ! if (TREE_CODE (TREE_PURPOSE (tail)) == FIELD_DECL) ! /* Handle the case of a call by build_c_cast. */ ! field = TREE_PURPOSE (tail), win = 1; ! else if (TREE_CODE (TREE_PURPOSE (tail)) != IDENTIFIER_NODE) ! error ("index value instead of field name in union initializer"); ! else { ! tree temp; ! for (temp = TYPE_FIELDS (type); ! temp; ! temp = TREE_CHAIN (temp)) ! if (DECL_NAME (temp) == TREE_PURPOSE (tail)) ! break; ! if (temp) ! field = temp, win = 1; ! else ! error ("no field `%s' in union being initialized", ! IDENTIFIER_POINTER (TREE_PURPOSE (tail))); } - if (!win) - TREE_VALUE (tail) = error_mark_node; - } ! if (TREE_VALUE (tail) != 0) ! { ! tree tail1 = tail; ! ! /* Build the name of this member, with a "." for membership. */ ! SAVE_SPELLING_DEPTH ! ({ ! push_member_name (IDENTIFIER_POINTER (DECL_NAME (field))); ! next1 = digest_init (TREE_TYPE (field), ! TREE_VALUE (tail), &tail1, ! constant_value, constant_element, NULL_PTR); ! }); ! if (tail1 != 0 && TREE_CODE (tail1) != TREE_LIST) ! abort (); ! tail = tail1; ! } ! else ! { ! next1 = error_mark_node; ! tail = TREE_CHAIN (tail); ! } ! if (next1 == error_mark_node) ! erroneous = 1; ! else if (!TREE_CONSTANT (next1)) ! allconstant = 0; ! else if (initializer_constant_valid_p (next1, TREE_TYPE (next1)) == 0) ! allsimple = 0; ! if (free_tree_list) ! { ! TREE_CHAIN (free_tree_list) = members; ! TREE_PURPOSE (free_tree_list) = field; ! TREE_VALUE (free_tree_list) = next1; ! members = free_tree_list; ! free_tree_list = NULL_TREE; ! } ! else ! members = tree_cons (field, next1, members); ! } ! /* If arguments were specified as a list, just remove the ones we used. */ ! if (elts) ! *elts = tail; ! /* If arguments were specified as a constructor, ! complain unless we used all the elements of the constructor. */ ! else if (tail) ! { ! if (TREE_CODE (type) == UNION_TYPE) ! { ! pedwarn_init ("excess elements in union initializer%s", ! " after `%s'", NULL_PTR); } ! else { ! pedwarn_init ("excess elements in aggregate initializer%s", " after `%s'", NULL_PTR); } - } - - /* It might be possible to use SAVE_SPELLING_DEPTH, but I suspect that - some preprocessor somewhere won't accept that much text as an argument. - It's also likely to make debugging difficult. */ - - RESTORE_SPELLING_DEPTH (depth); - - if (erroneous) - return error_mark_node; ! if (elts) ! result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (members)); ! else ! { ! result = init; ! CONSTRUCTOR_ELTS (result) = nreverse (members); ! TREE_TYPE (result) = type; ! TREE_CONSTANT (result) = 0; ! TREE_STATIC (result) = 0; } ! if (allconstant) TREE_CONSTANT (result) = 1; ! if (allconstant && allsimple) TREE_STATIC (result) = 1; ! return result; } --- 4571,6022 ---- } ! /* Handle scalar types, including conversions. */ ! ! if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE ! || code == ENUMERAL_TYPE || code == COMPLEX_TYPE) { ! /* Note that convert_for_assignment calls default_conversion ! for arrays and functions. We must not call it in the ! case where inside_init is a null pointer constant. */ ! inside_init ! = convert_for_assignment (type, init, "initialization", ! NULL_TREE, NULL_TREE, 0); ! if (require_constant && ! TREE_CONSTANT (inside_init)) { error_init ("initializer element%s is not constant", ! " for `%s'", NULL); ! inside_init = error_mark_node; } else if (require_constant ! && initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0) { error_init ("initializer element%s is not computable at load time", ! " for `%s'", NULL); ! inside_init = error_mark_node; } ! return inside_init; } ! /* Come here only for records and arrays. */ ! if (TYPE_SIZE (type) && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) { ! error_init ("variable-sized object%s may not be initialized", ! " `%s'", NULL); ! return error_mark_node; ! } ! /* Traditionally, you can write struct foo x = 0; ! and it initializes the first element of x to 0. */ ! if (flag_traditional) ! { ! tree top = 0, prev = 0; ! while (TREE_CODE (type) == RECORD_TYPE ! || TREE_CODE (type) == ARRAY_TYPE ! || TREE_CODE (type) == QUAL_UNION_TYPE ! || TREE_CODE (type) == UNION_TYPE) ! { ! tree temp = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE); ! if (prev == 0) ! top = temp; ! else ! TREE_OPERAND (prev, 1) = build_tree_list (NULL_TREE, temp); ! prev = temp; ! if (TREE_CODE (type) == ARRAY_TYPE) ! type = TREE_TYPE (type); ! else if (TYPE_FIELDS (type)) ! type = TREE_TYPE (TYPE_FIELDS (type)); ! else ! { ! error_init ("invalid initializer%s", " for `%s'", NULL); ! return error_mark_node; ! } } + TREE_OPERAND (prev, 1) + = build_tree_list (NULL_TREE, + digest_init (type, init, require_constant, + constructor_constant)); + return top; + } + error_init ("invalid initializer%s", " for `%s'", NULL); + return error_mark_node; + } + + /* Handle initializers that use braces. */ + + static void output_init_element (); + static void output_pending_init_elements (); + static void check_init_type_bitfields (); + + /* Type of object we are accumulating a constructor for. + This type is always a RECORD_TYPE, UNION_TYPE or ARRAY_TYPE. */ + static tree constructor_type; + + /* For a RECORD_TYPE or UNION_TYPE, this is the chain of fields + left to fill. */ + static tree constructor_fields; + + /* For an ARRAY_TYPE, this is the specified index + at which to store the next element we get. + This is a special INTEGER_CST node that we modify in place. */ + static tree constructor_index; + + /* For an ARRAY_TYPE, this is the end index of the range + to intitialize with the next element, or NULL in the ordinary case + where the element is used just once. */ + static tree constructor_range_end; + + /* For an ARRAY_TYPE, this is the maximum index. */ + static tree constructor_max_index; + + /* For a RECORD_TYPE, this is the first field not yet written out. */ + static tree constructor_unfilled_fields; + + /* For an ARRAY_TYPE, this is the index of the first element + not yet written out. + This is a special INTEGER_CST node that we modify in place. */ + static tree constructor_unfilled_index; + + /* In a RECORD_TYPE, the byte index of the next consecutive field. + This is so we can generate gaps between fields, when appropriate. + This is a special INTEGER_CST node that we modify in place. */ + static tree constructor_bit_index; + + /* If we are saving up the elements rather than allocating them, + this is the list of elements so far (in reverse order, + most recent first). */ + static tree constructor_elements; + + /* 1 if so far this constructor's elements are all compile-time constants. */ + static int constructor_constant; + + /* 1 if so far this constructor's elements are all valid address constants. */ + static int constructor_simple; + + /* 1 if this constructor is erroneous so far. */ + static int constructor_erroneous; + + /* 1 if have called defer_addressed_constants. */ + static int constructor_subconstants_deferred; + + /* List of pending elements at this constructor level. + These are elements encountered out of order + which belong at places we haven't reached yet in actually + writing the output. */ + static tree constructor_pending_elts; + + /* The SPELLING_DEPTH of this constructor. */ + static int constructor_depth; + + /* 0 if implicitly pushing constructor levels is allowed. */ + int constructor_no_implicit = 0; /* 0 for C; 1 for some other languages. */ + + /* 1 if this constructor level was entered implicitly. */ + static int constructor_implicit; + + static int require_constant_value; + static int require_constant_elements; + + /* 1 if it is ok to output this constructor as we read it. + 0 means must accumulate a CONSTRUCTOR expression. */ + static int constructor_incremental; + + /* DECL node for which an initializer is being read. + 0 means we are reading a constructor expression + such as (struct foo) {...}. */ + static tree constructor_decl; + + /* start_init saves the ASMSPEC arg here for really_start_incremental_init. */ + static char *constructor_asmspec; + + /* Nonzero if this is an initializer for a top-level decl. */ + static int constructor_top_level; + + /* When we finish reading a constructor expression + (constructor_decl is 0), the CONSTRUCTOR goes here. */ + static tree constructor_result; + + /* This stack has a level for each implicit or explicit level of + structuring in the initializer, including the outermost one. It + saves the values of most of the variables above. */ + + struct constructor_stack + { + struct constructor_stack *next; + tree type; + tree fields; + tree index; + tree range_end; + tree max_index; + tree unfilled_index; + tree unfilled_fields; + tree bit_index; + tree elements; + int offset; + tree pending_elts; + int depth; + /* If nonzero, this value should replace the entire + constructor at this level. */ + tree replacement_value; + char constant; + char simple; + char implicit; + char incremental; + char erroneous; + char outer; + }; + + struct constructor_stack *constructor_stack; + + /* This stack records separate initializers that are nested. + Nested initializers can't happen in ANSI C, but GNU C allows them + in cases like { ... (struct foo) { ... } ... }. */ + + struct initializer_stack + { + struct initializer_stack *next; + tree decl; + char *asmspec; + struct constructor_stack *constructor_stack; + struct spelling *spelling; + struct spelling *spelling_base; + int spelling_size; + char top_level; + char incremental; + char require_constant_value; + char require_constant_elements; + char deferred; + }; + + struct initializer_stack *initializer_stack; + + /* Prepare to parse and output the initializer for variable DECL. */ + + void + start_init (decl, asmspec_tree, top_level) + tree decl; + tree asmspec_tree; + int top_level; + { + char *locus; + struct initializer_stack *p + = (struct initializer_stack *) xmalloc (sizeof (struct initializer_stack)); + char *asmspec = 0; + + if (asmspec_tree) + asmspec = TREE_STRING_POINTER (asmspec_tree); + + p->decl = constructor_decl; + p->asmspec = constructor_asmspec; + p->incremental = constructor_incremental; + p->require_constant_value = require_constant_value; + p->require_constant_elements = require_constant_elements; + p->constructor_stack = constructor_stack; + p->spelling = spelling; + p->spelling_base = spelling_base; + p->spelling_size = spelling_size; + p->deferred = constructor_subconstants_deferred; + p->top_level = constructor_top_level; + p->next = initializer_stack; + initializer_stack = p; + + constructor_decl = decl; + constructor_incremental = top_level; + constructor_asmspec = asmspec; + constructor_subconstants_deferred = 0; + constructor_top_level = top_level; + + if (decl != 0) + { + require_constant_value = TREE_STATIC (decl); + require_constant_elements + = ((TREE_STATIC (decl) || pedantic) + /* For a scalar, you can always use any value to initialize, + even within braces. */ + && (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE + || TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE + || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE + || TREE_CODE (TREE_TYPE (decl)) == QUAL_UNION_TYPE)); + locus = IDENTIFIER_POINTER (DECL_NAME (decl)); + constructor_incremental |= TREE_STATIC (decl); + } + else + { + require_constant_value = 0; + require_constant_elements = 0; + locus = "(anonymous)"; + } + + constructor_stack = 0; + + spelling_base = 0; + spelling_size = 0; + RESTORE_SPELLING_DEPTH (0); + + if (locus) + push_string (locus); + } + + void + finish_init () + { + struct initializer_stack *p = initializer_stack; + + /* Output subconstants (string constants, usually) + that were referenced within this initializer and saved up. + Must do this if and only if we called defer_addressed_constants. */ + if (constructor_subconstants_deferred) + output_deferred_addressed_constants (); + + /* Free the whole constructor stack of this initializer. */ + while (constructor_stack) + { + struct constructor_stack *q = constructor_stack; + constructor_stack = q->next; + free (q); + } + + /* Pop back to the data of the outer initializer (if any). */ + constructor_decl = p->decl; + constructor_asmspec = p->asmspec; + constructor_incremental = p->incremental; + require_constant_value = p->require_constant_value; + require_constant_elements = p->require_constant_elements; + constructor_stack = p->constructor_stack; + spelling = p->spelling; + spelling_base = p->spelling_base; + spelling_size = p->spelling_size; + constructor_subconstants_deferred = p->deferred; + constructor_top_level = p->top_level; + initializer_stack = p->next; + free (p); + } + + /* Call here when we see the initializer is surrounded by braces. + This is instead of a call to push_init_level; + it is matched by a call to pop_init_level. + + TYPE is the type to initialize, for a constructor expression. + For an initializer for a decl, TYPE is zero. */ + + void + really_start_incremental_init (type) + tree type; + { + struct constructor_stack *p + = (struct constructor_stack *) xmalloc (sizeof (struct constructor_stack)); + + if (type == 0) + type = TREE_TYPE (constructor_decl); ! /* Turn off constructor_incremental if type is a struct with bitfields. ! Do this before the first push, so that the corrected value ! is available in finish_init. */ ! check_init_type_bitfields (type); ! ! p->type = constructor_type; ! p->fields = constructor_fields; ! p->index = constructor_index; ! p->range_end = constructor_range_end; ! p->max_index = constructor_max_index; ! p->unfilled_index = constructor_unfilled_index; ! p->unfilled_fields = constructor_unfilled_fields; ! p->bit_index = constructor_bit_index; ! p->elements = 0; ! p->constant = constructor_constant; ! p->simple = constructor_simple; ! p->erroneous = constructor_erroneous; ! p->pending_elts = constructor_pending_elts; ! p->depth = constructor_depth; ! p->replacement_value = 0; ! p->implicit = 0; ! p->incremental = constructor_incremental; ! p->outer = 0; ! p->next = 0; ! constructor_stack = p; ! ! constructor_constant = 1; ! constructor_simple = 1; ! constructor_depth = SPELLING_DEPTH (); ! constructor_elements = 0; ! constructor_pending_elts = 0; ! constructor_type = type; ! ! if (TREE_CODE (constructor_type) == RECORD_TYPE ! || TREE_CODE (constructor_type) == UNION_TYPE) ! { ! constructor_fields = TYPE_FIELDS (constructor_type); ! constructor_unfilled_fields = constructor_fields; ! constructor_bit_index = copy_node (integer_zero_node); ! } ! else if (TREE_CODE (constructor_type) == ARRAY_TYPE) ! { ! constructor_range_end = 0; ! if (TYPE_DOMAIN (constructor_type)) ! { ! constructor_max_index ! = TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type)); ! constructor_index ! = copy_node (TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type))); } else ! constructor_index = copy_node (integer_zero_node); ! constructor_unfilled_index = copy_node (constructor_index); ! } ! else ! { ! /* Handle the case of int x = {5}; */ ! constructor_fields = constructor_type; ! constructor_unfilled_fields = constructor_type; ! } ! if (constructor_incremental) ! { ! int momentary = suspend_momentary (); ! push_obstacks_nochange (); ! if (TREE_PERMANENT (constructor_decl)) ! end_temporary_allocation (); ! make_decl_rtl (constructor_decl, constructor_asmspec, ! constructor_top_level); ! assemble_variable (constructor_decl, constructor_top_level, 0, 1); ! pop_obstacks (); ! resume_momentary (momentary); } ! if (constructor_incremental) ! { ! defer_addressed_constants (); ! constructor_subconstants_deferred = 1; ! } ! } ! ! /* Push down into a subobject, for initialization. ! If this is for an explicit set of braces, IMPLICIT is 0. ! If it is because the next element belongs at a lower level, ! IMPLICIT is 1. */ ! void ! push_init_level (implicit) ! int implicit; ! { ! struct constructor_stack *p; ! ! /* If we've exhausted any levels that didn't have braces, ! pop them now. */ ! while (constructor_stack->implicit) ! { ! if ((TREE_CODE (constructor_type) == RECORD_TYPE ! || TREE_CODE (constructor_type) == UNION_TYPE) ! && constructor_fields == 0) ! process_init_element (pop_init_level (1)); ! else if (TREE_CODE (constructor_type) == ARRAY_TYPE ! && tree_int_cst_lt (constructor_max_index, constructor_index)) ! process_init_element (pop_init_level (1)); ! else ! break; ! } ! ! p = (struct constructor_stack *) xmalloc (sizeof (struct constructor_stack)); ! p->type = constructor_type; ! p->fields = constructor_fields; ! p->index = constructor_index; ! p->range_end = constructor_range_end; ! p->max_index = constructor_max_index; ! p->unfilled_index = constructor_unfilled_index; ! p->unfilled_fields = constructor_unfilled_fields; ! p->bit_index = constructor_bit_index; ! p->elements = constructor_elements; ! p->constant = constructor_constant; ! p->simple = constructor_simple; ! p->erroneous = constructor_erroneous; ! p->pending_elts = constructor_pending_elts; ! p->depth = constructor_depth; ! p->replacement_value = 0; ! p->implicit = implicit; ! p->incremental = constructor_incremental; ! p->outer = 0; ! p->next = constructor_stack; ! constructor_stack = p; ! ! constructor_constant = 1; ! constructor_simple = 1; ! constructor_depth = SPELLING_DEPTH (); ! constructor_elements = 0; ! constructor_pending_elts = 0; ! ! /* Don't die if an entire brace-pair level is superfluous ! in the containing level. */ ! if (constructor_type == 0) ! ; ! else if (TREE_CODE (constructor_type) == RECORD_TYPE ! || TREE_CODE (constructor_type) == UNION_TYPE) { ! /* Don't die if there are extra init elts at the end. */ ! if (constructor_fields == 0) ! constructor_type = 0; ! else { ! constructor_type = TREE_TYPE (constructor_fields); ! push_member_name (constructor_fields); } + } + else if (TREE_CODE (constructor_type) == ARRAY_TYPE) + { + constructor_type = TREE_TYPE (constructor_type); + push_array_bounds (TREE_INT_CST_LOW (constructor_index)); + } ! /* Turn off constructor_incremental if type is a struct with bitfields. */ ! if (constructor_type != 0) ! check_init_type_bitfields (constructor_type); ! ! if (constructor_type == 0) ! { ! error_init ("extra brace group at end of initializer%s", ! " for `%s'", NULL); ! constructor_fields = 0; ! constructor_unfilled_fields = 0; ! } ! else if (TREE_CODE (constructor_type) == RECORD_TYPE ! || TREE_CODE (constructor_type) == UNION_TYPE) ! { ! constructor_fields = TYPE_FIELDS (constructor_type); ! constructor_unfilled_fields = constructor_fields; ! constructor_bit_index = copy_node (integer_zero_node); ! } ! else if (TREE_CODE (constructor_type) == ARRAY_TYPE) ! { ! constructor_range_end = 0; ! if (TYPE_DOMAIN (constructor_type)) { ! constructor_max_index ! = TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type)); ! constructor_index ! = copy_node (TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type))); } + else + constructor_index = copy_node (integer_zero_node); + constructor_unfilled_index = copy_node (constructor_index); + } + else + { + warning ("braces around scalar initializer"); + constructor_fields = constructor_type; + constructor_unfilled_fields = constructor_type; + } + } + + /* Don't read a struct incrementally if it has any bitfields, + because the incremental reading code doesn't know how to + handle bitfields yet. */ + + static void + check_init_type_bitfields (type) + tree type; + { + if (TREE_CODE (type) == RECORD_TYPE) + { + tree tail; + for (tail = TYPE_FIELDS (type); tail; + tail = TREE_CHAIN (tail)) + if (DECL_BIT_FIELD (tail) + /* This catches cases like `int foo : 8;'. */ + || DECL_MODE (tail) != TYPE_MODE (TREE_TYPE (tail))) + { + constructor_incremental = 0; + break; + } + } + } + + /* At the end of an implicit or explicit brace level, + finish up that level of constructor. + If we were outputting the elements as they are read, return 0 + from inner levels (process_init_element ignores that), + but return error_mark_node from the outermost level + (that's what we want to put in DECL_INITIAL). + Otherwise, return a CONSTRUCTOR expression. */ + + tree + pop_init_level (implicit) + int implicit; + { + struct constructor_stack *p; + int size; + tree constructor = 0; + + if (implicit == 0) + { + /* When we come to an explicit close brace, + pop any inner levels that didn't have explicit braces. */ + while (constructor_stack->implicit) + process_init_element (pop_init_level (1)); + } + + p = constructor_stack; + + if (constructor_type != 0) + size = int_size_in_bytes (constructor_type); + + /* Now output all pending elements. */ + output_pending_init_elements (1); + + #if 0 /* c-parse.in warns about {}. */ + /* In ANSI, each brace level must have at least one element. */ + if (! implicit && pedantic + && (TREE_CODE (constructor_type) == ARRAY_TYPE + ? integer_zerop (constructor_unfilled_index) + : constructor_unfilled_fields == TYPE_FIELDS (constructor_type))) + pedwarn_init ("empty braces in initializer%s", " for `%s'", NULL); #endif ! /* Pad out the end of the structure. */ ! ! if (p->replacement_value) ! { ! /* If this closes a superfluous brace pair, ! just pass out the element between them. */ ! constructor = p->replacement_value; ! /* If this is the top level thing within the initializer, ! and it's for a variable, then since we already called ! assemble_variable, we must output the value now. */ ! if (p->next == 0 && constructor_decl != 0 ! && constructor_incremental) ! { ! constructor = digest_init (constructor_type, constructor, ! 0, 0); ! ! /* If initializing an array of unknown size, ! determine the size now. */ ! if (TREE_CODE (constructor_type) == ARRAY_TYPE ! && TYPE_DOMAIN (constructor_type) == 0) ! { ! int failure; ! ! push_obstacks_nochange (); ! if (TREE_PERMANENT (constructor_type)) ! end_temporary_allocation (); ! ! /* We shouldn't have an incomplete array type within ! some other type. */ ! if (constructor_stack->next) ! abort (); ! failure ! = complete_array_type (constructor_type, ! constructor, 0); ! if (failure) ! abort (); ! ! size = int_size_in_bytes (constructor_type); ! pop_obstacks (); ! } ! ! output_constant (constructor, size); ! } ! } ! else if (constructor_type == 0) ! ; ! else if (TREE_CODE (constructor_type) != RECORD_TYPE ! && TREE_CODE (constructor_type) != UNION_TYPE ! && TREE_CODE (constructor_type) != ARRAY_TYPE ! && ! constructor_incremental) ! { ! /* A nonincremental scalar initializer--just return ! the element, after verifying there is just one. */ ! if (constructor_elements == 0) ! { ! error_init ("empty scalar initializer%s", ! " for `%s'", NULL); ! constructor = error_mark_node; ! } ! else if (TREE_CHAIN (constructor_elements) != 0) ! { ! error_init ("extra elements in scalar initializer%s", ! " for `%s'", NULL); ! constructor = TREE_VALUE (constructor_elements); ! } ! else ! constructor = TREE_VALUE (constructor_elements); ! } ! else if (! constructor_incremental) ! { ! if (constructor_erroneous) ! constructor = error_mark_node; ! else { ! int momentary = suspend_momentary (); ! ! constructor = build (CONSTRUCTOR, constructor_type, NULL_TREE, ! nreverse (constructor_elements)); ! if (constructor_constant) ! TREE_CONSTANT (constructor) = 1; ! if (constructor_constant && constructor_simple) ! TREE_STATIC (constructor) = 1; ! ! resume_momentary (momentary); } ! } ! else ! { ! tree filled; ! int momentary = suspend_momentary (); ! ! if (TREE_CODE (constructor_type) == RECORD_TYPE ! || TREE_CODE (constructor_type) == UNION_TYPE) { ! /* Find the offset of the end of that field. */ ! filled = size_binop (CEIL_DIV_EXPR, ! constructor_bit_index, ! size_int (BITS_PER_UNIT)); ! } ! else if (TREE_CODE (constructor_type) == ARRAY_TYPE) ! { ! /* If initializing an array of unknown size, ! determine the size now. */ ! if (TREE_CODE (constructor_type) == ARRAY_TYPE ! && TYPE_DOMAIN (constructor_type) == 0) ! { ! tree maxindex ! = size_binop (MINUS_EXPR, ! constructor_unfilled_index, ! integer_one_node); ! ! push_obstacks_nochange (); ! if (TREE_PERMANENT (constructor_type)) ! end_temporary_allocation (); ! maxindex = copy_node (maxindex); ! TYPE_DOMAIN (constructor_type) = build_index_type (maxindex); ! TREE_TYPE (maxindex) = TYPE_DOMAIN (constructor_type); ! ! /* We shouldn't have an incomplete array type within ! some other type. */ ! if (constructor_stack->next) ! abort (); ! ! if (pedantic ! && tree_int_cst_lt (TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type)), ! integer_zero_node)) ! error_with_decl (constructor_decl, "zero-size array `%s'"); ! layout_type (constructor_type); ! size = int_size_in_bytes (constructor_type); ! pop_obstacks (); ! } ! ! filled = size_binop (MULT_EXPR, constructor_unfilled_index, ! size_in_bytes (TREE_TYPE (constructor_type))); } + else + filled = 0; ! if (filled != 0) ! assemble_zeros (size - TREE_INT_CST_LOW (filled)); ! ! resume_momentary (momentary); } ! ! constructor_type = p->type; ! constructor_fields = p->fields; ! constructor_index = p->index; ! constructor_range_end = p->range_end; ! constructor_max_index = p->max_index; ! constructor_unfilled_index = p->unfilled_index; ! constructor_unfilled_fields = p->unfilled_fields; ! constructor_bit_index = p->bit_index; ! constructor_elements = p->elements; ! constructor_constant = p->constant; ! constructor_simple = p->simple; ! constructor_erroneous = p->erroneous; ! constructor_pending_elts = p->pending_elts; ! constructor_depth = p->depth; ! constructor_incremental = p->incremental; ! RESTORE_SPELLING_DEPTH (constructor_depth); ! constructor_stack = p->next; ! free (p); ! ! if (constructor == 0) { ! if (constructor_stack == 0) ! return error_mark_node; ! return NULL_TREE; } + return constructor; + } ! /* Within an array initializer, specify the next index to be initialized. ! FIRST is that index. If LAST is nonzero, then initialize a range ! of indices, running from FIRST through LAST. */ ! ! void ! set_init_index (first, last) ! tree first, last; ! { ! while ((TREE_CODE (first) == NOP_EXPR ! || TREE_CODE (first) == CONVERT_EXPR ! || TREE_CODE (first) == NON_LVALUE_EXPR) ! && (TYPE_MODE (TREE_TYPE (first)) ! == TYPE_MODE (TREE_TYPE (TREE_OPERAND (first, 0))))) ! (first) = TREE_OPERAND (first, 0); ! if (last) ! while ((TREE_CODE (last) == NOP_EXPR ! || TREE_CODE (last) == CONVERT_EXPR ! || TREE_CODE (last) == NON_LVALUE_EXPR) ! && (TYPE_MODE (TREE_TYPE (last)) ! == TYPE_MODE (TREE_TYPE (TREE_OPERAND (last, 0))))) ! (last) = TREE_OPERAND (last, 0); ! ! if (TREE_CODE (first) != INTEGER_CST) ! error_init ("nonconstant array index in initializer%s", " for `%s'", NULL); ! else if (last != 0 && TREE_CODE (last) != INTEGER_CST) ! error_init ("nonconstant array index in initializer%s", " for `%s'", NULL); ! else if (tree_int_cst_lt (first, constructor_unfilled_index)) ! error_init ("duplicate array index in initializer%s", " for `%s'", NULL); ! else { ! TREE_INT_CST_LOW (constructor_index) ! = TREE_INT_CST_LOW (first); ! TREE_INT_CST_HIGH (constructor_index) ! = TREE_INT_CST_HIGH (first); ! if (last != 0 && tree_int_cst_lt (last, first)) ! error_init ("empty index range in initializer%s", " for `%s'", NULL); ! else ! { ! if (pedantic) ! pedwarn ("ANSI C forbids specifying element to initialize"); ! constructor_range_end = last; ! } ! } } ! /* Within a struct initializer, specify the next field to be initialized. */ ! void ! set_init_label (fieldname) ! tree fieldname; { ! tree tail; ! int passed = 0; ! ! for (tail = TYPE_FIELDS (constructor_type); tail; ! tail = TREE_CHAIN (tail)) ! { ! if (tail == constructor_unfilled_fields) ! passed = 1; ! if (DECL_NAME (tail) == fieldname) ! break; } + + if (tail == 0) + error ("unknown field `%s' specified in initializer", + IDENTIFIER_POINTER (fieldname)); + else if (!passed) + error ("field `%s' already initialized", + IDENTIFIER_POINTER (fieldname)); else ! { ! constructor_fields = tail; ! if (pedantic) ! pedwarn ("ANSI C forbids specifying structure member to initialize"); ! } ! } ! ! /* "Output" the next constructor element. ! At top level, really output it to assembler code now. ! Otherwise, collect it in a list from which we will make a CONSTRUCTOR. ! TYPE is the data type that the containing data type wants here. ! FIELD is the field (a FIELD_DECL) or the index that this element fills. ! ! PENDING if non-nil means output pending elements that belong ! right after this element. (PENDING is normally 1; ! it is 0 while outputting pending elements, to avoid recursion.) */ ! ! static void ! output_init_element (value, type, field, pending) ! tree value, type, field; ! int pending; ! { ! int duplicate = 0; ! ! if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE ! || (TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE ! && !(TREE_CODE (value) == STRING_CST ! && TREE_CODE (type) == ARRAY_TYPE ! && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE) ! && !comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (value)), ! TYPE_MAIN_VARIANT (type)))) ! value = default_conversion (value); ! if (value == error_mark_node) ! constructor_erroneous = 1; ! else if (!TREE_CONSTANT (value)) ! constructor_constant = 0; ! else if (initializer_constant_valid_p (value, TREE_TYPE (value)) == 0) ! constructor_simple = 0; ! if (require_constant_value && ! TREE_CONSTANT (value)) ! { ! error_init ("initializer element%s is not constant", ! " for `%s'", NULL); ! value = error_mark_node; ! } ! else if (require_constant_elements ! && initializer_constant_valid_p (value, TREE_TYPE (value)) == 0) ! { ! error_init ("initializer element%s is not computable at load time", ! " for `%s'", NULL); ! value = error_mark_node; ! } ! ! /* If this element duplicates one on constructor_pending_elts, ! print a message and ignore it. Don't do this when we're ! processing elements taken off constructor_pending_elts, ! because we'd always get spurious errors. */ ! if (pending) { ! if (TREE_CODE (constructor_type) == RECORD_TYPE ! || TREE_CODE (constructor_type) == UNION_TYPE) { ! if (purpose_member (field, constructor_pending_elts)) ! { ! error_init ("duplicate initializer%s", " for `%s'", NULL); ! duplicate = 1; ! } } ! if (TREE_CODE (constructor_type) == ARRAY_TYPE) { ! tree tail; ! for (tail = constructor_pending_elts; tail; ! tail = TREE_CHAIN (tail)) ! if (TREE_PURPOSE (tail) != 0 ! && TREE_CODE (TREE_PURPOSE (tail)) == INTEGER_CST ! && tree_int_cst_equal (TREE_PURPOSE (tail), constructor_index)) ! break; ! if (tail != 0) ! { ! error_init ("duplicate initializer%s", " for `%s'", NULL); ! duplicate = 1; ! } ! } ! } ! /* If this element doesn't come next in sequence, ! put it on constructor_pending_elts. */ ! if (TREE_CODE (constructor_type) == ARRAY_TYPE ! && !tree_int_cst_equal (field, constructor_unfilled_index)) ! { ! if (! duplicate) ! /* The copy_node is needed in case field is actually ! constructor_index, which is modified in place. */ ! constructor_pending_elts ! = tree_cons (copy_node (field), ! digest_init (type, value, 0, 0), ! constructor_pending_elts); ! } ! else if (TREE_CODE (constructor_type) == RECORD_TYPE ! && field != constructor_unfilled_fields) ! { ! /* We do this for records but not for unions. In a union, ! no matter which field is specified, it can be initialized ! right away since it starts at the beginning of the union. */ ! if (!duplicate) ! constructor_pending_elts ! = tree_cons (field, ! digest_init (type, value, 0, 0), ! constructor_pending_elts); ! } ! else ! { ! /* Otherwise, output this element either to ! constructor_elements or to the assembler file. */ ! if (!duplicate) { ! if (! constructor_incremental) { ! if (field && TREE_CODE (field) == INTEGER_CST) ! field = copy_node (field); ! constructor_elements ! = tree_cons (field, digest_init (type, value, 0, 0), ! constructor_elements); } ! else { ! /* Structure elements may require alignment. ! Do this, if necessary. */ ! if (TREE_CODE (constructor_type) == RECORD_TYPE) { ! /* Advance to offset of this element. */ ! if (! tree_int_cst_equal (constructor_bit_index, ! DECL_FIELD_BITPOS (constructor_fields))) { ! int next = (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field)) ! / BITS_PER_UNIT); ! int here = (TREE_INT_CST_LOW (constructor_bit_index) ! / BITS_PER_UNIT); ! ! assemble_zeros (next - here); } } ! output_constant (digest_init (type, value, 0, 0), ! int_size_in_bytes (type)); ! /* For a record or union, ! keep track of end position of last field. */ ! if (TREE_CODE (constructor_type) == RECORD_TYPE ! || TREE_CODE (constructor_type) == UNION_TYPE) { ! tree temp = size_binop (PLUS_EXPR, ! DECL_FIELD_BITPOS (constructor_fields), ! DECL_SIZE (constructor_fields)); ! TREE_INT_CST_LOW (constructor_bit_index) ! = TREE_INT_CST_LOW (temp); ! TREE_INT_CST_HIGH (constructor_bit_index) ! = TREE_INT_CST_HIGH (temp); } } + } ! /* Advance the variable that indicates sequential elements output. */ ! if (TREE_CODE (constructor_type) == ARRAY_TYPE) ! { ! tree tem = size_binop (PLUS_EXPR, constructor_unfilled_index, ! integer_one_node); ! TREE_INT_CST_LOW (constructor_unfilled_index) ! = TREE_INT_CST_LOW (tem); ! TREE_INT_CST_HIGH (constructor_unfilled_index) ! = TREE_INT_CST_HIGH (tem); ! } ! else if (TREE_CODE (constructor_type) == RECORD_TYPE) ! constructor_unfilled_fields = TREE_CHAIN (constructor_unfilled_fields); ! else if (TREE_CODE (constructor_type) == UNION_TYPE) ! constructor_unfilled_fields = 0; ! /* Now output any pending elements which have become next. */ ! if (pending) ! output_pending_init_elements (0); ! } ! } ! /* Output any pending elements which have become next. ! As we output elements, constructor_unfilled_{fields,index} ! advances, which may cause other elements to become next; ! if so, they too are output. ! If ALL is 0, we return when there are ! no more pending elements to output now. ! If ALL is 1, we output space as necessary so that ! we can output all the pending elements. */ ! ! static void ! output_pending_init_elements (all) ! int all; ! { ! tree tail; ! tree next; ! retry: ! /* Look thru the whole pending list. ! If we find an element that should be output now, ! output it. Otherwise, set NEXT to the element ! that comes first among those still pending. */ ! ! next = 0; ! for (tail = constructor_pending_elts; tail; ! tail = TREE_CHAIN (tail)) ! { ! if (TREE_CODE (constructor_type) == ARRAY_TYPE) ! { ! if (tree_int_cst_equal (TREE_PURPOSE (tail), ! constructor_unfilled_index)) { ! output_init_element (TREE_VALUE (tail), TREE_TYPE (constructor_type), ! constructor_unfilled_index, 0); ! goto retry; ! } ! else if (tree_int_cst_lt (TREE_PURPOSE (tail), ! constructor_unfilled_index)) ! ; ! else if (next == 0 ! || tree_int_cst_lt (TREE_PURPOSE (tail), ! next)) ! next = TREE_PURPOSE (tail); ! } ! else if (TREE_CODE (constructor_type) == RECORD_TYPE ! || TREE_CODE (constructor_type) == UNION_TYPE) ! { ! if (TREE_PURPOSE (tail) == constructor_unfilled_fields) ! { ! output_init_element (TREE_VALUE (tail), ! TREE_TYPE (constructor_unfilled_fields), ! constructor_unfilled_fields, ! 0); ! goto retry; } + else if (tree_int_cst_lt (DECL_FIELD_BITPOS (TREE_PURPOSE (tail)), + DECL_FIELD_BITPOS (constructor_unfilled_fields))) + ; + else if (next == 0 + || tree_int_cst_lt (DECL_FIELD_BITPOS (TREE_PURPOSE (tail)), + DECL_FIELD_BITPOS (next))) + next = TREE_PURPOSE (tail); + } + } ! /* Ordinarily return, but not if we want to output all ! and there are elements left. */ ! if (! (all && next != 0)) ! return; ! ! /* Generate space up to the position of NEXT. */ ! if (constructor_incremental) ! { ! tree filled; ! tree nextpos_tree; ! ! if (TREE_CODE (constructor_type) == RECORD_TYPE ! || TREE_CODE (constructor_type) == UNION_TYPE) ! { ! /* Find the last field written out. */ ! for (tail = TYPE_FIELDS (constructor_type); tail; ! tail = TREE_CHAIN (tail)) ! if (TREE_CHAIN (tail) == constructor_unfilled_fields) ! break; ! /* Find the offset of the end of that field. */ ! filled = size_binop (CEIL_DIV_EXPR, ! size_binop (PLUS_EXPR, ! DECL_FIELD_BITPOS (tail), ! DECL_SIZE (tail)), ! size_int (BITS_PER_UNIT)); ! nextpos_tree = size_binop (CEIL_DIV_EXPR, ! DECL_FIELD_BITPOS (next), ! size_int (BITS_PER_UNIT)); ! constructor_unfilled_fields = next; ! } ! else if (TREE_CODE (constructor_type) == ARRAY_TYPE) ! { ! filled = size_binop (MULT_EXPR, constructor_unfilled_index, ! size_in_bytes (TREE_TYPE (constructor_type))); ! nextpos_tree ! = size_binop (MULT_EXPR, next, ! size_in_bytes (TREE_TYPE (constructor_type))); ! TREE_INT_CST_LOW (constructor_unfilled_index) ! = TREE_INT_CST_LOW (next); ! TREE_INT_CST_HIGH (constructor_unfilled_index) ! = TREE_INT_CST_HIGH (next); } + else + filled = 0; + + if (filled) + { + int nextpos = TREE_INT_CST_LOW (nextpos_tree); + + assemble_zeros (nextpos - TREE_INT_CST_LOW (filled)); + } } ! else { ! /* If it's not incremental, just skip over the gap, ! so that after jumping to retry we will output the next ! successive element. */ ! if (TREE_CODE (constructor_type) == RECORD_TYPE ! || TREE_CODE (constructor_type) == UNION_TYPE) ! constructor_unfilled_fields = next; ! else if (TREE_CODE (constructor_type) == ARRAY_TYPE) ! { ! TREE_INT_CST_LOW (constructor_unfilled_index) ! = TREE_INT_CST_LOW (next); ! TREE_INT_CST_HIGH (constructor_unfilled_index) ! = TREE_INT_CST_HIGH (next); ! } ! } ! goto retry; ! } ! ! /* Add one non-braced element to the current constructor level. ! This adjusts the current position within the constructor's type. ! This may also start or terminate implicit levels ! to handle a partly-braced initializer. ! ! Once this has found the correct level for the new element, ! it calls output_init_element. ! ! Note: if we are incrementally outputting this constructor, ! this function may be called with a null argument ! representing a sub-constructor that was already incrementally output. ! When that happens, we output nothing, but we do the bookkeeping ! to skip past that element of the current constructor. */ ! ! void ! process_init_element (value) ! tree value; ! { ! tree orig_value = value; ! int string_flag = value != 0 && TREE_CODE (value) == STRING_CST; ! ! /* Handle superfluous braces around string cst as in ! char x[] = {"foo"}; */ ! if (string_flag ! && TREE_CODE (constructor_type) == ARRAY_TYPE ! && TREE_CODE (TREE_TYPE (constructor_type)) == INTEGER_TYPE ! && integer_zerop (constructor_unfilled_index)) ! { ! constructor_stack->replacement_value = value; ! return; ! } ! ! if (constructor_stack->replacement_value != 0) ! { ! error_init ("excess elements in struct initializer%s", ! " after `%s'", NULL_PTR); ! return; ! } ! ! /* Ignore elements of a brace group if it is entirely superfluous ! and has already been diagnosed. */ ! if (constructor_type == 0) ! return; ! ! /* If we've exhausted any levels that didn't have braces, ! pop them now. */ ! while (constructor_stack->implicit) ! { ! if ((TREE_CODE (constructor_type) == RECORD_TYPE ! || TREE_CODE (constructor_type) == UNION_TYPE) ! && constructor_fields == 0) ! process_init_element (pop_init_level (1)); ! else if (TREE_CODE (constructor_type) == ARRAY_TYPE ! && tree_int_cst_lt (constructor_max_index, constructor_index)) ! process_init_element (pop_init_level (1)); ! else ! break; ! } ! while (1) ! { ! if (TREE_CODE (constructor_type) == RECORD_TYPE) { ! tree fieldtype; ! enum tree_code fieldcode; ! if (constructor_fields == 0) { ! pedwarn_init ("excess elements in struct initializer%s", ! " after `%s'", NULL_PTR); ! break; ! } ! fieldtype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_fields)); ! fieldcode = TREE_CODE (fieldtype); ! ! /* Accept a string constant to initialize a subarray. */ ! if (value != 0 ! && fieldcode == ARRAY_TYPE ! && TREE_CODE (TREE_TYPE (fieldtype)) == INTEGER_TYPE ! && string_flag) ! value = orig_value; ! /* Otherwise, if we have come to a subaggregate, ! and we don't have an element of its type, push into it. */ ! else if (value != 0 && !constructor_no_implicit ! && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype ! && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE ! || fieldcode == UNION_TYPE)) ! { ! /* Structure elements may require alignment. Do this now ! if necessary for the subaggregate. */ ! if (constructor_incremental) { ! /* Advance to offset of this element. */ ! if (! tree_int_cst_equal (constructor_bit_index, ! DECL_FIELD_BITPOS (constructor_fields))) ! { ! int next = (TREE_INT_CST_LOW ! (DECL_FIELD_BITPOS (constructor_fields)) ! / BITS_PER_UNIT); ! int here = (TREE_INT_CST_LOW (constructor_bit_index) ! / BITS_PER_UNIT); ! ! assemble_zeros (next - here); ! } } ! push_init_level (1); ! continue; } ! if (value) { ! push_member_name (constructor_fields); ! output_init_element (value, fieldtype, constructor_fields, 1); ! RESTORE_SPELLING_DEPTH (constructor_depth); } ! else ! /* Do the bookkeeping for an element that was ! directly output as a constructor. */ { ! /* For a record, keep track of end position of last field. */ ! tree temp = size_binop (PLUS_EXPR, ! DECL_FIELD_BITPOS (constructor_fields), ! DECL_SIZE (constructor_fields)); ! TREE_INT_CST_LOW (constructor_bit_index) ! = TREE_INT_CST_LOW (temp); ! TREE_INT_CST_HIGH (constructor_bit_index) ! = TREE_INT_CST_HIGH (temp); ! constructor_unfilled_fields = TREE_CHAIN (constructor_fields); } ! ! constructor_fields = TREE_CHAIN (constructor_fields); ! break; ! } ! if (TREE_CODE (constructor_type) == UNION_TYPE) ! { ! tree fieldtype; ! enum tree_code fieldcode; ! ! if (constructor_fields == 0) { ! pedwarn_init ("excess elements in union initializer%s", ! " after `%s'", NULL_PTR); ! break; } ! fieldtype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_fields)); ! fieldcode = TREE_CODE (fieldtype); ! ! /* Accept a string constant to initialize a subarray. */ ! if (value != 0 ! && fieldcode == ARRAY_TYPE ! && TREE_CODE (TREE_TYPE (fieldtype)) == INTEGER_TYPE ! && string_flag) ! value = orig_value; ! /* Otherwise, if we have come to a subaggregate, ! and we don't have an element of its type, push into it. */ ! else if (value != 0 && !constructor_no_implicit ! && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype ! && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE ! || fieldcode == UNION_TYPE)) { ! push_init_level (1); ! continue; } ! if (value) ! { ! push_member_name (constructor_fields); ! output_init_element (value, fieldtype, constructor_fields, 1); ! RESTORE_SPELLING_DEPTH (constructor_depth); ! } ! else ! /* Do the bookkeeping for an element that was ! directly output as a constructor. */ ! { ! TREE_INT_CST_LOW (constructor_bit_index) ! = TREE_INT_CST_LOW (DECL_SIZE (constructor_fields)); ! TREE_INT_CST_HIGH (constructor_bit_index) ! = TREE_INT_CST_HIGH (DECL_SIZE (constructor_fields)); ! constructor_unfilled_fields = TREE_CHAIN (constructor_fields); ! } ! constructor_fields = 0; ! break; } ! if (TREE_CODE (constructor_type) == ARRAY_TYPE) { ! tree elttype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type)); ! enum tree_code eltcode = TREE_CODE (elttype); ! /* Accept a string constant to initialize a subarray. */ ! if (value != 0 ! && eltcode == ARRAY_TYPE ! && TREE_CODE (TREE_TYPE (elttype)) == INTEGER_TYPE ! && string_flag) ! value = orig_value; ! /* Otherwise, if we have come to a subaggregate, ! and we don't have an element of its type, push into it. */ ! else if (value != 0 && !constructor_no_implicit ! && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != elttype ! && (eltcode == RECORD_TYPE || eltcode == ARRAY_TYPE ! || eltcode == UNION_TYPE)) { ! push_init_level (1); ! continue; } ! if (constructor_max_index != 0 ! && tree_int_cst_lt (constructor_max_index, constructor_index)) ! { ! pedwarn_init ("excess elements in array initializer%s", ! " after `%s'", NULL_PTR); ! break; ! } ! /* Now output the actual element. ! Ordinarily, output once. ! If there is a range, repeat it till we advance past the range. */ ! do ! { ! tree tem; ! if (value) ! { ! push_array_bounds (TREE_INT_CST_LOW (constructor_index)); ! output_init_element (value, elttype, constructor_index, 1); ! RESTORE_SPELLING_DEPTH (constructor_depth); ! } ! ! tem = size_binop (PLUS_EXPR, constructor_index, ! integer_one_node); ! TREE_INT_CST_LOW (constructor_index) ! = TREE_INT_CST_LOW (tem); ! TREE_INT_CST_HIGH (constructor_index) ! = TREE_INT_CST_HIGH (tem); ! ! if (!value) ! /* If we are doing the bookkeeping for an element that was ! directly output as a constructor, ! we must update constructor_unfilled_index. */ ! { ! TREE_INT_CST_LOW (constructor_unfilled_index) ! = TREE_INT_CST_LOW (constructor_index); ! TREE_INT_CST_HIGH (constructor_unfilled_index) ! = TREE_INT_CST_HIGH (constructor_index); ! } ! } ! while (! (constructor_range_end == 0 ! || tree_int_cst_lt (constructor_range_end, ! constructor_index))); ! ! break; } ! ! /* Handle the sole element allowed in a braced initializer ! for a scalar variable. */ ! if (constructor_fields == 0) { ! pedwarn_init ("excess elements in scalar initializer%s", " after `%s'", NULL_PTR); + break; } ! if (value) ! output_init_element (value, constructor_type, NULL_TREE, 1); ! constructor_fields = 0; ! break; } ! ! /* If the (lexically) previous elments are not now saved, ! we can discard the storage for them. */ ! if (constructor_incremental && constructor_pending_elts == 0 && value != 0) ! clear_momentary (); } *************** *** 5780,5783 **** --- 6125,6129 ---- t = build (MODIFY_EXPR, TREE_TYPE (res), res, convert (TREE_TYPE (res), t)); + TREE_SIDE_EFFECTS (t) = 1; expand_return (t); current_function_returns_value = 1; diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/caller-save.c gcc-2.5.0/caller-save.c *** gcc-2.4.5/caller-save.c Fri May 14 00:21:17 1993 --- gcc-2.5.0/caller-save.c Sat Aug 7 15:55:47 1993 *************** *** 29,32 **** --- 29,40 ---- #include "expr.h" + #ifndef MAX_MOVE_MAX + #define MAX_MOVE_MAX MOVE_MAX + #endif + + #ifndef MAX_UNITS_PER_WORD + #define MAX_UNITS_PER_WORD UNITS_PER_WORD + #endif + /* Modes for each hard register that we can save. The smallest mode is wide enough to save the entire contents of the register. When saving the *************** *** 35,39 **** static enum machine_mode ! regno_save_mode[FIRST_PSEUDO_REGISTER][MOVE_MAX / UNITS_PER_WORD + 1]; /* For each hard register, a place on the stack where it can be saved, --- 43,47 ---- static enum machine_mode ! regno_save_mode[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MAX_UNITS_PER_WORD + 1]; /* For each hard register, a place on the stack where it can be saved, *************** *** 41,45 **** static rtx ! regno_save_mem[FIRST_PSEUDO_REGISTER][MOVE_MAX / UNITS_PER_WORD + 1]; /* We will only make a register eligible for caller-save if it can be --- 49,53 ---- static rtx ! regno_save_mem[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MAX_UNITS_PER_WORD + 1]; /* We will only make a register eligible for caller-save if it can be *************** *** 50,56 **** static enum insn_code ! reg_save_code[FIRST_PSEUDO_REGISTER][MOVE_MAX / UNITS_PER_WORD + 1]; static enum insn_code ! reg_restore_code[FIRST_PSEUDO_REGISTER][MOVE_MAX / UNITS_PER_WORD + 1]; /* Set of hard regs currently live (during scan of all insns). */ --- 58,64 ---- static enum insn_code ! reg_save_code[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MAX_UNITS_PER_WORD + 1]; static enum insn_code ! reg_restore_code[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MAX_UNITS_PER_WORD + 1]; /* Set of hard regs currently live (during scan of all insns). */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/calls.c gcc-2.5.0/calls.c *** gcc-2.4.5/calls.c Sun Jun 20 18:20:47 1993 --- gcc-2.5.0/calls.c Fri Oct 8 18:26:59 1993 *************** *** 1,4 **** /* Convert function calls to rtl insns, for GNU C compiler. ! Copyright (C) 1989, 1992 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,4 ---- /* Convert function calls to rtl insns, for GNU C compiler. ! Copyright (C) 1989, 1992, 1993 Free Software Foundation, Inc. This file is part of GNU CC. *************** *** 34,38 **** #ifdef PUSH_ROUNDING ! #if defined (STACK_GROWS_DOWNWARD) != defined (ARGS_GROW_DOWNARD) #define PUSH_ARGS_REVERSED /* If it's last to first */ #endif --- 34,38 ---- #ifdef PUSH_ROUNDING ! #if defined (STACK_GROWS_DOWNWARD) != defined (ARGS_GROW_DOWNWARD) #define PUSH_ARGS_REVERSED /* If it's last to first */ #endif *************** *** 120,123 **** --- 120,124 ---- static int calls_function PROTO((tree, int)); + static int calls_function_1 PROTO((tree, int)); static void emit_call_1 PROTO((rtx, tree, int, int, rtx, rtx, int, rtx, int)); *************** *** 133,136 **** --- 134,139 ---- assume any function call might require the stack. */ + static tree calls_function_save_exprs; + static int calls_function (exp, which) *************** *** 138,141 **** --- 141,156 ---- int which; { + int val; + calls_function_save_exprs = 0; + val = calls_function_1 (exp, which); + calls_function_save_exprs = 0; + return val; + } + + static int + calls_function_1 (exp, which) + tree exp; + int which; + { register int i; int type = TREE_CODE_CLASS (TREE_CODE (exp)); *************** *** 168,172 **** if (SAVE_EXPR_RTL (exp) != 0) return 0; ! break; case BLOCK: --- 183,192 ---- if (SAVE_EXPR_RTL (exp) != 0) return 0; ! if (value_member (exp, calls_function_save_exprs)) ! return 0; ! calls_function_save_exprs = tree_cons (NULL_TREE, exp, ! calls_function_save_exprs); ! return (TREE_OPERAND (exp, 0) != 0 ! && calls_function_1 (TREE_OPERAND (exp, 0), which)); case BLOCK: *************** *** 176,180 **** for (local = BLOCK_VARS (exp); local; local = TREE_CHAIN (local)) if (DECL_INITIAL (local) != 0 ! && calls_function (DECL_INITIAL (local), which)) return 1; } --- 196,200 ---- for (local = BLOCK_VARS (exp); local; local = TREE_CHAIN (local)) if (DECL_INITIAL (local) != 0 ! && calls_function_1 (DECL_INITIAL (local), which)) return 1; } *************** *** 185,189 **** subblock; subblock = TREE_CHAIN (subblock)) ! if (calls_function (subblock, which)) return 1; } --- 205,209 ---- subblock; subblock = TREE_CHAIN (subblock)) ! if (calls_function_1 (subblock, which)) return 1; } *************** *** 204,208 **** for (i = 0; i < length; i++) if (TREE_OPERAND (exp, i) != 0 ! && calls_function (TREE_OPERAND (exp, i), which)) return 1; --- 224,228 ---- for (i = 0; i < length; i++) if (TREE_OPERAND (exp, i) != 0 ! && calls_function_1 (TREE_OPERAND (exp, i), which)) return 1; *************** *** 574,582 **** && TYPE_MODE (TREE_TYPE (exp)) != VOIDmode) is_const = 1; } } - is_volatile = TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (p))); - #ifdef REG_PARM_STACK_SPACE #ifdef MAYBE_REG_PARM_STACK_SPACE --- 594,603 ---- && TYPE_MODE (TREE_TYPE (exp)) != VOIDmode) is_const = 1; + + if (TREE_THIS_VOLATILE (fndecl)) + is_volatile = 1; } } #ifdef REG_PARM_STACK_SPACE #ifdef MAYBE_REG_PARM_STACK_SPACE *************** *** 922,929 **** with those made by function.c. */ - #ifdef FUNCTION_ARG_PASS_BY_REFERENCE /* See if this argument should be passed by invisible reference. */ ! if (FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, TYPE_MODE (type), type, ! argpos < n_named_args)) { #ifdef FUNCTION_ARG_CALLEE_COPIES --- 943,954 ---- with those made by function.c. */ /* See if this argument should be passed by invisible reference. */ ! if ((TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST ! && contains_placeholder_p (TYPE_SIZE (type))) ! #ifdef FUNCTION_ARG_PASS_BY_REFERENCE ! || FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, TYPE_MODE (type), ! type, argpos < n_named_args) ! #endif ! ) { #ifdef FUNCTION_ARG_CALLEE_COPIES *************** *** 972,975 **** --- 997,1006 ---- } + MEM_IN_STRUCT_P (copy) + = (TREE_CODE (type) == RECORD_TYPE + || TREE_CODE (type) == UNION_TYPE + || TREE_CODE (type) == QUAL_UNION_TYPE + || TREE_CODE (type) == ARRAY_TYPE); + store_expr (args[i].tree_value, copy, 0); *************** *** 980,984 **** } } - #endif /* FUNCTION_ARG_PASS_BY_REFERENCE */ mode = TYPE_MODE (type); --- 1011,1014 ---- *************** *** 1429,1432 **** --- 1459,1467 ---- addr = plus_constant (addr, arg_offset); args[i].stack = gen_rtx (MEM, args[i].mode, addr); + MEM_IN_STRUCT_P (args[i].stack) + = (TREE_CODE (TREE_TYPE (args[i].tree_value)) == RECORD_TYPE + || TREE_CODE (TREE_TYPE (args[i].tree_value)) == UNION_TYPE + || TREE_CODE (TREE_TYPE (args[i].tree_value)) == QUAL_UNION_TYPE + || TREE_CODE (TREE_TYPE (args[i].tree_value)) == ARRAY_TYPE); if (GET_CODE (slot_offset) == CONST_INT) *************** *** 1457,1462 **** /* Get the function to call, in the form of RTL. */ if (fndecl) ! /* Get a SYMBOL_REF rtx for the function address. */ ! funexp = XEXP (DECL_RTL (fndecl), 0); else /* Generate an rtx (probably a pseudo-register) for the address. */ --- 1492,1507 ---- /* Get the function to call, in the form of RTL. */ if (fndecl) ! { ! /* If this is the first use of the function, see if we need to ! make an external definition for it. */ ! if (! TREE_USED (fndecl)) ! { ! assemble_external (fndecl); ! TREE_USED (fndecl) = 1; ! } ! ! /* Get a SYMBOL_REF rtx for the function address. */ ! funexp = XEXP (DECL_RTL (fndecl), 0); ! } else /* Generate an rtx (probably a pseudo-register) for the address. */ *************** *** 1502,1509 **** do it now. */ ! if (GET_MODE (args[i].value) != VOIDmode ! && GET_MODE (args[i].value) != args[i].mode) ! args[i].value = convert_to_mode (args[i].mode, args[i].value, ! args[i].unsignedp); } --- 1547,1555 ---- do it now. */ ! if (args[i].mode != TYPE_MODE (TREE_TYPE (args[i].tree_value))) ! args[i].value ! = convert_modes (args[i].mode, ! TYPE_MODE (TREE_TYPE (args[i].tree_value)), ! args[i].value, args[i].unsignedp); } *************** *** 1594,1597 **** --- 1640,1644 ---- { int bytes = int_size_in_bytes (TREE_TYPE (args[i].tree_value)); + int big_endian_correction = 0; args[i].n_aligned_regs *************** *** 1602,1605 **** --- 1649,1659 ---- * args[i].n_aligned_regs); + /* Structures smaller than a word are aligned to the least signifcant + byte (to the right). On a BYTES_BIG_ENDIAN machine, this means we + must skip the empty high order bytes when calculating the bit + offset. */ + if (BYTES_BIG_ENDIAN && bytes < UNITS_PER_WORD) + big_endian_correction = (BITS_PER_WORD - (bytes * BITS_PER_UNIT)); + for (j = 0; j < args[i].n_aligned_regs; j++) { *************** *** 1622,1631 **** bitpos += bitsize, bytes -= bitsize / BITS_PER_UNIT) { ! int xbitpos = (BYTES_BIG_ENDIAN ! ? BITS_PER_WORD - bitpos - bitsize ! : bitpos); store_bit_field (reg, bitsize, xbitpos, word_mode, ! extract_bit_field (word, bitsize, xbitpos, 1, NULL_RTX, word_mode, word_mode, --- 1676,1683 ---- bitpos += bitsize, bytes -= bitsize / BITS_PER_UNIT) { ! int xbitpos = bitpos + big_endian_correction; store_bit_field (reg, bitsize, xbitpos, word_mode, ! extract_bit_field (word, bitsize, bitpos, 1, NULL_RTX, word_mode, word_mode, *************** *** 1659,1663 **** was not preallocated, allocate stack space here for arguments passed in registers. */ ! #if ! defined(ALLOCATE_OUTGOING_ARGS) && defined(OUTGOING_REG_PARM_STACK_SPACE) if (must_preallocate == 0 && reg_parm_stack_space > 0) anti_adjust_stack (GEN_INT (reg_parm_stack_space)); --- 1711,1715 ---- was not preallocated, allocate stack space here for arguments passed in registers. */ ! #if ! defined(ACCUMULATE_OUTGOING_ARGS) && defined(OUTGOING_REG_PARM_STACK_SPACE) if (must_preallocate == 0 && reg_parm_stack_space > 0) anti_adjust_stack (GEN_INT (reg_parm_stack_space)); *************** *** 2053,2056 **** --- 2105,2110 ---- args_size.var = 0; + push_temp_slots (); + for (count = 0; count < nargs; count++) { *************** *** 2079,2090 **** val = force_operand (val, NULL_RTX); - argvec[count].value = val; - argvec[count].mode = mode; - #ifdef FUNCTION_ARG_PASS_BY_REFERENCE if (FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, mode, NULL_TREE, 1)) ! abort (); #endif argvec[count].reg = FUNCTION_ARG (args_so_far, mode, NULL_TREE, 1); if (argvec[count].reg && GET_CODE (argvec[count].reg) == EXPR_LIST) --- 2133,2151 ---- val = force_operand (val, NULL_RTX); #ifdef FUNCTION_ARG_PASS_BY_REFERENCE if (FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, mode, NULL_TREE, 1)) ! { ! /* We do not support FUNCTION_ARG_CALLEE_COPIES here since it can ! be viewed as just an efficiency improvement. */ ! rtx slot = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0); ! emit_move_insn (slot, val); ! val = XEXP (slot, 0); ! mode = Pmode; ! } #endif + argvec[count].value = val; + argvec[count].mode = mode; + argvec[count].reg = FUNCTION_ARG (args_so_far, mode, NULL_TREE, 1); if (argvec[count].reg && GET_CODE (argvec[count].reg) == EXPR_LIST) *************** *** 2252,2255 **** --- 2313,2318 ---- old_inhibit_defer_pop + 1, use_insns, no_queue); + pop_temp_slots (); + /* Now restore inhibit_defer_pop to its actual original value. */ OK_DEFER_POP; *************** *** 2258,2264 **** /* Like emit_library_call except that an extra argument, VALUE, comes second and says where to store the result. ! (If VALUE is zero, the result comes in the function value register.) */ ! void emit_library_call_value (va_alist) va_dcl --- 2321,2331 ---- /* Like emit_library_call except that an extra argument, VALUE, comes second and says where to store the result. ! (If VALUE is zero, this function chooses a convenient way ! to return the value. ! This function returns an rtx for where the value is to be found. ! If VALUE is nonzero, VALUE is returned. */ ! ! rtx emit_library_call_value (va_alist) va_dcl *************** *** 2286,2289 **** --- 2353,2358 ---- rtx value; rtx mem_value = 0; + int pcc_struct_value = 0; + int struct_value_size = 0; /* library calls are never indirect calls. */ int current_call_is_indirect = 0; *************** *** 2298,2307 **** /* If this kind of value comes back in memory, decide where in memory it should come back. */ ! if (RETURN_IN_MEMORY (type_for_mode (outmode, 0))) { ! if (GET_CODE (value) == MEM) mem_value = value; else mem_value = assign_stack_temp (outmode, GET_MODE_SIZE (outmode), 0); } --- 2367,2387 ---- /* If this kind of value comes back in memory, decide where in memory it should come back. */ ! if (aggregate_value_p (type_for_mode (outmode, 0))) { ! #ifdef PCC_STATIC_STRUCT_RETURN ! rtx pointer_reg ! = hard_function_value (build_pointer_type (type_for_mode (outmode, 0)), ! 0); ! mem_value = gen_rtx (MEM, outmode, pointer_reg); ! pcc_struct_value = 1; ! if (value == 0) ! value = gen_reg_rtx (outmode); ! #else /* not PCC_STATIC_STRUCT_RETURN */ ! struct_value_size = GET_MODE_SIZE (outmode); ! if (value != 0 && GET_CODE (value) == MEM) mem_value = value; else mem_value = assign_stack_temp (outmode, GET_MODE_SIZE (outmode), 0); + #endif } *************** *** 2324,2367 **** count = 0; /* If there's a structure value address to be passed, either pass it in the special place, or pass it as an extra argument. */ ! if (mem_value) { rtx addr = XEXP (mem_value, 0); ! ! if (! struct_value_rtx) ! { ! nargs++; ! /* Make sure it is a reasonable operand for a move or push insn. */ ! if (GET_CODE (addr) != REG && GET_CODE (addr) != MEM ! && ! (CONSTANT_P (addr) && LEGITIMATE_CONSTANT_P (addr))) ! addr = force_operand (addr, NULL_RTX); ! argvec[count].value = addr; ! argvec[count].mode = outmode; ! argvec[count].partial = 0; ! argvec[count].reg = FUNCTION_ARG (args_so_far, outmode, NULL_TREE, 1); #ifdef FUNCTION_ARG_PARTIAL_NREGS ! if (FUNCTION_ARG_PARTIAL_NREGS (args_so_far, outmode, NULL_TREE, 1)) ! abort (); #endif ! locate_and_pad_parm (outmode, NULL_TREE, ! argvec[count].reg && argvec[count].partial == 0, ! NULL_TREE, &args_size, &argvec[count].offset, ! &argvec[count].size); ! if (argvec[count].reg == 0 || argvec[count].partial != 0 #ifdef REG_PARM_STACK_SPACE ! || 1 #endif ! ) ! args_size.constant += argvec[count].size.constant; ! FUNCTION_ARG_ADVANCE (args_so_far, outmode, (tree)0, 1); ! } } --- 2404,2447 ---- count = 0; + push_temp_slots (); + /* If there's a structure value address to be passed, either pass it in the special place, or pass it as an extra argument. */ ! if (mem_value && struct_value_rtx == 0 && ! pcc_struct_value) { rtx addr = XEXP (mem_value, 0); ! nargs++; ! /* Make sure it is a reasonable operand for a move or push insn. */ ! if (GET_CODE (addr) != REG && GET_CODE (addr) != MEM ! && ! (CONSTANT_P (addr) && LEGITIMATE_CONSTANT_P (addr))) ! addr = force_operand (addr, NULL_RTX); ! argvec[count].value = addr; ! argvec[count].mode = outmode; ! argvec[count].partial = 0; ! argvec[count].reg = FUNCTION_ARG (args_so_far, outmode, NULL_TREE, 1); #ifdef FUNCTION_ARG_PARTIAL_NREGS ! if (FUNCTION_ARG_PARTIAL_NREGS (args_so_far, outmode, NULL_TREE, 1)) ! abort (); #endif ! locate_and_pad_parm (outmode, NULL_TREE, ! argvec[count].reg && argvec[count].partial == 0, ! NULL_TREE, &args_size, &argvec[count].offset, ! &argvec[count].size); ! if (argvec[count].reg == 0 || argvec[count].partial != 0 #ifdef REG_PARM_STACK_SPACE ! || 1 #endif ! ) ! args_size.constant += argvec[count].size.constant; ! FUNCTION_ARG_ADVANCE (args_so_far, outmode, (tree)0, 1); ! ! count++; } *************** *** 2392,2403 **** val = force_operand (val, NULL_RTX); - argvec[count].value = val; - argvec[count].mode = mode; - #ifdef FUNCTION_ARG_PASS_BY_REFERENCE if (FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, mode, NULL_TREE, 1)) ! abort (); #endif argvec[count].reg = FUNCTION_ARG (args_so_far, mode, NULL_TREE, 1); if (argvec[count].reg && GET_CODE (argvec[count].reg) == EXPR_LIST) --- 2472,2490 ---- val = force_operand (val, NULL_RTX); #ifdef FUNCTION_ARG_PASS_BY_REFERENCE if (FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, mode, NULL_TREE, 1)) ! { ! /* We do not support FUNCTION_ARG_CALLEE_COPIES here since it can ! be viewed as just an efficiency improvement. */ ! rtx slot = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0); ! emit_move_insn (slot, val); ! val = XEXP (slot, 0); ! mode = Pmode; ! } #endif + argvec[count].value = val; + argvec[count].mode = mode; + argvec[count].reg = FUNCTION_ARG (args_so_far, mode, NULL_TREE, 1); if (argvec[count].reg && GET_CODE (argvec[count].reg) == EXPR_LIST) *************** *** 2526,2532 **** /* Now load any reg parms into their regs. */ - if (mem_value != 0 && struct_value_rtx != 0) - emit_move_insn (struct_value_rtx, XEXP (mem_value, 0)); - for (count = 0; count < nargs; count++, argnum += inc) { --- 2613,2616 ---- *************** *** 2556,2559 **** --- 2640,2659 ---- end_sequence (); + /* Pass the function the address in which to return a structure value. */ + if (mem_value != 0 && struct_value_rtx != 0 && ! pcc_struct_value) + { + emit_move_insn (struct_value_rtx, + force_reg (Pmode, + force_operand (XEXP (mem_value, 0), + NULL_RTX))); + if (GET_CODE (struct_value_rtx) == REG) + { + push_to_sequence (use_insns); + emit_insn (gen_rtx (USE, VOIDmode, struct_value_rtx)); + use_insns = get_insns (); + end_sequence (); + } + } + fun = prepare_call_address (fun, NULL_TREE, &use_insns); *************** *** 2565,2571 **** will set inhibit_defer_pop to that value. */ ! emit_call_1 (fun, get_identifier (XSTR (orgfun, 0)), args_size.constant, 0, FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1), ! outmode != VOIDmode ? hard_libcall_value (outmode) : NULL_RTX, old_inhibit_defer_pop + 1, use_insns, no_queue); --- 2665,2673 ---- will set inhibit_defer_pop to that value. */ ! emit_call_1 (fun, get_identifier (XSTR (orgfun, 0)), args_size.constant, ! struct_value_size, FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1), ! (outmode != VOIDmode && mem_value == 0 ! ? hard_libcall_value (outmode) : NULL_RTX), old_inhibit_defer_pop + 1, use_insns, no_queue); *************** *** 2573,2576 **** --- 2675,2680 ---- OK_DEFER_POP; + pop_temp_slots (); + /* Copy the value to the right place. */ if (outmode != VOIDmode) *************** *** 2579,2583 **** { if (value == 0) ! value = hard_libcall_value (outmode); if (value != mem_value) emit_move_insn (value, mem_value); --- 2683,2687 ---- { if (value == 0) ! value = mem_value; if (value != mem_value) emit_move_insn (value, mem_value); *************** *** 2585,2589 **** --- 2689,2697 ---- else if (value != 0) emit_move_insn (value, hard_libcall_value (outmode)); + else + value = hard_libcall_value (outmode); } + + return value; } *************** *** 2769,2773 **** stack_arg_under_construction++; #endif ! arg->value = expand_expr (pval, partial ? NULL_RTX : arg->stack, VOIDmode, 0); --- 2877,2884 ---- stack_arg_under_construction++; #endif ! arg->value = expand_expr (pval, ! (partial ! || TYPE_MODE (TREE_TYPE (pval)) != arg->mode) ! ? NULL_RTX : arg->stack, VOIDmode, 0); diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/cccp.c gcc-2.5.0/cccp.c *** gcc-2.4.5/cccp.c Fri May 21 19:13:17 1993 --- gcc-2.5.0/cccp.c Wed Oct 20 19:12:25 1993 *************** *** 1,4 **** /* C Compatible Compiler Preprocessor (CCCP) ! Copyright (C) 1986, 1987, 1989, 1992 Free Software Foundation, Inc. Written by Paul Rubin, June 1986 Adapted to ANSI C, Richard Stallman, Jan 1987 --- 1,4 ---- /* C Compatible Compiler Preprocessor (CCCP) ! Copyright (C) 1986, 1987, 1989, 1992, 1993 Free Software Foundation, Inc. Written by Paul Rubin, June 1986 Adapted to ANSI C, Richard Stallman, Jan 1987 *************** *** 188,192 **** --- 188,197 ---- extern struct tm *localtime (); extern int sys_nerr; + #if defined(bsd4_4) + extern const char *const sys_errlist[]; + #else extern char *sys_errlist[]; + #endif + extern int parse_escape (); #ifndef errno *************** *** 309,312 **** --- 314,318 ---- static U_CHAR *skip_quoted_string (); static U_CHAR *skip_paren_group (); + static char *quote_string (); static char *check_precompiled (); *************** *** 313,316 **** --- 319,323 ---- /* static struct macrodef create_definition (); [moved below] */ static void dump_single_macro (); + static void output_dots (); #ifndef FAILURE_EXIT_CODE *************** *** 538,541 **** --- 545,551 ---- Don't include the file again if that macro is defined. */ U_CHAR *control_macro; + /* If the following is nonzero, it is a C-language system include + directory. */ + int c_system_include_path; }; *************** *** 999,1002 **** --- 1009,1014 ---- /* Non-0 means don't output the preprocessed program. */ int inhibit_output = 0; + /* Non-0 means -v, so print the full set of include dirs. */ + int verbose = 0; /* File name which deps are being written to. *************** *** 1023,1027 **** --- 1035,1041 ---- #endif /* RLIMIT_STACK defined */ + #ifdef SIGPIPE signal (SIGPIPE, pipe_closed); + #endif p = argv[0] + strlen (argv[0]); *************** *** 1102,1105 **** --- 1116,1129 ---- if (!strcmp (argv[i], "-iwithprefix")) { struct file_name_list *dirtmp; + char *prefix; + + if (include_prefix != 0) + prefix = include_prefix; + else { + prefix = savestring (GCC_INCLUDE_DIR); + /* Remove the `include' from /usr/local/lib/gcc.../include. */ + if (!strcmp (prefix + strlen (prefix) - 8, "/include")) + prefix[strlen (prefix) - 7] = 0; + } dirtmp = (struct file_name_list *) *************** *** 1107,1110 **** --- 1131,1135 ---- dirtmp->next = 0; /* New one goes on the end */ dirtmp->control_macro = 0; + dirtmp->c_system_include_path = 0; if (i + 1 == argc) fatal ("Directory name missing after `-iwithprefix' option"); *************** *** 1111,1116 **** dirtmp->fname = (char *) xmalloc (strlen (argv[i+1]) ! + strlen (include_prefix) + 1); ! strcpy (dirtmp->fname, include_prefix); strcat (dirtmp->fname, argv[++i]); --- 1136,1141 ---- dirtmp->fname = (char *) xmalloc (strlen (argv[i+1]) ! + strlen (prefix) + 1); ! strcpy (dirtmp->fname, prefix); strcat (dirtmp->fname, argv[++i]); *************** *** 1121,1124 **** --- 1146,1179 ---- last_after_include = dirtmp; /* Tail follows the last one */ } + /* Add directory to main path for includes, + with the default prefix at the front of its name. */ + if (!strcmp (argv[i], "-iwithprefixbefore")) { + struct file_name_list *dirtmp; + char *prefix; + + if (include_prefix != 0) + prefix = include_prefix; + else { + prefix = savestring (GCC_INCLUDE_DIR); + /* Remove the `include' from /usr/local/lib/gcc.../include. */ + if (!strcmp (prefix + strlen (prefix) - 8, "/include")) + prefix[strlen (prefix) - 7] = 0; + } + + dirtmp = (struct file_name_list *) + xmalloc (sizeof (struct file_name_list)); + dirtmp->next = 0; /* New one goes on the end */ + dirtmp->control_macro = 0; + dirtmp->c_system_include_path = 0; + if (i + 1 == argc) + fatal ("Directory name missing after `-iwithprefixbefore' option"); + + dirtmp->fname = (char *) xmalloc (strlen (argv[i+1]) + + strlen (prefix) + 1); + strcpy (dirtmp->fname, prefix); + strcat (dirtmp->fname, argv[++i]); + + append_include_chain (dirtmp, dirtmp); + } /* Add directory to end of path for includes. */ if (!strcmp (argv[i], "-idirafter")) { *************** *** 1129,1132 **** --- 1184,1188 ---- dirtmp->next = 0; /* New one goes on the end */ dirtmp->control_macro = 0; + dirtmp->c_system_include_path = 0; if (i + 1 == argc) fatal ("Directory name missing after `-idirafter' option"); *************** *** 1185,1188 **** --- 1241,1246 ---- if (! strcmp (argv[i], "-lang-c++")) cplusplus = 1, cplusplus_comments = 1, objc = 0; + if (! strcmp (argv[i], "-lang-c-c++-comments")) + cplusplus = 0, cplusplus_comments = 1, objc = 0; if (! strcmp (argv[i], "-lang-objc")) objc = 1, cplusplus = 0, cplusplus_comments = 1; *************** *** 1291,1294 **** --- 1349,1353 ---- #endif fprintf (stderr, "\n"); + verbose = 1; break; *************** *** 1377,1380 **** --- 1436,1440 ---- dirtmp->next = 0; /* New one goes on the end */ dirtmp->control_macro = 0; + dirtmp->c_system_include_path = 0; if (argv[i][2] != 0) dirtmp->fname = argv[i] + 2; *************** *** 1640,1643 **** --- 1700,1704 ---- new->fname = str; new->control_macro = 0; + new->c_system_include_path = !p->cplusplus; append_include_chain (new, new); if (first_system_include == 0) *************** *** 1653,1656 **** --- 1714,1718 ---- = (struct file_name_list *) xmalloc (sizeof (struct file_name_list)); new->control_macro = 0; + new->c_system_include_path = !p->cplusplus; new->fname = p->fname; append_include_chain (new, new); *************** *** 1666,1669 **** --- 1728,1743 ---- first_system_include = after_include; + /* With -v, print the list of dirs to search. */ + if (verbose) { + struct file_name_list *p; + fprintf (stderr, "#include \"...\" search starts here:\n"); + for (p = include; p; p = p->next) { + if (p == first_bracket_include) + fprintf (stderr, "#include <...> search starts here:\n"); + fprintf (stderr, " %s\n", p->fname); + } + fprintf (stderr, "End of search list.\n"); + } + /* Scan the -imacros files before the main input. Much like #including them, but with no_output set *************** *** 1959,1962 **** --- 2033,2037 ---- dirtmp->next = 0; /* New one goes on the end */ dirtmp->control_macro = 0; + dirtmp->c_system_include_path = 0; dirtmp->fname = name; append_include_chain (dirtmp, dirtmp); *************** *** 2409,2412 **** --- 2484,2496 ---- } ++obp; /* Copy the '#' after all */ + /* Don't expand an identifier that could be a macro directive. + (Section 3.8.3 of the ANSI C standard) */ + SKIP_WHITE_SPACE (ibp); + if (is_idstart[*ibp]) + { + *obp++ = *ibp++; + while (is_idchar[*ibp]) + *obp++ = *ibp++; + } goto randomchar; } *************** *** 3609,3614 **** if (string) { ! buf = (char *) alloca (3 + strlen (string)); ! sprintf (buf, "\"%s\"", string); } else --- 3693,3698 ---- if (string) { ! buf = (char *) alloca (3 + 4 * strlen (string)); ! quote_string (buf, string); } else *************** *** 3633,3636 **** --- 3717,3721 ---- break; + #ifndef NO_BUILTIN_SIZE_TYPE case T_SIZE_TYPE: buf = (char *) alloca (3 + strlen (SIZE_TYPE)); *************** *** 3637,3641 **** --- 3722,3728 ---- sprintf (buf, "%s", SIZE_TYPE); break; + #endif + #ifndef NO_BUILTIN_PTRDIFF_TYPE case T_PTRDIFF_TYPE: buf = (char *) alloca (3 + strlen (PTRDIFF_TYPE)); *************** *** 3642,3645 **** --- 3729,3733 ---- sprintf (buf, "%s", PTRDIFF_TYPE); break; + #endif case T_WCHAR_TYPE: *************** *** 4025,4028 **** --- 4113,4117 ---- ptr = (struct file_name_list *) xmalloc (sizeof (struct file_name_list)); ptr->control_macro = 0; + ptr->c_system_include_path = 0; ptr->next = all_include_files; all_include_files = ptr; *************** *** 4038,4043 **** /* Handle -H option. */ ! if (print_include_names) fprintf (stderr, "%s\n", fname); if (angle_brackets) --- 4127,4134 ---- /* Handle -H option. */ ! if (print_include_names) { ! output_dots (stderr, indepth); fprintf (stderr, "%s\n", fname); + } if (angle_brackets) *************** *** 4132,4136 **** if (! strncmp (sys_dir, filename, length) && filename[length] == '/') ! return 1; } return 0; --- 4223,4232 ---- if (! strncmp (sys_dir, filename, length) && filename[length] == '/') ! { ! if (searchptr->c_system_include_path) ! return 2; ! else ! return 1; ! } } return 0; *************** *** 4673,4682 **** && cur_buf_loc - outbuf.buf == next_string->output_mark) { if (next_string->writeflag) { ! len = strlen (next_string->filename); ! if (len > line_command_len) line_command = xrealloc (line_command, line_command_len *= 2); ! sprintf (line_command, "\n# %d \"%s\"\n", ! next_string->lineno, next_string->filename); if (write (fileno (stdout), line_command, strlen (line_command)) < 0) pfatal_with_name (out_fname); --- 4769,4780 ---- && cur_buf_loc - outbuf.buf == next_string->output_mark) { if (next_string->writeflag) { ! len = 4 * strlen (next_string->filename) + 32; ! while (len > line_command_len) line_command = xrealloc (line_command, line_command_len *= 2); ! sprintf (line_command, "\n# %d ", next_string->lineno); ! strcpy (quote_string (line_command + strlen (line_command), ! next_string->filename), ! "\n"); if (write (fileno (stdout), line_command, strlen (line_command)) < 0) pfatal_with_name (out_fname); *************** *** 5827,5831 **** static HASHNODE *fname_table[FNAME_HASHSIZE]; HASHNODE *hp, **hash_bucket; ! U_CHAR *fname; int fname_length; --- 5925,5929 ---- static HASHNODE *fname_table[FNAME_HASHSIZE]; HASHNODE *hp, **hash_bucket; ! U_CHAR *fname, *p; int fname_length; *************** *** 5832,5845 **** fname = ++bp; ! while (*bp && *bp != '\"') ! bp++; ! if (*bp != '\"') { ! error ("invalid format `#line' command"); ! return 0; ! } ! fname_length = bp - fname; ! bp++; SKIP_WHITE_SPACE (bp); if (*bp) { --- 5930,5961 ---- fname = ++bp; ! /* Turn the file name, which is a character string literal, ! into a null-terminated string. Do this in place. */ ! p = bp; ! for (;;) ! switch ((*p++ = *bp++)) { ! case '\0': ! error ("invalid format `#line' command"); ! return 0; ! case '\\': ! { ! char *bpc = (char *) bp; ! int c = parse_escape (&bpc); ! bp = (U_CHAR *) bpc; ! if (c < 0) ! p--; ! else ! p[-1] = c; ! } ! break; ! case '\"': ! p[-1] = 0; ! goto fname_done; ! } ! fname_done: ! fname_length = p - fname; ! SKIP_WHITE_SPACE (bp); if (*bp) { *************** *** 5852,5855 **** --- 5968,5973 ---- else if (*bp == '3') ip->system_header_p = 1; + else if (*bp == '4') + ip->system_header_p = 2; else { error ("invalid format `#line' command"); *************** *** 5864,5867 **** --- 5982,5990 ---- SKIP_WHITE_SPACE (bp); } + if (*bp == '4') { + ip->system_header_p = 2; + bp++; + SKIP_WHITE_SPACE (bp); + } if (*bp) { error ("invalid format `#line' command"); *************** *** 6008,6011 **** --- 6131,6135 ---- new->fname = savestring (ip->fname); new->control_macro = 0; + new->c_system_include_path = 0; } return 0; *************** *** 6376,6395 **** If not, this # is not special. */ bp = beg_of_line; ! while (1) { ! if (is_hor_space[*bp]) ! bp++; ! else if (*bp == '\\' && bp[1] == '\n') ! bp += 2; ! else if (*bp == '/' && bp[1] == '*') { ! bp += 2; ! while (!(*bp == '*' && bp[1] == '/')) bp++; ! bp += 2; ! } else if (cplusplus_comments && *bp == '/' && bp[1] == '/') { ! bp += 2; ! while (*bp++ != '\n') ; ! } ! else break; ! } if (bp != ip->bufp) { bp = ip->bufp + 1; /* Reset bp to after the #. */ --- 6500,6521 ---- If not, this # is not special. */ bp = beg_of_line; ! /* If -traditional, require # to be at beginning of line. */ ! if (!traditional) ! while (1) { ! if (is_hor_space[*bp]) bp++; ! else if (*bp == '\\' && bp[1] == '\n') ! bp += 2; ! else if (*bp == '/' && bp[1] == '*') { ! bp += 2; ! while (!(*bp == '*' && bp[1] == '/')) ! bp++; ! bp += 2; ! } else if (cplusplus_comments && *bp == '/' && bp[1] == '/') { ! bp += 2; ! while (*bp++ != '\n') ; ! } ! else break; ! } if (bp != ip->bufp) { bp = ip->bufp + 1; /* Reset bp to after the #. */ *************** *** 6845,6848 **** --- 6971,7009 ---- } + /* Place into DST a quoted string representing the string SRC. + Return the address of DST's terminating null. */ + static char * + quote_string (dst, src) + char *dst, *src; + { + U_CHAR c; + + *dst++ = '\"'; + for (;;) + switch ((c = *src++)) + { + default: + if (isprint (c)) + *dst++ = c; + else + { + sprintf (dst, "\\%03o", c); + dst += 4; + } + break; + + case '\"': + case '\\': + *dst++ = '\\'; + *dst++ = c; + break; + + case '\0': + *dst++ = '\"'; + *dst = '\0'; + return dst; + } + } + /* Skip across a group of balanced parens, starting from IP->bufp. IP->bufp is updated. Use this with IP->bufp pointing at an open-paren. *************** *** 6911,6915 **** { int len; ! char *line_cmd_buf; if (no_line_commands --- 7072,7076 ---- { int len; ! char *line_cmd_buf, *line_end; if (no_line_commands *************** *** 6943,6959 **** } ! line_cmd_buf = (char *) alloca (strlen (ip->nominal_fname) + 100); #ifdef OUTPUT_LINE_COMMANDS ! sprintf (line_cmd_buf, "#line %d \"%s\"", ip->lineno, ip->nominal_fname); #else ! sprintf (line_cmd_buf, "# %d \"%s\"", ip->lineno, ip->nominal_fname); #endif ! if (file_change != same_file) ! strcat (line_cmd_buf, file_change == enter_file ? " 1" : " 2"); /* Tell cc1 if following text comes from a system header file. */ ! if (ip->system_header_p) ! strcat (line_cmd_buf, " 3"); ! len = strlen (line_cmd_buf); ! line_cmd_buf[len++] = '\n'; check_expand (op, len + 1); if (op->bufp > op->buf && op->bufp[-1] != '\n') --- 7104,7131 ---- } ! line_cmd_buf = (char *) alloca (4 * strlen (ip->nominal_fname) + 100); #ifdef OUTPUT_LINE_COMMANDS ! sprintf (line_cmd_buf, "#line %d ", ip->lineno); #else ! sprintf (line_cmd_buf, "# %d ", ip->lineno); #endif ! line_end = quote_string (line_cmd_buf + strlen (line_cmd_buf), ! ip->nominal_fname); ! if (file_change != same_file) { ! *line_end++ = ' '; ! *line_end++ = file_change == enter_file ? '1' : '2'; ! } /* Tell cc1 if following text comes from a system header file. */ ! if (ip->system_header_p) { ! *line_end++ = ' '; ! *line_end++ = '3'; ! } ! /* Tell cc1plus if following text should be treated as C. */ ! if (ip->system_header_p == 2 && cplusplus) { ! *line_end++ = ' '; ! *line_end++ = '4'; ! } ! *line_end++ = '\n'; ! len = line_end - line_cmd_buf; check_expand (op, len + 1); if (op->bufp > op->buf && op->bufp[-1] != '\n') *************** *** 7988,7992 **** fprintf (stderr, "In file included"); } else { ! fprintf (stderr, ","); } --- 8160,8164 ---- fprintf (stderr, "In file included"); } else { ! fprintf (stderr, ",\n "); } *************** *** 8436,8446 **** --- 8608,8622 ---- pass_thru_directive (directive, &directive[strlen (directive)], outp, dp); + #ifndef NO_BUILTIN_SIZE_TYPE sprintf (directive, " __SIZE_TYPE__ %s\n", SIZE_TYPE); output_line_command (inp, outp, 0, same_file); pass_thru_directive (directive, &directive[strlen (directive)], outp, dp); + #endif + #ifndef NO_BUILTIN_PTRDIFF_TYPE sprintf (directive, " __PTRDIFF_TYPE__ %s\n", PTRDIFF_TYPE); output_line_command (inp, outp, 0, same_file); pass_thru_directive (directive, &directive[strlen (directive)], outp, dp); + #endif sprintf (directive, " __WCHAR_TYPE__ %s\n", WCHAR_TYPE); *************** *** 8880,8883 **** --- 9056,9071 ---- return 0; } + + static void + output_dots (fd, depth) + FILE* fd; + int depth; + { + while (depth > 0) { + putc ('.', fd); + depth--; + } + } + #ifdef VMS diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/cexp.y gcc-2.5.0/cexp.y *** gcc-2.4.5/cexp.y Wed May 5 15:14:23 1993 --- gcc-2.5.0/cexp.y Wed Oct 6 13:47:31 1993 *************** *** 100,103 **** --- 100,119 ---- #endif + #ifndef MAX_CHAR_TYPE_SIZE + #define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE + #endif + + #ifndef MAX_INT_TYPE_SIZE + #define MAX_INT_TYPE_SIZE INT_TYPE_SIZE + #endif + + #ifndef MAX_LONG_TYPE_SIZE + #define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE + #endif + + #ifndef MAX_WCHAR_TYPE_SIZE + #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE + #endif + /* Yield nonzero if adding two numbers with A's and B's signs can yield a number with SUM's sign, where A, B, and SUM are all C integers. */ *************** *** 534,538 **** register int result = 0; register num_chars = 0; ! unsigned width = CHAR_TYPE_SIZE; int max_chars; char *token_buffer; --- 550,554 ---- register int result = 0; register num_chars = 0; ! unsigned width = MAX_CHAR_TYPE_SIZE; int max_chars; char *token_buffer; *************** *** 540,544 **** if (wide_flag) { ! width = WCHAR_TYPE_SIZE; #ifdef MULTIBYTE_CHARS max_chars = MB_CUR_MAX; --- 556,560 ---- if (wide_flag) { ! width = MAX_WCHAR_TYPE_SIZE; #ifdef MULTIBYTE_CHARS max_chars = MB_CUR_MAX; *************** *** 548,552 **** } else ! max_chars = LONG_TYPE_SIZE / width; token_buffer = (char *) alloca (max_chars + 1); --- 564,568 ---- } else ! max_chars = MAX_LONG_TYPE_SIZE / width; token_buffer = (char *) alloca (max_chars + 1); *************** *** 791,797 **** } } ! if ((i & ~((1 << CHAR_TYPE_SIZE) - 1)) != 0) { ! i &= (1 << CHAR_TYPE_SIZE) - 1; warning ("octal character constant does not fit in a byte"); } --- 807,813 ---- } } ! if ((i & ~((1 << MAX_CHAR_TYPE_SIZE) - 1)) != 0) { ! i &= (1 << MAX_CHAR_TYPE_SIZE) - 1; warning ("octal character constant does not fit in a byte"); } diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/collect2.c gcc-2.5.0/collect2.c *** gcc-2.4.5/collect2.c Mon May 24 23:06:45 1993 --- gcc-2.5.0/collect2.c Wed Oct 20 19:12:32 1993 *************** *** 3,7 **** routines. ! Copyright (C) 1992 Free Software Foundation, Inc. Contributed by Chris Smith (csmith@convex.com). Heavily modified by Michael Meissner (meissner@osf.org), --- 3,7 ---- routines. ! Copyright (C) 1992, 1993 Free Software Foundation, Inc. Contributed by Chris Smith (csmith@convex.com). Heavily modified by Michael Meissner (meissner@osf.org), *************** *** 42,45 **** --- 42,52 ---- #endif + #if defined(bsd4_4) + extern const char *const sys_errlist[]; + #else + extern char *sys_errlist[]; + #endif + extern int sys_nerr; + #define COLLECT *************** *** 58,61 **** --- 65,77 ---- #endif + /* Add prototype support. */ + #ifndef PROTO + #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) + #define PROTO(ARGS) ARGS + #else + #define PROTO(ARGS) () + #endif + #endif + #ifndef R_OK #define R_OK 4 *************** *** 150,153 **** --- 166,179 ---- #endif /* OBJECT_FORMAT_NONE */ + + /* Some systems use __main in a way incompatible with its use in gcc, in these + cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to + give the same symbol without quotes for an alternative entry point. You + must define both, or niether. */ + #ifndef NAME__MAIN + #define NAME__MAIN "__main" + #define SYMBOL__MAIN __main + #endif + /* Linked lists of constructor and destructor names. */ *************** *** 198,210 **** extern char *getenv (); extern char *mktemp (); ! static void add_to_list (); ! static void scan_prog_file (); ! static void fork_execute (); ! static void do_wait (); ! static void write_c_file (); ! static void my_exit (); ! static void handler (); ! static void maybe_unlink (); ! static void choose_temp_base (); generic *xcalloc (); --- 224,261 ---- extern char *getenv (); extern char *mktemp (); ! extern FILE *fdopen (); ! ! /* Structure to hold all the directories in which to search for files to ! execute. */ ! ! struct prefix_list ! { ! char *prefix; /* String to prepend to the path. */ ! struct prefix_list *next; /* Next in linked list. */ ! }; ! ! struct path_prefix ! { ! struct prefix_list *plist; /* List of prefixes to try */ ! int max_len; /* Max length of a prefix in PLIST */ ! char *name; /* Name of this list (used in config stuff) */ ! }; ! ! static void my_exit PROTO((int)); ! static void handler PROTO((int)); ! static int is_ctor_dtor PROTO((char *)); ! static void choose_temp_base PROTO((void)); ! static int is_in_prefix_list PROTO((struct path_prefix *, char *, int)); ! static char *find_a_file PROTO((struct path_prefix *, char *)); ! static void add_prefix PROTO((struct path_prefix *, char *)); ! static void prefix_from_env PROTO((char *, struct path_prefix *)); ! static void do_wait PROTO((char *)); ! static void fork_execute PROTO((char *, char **)); ! static void maybe_unlink PROTO((char *)); ! static void add_to_list PROTO((struct head *, char *)); ! static void write_list PROTO((FILE *, char *, struct id *)); ! static void write_list_with_asm PROTO((FILE *, char *, struct id *)); ! static void write_c_file PROTO((FILE *, char *)); ! static void scan_prog_file PROTO((char *, enum pass)); generic *xcalloc (); *************** *** 215,218 **** --- 266,270 ---- #ifdef NO_DUP2 + int dup2 (oldfd, newfd) int oldfd; *************** *** 230,233 **** --- 282,287 ---- while (fdx > 0) close (fdtmp[--fdx]); + + return 0; } #endif *************** *** 237,242 **** int e; { - extern char *sys_errlist[]; - extern int sys_nerr; static char buffer[30]; --- 291,294 ---- *************** *** 278,282 **** int e = errno; ! fprintf (stderr, "collect: "); fprintf (stderr, string, arg1, arg2, arg3); fprintf (stderr, ": %s\n", my_strerror (e)); --- 330,334 ---- int e = errno; ! fprintf (stderr, "collect2: "); fprintf (stderr, string, arg1, arg2, arg3); fprintf (stderr, ": %s\n", my_strerror (e)); *************** *** 290,294 **** char *string; { ! fprintf (stderr, "collect: "); fprintf (stderr, string, arg1, arg2, arg3); fprintf (stderr, "\n"); --- 342,346 ---- char *string; { ! fprintf (stderr, "collect2: "); fprintf (stderr, string, arg1, arg2, arg3); fprintf (stderr, "\n"); *************** *** 302,306 **** char *string; { ! fprintf (stderr, "collect: "); fprintf (stderr, string, arg1, arg2, arg3, arg4); fprintf (stderr, "\n"); --- 354,358 ---- char *string; { ! fprintf (stderr, "collect2: "); fprintf (stderr, string, arg1, arg2, arg3, arg4); fprintf (stderr, "\n"); *************** *** 321,328 **** int signo; { ! if (c_file[0]) maybe_unlink (c_file); ! if (o_file[0]) maybe_unlink (o_file); --- 373,380 ---- int signo; { ! if (c_file != 0 && c_file[0]) maybe_unlink (c_file); ! if (o_file != 0 && o_file[0]) maybe_unlink (o_file); *************** *** 385,390 **** #ifdef NO_DOLLAR_IN_LABEL #ifdef NO_DOT_IN_LABEL ! { "___GLOBAL__I_", sizeof ("___GLOBAL__I_")-1, 1, 0 }, ! { "___GLOBAL__D_", sizeof ("___GLOBAL__D_")-1, 2, 0 }, #else { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 }, --- 437,442 ---- #ifdef NO_DOLLAR_IN_LABEL #ifdef NO_DOT_IN_LABEL ! { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 }, ! { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 }, #else { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 }, *************** *** 393,397 **** #else { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 }, ! { "GLOBAL_$D$", sizeof ("GLOBAL_$I$")-1, 2, 0 }, #endif #ifdef CFRONT_LOSSAGE /* Don't collect cfront initialization functions. --- 445,449 ---- #else { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 }, ! { "GLOBAL_$D$", sizeof ("GLOBAL_$D$")-1, 2, 0 }, #endif #ifdef CFRONT_LOSSAGE /* Don't collect cfront initialization functions. *************** *** 464,467 **** --- 516,520 ---- #ifndef HAVE_PUTENV + int putenv (str) char *str; *************** *** 492,496 **** { *envp = str; ! return; } } --- 545,549 ---- { *envp = str; ! return 0; } } *************** *** 500,504 **** *environ = str; bcopy (old_environ, environ+1, sizeof (char *) * (num_envs+1)); ! #endif /* VMS */ } --- 553,557 ---- *environ = str; bcopy (old_environ, environ+1, sizeof (char *) * (num_envs+1)); ! return 0; #endif /* VMS */ } *************** *** 511,530 **** #endif - /* Structure to hold all the directories in which to search for files to - execute. */ - - struct prefix_list - { - char *prefix; /* String to prepend to the path. */ - struct prefix_list *next; /* Next in linked list. */ - }; - - struct path_prefix - { - struct prefix_list *plist; /* List of prefixes to try */ - int max_len; /* Max length of a prefix in PLIST */ - char *name; /* Name of this list (used in config stuff) */ - }; - /* We maintain two prefix lists: one from COMPILER_PATH environment variable and one from the PATH variable. */ --- 564,567 ---- *************** *** 542,547 **** searches. */ ! static char *our_file_name, *last_file_name; /* Search for NAME using prefix list PPREFIX. We only look for executable files. --- 579,621 ---- searches. */ ! static struct path_prefix our_file_names; + /* Determine if STRING is in PPREFIX. + + This utility is currently only used to look up file names. Prefix lists + record directory names. This matters to us because the latter has a + trailing slash, so I've added a flag to handle both. */ + + static int + is_in_prefix_list (pprefix, string, filep) + struct path_prefix *pprefix; + char *string; + int filep; + { + struct prefix_list *pl; + + if (filep) + { + int len = strlen (string); + + for (pl = pprefix->plist; pl; pl = pl->next) + { + if (strncmp (pl->prefix, string, len) == 0 + && strcmp (pl->prefix + len, "/") == 0) + return 1; + } + } + else + { + for (pl = pprefix->plist; pl; pl = pl->next) + { + if (strcmp (pl->prefix, string) == 0) + return 1; + } + } + + return 0; + } + /* Search for NAME using prefix list PPREFIX. We only look for executable files. *************** *** 579,584 **** strcpy (temp, pl->prefix); strcat (temp, name); ! if (strcmp (temp, our_file_name) != 0 ! && ! (last_file_name != 0 && strcmp (temp, last_file_name) == 0) /* This is a kludge, but there seems no way around it. */ && strcmp (temp, "./ld") != 0 --- 653,657 ---- strcpy (temp, pl->prefix); strcat (temp, name); ! if (! is_in_prefix_list (&our_file_names, temp, 1) /* This is a kludge, but there seems no way around it. */ && strcmp (temp, "./ld") != 0 *************** *** 590,595 **** So try appending that. */ strcat (temp, EXECUTABLE_SUFFIX); ! if (strcmp (temp, our_file_name) != 0 ! && ! (last_file_name != 0 && strcmp (temp, last_file_name) == 0) && access (temp, X_OK) == 0) return temp; --- 663,667 ---- So try appending that. */ strcat (temp, EXECUTABLE_SUFFIX); ! if (! is_in_prefix_list (&our_file_names, temp, 1) && access (temp, X_OK) == 0) return temp; *************** *** 691,696 **** --- 763,770 ---- char *real_ld_suffix = "real-ld"; char *full_real_ld_suffix = real_ld_suffix; + #if 0 char *gld_suffix = "gld"; char *full_gld_suffix = gld_suffix; + #endif char *nm_suffix = "nm"; char *full_nm_suffix = nm_suffix; *************** *** 705,708 **** --- 779,784 ---- char *ld_file_name; char *c_file_name; + char *collect_name; + char *collect_names; char *p; char **c_argv; *************** *** 722,741 **** #endif - our_file_name = argv[0]; - output_file = "a.out"; /* We must check that we do not call ourselves in an infinite ! recursion loop. We save the name used for us in the COLLECT_NAME ! environment variable, first getting the previous value. ! To be fully safe, we need to maintain a list of names that name ! been used, but, in practice, two names are enough. */ ! last_file_name = getenv ("COLLECT_NAME"); ! p = (char *) xcalloc (sizeof (char *), ! strlen (our_file_name) + strlen ("COLLECT_NAME=") + 1); ! sprintf (p, "COLLECT_NAME=%s", our_file_name); putenv (p); --- 798,844 ---- #endif output_file = "a.out"; /* We must check that we do not call ourselves in an infinite ! recursion loop. We append the name used for us to the COLLECT_NAMES ! environment variable. ! In practice, collect will rarely invoke itself. This can happen now ! that we are no longer called gld. A perfect example is when running ! gcc in a build directory that has been installed. When looking for ! ld's, we'll find our installed version and believe that's the real ld. */ ! ! /* We must also append COLLECT_NAME to COLLECT_NAMES to watch for the ! previous version of collect (the one that used COLLECT_NAME and only ! handled two levels of recursion). If we don't we may mutually recurse ! forever. This can happen (I think) when bootstrapping the old version ! and a new one is installed (rare, but we should handle it). ! ??? Hopefully references to COLLECT_NAME can be removed at some point. */ ! ! collect_name = (char *) getenv ("COLLECT_NAME"); ! collect_names = (char *) getenv ("COLLECT_NAMES"); ! ! p = (char *) xmalloc (strlen ("COLLECT_NAMES=") ! + (collect_name ? strlen (collect_name) + 1 : 0) ! + (collect_names ? strlen (collect_names) + 1 : 0) ! + strlen (argv[0]) + 1); ! strcpy (p, "COLLECT_NAMES="); ! if (collect_name != 0) ! sprintf (p + strlen (p), "%s%c", collect_name, PATH_SEPARATOR); ! if (collect_names != 0) ! sprintf (p + strlen (p), "%s%c", collect_names, PATH_SEPARATOR); ! strcat (p, argv[0]); ! putenv (p); ! ! prefix_from_env ("COLLECT_NAMES", &our_file_names); ! /* Set environment variable COLLECT_NAME to our name so the previous version ! of collect won't find us. If it does we'll mutually recurse forever. ! This can happen when bootstrapping the new version and an old version is ! installed. ! ??? Hopefully this bit of code can be removed at some point. */ ! p = xmalloc (strlen ("COLLECT_NAME=") + strlen (argv[0]) + 1); ! sprintf (p, "COLLECT_NAME=%s", argv[0]); putenv (p); *************** *** 801,804 **** --- 904,908 ---- strcat (full_real_ld_suffix, real_ld_suffix); + #if 0 full_gld_suffix = xcalloc (strlen (gld_suffix) + strlen (target_machine) + 2, 1); *************** *** 806,809 **** --- 910,914 ---- strcat (full_gld_suffix, "-"); strcat (full_gld_suffix, gld_suffix); + #endif full_nm_suffix *************** *** 834,837 **** --- 939,943 ---- /* Try to discover a valid linker/nm/strip to use. */ + #if 0 /* Search the (target-specific) compiler dirs for `gld'. */ ld_file_name = find_a_file (&cpath, gld_suffix); *************** *** 840,843 **** --- 946,952 ---- if (ld_file_name == 0) ld_file_name = find_a_file (&path, full_gld_suffix); + #else + ld_file_name = 0; + #endif /* Likewise for `real-ld'. */ if (ld_file_name == 0) *************** *** 850,856 **** ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME); #endif ! /* This would be the right place to search the compiler dirs ! for `ld', but we don't do that, since this program is installed ! there as `ld'. */ /* Search the ordinary system bin directories for `ld' (if native linking) or `TARGET-ld' (if cross). */ --- 959,964 ---- ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME); #endif ! if (ld_file_name == 0) ! ld_file_name = find_a_file (&cpath, full_ld_suffix); /* Search the ordinary system bin directories for `ld' (if native linking) or `TARGET-ld' (if cross). */ *************** *** 858,861 **** --- 966,981 ---- ld_file_name = find_a_file (&path, full_ld_suffix); + /* If we've invoked ourselves, try again with LD_FILE_NAME. */ + + if (collect_names != 0) + { + if (ld_file_name != 0) + { + argv[0] = ld_file_name; + execvp (argv[0], argv); + } + fatal ("cannot find `ld'"); + } + nm_file_name = find_a_file (&cpath, gnm_suffix); if (nm_file_name == 0) *************** *** 1023,1026 **** --- 1143,1150 ---- (o_file ? o_file : "not found")); + ptr = getenv ("COLLECT_NAMES"); + if (ptr) + fprintf (stderr, "COLLECT_NAMES = %s\n", ptr); + ptr = getenv ("COLLECT_GCC_OPTIONS"); if (ptr) *************** *** 1186,1190 **** pid = vfork (); if (pid == -1) ! fatal_perror ("vfork"); if (pid == 0) /* child context */ --- 1310,1320 ---- pid = vfork (); if (pid == -1) ! { ! #ifdef vfork ! fatal_perror ("fork"); ! #else ! fatal_perror ("vfork"); ! #endif ! } if (pid == 0) /* child context */ *************** *** 1286,1291 **** fprintf (stream, "\t0\n};\n\n"); ! fprintf (stream, "extern entry_pt __main;\n"); ! fprintf (stream, "entry_pt *__main_reference = __main;\n\n"); } --- 1416,1421 ---- fprintf (stream, "\t0\n};\n\n"); ! fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN); ! fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN); } *************** *** 1356,1360 **** pid = vfork (); if (pid == -1) ! fatal_perror ("vfork"); if (pid == 0) /* child context */ --- 1486,1496 ---- pid = vfork (); if (pid == -1) ! { ! #ifdef vfork ! fatal_perror ("fork"); ! #else ! fatal_perror ("vfork"); ! #endif ! } if (pid == 0) /* child context */ *************** *** 1602,1620 **** extern int decode_mach_o_hdr (); - extern int encode_mach_o_hdr (); ! static void bad_header (); ! ! static void print_header (); ! ! static void print_load_command (); ! ! static void add_func_table (); ! ! static struct file_info *read_file (); ! ! static void end_file (); ! /* OSF/rose specific version to scan the name list of the loaded --- 1738,1750 ---- extern int decode_mach_o_hdr (); extern int encode_mach_o_hdr (); ! static void add_func_table PROTO((mo_header_t *, load_all_t *, ! symbol_info_t *, int)); ! static void print_header PROTO((mo_header_t *)); ! static void print_load_command PROTO((load_union_t*, size_t, int)); ! static void bad_header PROTO((int)); ! static struct file_info *read_file PROTO((char *, int, int)); ! static void end_file PROTO((struct file_info *)); /* OSF/rose specific version to scan the name list of the loaded *************** *** 1773,1781 **** if (rw) { ! char *n = name; ! while (*n == '_') ! ++n; ! if (*n != 'm' || (n - name) < 2 || strcmp (n, "main")) continue; main_sym = sym; --- 1903,1913 ---- if (rw) { ! char *n = name + strlen (name) - strlen (NAME__MAIN); ! ! if ((n - name) < 0 || strcmp (n, NAME__MAIN)) continue; + while (n != name) + if (*--n != '_') + continue; main_sym = sym; *************** *** 2176,2180 **** return p; } - /* Do anything necessary to write a file back from memory. */ --- 2308,2311 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/combine.c gcc-2.5.0/combine.c *** gcc-2.4.5/combine.c Fri Jun 4 01:57:52 1993 --- gcc-2.5.0/combine.c Tue Oct 19 00:41:14 1993 *************** *** 76,79 **** --- 76,83 ---- #include "config.h" #include "gvarargs.h" + + /* Must precede rtl.h for FFS. */ + #include + #include "rtl.h" #include "flags.h" *************** *** 88,92 **** #include "recog.h" #include "real.h" - #include /* It is not safe to use ordinary gen_lowpart in combine. --- 92,95 ---- *************** *** 94,111 **** #define gen_lowpart dont_use_gen_lowpart_you_dummy - /* If byte loads either zero- or sign- extend, define BYTE_LOADS_EXTEND - for cases when we don't care which is true. Define LOAD_EXTEND to - be ZERO_EXTEND or SIGN_EXTEND, depending on which was defined. */ - - #ifdef BYTE_LOADS_ZERO_EXTEND - #define BYTE_LOADS_EXTEND - #define LOAD_EXTEND ZERO_EXTEND - #endif - - #ifdef BYTE_LOADS_SIGN_EXTEND - #define BYTE_LOADS_EXTEND - #define LOAD_EXTEND SIGN_EXTEND - #endif - /* Number of attempts to combine instructions in this function. */ --- 97,100 ---- *************** *** 186,189 **** --- 175,181 ---- static int previous_num_undos; + + /* Basic block number of the block in which we are performing combines. */ + static int this_basic_block; /* The next group of arrays allows the recording of the last value assigned *************** *** 299,304 **** { int is_int; ! union {rtx rtx; int i;} old_contents; ! union {rtx *rtx; int *i;} where; }; --- 291,296 ---- { int is_int; ! union {rtx r; int i;} old_contents; ! union {rtx *r; int *i;} where; }; *************** *** 335,342 **** { \ undobuf.undo[undobuf.num_undo].is_int = 0; \ ! undobuf.undo[undobuf.num_undo].where.rtx = &INTO; \ ! undobuf.undo[undobuf.num_undo].old_contents.rtx = INTO; \ INTO = _new; \ ! if (undobuf.undo[undobuf.num_undo].old_contents.rtx != INTO) \ undobuf.num_undo++; \ } \ --- 327,334 ---- { \ undobuf.undo[undobuf.num_undo].is_int = 0; \ ! undobuf.undo[undobuf.num_undo].where.r = &INTO; \ ! undobuf.undo[undobuf.num_undo].old_contents.r = INTO; \ INTO = _new; \ ! if (undobuf.undo[undobuf.num_undo].old_contents.r != INTO) \ undobuf.num_undo++; \ } \ *************** *** 364,404 **** static int n_occurrences; ! static void set_nonzero_bits_and_sign_copies (); ! static void setup_incoming_promotions (); ! static void move_deaths (); ! rtx remove_death (); ! static void record_value_for_reg (); ! static void record_dead_and_set_regs (); ! static int use_crosses_set_p (); ! static rtx try_combine (); ! static rtx *find_split_point (); ! static rtx subst (); ! static void undo_all (); ! static int reg_dead_at_p (); ! static rtx expand_compound_operation (); ! static rtx expand_field_assignment (); ! static rtx make_extraction (); ! static int get_pos_from_mask (); ! static rtx force_to_mode (); ! static rtx known_cond (); ! static rtx make_field_assignment (); ! static rtx make_compound_operation (); ! static rtx apply_distributive_law (); ! static rtx simplify_and_const_int (); ! static unsigned HOST_WIDE_INT nonzero_bits (); ! static int num_sign_bit_copies (); ! static int merge_outer_ops (); ! static rtx simplify_shift_const (); ! static int recog_for_combine (); ! static rtx gen_lowpart_for_combine (); ! static rtx gen_rtx_combine (); ! static rtx gen_binary (); ! static rtx gen_unary (); ! static enum rtx_code simplify_comparison (); ! static int reversible_comparison_p (); ! static int get_last_value_validate (); ! static rtx get_last_value (); ! static void distribute_notes (); ! static void distribute_links (); /* Main entry point for combiner. F is the first insn of the function. --- 356,409 ---- static int n_occurrences; ! static void init_reg_last_arrays PROTO(()); ! static void setup_incoming_promotions PROTO(()); ! static void set_nonzero_bits_and_sign_copies PROTO((rtx, rtx)); ! static int can_combine_p PROTO((rtx, rtx, rtx, rtx, rtx *, rtx *)); ! static int combinable_i3pat PROTO((rtx, rtx *, rtx, rtx, int, rtx *)); ! static rtx try_combine PROTO((rtx, rtx, rtx)); ! static void undo_all PROTO((void)); ! static rtx *find_split_point PROTO((rtx *, rtx)); ! static rtx subst PROTO((rtx, rtx, rtx, int, int)); ! static rtx expand_compound_operation PROTO((rtx)); ! static rtx expand_field_assignment PROTO((rtx)); ! static rtx make_extraction PROTO((enum machine_mode, rtx, int, rtx, int, ! int, int, int)); ! static rtx make_compound_operation PROTO((rtx, enum rtx_code)); ! static int get_pos_from_mask PROTO((unsigned HOST_WIDE_INT, int *)); ! static rtx force_to_mode PROTO((rtx, enum machine_mode, ! unsigned HOST_WIDE_INT, rtx)); ! static rtx known_cond PROTO((rtx, enum rtx_code, rtx, rtx)); ! static rtx make_field_assignment PROTO((rtx)); ! static rtx apply_distributive_law PROTO((rtx)); ! static rtx simplify_and_const_int PROTO((rtx, enum machine_mode, rtx, ! unsigned HOST_WIDE_INT)); ! static unsigned HOST_WIDE_INT nonzero_bits PROTO((rtx, enum machine_mode)); ! static int num_sign_bit_copies PROTO((rtx, enum machine_mode)); ! static int merge_outer_ops PROTO((enum rtx_code *, HOST_WIDE_INT *, ! enum rtx_code, HOST_WIDE_INT, ! enum machine_mode, int *)); ! static rtx simplify_shift_const PROTO((rtx, enum rtx_code, enum machine_mode, ! rtx, int)); ! static int recog_for_combine PROTO((rtx *, rtx, rtx *)); ! static rtx gen_lowpart_for_combine PROTO((enum machine_mode, rtx)); ! static rtx gen_rtx_combine (); /* This is varargs. */ ! static rtx gen_binary PROTO((enum rtx_code, enum machine_mode, ! rtx, rtx)); ! static rtx gen_unary PROTO((enum rtx_code, enum machine_mode, rtx)); ! static enum rtx_code simplify_comparison PROTO((enum rtx_code, rtx *, rtx *)); ! static int reversible_comparison_p PROTO((rtx)); ! static void update_table_tick PROTO((rtx)); ! static void record_value_for_reg PROTO((rtx, rtx, rtx)); ! static void record_dead_and_set_regs_1 PROTO((rtx, rtx)); ! static void record_dead_and_set_regs PROTO((rtx)); ! static int get_last_value_validate PROTO((rtx *, int, int)); ! static rtx get_last_value PROTO((rtx)); ! static int use_crosses_set_p PROTO((rtx, int)); ! static void reg_dead_at_p_1 PROTO((rtx, rtx)); ! static int reg_dead_at_p PROTO((rtx, rtx)); ! static void move_deaths PROTO((rtx, int, rtx, rtx *)); ! static int reg_bitfield_target_p PROTO((rtx, rtx)); ! static void distribute_notes PROTO((rtx, rtx, rtx, rtx, rtx, rtx)); ! static void distribute_links PROTO((rtx)); /* Main entry point for combiner. F is the first insn of the function. *************** *** 422,425 **** --- 427,437 ---- combine_max_regno = nregs; + reg_nonzero_bits + = (unsigned HOST_WIDE_INT *) alloca (nregs * sizeof (HOST_WIDE_INT)); + reg_sign_bit_copies = (char *) alloca (nregs * sizeof (char)); + + bzero (reg_nonzero_bits, nregs * sizeof (HOST_WIDE_INT)); + bzero (reg_sign_bit_copies, nregs * sizeof (char)); + reg_last_death = (rtx *) alloca (nregs * sizeof (rtx)); reg_last_set = (rtx *) alloca (nregs * sizeof (rtx)); *************** *** 435,453 **** = (char *) alloca (nregs * sizeof (char)); ! reg_nonzero_bits ! = (unsigned HOST_WIDE_INT *) alloca (nregs * sizeof (HOST_WIDE_INT)); ! reg_sign_bit_copies = (char *) alloca (nregs * sizeof (char)); ! ! bzero (reg_last_death, nregs * sizeof (rtx)); ! bzero (reg_last_set, nregs * sizeof (rtx)); ! bzero (reg_last_set_value, nregs * sizeof (rtx)); ! bzero (reg_last_set_table_tick, nregs * sizeof (int)); ! bzero (reg_last_set_label, nregs * sizeof (int)); ! bzero (reg_last_set_invalid, nregs * sizeof (char)); ! bzero (reg_last_set_mode, nregs * sizeof (enum machine_mode)); ! bzero (reg_last_set_nonzero_bits, nregs * sizeof (HOST_WIDE_INT)); ! bzero (reg_last_set_sign_bit_copies, nregs * sizeof (char)); ! bzero (reg_nonzero_bits, nregs * sizeof (HOST_WIDE_INT)); ! bzero (reg_sign_bit_copies, nregs * sizeof (char)); init_recog_no_volatile (); --- 447,451 ---- = (char *) alloca (nregs * sizeof (char)); ! init_reg_last_arrays (); init_recog_no_volatile (); *************** *** 503,516 **** /* Now scan all the insns in forward order. */ label_tick = 1; last_call_cuid = 0; mem_last_set = 0; ! bzero (reg_last_death, nregs * sizeof (rtx)); ! bzero (reg_last_set, nregs * sizeof (rtx)); ! bzero (reg_last_set_value, nregs * sizeof (rtx)); ! bzero (reg_last_set_table_tick, nregs * sizeof (int)); ! bzero (reg_last_set_label, nregs * sizeof (int)); ! bzero (reg_last_set_invalid, nregs * sizeof (char)); ! setup_incoming_promotions (); --- 501,509 ---- /* Now scan all the insns in forward order. */ + this_basic_block = -1; label_tick = 1; last_call_cuid = 0; mem_last_set = 0; ! init_reg_last_arrays (); setup_incoming_promotions (); *************** *** 519,528 **** next = 0; if (GET_CODE (insn) == CODE_LABEL) label_tick++; ! else if (GET_CODE (insn) == INSN ! || GET_CODE (insn) == CALL_INSN ! || GET_CODE (insn) == JUMP_INSN) { /* Try this insn with each insn it links back to. */ --- 512,524 ---- next = 0; + /* If INSN starts a new basic block, update our basic block number. */ + if (this_basic_block + 1 < n_basic_blocks + && basic_block_head[this_basic_block + 1] == insn) + this_basic_block++; + if (GET_CODE (insn) == CODE_LABEL) label_tick++; ! else if (GET_RTX_CLASS (GET_CODE (insn)) == 'i') { /* Try this insn with each insn it links back to. */ *************** *** 620,623 **** --- 616,637 ---- nonzero_sign_valid = 0; } + + /* Wipe the reg_last_xxx arrays in preparation for another pass. */ + + static void + init_reg_last_arrays () + { + int nregs = combine_max_regno; + + bzero (reg_last_death, nregs * sizeof (rtx)); + bzero (reg_last_set, nregs * sizeof (rtx)); + bzero (reg_last_set_value, nregs * sizeof (rtx)); + bzero (reg_last_set_table_tick, nregs * sizeof (int)); + bzero (reg_last_set_label, nregs * sizeof (int)); + bzero (reg_last_set_invalid, nregs * sizeof (char)); + bzero (reg_last_set_mode, nregs * sizeof (enum machine_mode)); + bzero (reg_last_set_nonzero_bits, nregs * sizeof (HOST_WIDE_INT)); + bzero (reg_last_set_sign_bit_copies, nregs * sizeof (char)); + } /* Set up any promoted values for incoming argument registers. */ *************** *** 823,840 **** /* Don't eliminate a store in the stack pointer. */ if (dest == stack_pointer_rtx - /* Don't install a subreg involving two modes not tieable. - It can worsen register allocation, and can even make invalid reload - insns, since the reg inside may need to be copied from in the - outside mode, and that may be invalid if it is an fp reg copied in - integer mode. As a special exception, we can allow this if - I3 is simply copying DEST, a REG, to CC0. */ - || (GET_CODE (src) == SUBREG - && ! MODES_TIEABLE_P (GET_MODE (src), GET_MODE (SUBREG_REG (src))) - #ifdef HAVE_cc0 - && ! (GET_CODE (i3) == INSN && GET_CODE (PATTERN (i3)) == SET - && SET_DEST (PATTERN (i3)) == cc0_rtx - && GET_CODE (dest) == REG && dest == SET_SRC (PATTERN (i3))) - #endif - ) /* If we couldn't eliminate a field assignment, we can't combine. */ || GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == STRICT_LOW_PART --- 837,840 ---- *************** *** 857,864 **** think it might (this can happen for a sequence of insns each setting the same destination; reg_last_set of that register might point to ! a NOTE). Also, don't move a volatile asm or UNSPEC_VOLATILE across ! any other insns. */ || (! all_adjacent ! && (use_crosses_set_p (src, INSN_CUID (insn)) || (GET_CODE (src) == ASM_OPERANDS && MEM_VOLATILE_P (src)) || GET_CODE (src) == UNSPEC_VOLATILE)) --- 857,868 ---- think it might (this can happen for a sequence of insns each setting the same destination; reg_last_set of that register might point to ! a NOTE). If INSN has a REG_EQUIV note, the register is always ! equivalent to the memory so the substitution is valid even if there ! are intervening stores. Also, don't move a volatile asm or ! UNSPEC_VOLATILE across any other insns. */ || (! all_adjacent ! && (((GET_CODE (src) != MEM ! || ! find_reg_note (insn, REG_EQUIV, src)) ! && use_crosses_set_p (src, INSN_CUID (insn))) || (GET_CODE (src) == ASM_OPERANDS && MEM_VOLATILE_P (src)) || GET_CODE (src) == UNSPEC_VOLATILE)) *************** *** 924,927 **** --- 928,939 ---- return 0; + /* If there are any volatile insns between INSN and I3, reject, because + they might affect machine state. */ + + for (p = NEXT_INSN (insn); p != i3; p = NEXT_INSN (p)) + if (GET_RTX_CLASS (GET_CODE (p)) == 'i' + && p != succ && volatile_insn_p (PATTERN (p))) + return 0; + /* If INSN or I2 contains an autoincrement or autodecrement, make sure that register is not used between there and I3, *************** *** 1082,1085 **** --- 1094,1100 ---- && reg_referenced_p (dest, PATTERN (i3)) && REGNO (dest) != FRAME_POINTER_REGNUM + #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM + && REGNO (dest) != HARD_FRAME_POINTER_REGNUM + #endif #if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM && (REGNO (dest) != ARG_POINTER_REGNUM *************** *** 1147,1150 **** --- 1162,1167 ---- /* Notes that must be added to REG_NOTES in I3 and I2. */ rtx new_i3_notes, new_i2_notes; + /* Notes that we substituted I3 into I2 instead of the normal case. */ + int i3_subst_into_i2 = 0; int maxreg; *************** *** 1249,1252 **** --- 1266,1270 ---- newpat = p2; + i3_subst_into_i2 = 1; goto validate_replacement; } *************** *** 1805,1809 **** We can split this into a load from memory followed by a register-register copy. This saves at least one insn, more if register allocation can ! eliminate the copy. */ else if (i1 && insn_code_number < 0 && asm_noperands (newpat) < 0 --- 1823,1831 ---- We can split this into a load from memory followed by a register-register copy. This saves at least one insn, more if register allocation can ! eliminate the copy. ! ! We cannot do this if the destination of the second assignment is ! a register that we have already assumed is zero-extended. Similarly ! for a SUBREG of such a register. */ else if (i1 && insn_code_number < 0 && asm_noperands (newpat) < 0 *************** *** 1819,1822 **** --- 1841,1859 ---- && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != ZERO_EXTRACT && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != STRICT_LOW_PART + && ! (temp = SET_DEST (XVECEXP (newpat, 0, 1)), + (GET_CODE (temp) == REG + && reg_nonzero_bits[REGNO (temp)] != 0 + && GET_MODE_BITSIZE (GET_MODE (temp)) < BITS_PER_WORD + && GET_MODE_BITSIZE (GET_MODE (temp)) < HOST_BITS_PER_INT + && (reg_nonzero_bits[REGNO (temp)] + != GET_MODE_MASK (word_mode)))) + && ! (GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) == SUBREG + && (temp = SUBREG_REG (SET_DEST (XVECEXP (newpat, 0, 1))), + (GET_CODE (temp) == REG + && reg_nonzero_bits[REGNO (temp)] != 0 + && GET_MODE_BITSIZE (GET_MODE (temp)) < BITS_PER_WORD + && GET_MODE_BITSIZE (GET_MODE (temp)) < HOST_BITS_PER_INT + && (reg_nonzero_bits[REGNO (temp)] + != GET_MODE_MASK (word_mode))))) && ! reg_overlap_mentioned_p (SET_DEST (XVECEXP (newpat, 0, 1)), SET_SRC (XVECEXP (newpat, 0, 1))) *************** *** 1862,1867 **** for (insn = NEXT_INSN (i3); ! insn && GET_CODE (insn) != CODE_LABEL ! && GET_CODE (PREV_INSN (insn)) != JUMP_INSN; insn = NEXT_INSN (insn)) { --- 1899,1904 ---- for (insn = NEXT_INSN (i3); ! insn && (this_basic_block == n_basic_blocks - 1 ! || insn != basic_block_head[this_basic_block + 1]); insn = NEXT_INSN (insn)) { *************** *** 2016,2042 **** we replaced a destination of one of those sets with the destination of I3. In that case, we have to update LOG_LINKS of insns later ! in this basic block. Note that this (expensive) case is rare. */ ! if (GET_CODE (PATTERN (i2)) == PARALLEL) ! for (i = 0; i < XVECLEN (PATTERN (i2), 0); i++) ! if (GET_CODE (SET_DEST (XVECEXP (PATTERN (i2), 0, i))) == REG ! && SET_DEST (XVECEXP (PATTERN (i2), 0, i)) != i2dest ! && ! find_reg_note (i2, REG_UNUSED, ! SET_DEST (XVECEXP (PATTERN (i2), 0, i)))) ! { ! register rtx insn; ! for (insn = NEXT_INSN (i2); insn; insn = NEXT_INSN (insn)) ! { ! if (insn != i3 && GET_RTX_CLASS (GET_CODE (insn)) == 'i') ! for (link = LOG_LINKS (insn); link; link = XEXP (link, 1)) ! if (XEXP (link, 0) == i2) ! XEXP (link, 0) = i3; ! if (GET_CODE (insn) == CODE_LABEL ! || GET_CODE (insn) == JUMP_INSN) ! break; ! } } LOG_LINKS (i3) = 0; --- 2053,2089 ---- we replaced a destination of one of those sets with the destination of I3. In that case, we have to update LOG_LINKS of insns later ! in this basic block. Note that this (expensive) case is rare. ! Also, in this case, we must pretend that all REG_NOTEs for I2 ! actually came from I3, so that REG_UNUSED notes from I2 will be ! properly handled. */ ! if (i3_subst_into_i2) ! { ! for (i = 0; i < XVECLEN (PATTERN (i2), 0); i++) ! if (GET_CODE (SET_DEST (XVECEXP (PATTERN (i2), 0, i))) == REG ! && SET_DEST (XVECEXP (PATTERN (i2), 0, i)) != i2dest ! && ! find_reg_note (i2, REG_UNUSED, ! SET_DEST (XVECEXP (PATTERN (i2), 0, i)))) ! for (temp = NEXT_INSN (i2); ! temp && (this_basic_block == n_basic_blocks - 1 ! || basic_block_head[this_basic_block] != temp); ! temp = NEXT_INSN (temp)) ! if (temp != i3 && GET_RTX_CLASS (GET_CODE (temp)) == 'i') ! for (link = LOG_LINKS (temp); link; link = XEXP (link, 1)) ! if (XEXP (link, 0) == i2) ! XEXP (link, 0) = i3; ! if (i3notes) ! { ! rtx link = i3notes; ! while (XEXP (link, 1)) ! link = XEXP (link, 1); ! XEXP (link, 1) = i2notes; } + else + i3notes = i2notes; + i2notes = 0; + } LOG_LINKS (i3) = 0; *************** *** 2253,2257 **** *undobuf.undo[i].where.i = undobuf.undo[i].old_contents.i; else ! *undobuf.undo[i].where.rtx = undobuf.undo[i].old_contents.rtx; } --- 2300,2304 ---- *undobuf.undo[i].where.i = undobuf.undo[i].old_contents.i; else ! *undobuf.undo[i].where.r = undobuf.undo[i].old_contents.r; } *************** *** 2756,2759 **** --- 2803,2827 ---- if (COMBINE_RTX_EQUAL_P (XEXP (x, i), from)) { + /* In general, don't install a subreg involving two modes not + tieable. It can worsen register allocation, and can even + make invalid reload insns, since the reg inside may need to + be copied from in the outside mode, and that may be invalid + if it is an fp reg copied in integer mode. + + We allow two exceptions to this: It is valid if it is inside + another SUBREG and the mode of that SUBREG and the mode of + the inside of TO is tieable and it is valid if X is a SET + that copies FROM to CC0. */ + if (GET_CODE (to) == SUBREG + && ! MODES_TIEABLE_P (GET_MODE (to), + GET_MODE (SUBREG_REG (to))) + && ! (code == SUBREG + && MODES_TIEABLE_P (mode, GET_MODE (SUBREG_REG (to)))) + #ifdef HAVE_cc0 + && ! (code == SET && i == 1 && XEXP (x, 0) == cc0_rtx) + #endif + ) + return gen_rtx (CLOBBER, VOIDmode, const0_rtx); + new = (unique_copy && n_occurrences ? copy_rtx (to) : to); n_occurrences++; *************** *** 2886,2889 **** --- 2954,2974 ---- } + else if ((GET_RTX_CLASS (code) == '2' || GET_RTX_CLASS (code) == 'c') + && GET_CODE (XEXP (x, 1)) == IF_THEN_ELSE) + { + /* Don't do this by using SUBST inside X since we might be messing + up a shared expression. */ + rtx cond = XEXP (XEXP (x, 1), 0); + rtx t_arm = subst (gen_binary (code, mode, XEXP (x, 0), + XEXP (XEXP (x, 1), 1)), + pc_rtx, pc_rtx, 0, 0); + rtx f_arm = subst (gen_binary (code, mode, XEXP (x, 0), + XEXP (XEXP (x, 1), 2)), + pc_rtx, pc_rtx, 0, 0); + + x = gen_rtx (IF_THEN_ELSE, mode, cond, t_arm, f_arm); + goto restart; + } + else if (GET_RTX_CLASS (code) == '1' && GET_CODE (XEXP (x, 0)) == IF_THEN_ELSE *************** *** 2932,2936 **** /* First see if we can apply the inverse distributive law. */ ! if (code == PLUS || code == MINUS || code == IOR || code == XOR) { x = apply_distributive_law (x); --- 3017,3022 ---- /* First see if we can apply the inverse distributive law. */ ! if (code == PLUS || code == MINUS ! || code == AND || code == IOR || code == XOR) { x = apply_distributive_law (x); *************** *** 2945,2949 **** || code == DIV || code == UDIV || code == SMAX || code == SMIN || code == UMAX || code == UMIN) ! && GET_MODE_CLASS (mode) == MODE_INT) { if (GET_CODE (XEXP (x, 0)) == code) --- 3031,3035 ---- || code == DIV || code == UDIV || code == SMAX || code == SMIN || code == UMAX || code == UMIN) ! && INTEGRAL_MODE_P (mode)) { if (GET_CODE (XEXP (x, 0)) == code) *************** *** 3057,3060 **** --- 3143,3149 ---- && REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER && REGNO (SUBREG_REG (x)) != FRAME_POINTER_REGNUM + #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM + && REGNO (SUBREG_REG (x)) != HARD_FRAME_POINTER_REGNUM + #endif #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM && REGNO (SUBREG_REG (x)) != ARG_POINTER_REGNUM *************** *** 3098,3108 **** return gen_lowpart_for_combine (mode, SUBREG_REG (x)); ! /* If we are narrowing the object, we need to see if we can simplify ! the expression for the object knowing that we only need the low-order bits. */ ! if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))) && subreg_lowpart_p (x)) ! return force_to_mode (SUBREG_REG (x), mode, GET_MODE_BITSIZE (mode), NULL_RTX); break; --- 3187,3199 ---- return gen_lowpart_for_combine (mode, SUBREG_REG (x)); ! /* If we are narrowing an integral object, we need to see if we can ! simplify the expression for the object knowing that we only need the low-order bits. */ ! if (GET_MODE_CLASS (mode) == MODE_INT ! && GET_MODE_CLASS (GET_MODE (SUBREG_REG (x))) == MODE_INT ! && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))) && subreg_lowpart_p (x)) ! return force_to_mode (SUBREG_REG (x), mode, GET_MODE_MASK (mode), NULL_RTX); break; *************** *** 3229,3233 **** if (GET_CODE (XEXP (x, 0)) == NOT) { ! x = gen_rtx_combine (PLUS, mode, XEXP (XEXP (x, 0), 0), const1_rtx); goto restart; } --- 3320,3324 ---- if (GET_CODE (XEXP (x, 0)) == NOT) { ! x = plus_constant (XEXP (XEXP (x, 0), 0), 1); goto restart; } *************** *** 3235,3239 **** /* (neg (minus X Y)) can become (minus Y X). */ if (GET_CODE (XEXP (x, 0)) == MINUS ! && (GET_MODE_CLASS (mode) != MODE_FLOAT /* x-y != -(y-x) with IEEE floating point. */ || TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT)) --- 3326,3330 ---- /* (neg (minus X Y)) can become (minus Y X). */ if (GET_CODE (XEXP (x, 0)) == MINUS ! && (! FLOAT_MODE_P (mode) /* x-y != -(y-x) with IEEE floating point. */ || TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT)) *************** *** 3330,3334 **** /* In IEEE floating point, x-0 is not the same as x. */ if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT ! || GET_MODE_CLASS (GET_MODE (XEXP (x, 0))) == MODE_INT) && XEXP (x, 1) == CONST0_RTX (GET_MODE (XEXP (x, 0)))) return XEXP (x, 0); --- 3421,3425 ---- /* In IEEE floating point, x-0 is not the same as x. */ if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT ! || ! FLOAT_MODE_P (GET_MODE (XEXP (x, 0)))) && XEXP (x, 1) == CONST0_RTX (GET_MODE (XEXP (x, 0)))) return XEXP (x, 0); *************** *** 3394,3398 **** } ! /* If only the low-order bit of X is possible nonzero, (plus x -1) can become (ashiftrt (ashift (xor x 1) C) C) where C is the bitsize of the mode - 1. This allows simplification of --- 3485,3504 ---- } ! /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if ! C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE ! is 1. This produces better code than the alternative immediately ! below. */ ! if (GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<' ! && reversible_comparison_p (XEXP (x, 0)) ! && ((STORE_FLAG_VALUE == -1 && XEXP (x, 1) == const1_rtx) ! || (STORE_FLAG_VALUE == 1 && XEXP (x, 1) == constm1_rtx))) ! { ! x = gen_binary (reverse_condition (GET_CODE (XEXP (x, 0))), ! mode, XEXP (XEXP (x, 0), 0), XEXP (XEXP (x, 0), 1)); ! x = gen_unary (NEG, mode, x); ! goto restart; ! } ! ! /* If only the low-order bit of X is possibly nonzero, (plus x -1) can become (ashiftrt (ashift (xor x 1) C) C) where C is the bitsize of the mode - 1. This allows simplification of *************** *** 3429,3432 **** --- 3535,3549 ---- case MINUS: + #if STORE_FLAG_VALUE == 1 + /* (minus 1 (comparison foo bar)) can be done by reversing the comparison + code if valid. */ + if (XEXP (x, 0) == const1_rtx + && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<' + && reversible_comparison_p (XEXP (x, 1))) + return gen_binary (reverse_condition (GET_CODE (XEXP (x, 1))), + mode, XEXP (XEXP (x, 1), 0), + XEXP (XEXP (x, 1), 1)); + #endif + /* (minus (and (const_int -pow2))) becomes (and (const_int pow2-1)) */ *************** *** 3523,3546 **** /* If STORE_FLAG_VALUE is 1, we can convert (ne x 0) to simply X if only the low-order bit is possibly nonzero in X (such as when ! X is a ZERO_EXTRACT of one bit. Similarly, we can convert ! EQ to (xor X 1). Remove any ZERO_EXTRACT we made when thinking ! this was a comparison. It may now be simpler to use, e.g., an ! AND. If a ZERO_EXTRACT is indeed appropriate, it will ! be placed back by the call to make_compound_operation in the ! SET case. */ if (new_code == NE && GET_MODE_CLASS (mode) == MODE_INT && op1 == const0_rtx ! && nonzero_bits (op0, GET_MODE (op0)) == 1) return gen_lowpart_for_combine (mode, expand_compound_operation (op0)); else if (new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT && op1 == const0_rtx ! && nonzero_bits (op0, GET_MODE (op0)) == 1) { op0 = expand_compound_operation (op0); ! x = gen_rtx_combine (XOR, mode, ! gen_lowpart_for_combine (mode, op0), ! const1_rtx); goto restart; } --- 3640,3687 ---- /* If STORE_FLAG_VALUE is 1, we can convert (ne x 0) to simply X if only the low-order bit is possibly nonzero in X (such as when ! X is a ZERO_EXTRACT of one bit). Similarly, we can convert EQ to ! (xor X 1) or (minus 1 X); we use the former. Finally, if X is ! known to be either 0 or -1, NE becomes a NEG and EQ becomes ! (plus X 1). ! ! Remove any ZERO_EXTRACT we made when thinking this was a ! comparison. It may now be simpler to use, e.g., an AND. If a ! ZERO_EXTRACT is indeed appropriate, it will be placed back by ! the call to make_compound_operation in the SET case. */ ! if (new_code == NE && GET_MODE_CLASS (mode) == MODE_INT && op1 == const0_rtx ! && nonzero_bits (op0, mode) == 1) return gen_lowpart_for_combine (mode, expand_compound_operation (op0)); + + else if (new_code == NE && GET_MODE_CLASS (mode) == MODE_INT + && op1 == const0_rtx + && (num_sign_bit_copies (op0, mode) + == GET_MODE_BITSIZE (mode))) + { + op0 = expand_compound_operation (op0); + x = gen_unary (NEG, mode, gen_lowpart_for_combine (mode, op0)); + goto restart; + } + else if (new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT && op1 == const0_rtx ! && nonzero_bits (op0, mode) == 1) { op0 = expand_compound_operation (op0); + x = gen_binary (XOR, mode, + gen_lowpart_for_combine (mode, op0), + const1_rtx); + goto restart; + } ! else if (new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT ! && op1 == const0_rtx ! && (num_sign_bit_copies (op0, mode) ! == GET_MODE_BITSIZE (mode))) ! { ! op0 = expand_compound_operation (op0); ! x = plus_constant (gen_lowpart_for_combine (mode, op0), 1); goto restart; } *************** *** 3548,3564 **** #if STORE_FLAG_VALUE == -1 ! /* If STORE_FLAG_VALUE is -1, we can convert (ne x 0) ! to (neg x) if only the low-order bit of X can be nonzero. ! This converts (ne (zero_extract X 1 Y) 0) to ! (sign_extract X 1 Y). */ if (new_code == NE && GET_MODE_CLASS (mode) == MODE_INT && op1 == const0_rtx ! && nonzero_bits (op0, GET_MODE (op0)) == 1) { op0 = expand_compound_operation (op0); ! x = gen_rtx_combine (NEG, mode, ! gen_lowpart_for_combine (mode, op0)); goto restart; } #endif --- 3689,3729 ---- #if STORE_FLAG_VALUE == -1 ! /* If STORE_FLAG_VALUE is -1, we have cases similar to ! those above. */ if (new_code == NE && GET_MODE_CLASS (mode) == MODE_INT && op1 == const0_rtx ! && (num_sign_bit_copies (op0, mode) ! == GET_MODE_BITSIZE (mode))) ! return gen_lowpart_for_combine (mode, ! expand_compound_operation (op0)); ! ! else if (new_code == NE && GET_MODE_CLASS (mode) == MODE_INT ! && op1 == const0_rtx ! && nonzero_bits (op0, mode) == 1) { op0 = expand_compound_operation (op0); ! x = gen_unary (NEG, mode, gen_lowpart_for_combine (mode, op0)); goto restart; } + + else if (new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT + && op1 == const0_rtx + && (num_sign_bit_copies (op0, mode) + == GET_MODE_BITSIZE (mode))) + { + op0 = expand_compound_operation (op0); + x = gen_unary (NOT, mode, gen_lowpart_for_combine (mode, op0)); + goto restart; + } + + /* If X is 0/1, (eq X 0) is X-1. */ + else if (new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT + && op1 == const0_rtx + && nonzero_bits (op0, mode) == 1) + { + op0 = expand_compound_operation (op0); + x = plus_constant (gen_lowpart_for_combine (mode, op0), -1); + goto restart; + } #endif *************** *** 3574,3578 **** && op1 == const0_rtx && mode == GET_MODE (op0) ! && (i = exact_log2 (nonzero_bits (op0, GET_MODE (op0)))) >= 0) { x = simplify_shift_const (NULL_RTX, ASHIFT, mode, --- 3739,3743 ---- && op1 == const0_rtx && mode == GET_MODE (op0) ! && (i = exact_log2 (nonzero_bits (op0, mode))) >= 0) { x = simplify_shift_const (NULL_RTX, ASHIFT, mode, *************** *** 3703,3707 **** /* Look for MIN or MAX. */ ! if (GET_MODE_CLASS (mode) == MODE_INT && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<' && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)) --- 3868,3872 ---- /* Look for MIN or MAX. */ ! if (! FLOAT_MODE_P (mode) && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<' && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)) *************** *** 3728,3813 **** } ! /* If we have something like (if_then_else (ne A 0) (OP X C) X), ! A is known to be either 0 or 1, and OP is an identity when its ! second operand is zero, this can be done as (OP X (mult A C)). ! Similarly if A is known to be 0 or -1 and also similarly if we have ! a ZERO_EXTEND or SIGN_EXTEND as long as X is already extended (so ! we don't destroy it). */ ! ! if (mode != VOIDmode ! && (GET_CODE (XEXP (x, 0)) == EQ || GET_CODE (XEXP (x, 0)) == NE) ! && XEXP (XEXP (x, 0), 1) == const0_rtx ! && (nonzero_bits (XEXP (XEXP (x, 0), 0), mode) == 1 ! || (num_sign_bit_copies (XEXP (XEXP (x, 0), 0), mode) ! == GET_MODE_BITSIZE (mode)))) ! { ! rtx nz = make_compound_operation (GET_CODE (XEXP (x, 0)) == NE ! ? XEXP (x, 1) : XEXP (x, 2)); ! rtx z = GET_CODE (XEXP (x, 0)) == NE ? XEXP (x, 2) : XEXP (x, 1); ! rtx dir = (nonzero_bits (XEXP (XEXP (x, 0), 0), mode) == 1 ! ? const1_rtx : constm1_rtx); ! rtx c = 0; enum machine_mode m = mode; ! enum rtx_code op, extend_op = 0; ! if ((GET_CODE (nz) == PLUS || GET_CODE (nz) == MINUS ! || GET_CODE (nz) == IOR || GET_CODE (nz) == XOR ! || GET_CODE (nz) == ASHIFT ! || GET_CODE (nz) == LSHIFTRT || GET_CODE (nz) == ASHIFTRT) ! && rtx_equal_p (XEXP (nz, 0), z)) ! c = XEXP (nz, 1), op = GET_CODE (nz); ! else if (GET_CODE (nz) == SIGN_EXTEND ! && (GET_CODE (XEXP (nz, 0)) == PLUS ! || GET_CODE (XEXP (nz, 0)) == MINUS ! || GET_CODE (XEXP (nz, 0)) == IOR ! || GET_CODE (XEXP (nz, 0)) == XOR ! || GET_CODE (XEXP (nz, 0)) == ASHIFT ! || GET_CODE (XEXP (nz, 0)) == LSHIFTRT ! || GET_CODE (XEXP (nz, 0)) == ASHIFTRT) ! && GET_CODE (XEXP (XEXP (nz, 0), 0)) == SUBREG ! && subreg_lowpart_p (XEXP (XEXP (nz, 0), 0)) ! && rtx_equal_p (SUBREG_REG (XEXP (XEXP (nz, 0), 0)), z) ! && (num_sign_bit_copies (z, GET_MODE (z)) ! >= (GET_MODE_BITSIZE (mode) ! - GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (nz, 0), 0)))))) { ! c = XEXP (XEXP (nz, 0), 1); ! op = GET_CODE (XEXP (nz, 0)); extend_op = SIGN_EXTEND; ! m = GET_MODE (XEXP (nz, 0)); } ! else if (GET_CODE (nz) == ZERO_EXTEND ! && (GET_CODE (XEXP (nz, 0)) == PLUS ! || GET_CODE (XEXP (nz, 0)) == MINUS ! || GET_CODE (XEXP (nz, 0)) == IOR ! || GET_CODE (XEXP (nz, 0)) == XOR ! || GET_CODE (XEXP (nz, 0)) == ASHIFT ! || GET_CODE (XEXP (nz, 0)) == LSHIFTRT ! || GET_CODE (XEXP (nz, 0)) == ASHIFTRT) ! && GET_CODE (XEXP (XEXP (nz, 0), 0)) == SUBREG && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT ! && subreg_lowpart_p (XEXP (XEXP (nz, 0), 0)) ! && rtx_equal_p (SUBREG_REG (XEXP (XEXP (nz, 0), 0)), z) ! && ((nonzero_bits (z, GET_MODE (z)) ! & ~ GET_MODE_MASK (GET_MODE (XEXP (XEXP (nz, 0), 0)))) == 0)) { ! c = XEXP (XEXP (nz, 0), 1); ! op = GET_CODE (XEXP (nz, 0)); extend_op = ZERO_EXTEND; ! m = GET_MODE (XEXP (nz, 0)); } ! if (c && ! side_effects_p (c) && ! side_effects_p (z)) { ! temp ! = gen_binary (MULT, m, ! gen_lowpart_for_combine (m, ! XEXP (XEXP (x, 0), 0)), ! gen_binary (MULT, m, c, dir)); temp = gen_binary (op, m, gen_lowpart_for_combine (m, z), temp); ! if (extend_op != 0) temp = gen_unary (extend_op, mode, temp); --- 3893,4028 ---- } ! #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1 ! ! /* If we have (if_then_else COND (OP Z C1) Z) and OP is an identity when ! its second operand is zero, this can be done as (OP Z (mult COND C2)) ! where C2 = C1 * STORE_FLAG_VALUE. Similarly if OP has an outer ! ZERO_EXTEND or SIGN_EXTEND as long as Z is already extended (so ! we don't destroy it). We can do this kind of thing in some ! cases when STORE_FLAG_VALUE is neither of the above, but it isn't ! worth checking for. */ ! ! if (mode != VOIDmode && ! side_effects_p (x)) ! { ! rtx t = make_compound_operation (XEXP (x, 1), SET); ! rtx f = make_compound_operation (XEXP (x, 2), SET); ! rtx cond_op0 = XEXP (XEXP (x, 0), 0); ! rtx cond_op1 = XEXP (XEXP (x, 0), 1); ! enum rtx_code cond_op = GET_CODE (XEXP (x, 0)); ! enum rtx_code op, extend_op = NIL; enum machine_mode m = mode; ! rtx z = 0, c1, c2; ! ! if ((GET_CODE (t) == PLUS || GET_CODE (t) == MINUS ! || GET_CODE (t) == IOR || GET_CODE (t) == XOR ! || GET_CODE (t) == ASHIFT ! || GET_CODE (t) == LSHIFTRT || GET_CODE (t) == ASHIFTRT) ! && rtx_equal_p (XEXP (t, 0), f)) ! c1 = XEXP (t, 1), op = GET_CODE (t), z = f; ! else if (GET_CODE (t) == SIGN_EXTEND ! && (GET_CODE (XEXP (t, 0)) == PLUS ! || GET_CODE (XEXP (t, 0)) == MINUS ! || GET_CODE (XEXP (t, 0)) == IOR ! || GET_CODE (XEXP (t, 0)) == XOR ! || GET_CODE (XEXP (t, 0)) == ASHIFT ! || GET_CODE (XEXP (t, 0)) == LSHIFTRT ! || GET_CODE (XEXP (t, 0)) == ASHIFTRT) ! && GET_CODE (XEXP (XEXP (t, 0), 0)) == SUBREG ! && subreg_lowpart_p (XEXP (XEXP (t, 0), 0)) ! && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 0)), f) ! && (num_sign_bit_copies (f, GET_MODE (f)) ! > (GET_MODE_BITSIZE (mode) ! - GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (t, 0), 0)))))) ! { ! c1 = XEXP (XEXP (t, 0), 1); z = f; op = GET_CODE (XEXP (t, 0)); ! extend_op = SIGN_EXTEND; ! m = GET_MODE (XEXP (t, 0)); ! } ! else if (GET_CODE (t) == ZERO_EXTEND ! && (GET_CODE (XEXP (t, 0)) == PLUS ! || GET_CODE (XEXP (t, 0)) == MINUS ! || GET_CODE (XEXP (t, 0)) == IOR ! || GET_CODE (XEXP (t, 0)) == XOR ! || GET_CODE (XEXP (t, 0)) == ASHIFT ! || GET_CODE (XEXP (t, 0)) == LSHIFTRT ! || GET_CODE (XEXP (t, 0)) == ASHIFTRT) ! && GET_CODE (XEXP (XEXP (t, 0), 0)) == SUBREG ! && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT ! && subreg_lowpart_p (XEXP (XEXP (t, 0), 0)) ! && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 0)), f) ! && ((nonzero_bits (f, GET_MODE (f)) ! & ~ GET_MODE_MASK (GET_MODE (XEXP (XEXP (t, 0), 0)))) ! == 0)) ! { ! c1 = XEXP (XEXP (t, 0), 1); z = f; op = GET_CODE (XEXP (t, 0)); ! extend_op = ZERO_EXTEND; ! m = GET_MODE (XEXP (t, 0)); ! } ! if (reversible_comparison_p (XEXP (x, 0)) ! && (GET_CODE (f) == PLUS || GET_CODE (f) == MINUS ! || GET_CODE (f) == IOR || GET_CODE (f) == XOR ! || GET_CODE (f) == ASHIFT ! || GET_CODE (f) == LSHIFTRT || GET_CODE (f) == ASHIFTRT) ! && rtx_equal_p (XEXP (f, 0), t)) ! { ! c1 = XEXP (f, 1), op = GET_CODE (f), z = t; ! cond_op = reverse_condition (cond_op); ! } ! else if (GET_CODE (f) == SIGN_EXTEND ! && (GET_CODE (XEXP (f, 0)) == PLUS ! || GET_CODE (XEXP (f, 0)) == MINUS ! || GET_CODE (XEXP (f, 0)) == IOR ! || GET_CODE (XEXP (f, 0)) == XOR ! || GET_CODE (XEXP (f, 0)) == ASHIFT ! || GET_CODE (XEXP (f, 0)) == LSHIFTRT ! || GET_CODE (XEXP (f, 0)) == ASHIFTRT) ! && GET_CODE (XEXP (XEXP (f, 0), 0)) == SUBREG ! && subreg_lowpart_p (XEXP (XEXP (f, 0), 0)) ! && rtx_equal_p (SUBREG_REG (XEXP (XEXP (f, 0), 0)), f) ! && (num_sign_bit_copies (t, GET_MODE (t)) ! > (GET_MODE_BITSIZE (mode) ! - GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (f, 0), 0)))))) { ! c1 = XEXP (XEXP (f, 0), 1); z = t; op = GET_CODE (XEXP (f, 0)); extend_op = SIGN_EXTEND; ! m = GET_MODE (XEXP (f, 0)); ! cond_op = reverse_condition (cond_op); } ! else if (GET_CODE (f) == ZERO_EXTEND ! && (GET_CODE (XEXP (f, 0)) == PLUS ! || GET_CODE (XEXP (f, 0)) == MINUS ! || GET_CODE (XEXP (f, 0)) == IOR ! || GET_CODE (XEXP (f, 0)) == XOR ! || GET_CODE (XEXP (f, 0)) == ASHIFT ! || GET_CODE (XEXP (f, 0)) == LSHIFTRT ! || GET_CODE (XEXP (f, 0)) == ASHIFTRT) ! && GET_CODE (XEXP (XEXP (f, 0), 0)) == SUBREG && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT ! && subreg_lowpart_p (XEXP (XEXP (f, 0), 0)) ! && rtx_equal_p (SUBREG_REG (XEXP (XEXP (f, 0), 0)), t) ! && ((nonzero_bits (t, GET_MODE (t)) ! & ~ GET_MODE_MASK (GET_MODE (XEXP (XEXP (f, 0), 0)))) == 0)) { ! c1 = XEXP (XEXP (f, 0), 1); z = t; op = GET_CODE (XEXP (f, 0)); extend_op = ZERO_EXTEND; ! m = GET_MODE (XEXP (f, 0)); ! cond_op = reverse_condition (cond_op); } ! if (z) { ! temp = subst (gen_binary (cond_op, m, cond_op0, cond_op1), ! pc_rtx, pc_rtx, 0, 0); + + temp = gen_binary (MULT, m, temp, + gen_binary (MULT, m, c1, + GEN_INT (STORE_FLAG_VALUE))); + temp = gen_binary (op, m, gen_lowpart_for_combine (m, z), temp); ! if (extend_op != NIL) temp = gen_unary (extend_op, mode, temp); *************** *** 3815,3818 **** --- 4030,4053 ---- } } + #endif + + /* If we have (if_then_else (ne A 0) C1 0) and either A is known to + be 0 or 1 and C1 is a single bit or A is known to be 0 or -1 and + C1 is the negation of a single bit, we can convert this operation + to a shift. We can actually do this in more general cases, but it + doesn't seem worth it. */ + + if (GET_CODE (XEXP (x, 0)) == NE && XEXP (XEXP (x, 0), 1) == const0_rtx + && XEXP (x, 2) == const0_rtx && GET_CODE (XEXP (x, 1)) == CONST_INT + && ((1 == nonzero_bits (XEXP (XEXP (x, 0), 0), mode) + && (i = exact_log2 (INTVAL (XEXP (x, 1)))) >= 0) + || ((num_sign_bit_copies (XEXP (XEXP (x, 0), 0), mode) + == GET_MODE_BITSIZE (mode)) + && (i = exact_log2 (- INTVAL (XEXP (x, 1)))) >= 0))) + return + simplify_shift_const (NULL_RTX, ASHIFT, mode, + gen_lowpart_for_combine (mode, + XEXP (XEXP (x, 0), 0)), + i); break; *************** *** 3977,3986 **** means that we only care about the low bits of the result. ! However, on most machines (those with neither BYTE_LOADS_ZERO_EXTEND ! nor BYTES_LOADS_SIGN_EXTEND defined), we cannot perform a ! narrower operation that requested since the high-order bits will ! be undefined. On machine where BYTE_LOADS_*_EXTEND is defined, ! however, this transformation is safe as long as M1 and M2 have ! the same number of words. */ if (GET_CODE (SET_SRC (x)) == SUBREG --- 4212,4220 ---- means that we only care about the low bits of the result. ! However, on machines without WORD_REGISTER_OPERATIONS defined, ! we cannot perform a narrower operation that requested since the ! high-order bits will be undefined. On machine where it is defined, ! this transformation is safe as long as M1 and M2 have the same ! number of words. */ if (GET_CODE (SET_SRC (x)) == SUBREG *************** *** 3991,3995 **** == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_SRC (x)))) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)) ! #ifndef BYTE_LOADS_EXTEND && (GET_MODE_SIZE (GET_MODE (SET_SRC (x))) < GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_SRC (x))))) --- 4225,4229 ---- == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_SRC (x)))) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)) ! #ifndef WORD_REGISTER_OPERATIONS && (GET_MODE_SIZE (GET_MODE (SET_SRC (x))) < GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_SRC (x))))) *************** *** 4005,4009 **** } ! #ifdef BYTE_LOADS_EXTEND /* If we have (set FOO (subreg:M (mem:N BAR) 0)) with M wider than N, this would require a paradoxical subreg. --- 4239,4243 ---- } ! #ifdef LOAD_EXTEND_OP /* If we have (set FOO (subreg:M (mem:N BAR) 0)) with M wider than N, this would require a paradoxical subreg. *************** *** 4012,4015 **** --- 4246,4250 ---- if (GET_CODE (SET_SRC (x)) == SUBREG + && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (SET_SRC (x)))) != NIL && subreg_lowpart_p (SET_SRC (x)) && SUBREG_WORD (SET_SRC (x)) == 0 *************** *** 4017,4023 **** > GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_SRC (x))))) && GET_CODE (SUBREG_REG (SET_SRC (x))) == MEM) ! SUBST (SET_SRC (x), gen_rtx_combine (LOAD_EXTEND, ! GET_MODE (SET_SRC (x)), ! XEXP (SET_SRC (x), 0))); #endif --- 4252,4260 ---- > GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_SRC (x))))) && GET_CODE (SUBREG_REG (SET_SRC (x))) == MEM) ! SUBST (SET_SRC (x), ! gen_rtx_combine (LOAD_EXTEND_OP (GET_MODE ! (SUBREG_REG (SET_SRC (x)))), ! GET_MODE (SET_SRC (x)), ! XEXP (SET_SRC (x), 0))); #endif *************** *** 4447,4454 **** #ifdef SHIFT_COUNT_TRUNCATED ! else if (GET_CODE (XEXP (x, 1)) != REG) SUBST (XEXP (x, 1), force_to_mode (XEXP (x, 1), GET_MODE (x), ! exact_log2 (GET_MODE_BITSIZE (GET_MODE (x))), NULL_RTX)); #endif --- 4684,4693 ---- #ifdef SHIFT_COUNT_TRUNCATED ! else if (SHIFT_COUNT_TRUNCATED && GET_CODE (XEXP (x, 1)) != REG) SUBST (XEXP (x, 1), force_to_mode (XEXP (x, 1), GET_MODE (x), ! ((HOST_WIDE_INT) 1 ! << exact_log2 (GET_MODE_BITSIZE (GET_MODE (x)))) ! - 1, NULL_RTX)); #endif *************** *** 4740,4743 **** --- 4979,4983 ---- rtx new = 0; rtx orig_pos_rtx = pos_rtx; + int orig_pos; /* Get some information about INNER and get the innermost object. */ *************** *** 4826,4830 **** : 0)); else ! new = force_to_mode (inner, tmode, len, NULL_RTX); /* If this extraction is going into the destination of a SET, --- 5066,5074 ---- : 0)); else ! new = force_to_mode (inner, tmode, ! len >= HOST_BITS_PER_WIDE_INT ! ? GET_MODE_MASK (tmode) ! : ((HOST_WIDE_INT) 1 << len) - 1, ! NULL_RTX); /* If this extraction is going into the destination of a SET, *************** *** 4899,4902 **** --- 5143,5148 ---- wanted_mem_mode = extraction_mode; + orig_pos = pos; + #if BITS_BIG_ENDIAN /* If position is constant, compute new position. Otherwise, build *************** *** 4965,4970 **** else if (GET_CODE (inner) != MEM) inner = force_to_mode (inner, extraction_mode, ! (pos < 0 ? GET_MODE_BITSIZE (extraction_mode) ! : len + pos), NULL_RTX); --- 5211,5217 ---- else if (GET_CODE (inner) != MEM) inner = force_to_mode (inner, extraction_mode, ! pos_rtx || len + orig_pos >= HOST_BITS_PER_WIDE_INT ! ? GET_MODE_MASK (extraction_mode) ! : (((HOST_WIDE_INT) 1 << len) - 1) << orig_pos, NULL_RTX); *************** *** 5085,5088 **** --- 5332,5350 ---- 0, in_code == COMPARE); } + /* Same as previous, but for (xor/ior (lshift...) (lshift...)). */ + else if ((GET_CODE (XEXP (x, 0)) == XOR + || GET_CODE (XEXP (x, 0)) == IOR) + && GET_CODE (XEXP (XEXP (x, 0), 0)) == LSHIFTRT + && GET_CODE (XEXP (XEXP (x, 0), 1)) == LSHIFTRT + && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0) + { + /* Apply the distributive law, and then try to make extractions. */ + new = gen_rtx_combine (GET_CODE (XEXP (x, 0)), mode, + gen_rtx (AND, mode, XEXP (XEXP (x, 0), 0), + XEXP (x, 1)), + gen_rtx (AND, mode, XEXP (XEXP (x, 0), 1), + XEXP (x, 1))); + new = make_compound_operation (new, in_code); + } /* If we are have (and (rotate X C) M) and C is larger than the number *************** *** 5232,5237 **** next_code); new = make_extraction (mode, ! gen_unary (GET_CODE (XEXP (x, 0)), mode, ! new, 0), (INTVAL (XEXP (x, 1)) - INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1))), --- 5494,5498 ---- next_code); new = make_extraction (mode, ! gen_unary (GET_CODE (XEXP (x, 0)), mode, new), (INTVAL (XEXP (x, 1)) - INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1))), *************** *** 5252,5256 **** { rtx newer = force_to_mode (tem, mode, ! GET_MODE_BITSIZE (mode), NULL_RTX); /* If we have something other than a SUBREG, we might have --- 5513,5517 ---- { rtx newer = force_to_mode (tem, mode, ! GET_MODE_MASK (mode), NULL_RTX); /* If we have something other than a SUBREG, we might have *************** *** 5309,5316 **** } ! /* Rewrite X so that it is an expression in MODE. We only care about the ! low-order BITS bits so we can ignore AND operations that just clear ! higher-order bits. Also, if REG is non-zero and X is a register equal in value to REG, replace X with REG. */ --- 5570,5582 ---- } ! /* See if X can be simplified knowing that we will only refer to it in ! MODE and will only refer to those bits that are nonzero in MASK. ! If other bits are being computed or if masking operations are done ! that select a superset of the bits in MASK, they can sometimes be ! ignored. + Return a possibly simplified expression, but always convert X to + MODE. If X is a CONST_INT, AND the CONST_INT with MASK. + Also, if REG is non-zero and X is a register equal in value to REG, replace X with REG. */ *************** *** 5317,5338 **** static rtx ! force_to_mode (x, mode, bits, reg) rtx x; enum machine_mode mode; ! int bits; rtx reg; { enum rtx_code code = GET_CODE (x); ! enum machine_mode op_mode = mode; ! /* If X is narrower than MODE or if BITS is larger than the size of MODE, ! just get X in the proper mode. */ ! if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (mode) ! || bits > GET_MODE_BITSIZE (mode)) return gen_lowpart_for_combine (mode, x); switch (code) { case SIGN_EXTEND: case ZERO_EXTEND: --- 5583,5667 ---- static rtx ! force_to_mode (x, mode, mask, reg) rtx x; enum machine_mode mode; ! unsigned HOST_WIDE_INT mask; rtx reg; { enum rtx_code code = GET_CODE (x); ! enum machine_mode op_mode; ! unsigned HOST_WIDE_INT fuller_mask, nonzero; ! rtx op0, op1, temp; ! ! /* We want to perform the operation is its present mode unless we know ! that the operation is valid in MODE, in which case we do the operation ! in MODE. */ ! op_mode = ((code_to_optab[(int) code] != 0 ! && (code_to_optab[(int) code]->handlers[(int) mode].insn_code ! != CODE_FOR_nothing)) ! ? mode : GET_MODE (x)); ! ! /* Truncate MASK to fit OP_MODE. */ ! if (op_mode) ! mask &= GET_MODE_MASK (op_mode); ! ! /* When we have an arithmetic operation, or a shift whose count we ! do not know, we need to assume that all bit the up to the highest-order ! bit in MASK will be needed. This is how we form such a mask. */ ! if (op_mode) ! fuller_mask = (GET_MODE_BITSIZE (op_mode) >= HOST_BITS_PER_WIDE_INT ! ? GET_MODE_MASK (op_mode) ! : ((HOST_WIDE_INT) 1 << (floor_log2 (mask) + 1)) - 1); ! else ! fuller_mask = ~ (HOST_WIDE_INT) 0; ! ! /* Determine what bits of X are guaranteed to be (non)zero. */ ! nonzero = nonzero_bits (x, mode); ! ! /* If none of the bits in X are needed, return a zero. */ ! if ((nonzero & mask) == 0) ! return const0_rtx; ! /* If X is a CONST_INT, return a new one. Do this here since the ! test below will fail. */ ! if (GET_CODE (x) == CONST_INT) ! { ! HOST_WIDE_INT cval = INTVAL (x) & mask; ! int width = GET_MODE_BITSIZE (mode); ! ! /* If MODE is narrower that HOST_WIDE_INT and CVAL is a negative ! number, sign extend it. */ ! if (width > 0 && width < HOST_BITS_PER_WIDE_INT ! && (cval & ((HOST_WIDE_INT) 1 << (width - 1))) != 0) ! cval |= (HOST_WIDE_INT) -1 << width; ! ! return GEN_INT (cval); ! } ! /* If X is narrower than MODE, just get X in the proper mode. */ ! if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (mode)) return gen_lowpart_for_combine (mode, x); + /* If we aren't changing the mode and all zero bits in MASK are already + known to be zero in X, we need not do anything. */ + if (GET_MODE (x) == mode && (~ mask & nonzero) == 0) + return x; + switch (code) { + case CLOBBER: + /* If X is a (clobber (const_int)), return it since we know we are + generating something that won't match. */ + return x; + + #if ! BITS_BIG_ENDIAN + case USE: + /* X is a (use (mem ..)) that was made from a bit-field extraction that + spanned the boundary of the MEM. If we are now masking so it is + within that boundary, we don't need the USE any more. */ + if ((mask & ~ GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0) + return force_to_mode (XEXP (x, 0), mode, mask, reg); + #endif + case SIGN_EXTEND: case ZERO_EXTEND: *************** *** 5341,5345 **** x = expand_compound_operation (x); if (GET_CODE (x) != code) ! return force_to_mode (x, mode, bits, reg); break; --- 5670,5674 ---- x = expand_compound_operation (x); if (GET_CODE (x) != code) ! return force_to_mode (x, mode, mask, reg); break; *************** *** 5350,5392 **** break; - case CONST_INT: - if (bits < HOST_BITS_PER_WIDE_INT) - x = GEN_INT (INTVAL (x) & (((HOST_WIDE_INT) 1 << bits) - 1)); - return x; - case SUBREG: ! /* Ignore low-order SUBREGs. */ ! if (subreg_lowpart_p (x)) ! return force_to_mode (SUBREG_REG (x), mode, bits, reg); break; case AND: ! /* If this is an AND with a constant. Otherwise, we fall through to ! do the general binary case. */ ! if (GET_CODE (XEXP (x, 1)) == CONST_INT) { ! HOST_WIDE_INT mask = INTVAL (XEXP (x, 1)); ! int len = exact_log2 (mask + 1); ! rtx op = XEXP (x, 0); ! ! /* If this is masking some low-order bits, we may be able to ! impose a stricter constraint on what bits of the operand are ! required. */ - op = force_to_mode (op, mode, len > 0 ? MIN (len, bits) : bits, - reg); - - if (bits < HOST_BITS_PER_WIDE_INT) - mask &= ((HOST_WIDE_INT) 1 << bits) - 1; - - /* If we have no AND in MODE, use the original mode for the - operation. */ - - if (and_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) - op_mode = GET_MODE (x); - - x = simplify_and_const_int (x, op_mode, op, mask); - /* If X is still an AND, see if it is an AND with a mask that is just some low-order bits. If so, and it is BITS wide (it --- 5679,5710 ---- break; case SUBREG: ! if (subreg_lowpart_p (x) ! /* We can ignore the effect this SUBREG if it narrows the mode or, ! on machines where register operations are performed on the full ! word, if the constant masks to zero all the bits the mode ! doesn't have. */ ! && ((GET_MODE_SIZE (GET_MODE (x)) ! < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))) ! #ifdef WORD_REGISTER_OPERATIONS ! || (0 == (mask ! & GET_MODE_MASK (GET_MODE (x)) ! & ~ GET_MODE_MASK (GET_MODE (SUBREG_REG (x))))) ! #endif ! )) ! return force_to_mode (SUBREG_REG (x), mode, mask, reg); break; case AND: ! /* If this is an AND with a constant, convert it into an AND ! whose constant is the AND of that constant with MASK. If it ! remains an AND of MASK, delete it since it is redundant. */ ! if (GET_CODE (XEXP (x, 1)) == CONST_INT ! && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT) { ! x = simplify_and_const_int (x, op_mode, XEXP (x, 0), ! mask & INTVAL (XEXP (x, 1))); /* If X is still an AND, see if it is an AND with a mask that is just some low-order bits. If so, and it is BITS wide (it *************** *** 5394,5399 **** if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT ! && bits < HOST_BITS_PER_WIDE_INT ! && INTVAL (XEXP (x, 1)) == ((HOST_WIDE_INT) 1 << bits) - 1) x = XEXP (x, 0); --- 5712,5716 ---- if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT ! && INTVAL (XEXP (x, 1)) == mask) x = XEXP (x, 0); *************** *** 5401,5437 **** } ! /* ... fall through ... */ case PLUS: case MINUS: case MULT: case IOR: case XOR: /* For most binary operations, just propagate into the operation and ! change the mode if we have an operation of that mode. */ ! if ((code == PLUS ! && add_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) ! || (code == MINUS ! && sub_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) ! || (code == MULT && (smul_optab->handlers[(int) mode].insn_code ! == CODE_FOR_nothing)) ! || (code == AND ! && and_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) ! || (code == IOR ! && ior_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) ! || (code == XOR && (xor_optab->handlers[(int) mode].insn_code ! == CODE_FOR_nothing))) ! op_mode = GET_MODE (x); ! ! x = gen_binary (code, op_mode, ! gen_lowpart_for_combine (op_mode, ! force_to_mode (XEXP (x, 0), ! mode, bits, ! reg)), ! gen_lowpart_for_combine (op_mode, ! force_to_mode (XEXP (x, 1), ! mode, bits, ! reg))); break; --- 5718,5783 ---- } ! goto binop; case PLUS: + /* In (and (plus FOO C1) M), if M is a mask that just turns off + low-order bits (as in an alignment operation) and FOO is already + aligned to that boundary, mask C1 to that boundary as well. + This may eliminate that PLUS and, later, the AND. */ + if (GET_CODE (XEXP (x, 1)) == CONST_INT + && exact_log2 (- mask) >= 0 + && (nonzero_bits (XEXP (x, 0), mode) & ~ mask) == 0 + && (INTVAL (XEXP (x, 1)) & ~ mask) != 0) + return force_to_mode (plus_constant (XEXP (x, 0), + INTVAL (XEXP (x, 1)) & mask), + mode, mask, reg); + + /* ... fall through ... */ + case MINUS: case MULT: + /* For PLUS, MINUS and MULT, we need any bits less significant than the + most significant bit in MASK since carries from those bits will + affect the bits we are interested in. */ + mask = fuller_mask; + goto binop; + case IOR: case XOR: + /* If X is (ior (lshiftrt FOO C1) C2), try to commute the IOR and + LSHIFTRT so we end up with an (and (lshiftrt (ior ...) ...) ...) + operation which may be a bitfield extraction. Ensure that the + constant we form is not wider than the mode of X. */ + + if (GET_CODE (XEXP (x, 0)) == LSHIFTRT + && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT + && INTVAL (XEXP (XEXP (x, 0), 1)) >= 0 + && INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT + && GET_CODE (XEXP (x, 1)) == CONST_INT + && ((INTVAL (XEXP (XEXP (x, 0), 1)) + + floor_log2 (INTVAL (XEXP (x, 1)))) + < GET_MODE_BITSIZE (GET_MODE (x))) + && (INTVAL (XEXP (x, 1)) + & ~ nonzero_bits (XEXP (x, 0), GET_MODE (x)) == 0)) + { + temp = GEN_INT ((INTVAL (XEXP (x, 1)) & mask) + << INTVAL (XEXP (XEXP (x, 0), 1))); + temp = gen_binary (GET_CODE (x), GET_MODE (x), + XEXP (XEXP (x, 0), 0), temp); + x = gen_binary (LSHIFTRT, GET_MODE (x), temp, XEXP (x, 1)); + return force_to_mode (x, mode, mask, reg); + } + + binop: /* For most binary operations, just propagate into the operation and ! change the mode if we have an operation of that mode. */ ! ! op0 = gen_lowpart_for_combine (op_mode, force_to_mode (XEXP (x, 0), ! mode, mask, reg)); ! op1 = gen_lowpart_for_combine (op_mode, force_to_mode (XEXP (x, 1), ! mode, mask, reg)); ! if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0) || op1 != XEXP (x, 1)) ! x = gen_binary (code, op_mode, op0, op1); break; *************** *** 5442,5451 **** guarantee that the counts are smaller than the size of the mode because such a count will have a different meaning in a ! wider mode. ! ! If we can narrow the shift and know the count, we need even fewer ! bits of the first operand. */ if (! (GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) < GET_MODE_BITSIZE (mode)) && ! (GET_MODE (XEXP (x, 1)) != VOIDmode --- 5788,5795 ---- guarantee that the counts are smaller than the size of the mode because such a count will have a different meaning in a ! wider mode. */ if (! (GET_CODE (XEXP (x, 1)) == CONST_INT + && INTVAL (XEXP (x, 1)) >= 0 && INTVAL (XEXP (x, 1)) < GET_MODE_BITSIZE (mode)) && ! (GET_MODE (XEXP (x, 1)) != VOIDmode *************** *** 5454,5520 **** break; ! if (GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) < bits) ! bits -= INTVAL (XEXP (x, 1)); ! if ((code == ASHIFT ! && ashl_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) ! || (code == LSHIFT && (lshl_optab->handlers[(int) mode].insn_code ! == CODE_FOR_nothing))) ! op_mode = GET_MODE (x); ! ! x = gen_binary (code, op_mode, ! gen_lowpart_for_combine (op_mode, ! force_to_mode (XEXP (x, 0), ! mode, bits, ! reg)), ! XEXP (x, 1)); break; case LSHIFTRT: ! /* Here we can only do something if the shift count is a constant and ! the count plus BITS is no larger than the width of MODE. In that ! case, we can do the shift in MODE. */ if (GET_CODE (XEXP (x, 1)) == CONST_INT ! && INTVAL (XEXP (x, 1)) + bits <= GET_MODE_BITSIZE (mode)) { ! rtx inner = force_to_mode (XEXP (x, 0), mode, ! bits + INTVAL (XEXP (x, 1)), reg); ! if (lshr_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) op_mode = GET_MODE (x); ! x = gen_binary (LSHIFTRT, op_mode, ! gen_lowpart_for_combine (op_mode, inner), ! XEXP (x, 1)); } break; case ASHIFTRT: /* If this is a sign-extension operation that just affects bits ! we don't care about, remove it. */ ! if (GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) >= 0 ! && INTVAL (XEXP (x, 1)) <= GET_MODE_BITSIZE (GET_MODE (x)) - bits && GET_CODE (XEXP (x, 0)) == ASHIFT && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT && INTVAL (XEXP (XEXP (x, 0), 1)) == INTVAL (XEXP (x, 1))) ! return force_to_mode (XEXP (XEXP (x, 0), 0), mode, bits, reg); break; case NEG: case NOT: ! if ((code == NEG ! && neg_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) ! || (code == NOT && (one_cmpl_optab->handlers[(int) mode].insn_code ! == CODE_FOR_nothing))) ! op_mode = GET_MODE (x); ! ! /* Handle these similarly to the way we handle most binary operations. */ ! x = gen_unary (code, op_mode, ! gen_lowpart_for_combine (op_mode, ! force_to_mode (XEXP (x, 0), mode, ! bits, reg))); break; --- 5798,5980 ---- break; ! /* If the shift count is a constant and we can do arithmetic in ! the mode of the shift, refine which bits we need. Otherwise, use the ! conservative form of the mask. */ ! if (GET_CODE (XEXP (x, 1)) == CONST_INT ! && INTVAL (XEXP (x, 1)) >= 0 ! && INTVAL (XEXP (x, 1)) < GET_MODE_BITSIZE (op_mode) ! && GET_MODE_BITSIZE (op_mode) <= HOST_BITS_PER_WIDE_INT) ! mask >>= INTVAL (XEXP (x, 1)); ! else ! mask = fuller_mask; ! op0 = gen_lowpart_for_combine (op_mode, ! force_to_mode (XEXP (x, 0), op_mode, ! mask, reg)); ! ! if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0)) ! x = gen_binary (code, op_mode, op0, XEXP (x, 1)); break; case LSHIFTRT: ! /* Here we can only do something if the shift count is a constant, ! this shift constant is valid for the host, and we can do arithmetic ! in OP_MODE. */ if (GET_CODE (XEXP (x, 1)) == CONST_INT ! && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT ! && GET_MODE_BITSIZE (op_mode) <= HOST_BITS_PER_WIDE_INT) { ! rtx inner = XEXP (x, 0); ! ! /* Select the mask of the bits we need for the shift operand. */ ! mask <<= INTVAL (XEXP (x, 1)); ! /* We can only change the mode of the shift if we can do arithmetic ! in the mode of the shift and MASK is no wider than the width of ! OP_MODE. */ ! if (GET_MODE_BITSIZE (op_mode) > HOST_BITS_PER_WIDE_INT ! || (mask & ~ GET_MODE_MASK (op_mode)) != 0) op_mode = GET_MODE (x); ! inner = force_to_mode (inner, op_mode, mask, reg); ! ! if (GET_MODE (x) != op_mode || inner != XEXP (x, 0)) ! x = gen_binary (LSHIFTRT, op_mode, inner, XEXP (x, 1)); } + + /* If we have (and (lshiftrt FOO C1) C2) where the combination of the + shift and AND produces only copies of the sign bit (C2 is one less + than a power of two), we can do this with just a shift. */ + + if (GET_CODE (x) == LSHIFTRT + && GET_CODE (XEXP (x, 1)) == CONST_INT + && ((INTVAL (XEXP (x, 1)) + + num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0)))) + >= GET_MODE_BITSIZE (GET_MODE (x))) + && exact_log2 (mask + 1) >= 0 + && (num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0))) + >= exact_log2 (mask + 1))) + x = gen_binary (LSHIFTRT, GET_MODE (x), XEXP (x, 0), + GEN_INT (GET_MODE_BITSIZE (GET_MODE (x)) + - exact_log2 (mask + 1))); break; case ASHIFTRT: + /* If we are just looking for the sign bit, we don't need this shift at + all, even if it has a variable count. */ + if (mask == ((HOST_WIDE_INT) 1 + << (GET_MODE_BITSIZE (GET_MODE (x)) - 1))) + return force_to_mode (XEXP (x, 0), mode, mask, reg); + + /* If this is a shift by a constant, get a mask that contains those bits + that are not copies of the sign bit. We then have two cases: If + MASK only includes those bits, this can be a logical shift, which may + allow simplifications. If MASK is a single-bit field not within + those bits, we are requesting a copy of the sign bit and hence can + shift the sign bit to the appropriate location. */ + + if (GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) >= 0 + && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT) + { + int i = -1; + + nonzero = GET_MODE_MASK (GET_MODE (x)); + nonzero >>= INTVAL (XEXP (x, 1)); + + if ((mask & ~ nonzero) == 0 + || (i = exact_log2 (mask)) >= 0) + { + x = simplify_shift_const + (x, LSHIFTRT, GET_MODE (x), XEXP (x, 0), + i < 0 ? INTVAL (XEXP (x, 1)) + : GET_MODE_BITSIZE (GET_MODE (x)) - 1 - i); + + if (GET_CODE (x) != ASHIFTRT) + return force_to_mode (x, mode, mask, reg); + } + } + + /* If MASK is 1, convert this to a LSHIFTRT. This can be done + even if the shift count isn't a constant. */ + if (mask == 1) + x = gen_binary (LSHIFTRT, GET_MODE (x), XEXP (x, 0), XEXP (x, 1)); + /* If this is a sign-extension operation that just affects bits ! we don't care about, remove it. Be sure the call above returned ! something that is still a shift. */ ! if ((GET_CODE (x) == LSHIFTRT || GET_CODE (x) == ASHIFTRT) ! && GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) >= 0 ! && (INTVAL (XEXP (x, 1)) ! <= GET_MODE_BITSIZE (GET_MODE (x)) - (floor_log2 (mask) + 1)) && GET_CODE (XEXP (x, 0)) == ASHIFT && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT && INTVAL (XEXP (XEXP (x, 0), 1)) == INTVAL (XEXP (x, 1))) ! return force_to_mode (XEXP (XEXP (x, 0), 0), mode, mask, reg); ! break; + case ROTATE: + case ROTATERT: + /* If the shift count is constant and we can do computations + in the mode of X, compute where the bits we care about are. + Otherwise, we can't do anything. Don't change the mode of + the shift or propagate MODE into the shift, though. */ + if (GET_CODE (XEXP (x, 1)) == CONST_INT + && INTVAL (XEXP (x, 1)) >= 0) + { + temp = simplify_binary_operation (code == ROTATE ? ROTATERT : ROTATE, + GET_MODE (x), GEN_INT (mask), + XEXP (x, 1)); + if (temp) + SUBST (XEXP (x, 0), + force_to_mode (XEXP (x, 0), GET_MODE (x), + INTVAL (temp), reg)); + } + break; + case NEG: + /* We need any bits less significant than the most significant bit in + MASK since carries from those bits will affect the bits we are + interested in. */ + mask = fuller_mask; + goto unop; + case NOT: ! /* (not FOO) is (xor FOO CONST), so if FOO is an LSHIFTRT, we can do the ! same as the XOR case above. Ensure that the constant we form is not ! wider than the mode of X. */ ! ! if (GET_CODE (XEXP (x, 0)) == LSHIFTRT ! && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT ! && INTVAL (XEXP (XEXP (x, 0), 1)) >= 0 ! && (INTVAL (XEXP (XEXP (x, 0), 1)) + floor_log2 (mask) ! < GET_MODE_BITSIZE (GET_MODE (x))) ! && INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT) ! { ! temp = GEN_INT (mask << INTVAL (XEXP (XEXP (x, 0), 1))); ! temp = gen_binary (XOR, GET_MODE (x), XEXP (XEXP (x, 0), 0), temp); ! x = gen_binary (LSHIFTRT, GET_MODE (x), temp, XEXP (XEXP (x, 0), 1)); ! ! return force_to_mode (x, mode, mask, reg); ! } ! ! unop: ! op0 = gen_lowpart_for_combine (op_mode, force_to_mode (XEXP (x, 0), mode, ! mask, reg)); ! if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0)) ! x = gen_unary (code, op_mode, op0); ! break; ! ! case NE: ! /* (and (ne FOO 0) CONST) can be (and FOO CONST) if CONST is included ! in STORE_FLAG_VALUE and FOO has no bits that might be nonzero not ! in CONST. */ ! if ((mask & ~ STORE_FLAG_VALUE) == 0 && XEXP (x, 0) == const0_rtx ! && (nonzero_bits (XEXP (x, 0), mode) & ~ mask) == 0) ! return force_to_mode (XEXP (x, 0), mode, mask, reg); ! break; *************** *** 5526,5534 **** gen_lowpart_for_combine (GET_MODE (x), force_to_mode (XEXP (x, 1), mode, ! bits, reg))); SUBST (XEXP (x, 2), gen_lowpart_for_combine (GET_MODE (x), force_to_mode (XEXP (x, 2), mode, ! bits, reg))); break; } --- 5986,5994 ---- gen_lowpart_for_combine (GET_MODE (x), force_to_mode (XEXP (x, 1), mode, ! mask, reg))); SUBST (XEXP (x, 2), gen_lowpart_for_combine (GET_MODE (x), force_to_mode (XEXP (x, 2), mode, ! mask, reg))); break; } *************** *** 5716,5720 **** return x; ! pos = get_pos_from_mask (~c1, &len); if (pos < 0 || pos + len > GET_MODE_BITSIZE (GET_MODE (dest)) || (GET_MODE_BITSIZE (GET_MODE (other)) <= HOST_BITS_PER_WIDE_INT --- 6176,6180 ---- return x; ! pos = get_pos_from_mask (c1 ^ GET_MODE_MASK (GET_MODE (dest)), &len); if (pos < 0 || pos + len > GET_MODE_BITSIZE (GET_MODE (dest)) || (GET_MODE_BITSIZE (GET_MODE (other)) <= HOST_BITS_PER_WIDE_INT *************** *** 5734,5738 **** src = force_to_mode (simplify_shift_const (NULL_RTX, LSHIFTRT, GET_MODE (src), other, pos), ! mode, len, dest); return gen_rtx_combine (SET, VOIDmode, assign, src); --- 6194,6202 ---- src = force_to_mode (simplify_shift_const (NULL_RTX, LSHIFTRT, GET_MODE (src), other, pos), ! mode, ! GET_MODE_BITSIZE (mode) >= HOST_BITS_PER_WIDE_INT ! ? GET_MODE_MASK (mode) ! : ((HOST_WIDE_INT) 1 << len) - 1, ! dest); return gen_rtx_combine (SET, VOIDmode, assign, src); *************** *** 5754,5758 **** It can change the value. So don't do it. -- rms and moshier@world.std.com. */ ! if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) return x; --- 6218,6222 ---- It can change the value. So don't do it. -- rms and moshier@world.std.com. */ ! if (FLOAT_MODE_P (GET_MODE (x))) return x; *************** *** 5879,6150 **** register rtx temp; unsigned HOST_WIDE_INT nonzero; ! ! /* There is a large class of optimizations based on the principle that ! some operations produce results where certain bits are known to be zero, ! and hence are not significant to the AND. For example, if we have just ! done a left shift of one bit, the low-order bit is known to be zero and ! hence an AND with a mask of ~1 would not do anything. ! ! At the end of the following loop, we set: ! ! VAROP to be the item to be AND'ed with; ! CONSTOP to the constant value to AND it with. */ ! ! while (1) ! { ! /* If we ever encounter a mode wider than the host machine's widest ! integer size, we can't compute the masks accurately, so give up. */ ! if (GET_MODE_BITSIZE (GET_MODE (varop)) > HOST_BITS_PER_WIDE_INT) ! break; ! ! /* Unless one of the cases below does a `continue', ! a `break' will be executed to exit the loop. */ ! ! switch (GET_CODE (varop)) ! { ! case CLOBBER: ! /* If VAROP is a (clobber (const_int)), return it since we know ! we are generating something that won't match. */ ! return varop; ! ! #if ! BITS_BIG_ENDIAN ! case USE: ! /* VAROP is a (use (mem ..)) that was made from a bit-field ! extraction that spanned the boundary of the MEM. If we are ! now masking so it is within that boundary, we don't need the ! USE any more. */ ! if ((constop & ~ GET_MODE_MASK (GET_MODE (XEXP (varop, 0)))) == 0) ! { ! varop = XEXP (varop, 0); ! continue; ! } ! break; ! #endif ! ! case SUBREG: ! if (subreg_lowpart_p (varop) ! /* We can ignore the effect this SUBREG if it narrows the mode ! or, on machines where byte operations extend, if the ! constant masks to zero all the bits the mode doesn't have. */ ! && ((GET_MODE_SIZE (GET_MODE (varop)) ! < GET_MODE_SIZE (GET_MODE (SUBREG_REG (varop)))) ! #ifdef BYTE_LOADS_EXTEND ! || (0 == (constop ! & GET_MODE_MASK (GET_MODE (varop)) ! & ~ GET_MODE_MASK (GET_MODE (SUBREG_REG (varop))))) ! #endif ! )) ! { ! varop = SUBREG_REG (varop); ! continue; ! } ! break; ! ! case ZERO_EXTRACT: ! case SIGN_EXTRACT: ! case ZERO_EXTEND: ! case SIGN_EXTEND: ! /* Try to expand these into a series of shifts and then work ! with that result. If we can't, for example, if the extract ! isn't at a fixed position, give up. */ ! temp = expand_compound_operation (varop); ! if (temp != varop) ! { ! varop = temp; ! continue; ! } ! break; ! ! case AND: ! if (GET_CODE (XEXP (varop, 1)) == CONST_INT) ! { ! constop &= INTVAL (XEXP (varop, 1)); ! varop = XEXP (varop, 0); ! continue; ! } ! break; ! ! case IOR: ! case XOR: ! /* If VAROP is (ior (lshiftrt FOO C1) C2), try to commute the IOR and ! LSHIFT so we end up with an (and (lshiftrt (ior ...) ...) ...) ! operation which may be a bitfield extraction. Ensure ! that the constant we form is not wider than the mode of ! VAROP. */ ! ! if (GET_CODE (XEXP (varop, 0)) == LSHIFTRT ! && GET_CODE (XEXP (XEXP (varop, 0), 1)) == CONST_INT ! && INTVAL (XEXP (XEXP (varop, 0), 1)) >= 0 ! && INTVAL (XEXP (XEXP (varop, 0), 1)) < HOST_BITS_PER_WIDE_INT ! && GET_CODE (XEXP (varop, 1)) == CONST_INT ! && ((INTVAL (XEXP (XEXP (varop, 0), 1)) ! + floor_log2 (INTVAL (XEXP (varop, 1)))) ! < GET_MODE_BITSIZE (GET_MODE (varop))) ! && (INTVAL (XEXP (varop, 1)) ! & ~ nonzero_bits (XEXP (varop, 0), GET_MODE (varop)) == 0)) ! { ! temp = GEN_INT ((INTVAL (XEXP (varop, 1)) & constop) ! << INTVAL (XEXP (XEXP (varop, 0), 1))); ! temp = gen_binary (GET_CODE (varop), GET_MODE (varop), ! XEXP (XEXP (varop, 0), 0), temp); ! varop = gen_rtx_combine (LSHIFTRT, GET_MODE (varop), ! temp, XEXP (varop, 1)); ! continue; ! } ! ! /* Apply the AND to both branches of the IOR or XOR, then try to ! apply the distributive law. This may eliminate operations ! if either branch can be simplified because of the AND. ! It may also make some cases more complex, but those cases ! probably won't match a pattern either with or without this. */ ! return ! gen_lowpart_for_combine ! (mode, apply_distributive_law ! (gen_rtx_combine ! (GET_CODE (varop), GET_MODE (varop), ! simplify_and_const_int (NULL_RTX, GET_MODE (varop), ! XEXP (varop, 0), constop), ! simplify_and_const_int (NULL_RTX, GET_MODE (varop), ! XEXP (varop, 1), constop)))); ! ! case NOT: ! /* (and (not FOO)) is (and (xor FOO CONST)), so if FOO is an ! LSHIFTRT, we can do the same as above. Ensure that the constant ! we form is not wider than the mode of VAROP. */ ! ! if (GET_CODE (XEXP (varop, 0)) == LSHIFTRT ! && GET_CODE (XEXP (XEXP (varop, 0), 1)) == CONST_INT ! && INTVAL (XEXP (XEXP (varop, 0), 1)) >= 0 ! && (INTVAL (XEXP (XEXP (varop, 0), 1)) + floor_log2 (constop) ! < GET_MODE_BITSIZE (GET_MODE (varop))) ! && INTVAL (XEXP (XEXP (varop, 0), 1)) < HOST_BITS_PER_WIDE_INT) ! { ! temp = GEN_INT (constop << INTVAL (XEXP (XEXP (varop, 0), 1))); ! temp = gen_binary (XOR, GET_MODE (varop), ! XEXP (XEXP (varop, 0), 0), temp); ! varop = gen_rtx_combine (LSHIFTRT, GET_MODE (varop), ! temp, XEXP (XEXP (varop, 0), 1)); ! continue; ! } ! break; ! ! case ASHIFTRT: ! /* If we are just looking for the sign bit, we don't need this ! shift at all, even if it has a variable count. */ ! if (constop == ((HOST_WIDE_INT) 1 ! << (GET_MODE_BITSIZE (GET_MODE (varop)) - 1))) ! { ! varop = XEXP (varop, 0); ! continue; ! } ! ! /* If this is a shift by a constant, get a mask that contains ! those bits that are not copies of the sign bit. We then have ! two cases: If CONSTOP only includes those bits, this can be ! a logical shift, which may allow simplifications. If CONSTOP ! is a single-bit field not within those bits, we are requesting ! a copy of the sign bit and hence can shift the sign bit to ! the appropriate location. */ ! if (GET_CODE (XEXP (varop, 1)) == CONST_INT ! && INTVAL (XEXP (varop, 1)) >= 0 ! && INTVAL (XEXP (varop, 1)) < HOST_BITS_PER_WIDE_INT) ! { ! int i = -1; ! ! nonzero = GET_MODE_MASK (GET_MODE (varop)); ! nonzero >>= INTVAL (XEXP (varop, 1)); ! ! if ((constop & ~ nonzero) == 0 ! || (i = exact_log2 (constop)) >= 0) ! { ! varop = simplify_shift_const ! (varop, LSHIFTRT, GET_MODE (varop), XEXP (varop, 0), ! i < 0 ? INTVAL (XEXP (varop, 1)) ! : GET_MODE_BITSIZE (GET_MODE (varop)) - 1 - i); ! if (GET_CODE (varop) != ASHIFTRT) ! continue; ! } ! } ! ! /* If our mask is 1, convert this to a LSHIFTRT. This can be done ! even if the shift count isn't a constant. */ ! if (constop == 1) ! varop = gen_rtx_combine (LSHIFTRT, GET_MODE (varop), ! XEXP (varop, 0), XEXP (varop, 1)); ! break; ! ! case LSHIFTRT: ! /* If we have (and (lshiftrt FOO C1) C2) where the combination of the ! shift and AND produces only copies of the sign bit (C2 is one less ! than a power of two), we can do this with just a shift. */ ! ! if (GET_CODE (XEXP (varop, 1)) == CONST_INT ! && ((INTVAL (XEXP (varop, 1)) ! + num_sign_bit_copies (XEXP (varop, 0), ! GET_MODE (XEXP (varop, 0)))) ! >= GET_MODE_BITSIZE (GET_MODE (varop))) ! && exact_log2 (constop + 1) >= 0) ! varop ! = gen_rtx_combine (LSHIFTRT, GET_MODE (varop), XEXP (varop, 0), ! GEN_INT (GET_MODE_BITSIZE (GET_MODE (varop)) ! - exact_log2 (constop + 1))); ! break; ! ! case NE: ! /* (and (ne FOO 0) CONST) can be (and FOO CONST) if CONST is ! included in STORE_FLAG_VALUE and FOO has no bits that might be ! nonzero not in CONST. */ ! if ((constop & ~ STORE_FLAG_VALUE) == 0 ! && XEXP (varop, 0) == const0_rtx ! && (nonzero_bits (XEXP (varop, 0), mode) & ~ constop) == 0) ! { ! varop = XEXP (varop, 0); ! continue; ! } ! break; ! ! case PLUS: ! /* In (and (plus FOO C1) M), if M is a mask that just turns off ! low-order bits (as in an alignment operation) and FOO is already ! aligned to that boundary, we can convert remove this AND ! and possibly the PLUS if it is now adding zero. */ ! if (GET_CODE (XEXP (varop, 1)) == CONST_INT ! && exact_log2 (-constop) >= 0 ! && (nonzero_bits (XEXP (varop, 0), mode) & ~ constop) == 0) ! { ! varop = plus_constant (XEXP (varop, 0), ! INTVAL (XEXP (varop, 1)) & constop); ! constop = ~0; ! break; ! } ! ! /* ... fall through ... */ ! ! case MINUS: ! /* In (and (plus (and FOO M1) BAR) M2), if M1 and M2 are one ! less than powers of two and M2 is narrower than M1, we can ! eliminate the inner AND. This occurs when incrementing ! bit fields. */ ! ! if (GET_CODE (XEXP (varop, 0)) == ZERO_EXTRACT ! || GET_CODE (XEXP (varop, 0)) == ZERO_EXTEND) ! SUBST (XEXP (varop, 0), ! expand_compound_operation (XEXP (varop, 0))); ! ! if (GET_CODE (XEXP (varop, 0)) == AND ! && GET_CODE (XEXP (XEXP (varop, 0), 1)) == CONST_INT ! && exact_log2 (constop + 1) >= 0 ! && exact_log2 (INTVAL (XEXP (XEXP (varop, 0), 1)) + 1) >= 0 ! && (~ INTVAL (XEXP (XEXP (varop, 0), 1)) & constop) == 0) ! SUBST (XEXP (varop, 0), XEXP (XEXP (varop, 0), 0)); ! break; ! } ! ! break; ! } ! /* If we have reached a constant, this whole thing is constant. */ ! if (GET_CODE (varop) == CONST_INT) ! return GEN_INT (constop & INTVAL (varop)); /* See what bits may be nonzero in VAROP. Unlike the general case of --- 6343,6356 ---- register rtx temp; unsigned HOST_WIDE_INT nonzero; ! int i; ! /* Simplify VAROP knowing that we will be only looking at some of the ! bits in it. */ ! varop = force_to_mode (varop, mode, constop, NULL_RTX); ! ! /* If VAROP is a CLOBBER, we will fail so return it; if it is a ! CONST_INT, we are done. */ ! if (GET_CODE (varop) == CLOBBER || GET_CODE (varop) == CONST_INT) ! return varop; /* See what bits may be nonzero in VAROP. Unlike the general case of *************** *** 6164,6167 **** --- 6370,6396 ---- return const0_rtx; + /* If VAROP is a NEG of something known to be zero or 1 and CONSTOP is + a power of two, we can replace this with a ASHIFT. */ + if (GET_CODE (varop) == NEG && nonzero_bits (XEXP (varop, 0), mode) == 1 + && (i = exact_log2 (constop)) >= 0) + return simplify_shift_const (NULL_RTX, ASHIFT, mode, XEXP (varop, 0), i); + + /* If VAROP is an IOR or XOR, apply the AND to both branches of the IOR + or XOR, then try to apply the distributive law. This may eliminate + operations if either branch can be simplified because of the AND. + It may also make some cases more complex, but those cases probably + won't match a pattern either with or without this. */ + + if (GET_CODE (varop) == IOR || GET_CODE (varop) == XOR) + return + gen_lowpart_for_combine + (mode, + apply_distributive_law + (gen_binary (GET_CODE (varop), GET_MODE (varop), + simplify_and_const_int (NULL_RTX, GET_MODE (varop), + XEXP (varop, 0), constop), + simplify_and_const_int (NULL_RTX, GET_MODE (varop), + XEXP (varop, 1), constop)))); + /* Get VAROP in MODE. Try to get a SUBREG if not. Don't make a new SUBREG if we already had one (just check for the simplest cases). */ *************** *** 6183,6187 **** /* Otherwise, return an AND. See how much, if any, of X we can use. */ else if (x == 0 || GET_CODE (x) != AND || GET_MODE (x) != mode) ! x = gen_rtx_combine (AND, mode, varop, GEN_INT (constop)); else --- 6412,6416 ---- /* Otherwise, return an AND. See how much, if any, of X we can use. */ else if (x == 0 || GET_CODE (x) != AND || GET_MODE (x) != mode) ! x = gen_binary (AND, mode, varop, GEN_INT (constop)); else *************** *** 6227,6230 **** --- 6456,6478 ---- return nonzero; + #ifndef WORD_REGISTER_OPERATIONS + /* If MODE is wider than X, but both are a single word for both the host + and target machines, we can compute this from which bits of the + object might be nonzero in its own mode, taking into account the fact + that on many CISC machines, accessing an object in a wider mode + causes the high-order bits to become undefined. So they are + not known to be zero. */ + + if (GET_MODE (x) != VOIDmode && GET_MODE (x) != mode + && GET_MODE_BITSIZE (GET_MODE (x)) <= BITS_PER_WORD + && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT + && GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (GET_MODE (x))) + { + nonzero &= nonzero_bits (x, GET_MODE (x)); + nonzero |= GET_MODE_MASK (mode) & ~ GET_MODE_MASK (GET_MODE (x)); + return nonzero; + } + #endif + code = GET_CODE (x); switch (code) *************** *** 6304,6317 **** return INTVAL (x); - #ifdef BYTE_LOADS_ZERO_EXTEND case MEM: /* In many, if not most, RISC machines, reading a byte from memory zeros the rest of the register. Noticing that fact saves a lot of extra zero-extends. */ ! nonzero &= GET_MODE_MASK (GET_MODE (x)); ! break; #endif - #if STORE_FLAG_VALUE == 1 case EQ: case NE: case GT: case GTU: --- 6552,6565 ---- return INTVAL (x); case MEM: + #ifdef LOAD_EXTEND_OP /* In many, if not most, RISC machines, reading a byte from memory zeros the rest of the register. Noticing that fact saves a lot of extra zero-extends. */ ! if (LOAD_EXTEND_OP (GET_MODE (x)) == ZERO_EXTEND) ! nonzero &= GET_MODE_MASK (GET_MODE (x)); #endif + break; case EQ: case NE: case GT: case GTU: *************** *** 6320,6332 **** case LE: case LEU: ! if (GET_MODE_CLASS (mode) == MODE_INT) ! nonzero = 1; ! /* A comparison operation only sets the bits given by its mode. The ! rest are set undefined. */ ! if (GET_MODE_SIZE (GET_MODE (x)) < mode_width) ! nonzero |= (GET_MODE_MASK (mode) & ~ GET_MODE_MASK (GET_MODE (x))); break; - #endif case NEG: --- 6568,6579 ---- case LE: case LEU: ! /* If this produces an integer result, we know which bits are set. ! Code here used to clear bits outside the mode of X, but that is ! now done above. */ ! if (GET_MODE_CLASS (mode) == MODE_INT ! && mode_width <= HOST_BITS_PER_WIDE_INT) ! nonzero = STORE_FLAG_VALUE; break; case NEG: *************** *** 6466,6470 **** { nonzero &= nonzero_bits (SUBREG_REG (x), mode); ! #ifndef BYTE_LOADS_EXTEND /* On many CISC machines, accessing an object in a wider mode causes the high-order bits to become undefined. So they are --- 6713,6718 ---- { nonzero &= nonzero_bits (SUBREG_REG (x), mode); ! ! #ifndef WORD_REGISTER_OPERATIONS /* On many CISC machines, accessing an object in a wider mode causes the high-order bits to become undefined. So they are *************** *** 6541,6547 **** /* Return the number of bits at the high-order end of X that are known to ! be equal to the sign bit. This number will always be between 1 and ! the number of bits in the mode of X. MODE is the mode to be used ! if X is VOIDmode. */ static int --- 6789,6795 ---- /* Return the number of bits at the high-order end of X that are known to ! be equal to the sign bit. X will be used in mode MODE; if MODE is ! VOIDmode, X will be used in its own mode. The returned value will always ! be between 1 and the number of bits in MODE. */ static int *************** *** 6567,6570 **** --- 6815,6823 ---- bitwidth = GET_MODE_BITSIZE (mode); + /* For a smaller object, just ignore the high bits. */ + if (bitwidth < GET_MODE_BITSIZE (GET_MODE (x))) + return MAX (1, (num_sign_bit_copies (x, GET_MODE (x)) + - (GET_MODE_BITSIZE (GET_MODE (x)) - bitwidth))); + switch (code) { *************** *** 6586,6594 **** break; - #ifdef BYTE_LOADS_SIGN_EXTEND case MEM: /* Some RISC machines sign-extend all loads of smaller than a word. */ ! return MAX (1, bitwidth - GET_MODE_BITSIZE (GET_MODE (x)) + 1); #endif case CONST_INT: --- 6839,6849 ---- break; case MEM: + #ifdef LOAD_EXTEND_OP /* Some RISC machines sign-extend all loads of smaller than a word. */ ! if (LOAD_EXTEND_OP (GET_MODE (x)) == SIGN_EXTEND) ! return MAX (1, bitwidth - GET_MODE_BITSIZE (GET_MODE (x)) + 1); #endif + break; case CONST_INT: *************** *** 6620,6629 **** } ! #ifdef BYTE_LOADS_EXTEND ! /* For paradoxical SUBREGs, just look inside since, on machines with ! one of these defined, we assume that operations are actually ! performed on the full register. Note that we are passing MODE ! to the recursive call, so the number of sign bit copies will ! remain relative to that mode, not the inner mode. */ if (GET_MODE_SIZE (GET_MODE (x)) --- 6875,6883 ---- } ! #ifdef WORD_REGISTER_OPERATIONS ! /* For paradoxical SUBREGs on machines where all register operations ! affect the entire register, just look inside. Note that we are ! passing MODE to the recursive call, so the number of sign bit copies ! will remain relative to that mode, not the inner mode. */ if (GET_MODE_SIZE (GET_MODE (x)) *************** *** 6631,6635 **** return num_sign_bit_copies (SUBREG_REG (x), mode); #endif - break; --- 6885,6888 ---- *************** *** 7423,7432 **** the inverse distributive law. */ { ! rtx lhs = simplify_shift_const (NULL_RTX, code, result_mode, XEXP (varop, 0), count); ! rtx rhs = simplify_shift_const (NULL_RTX, code, result_mode, XEXP (varop, 1), count); ! varop = gen_binary (GET_CODE (varop), result_mode, lhs, rhs); varop = apply_distributive_law (varop); --- 7676,7685 ---- the inverse distributive law. */ { ! rtx lhs = simplify_shift_const (NULL_RTX, code, shift_mode, XEXP (varop, 0), count); ! rtx rhs = simplify_shift_const (NULL_RTX, code, shift_mode, XEXP (varop, 1), count); ! varop = gen_binary (GET_CODE (varop), GET_MODE (varop), lhs, rhs); varop = apply_distributive_law (varop); *************** *** 7616,7619 **** --- 7869,7882 ---- } + /* If we have an outer operation and we just made a shift, it is + possible that we could have simplified the shift were it not + for the outer operation. So try to do the simplification + recursively. */ + + if (outer_op != NIL && GET_CODE (x) == code + && GET_CODE (XEXP (x, 1)) == CONST_INT) + x = simplify_shift_const (x, code, shift_mode, XEXP (x, 0), + INTVAL (XEXP (x, 1))); + /* If we were doing a LSHIFTRT in a wider mode than it was originally, turn off all the bits that the shift would have turned off. */ *************** *** 7675,7678 **** --- 7938,7950 ---- rtx notes = 0; + /* If PAT is a PARALLEL, check to see if it contains the CLOBBER + we use to indicate that something didn't match. If we find such a + thing, force rejection. */ + if (GET_CODE (pat) == PARALLEL) + for (i = XVECLEN (pat, 0) - 1; i >= 0; i--) + if (GET_CODE (XVECEXP (pat, 0, i)) == CLOBBER + && XEXP (XVECEXP (pat, 0, i), 0) == const0_rtx) + return -1; + /* Is the result of combination a valid instruction? */ insn_code_number = recog (pat, insn, &num_clobbers_to_add); *************** *** 7881,7893 **** for (i = previous_num_undos; i < undobuf.num_undo; i++) if (!undobuf.undo[i].is_int ! && GET_CODE (undobuf.undo[i].old_contents.rtx) == code ! && GET_MODE (undobuf.undo[i].old_contents.rtx) == mode) { for (j = 0; j < n_args; j++) ! if (XEXP (undobuf.undo[i].old_contents.rtx, j) != args[j]) break; if (j == n_args) ! return undobuf.undo[i].old_contents.rtx; } --- 8153,8165 ---- for (i = previous_num_undos; i < undobuf.num_undo; i++) if (!undobuf.undo[i].is_int ! && GET_CODE (undobuf.undo[i].old_contents.r) == code ! && GET_MODE (undobuf.undo[i].old_contents.r) == mode) { for (j = 0; j < n_args; j++) ! if (XEXP (undobuf.undo[i].old_contents.r, j) != args[j]) break; if (j == n_args) ! return undobuf.undo[i].old_contents.r; } *************** *** 8267,8270 **** --- 8539,8551 ---- || code == LEU); + /* If this is a sign bit comparison and we can do arithmetic in + MODE, say that we will only be needing the sign bit of OP0. */ + if (sign_bit_comparison_p + && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT) + op0 = force_to_mode (op0, mode, + ((HOST_WIDE_INT) 1 + << (GET_MODE_BITSIZE (mode) - 1)), + NULL_RTX); + /* Now try cases based on the opcode of OP0. If none of the cases does a "continue", we exit this loop immediately after the *************** *** 8684,8688 **** < HOST_BITS_PER_WIDE_INT) && ((const_op ! & ((HOST_WIDE_INT) 1 << INTVAL (XEXP (op0, 1))) - 1) == 0) && mode_width <= HOST_BITS_PER_WIDE_INT && (nonzero_bits (XEXP (op0, 0), mode) --- 8965,8969 ---- < HOST_BITS_PER_WIDE_INT) && ((const_op ! & (((HOST_WIDE_INT) 1 << INTVAL (XEXP (op0, 1))) - 1)) == 0) && mode_width <= HOST_BITS_PER_WIDE_INT && (nonzero_bits (XEXP (op0, 0), mode) *************** *** 8894,8897 **** --- 9175,9180 ---- { case MODE_INT: + case MODE_PARTIAL_INT: + case MODE_COMPLEX_INT: return 1; *************** *** 8899,8903 **** x = get_last_value (XEXP (x, 0)); return (x && GET_CODE (x) == COMPARE ! && GET_MODE_CLASS (GET_MODE (XEXP (x, 0))) == MODE_INT); } --- 9182,9186 ---- x = get_last_value (XEXP (x, 0)); return (x && GET_CODE (x) == COMPARE ! && ! FLOAT_MODE_P (GET_MODE (XEXP (x, 0)))); } *************** *** 8968,8973 **** /* For each register modified, show we don't know its value, that ! its value has been updated, and that we don't know the location of ! the death of the register. */ for (i = regno; i < endregno; i ++) { --- 9251,9257 ---- /* For each register modified, show we don't know its value, that ! we don't know about its bitwise content, that its value has been ! updated, and that we don't know the location of the death of the ! register. */ for (i = regno; i < endregno; i ++) { *************** *** 8975,8978 **** --- 9259,9265 ---- reg_last_set[i] = insn; reg_last_set_value[i] = 0; + reg_last_set_mode[i] = 0; + reg_last_set_nonzero_bits[i] = 0; + reg_last_set_sign_bit_copies[i] = 0; reg_last_death[i] = 0; } *************** *** 9061,9067 **** INSN in the combiner loop. ! We update reg_last_set, reg_last_set_value, reg_last_death, and also the ! similar information mem_last_set (which insn most recently modified memory) ! and last_call_cuid (which insn was the most recent subroutine call). */ static void --- 9348,9356 ---- INSN in the combiner loop. ! We update reg_last_set, reg_last_set_value, reg_last_set_mode, ! reg_last_set_nonzero_bits, reg_last_set_sign_bit_copies, reg_last_death, ! and also the similar information mem_last_set (which insn most recently ! modified memory) and last_call_cuid (which insn was the most recent ! subroutine call). */ static void *************** *** 9096,9099 **** --- 9385,9391 ---- { reg_last_set_value[i] = 0; + reg_last_set_mode[i] = 0; + reg_last_set_nonzero_bits[i] = 0; + reg_last_set_sign_bit_copies[i] = 0; reg_last_death[i] = 0; } *************** *** 9258,9261 **** --- 9550,9556 ---- { register int regno = REGNO (x); + int endreg = regno + (regno < FIRST_PSEUDO_REGISTER + ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1); + #ifdef PUSH_ROUNDING /* Don't allow uses of the stack pointer to be moved, *************** *** 9264,9269 **** return 1; #endif ! return (reg_last_set[regno] ! && INSN_CUID (reg_last_set[regno]) > from_cuid); } --- 9559,9567 ---- return 1; #endif ! for (;regno < endreg; regno++) ! if (reg_last_set[regno] ! && INSN_CUID (reg_last_set[regno]) > from_cuid) ! return 1; ! return 0; } *************** *** 9604,9610 **** { case REG_UNUSED: /* If this register is set or clobbered in I3, put the note there unless there is one already. */ ! if (reg_set_p (XEXP (note, 0), PATTERN (i3))) { if (! (GET_CODE (XEXP (note, 0)) == REG --- 9902,9925 ---- { case REG_UNUSED: + /* If this note is from any insn other than i3, then we have no + use for it, and must ignore it. + + Any clobbers for i3 may still exist, and so we must process + REG_UNUSED notes from that insn. + + Any clobbers from i2 or i1 can only exist if they were added by + recog_for_combine. In that case, recog_for_combine created the + necessary REG_UNUSED notes. Trying to keep any original + REG_UNUSED notes from these insns can cause incorrect output + if it is for the same register as the original i3 dest. + In that case, we will notice that the register is set in i3, + and then add a REG_UNUSED note for the destination of i3, which + is wrong. */ + if (from_insn != i3) + break; + /* If this register is set or clobbered in I3, put the note there unless there is one already. */ ! else if (reg_set_p (XEXP (note, 0), PATTERN (i3))) { if (! (GET_CODE (XEXP (note, 0)) == REG *************** *** 9974,9979 **** for (insn = NEXT_INSN (XEXP (link, 0)); ! (insn && GET_CODE (insn) != CODE_LABEL ! && GET_CODE (PREV_INSN (insn)) != JUMP_INSN); insn = NEXT_INSN (insn)) if (GET_RTX_CLASS (GET_CODE (insn)) == 'i' --- 10289,10294 ---- for (insn = NEXT_INSN (XEXP (link, 0)); ! (insn && (this_basic_block == n_basic_blocks - 1 ! || basic_block_head[this_basic_block + 1] != insn)); insn = NEXT_INSN (insn)) if (GET_RTX_CLASS (GET_CODE (insn)) == 'i' diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/a29k/a29k.c gcc-2.5.0/config/a29k/a29k.c *** gcc-2.4.5/config/a29k/a29k.c Sat Dec 19 20:18:14 1992 --- gcc-2.5.0/config/a29k/a29k.c Mon Oct 4 17:43:26 1993 *************** *** 1,4 **** /* Subroutines used for code generation on AMD Am29000. ! Copyright (C) 1987, 1988, 1990, 1991, 1992 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@nyu.edu) --- 1,4 ---- /* Subroutines used for code generation on AMD Am29000. ! Copyright (C) 1987, 88, 90, 91, 92, 1993 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@nyu.edu) *************** *** 260,264 **** return 0; ! return regno >= FIRST_PSEUDO_REGISTER || regno < R_BP; } --- 260,265 ---- return 0; ! return (regno >= FIRST_PSEUDO_REGISTER || regno < R_BP ! || (regno >= R_KR (0) && regno <= R_KR (31))); } *************** *** 333,337 **** case SYMBOL_REF: return (TARGET_SMALL_MEMORY ! || ! strcmp (XSTR (op, 0), current_function_name)); case CONST_INT: --- 334,340 ---- case SYMBOL_REF: return (TARGET_SMALL_MEMORY ! || (! TARGET_LARGE_MEMORY ! && ((GET_CODE (op) == SYMBOL_REF && SYMBOL_REF_FLAG (op)) ! || ! strcmp (XSTR (op, 0), current_function_name)))); case CONST_INT: *************** *** 770,776 **** int i; if (! TARGET_NO_REUSE_ARGS) /* Mark all the used registers as not fixed and saved over calls. */ ! for (i = R_AR (start); i < R_AR (16) && i < R_AR (start + count); i++) { fixed_regs[i] = call_used_regs[i] = call_fixed_regs[i] = 0; --- 773,784 ---- int i; + /* We only use 16 argument registers, so truncate at the end of the + area. */ + if (start + count > 16) + count = 16 - start; + if (! TARGET_NO_REUSE_ARGS) /* Mark all the used registers as not fixed and saved over calls. */ ! for (i = R_AR (start); i < R_AR (start + count); i++) { fixed_regs[i] = call_used_regs[i] = call_fixed_regs[i] = 0; diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/a29k/a29k.h gcc-2.5.0/config/a29k/a29k.h *** gcc-2.4.5/config/a29k/a29k.h Fri Apr 16 20:24:32 1993 --- gcc-2.5.0/config/a29k/a29k.h Mon Oct 11 07:35:45 1993 *************** *** 1,4 **** /* Definitions of target machine for GNU compiler, for AMD Am29000 CPU. ! Copyright (C) 1988, 1990, 1991, 1992 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@nyu.edu) --- 1,4 ---- /* Definitions of target machine for GNU compiler, for AMD Am29000 CPU. ! Copyright (C) 1988, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@nyu.edu) *************** *** 22,26 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-D_AM29K -D_AM29000 -D_EPI" /* Print subsidiary information on the compiler version in use. */ --- 22,26 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-D_AM29K -D_AM29000 -D_EPI -Acpu(a29k) -Amachine(a29k)" /* Print subsidiary information on the compiler version in use. */ *************** *** 55,61 **** #define TARGET_SMALL_MEMORY (target_flags & 4) /* This means that we are compiling for a 29050. */ ! #define TARGET_29050 (target_flags & 8) /* This means that we are compiling for the kernel which means that we use --- 55,66 ---- #define TARGET_SMALL_MEMORY (target_flags & 4) + /* This means that we must always used on indirect call, even when + calling a function in the same file, since the file might be > 256KB. */ + + #define TARGET_LARGE_MEMORY (target_flags & 8) + /* This means that we are compiling for a 29050. */ ! #define TARGET_29050 (target_flags & 16) /* This means that we are compiling for the kernel which means that we use *************** *** 62,66 **** gr64-gr95 instead of gr96-126. */ ! #define TARGET_KERNEL_REGISTERS (target_flags & 16) /* This means that a call to "__msp_check" should be inserted after each stack --- 67,71 ---- gr64-gr95 instead of gr96-126. */ ! #define TARGET_KERNEL_REGISTERS (target_flags & 32) /* This means that a call to "__msp_check" should be inserted after each stack *************** *** 67,71 **** adjustment to check for stack overflow. */ ! #define TARGET_STACK_CHECK (target_flags & 32) /* This handles 29k processors which cannot handle the separation --- 72,76 ---- adjustment to check for stack overflow. */ ! #define TARGET_STACK_CHECK (target_flags & 64) /* This handles 29k processors which cannot handle the separation *************** *** 73,77 **** not the 29050. */ ! #define TARGET_NO_STOREM_BUG (target_flags & 64) /* This forces the compiler not to use incoming argument registers except --- 78,82 ---- not the 29050. */ ! #define TARGET_NO_STOREM_BUG (target_flags & 128) /* This forces the compiler not to use incoming argument registers except *************** *** 79,83 **** called with fewer arguments than it is declared with. */ ! #define TARGET_NO_REUSE_ARGS (target_flags & 128) #define TARGET_SWITCHES \ --- 84,88 ---- called with fewer arguments than it is declared with. */ ! #define TARGET_NO_REUSE_ARGS (target_flags & 256) #define TARGET_SWITCHES \ *************** *** 87,101 **** {"nbw", - (1|2)}, \ {"small", 4}, \ ! {"large", -4}, \ ! {"29050", 8+64}, \ ! {"29000", -8}, \ ! {"kernel-registers", 16}, \ ! {"user-registers", -16}, \ ! {"stack-check", 32}, \ ! {"no-stack-check", - 32}, \ ! {"storem-bug", -64}, \ ! {"no-storem-bug", 64}, \ ! {"reuse-arg-regs", -128}, \ ! {"no-reuse-arg-regs", 128}, \ {"", TARGET_DEFAULT}} --- 92,107 ---- {"nbw", - (1|2)}, \ {"small", 4}, \ ! {"normal", - (4|8)}, \ ! {"large", 8}, \ ! {"29050", 16+128}, \ ! {"29000", -16}, \ ! {"kernel-registers", 32}, \ ! {"user-registers", -32}, \ ! {"stack-check", 64}, \ ! {"no-stack-check", - 74}, \ ! {"storem-bug", -128}, \ ! {"no-storem-bug", 128}, \ ! {"reuse-arg-regs", -256}, \ ! {"no-reuse-arg-regs", 256}, \ {"", TARGET_DEFAULT}} *************** *** 238,245 **** the 29050. When -mkernel-registers is specified, we still use the same register map but change the names so 0-31 print as gr64-gr95. */ ! #define FIRST_PSEUDO_REGISTER 204 /* Because of the large number of registers on the 29k, we define macros --- 244,255 ---- the 29050. + Registers 204-235 are the 32 global registers for kernel mode when + -mkernel-registers is not specified, and the 32 global user registers + when it is. + When -mkernel-registers is specified, we still use the same register map but change the names so 0-31 print as gr64-gr95. */ ! #define FIRST_PSEUDO_REGISTER 236 /* Because of the large number of registers on the 29k, we define macros *************** *** 251,254 **** --- 261,265 ---- #define R_FP 176 /* frame pointer is register 176 */ #define R_AR(N) ((N) + 160) /* first incoming arg reg is 160 */ + #define R_KR(N) ((N) + 204) /* kernel registers (gr64 to gr95) */ /* Define the numbers of the special registers. */ *************** *** 310,314 **** 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1, \ ! 0, 0, 0, 0 } /* 1 for registers not available across function calls. --- 321,327 ---- 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1, \ ! 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, 1, 1, 1, 1, 1, 1, 1, 1 } /* 1 for registers not available across function calls. *************** *** 332,336 **** 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1, \ ! 1, 1, 1, 1 } /* List the order in which to allocate registers. Each register must be --- 345,351 ---- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1, \ ! 1, 1, 1, 1, \ ! 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ ! 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } /* List the order in which to allocate registers. Each register must be *************** *** 383,387 **** R_VAB, R_OPS, R_CPS, R_CFG, R_CHA, R_CHD, R_CHC, R_RBP, R_TMC, \ R_TMR, R_PC0, R_PC1, R_PC2, R_MMU, R_LRU, R_FPE, R_INT, R_FPS, \ ! R_EXO } /* Return number of consecutive hard regs needed starting at reg REGNO --- 398,408 ---- R_VAB, R_OPS, R_CPS, R_CFG, R_CHA, R_CHD, R_CHC, R_RBP, R_TMC, \ R_TMR, R_PC0, R_PC1, R_PC2, R_MMU, R_LRU, R_FPE, R_INT, R_FPS, \ ! R_EXO, \ ! R_KR (0), R_KR (1), R_KR (2), R_KR (3), R_KR (4), R_KR (5), \ ! R_KR (6), R_KR (7), R_KR (8), R_KR (9), R_KR (10), R_KR (11), \ ! R_KR (12), R_KR (13), R_KR (14), R_KR (15), R_KR (16), R_KR (17), \ ! R_KR (18), R_KR (19), R_KR (20), R_KR (21), R_KR (22), R_KR (23), \ ! R_KR (24), R_KR (25), R_KR (26), R_KR (27), R_KR (28), R_KR (29), \ ! R_KR (30), R_KR (31) } /* Return number of consecutive hard regs needed starting at reg REGNO *************** *** 391,395 **** #define HARD_REGNO_NREGS(REGNO, MODE) \ ! ((REGNO) >= R_ACC (0) ? 1 \ : (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) --- 412,416 ---- #define HARD_REGNO_NREGS(REGNO, MODE) \ ! ((REGNO) >= R_ACC (0) && (REGNO) <= R_ACC (3)? 1 \ : (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) *************** *** 408,412 **** compiler doesn't seem to accept it.) */ #define HARD_REGNO_MODE_OK(REGNO, MODE) \ ! (((REGNO) >= R_ACC (0) \ && (GET_MODE_CLASS (MODE) == MODE_FLOAT \ || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT)) \ --- 429,433 ---- compiler doesn't seem to accept it.) */ #define HARD_REGNO_MODE_OK(REGNO, MODE) \ ! (((REGNO) >= R_ACC (0) && (REGNO) <= R_ACC (3) \ && (GET_MODE_CLASS (MODE) == MODE_FLOAT \ || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT)) \ *************** *** 416,420 **** && GET_MODE_CLASS (MODE) != MODE_FLOAT \ && GET_MODE_CLASS (MODE) != MODE_COMPLEX_FLOAT) \ ! || ((REGNO) < R_BP \ && ((((REGNO) & 1) == 0) \ || GET_MODE_UNIT_SIZE (MODE) <= UNITS_PER_WORD))) --- 437,441 ---- && GET_MODE_CLASS (MODE) != MODE_FLOAT \ && GET_MODE_CLASS (MODE) != MODE_COMPLEX_FLOAT) \ ! || (((REGNO) < R_BP || (REGNO) >= R_KR (0)) \ && ((((REGNO) & 1) == 0) \ || GET_MODE_UNIT_SIZE (MODE) <= UNITS_PER_WORD))) *************** *** 512,527 **** #define REG_CLASS_CONTENTS \ ! { {0, 0, 0, 0, 0, 0, 0}, \ ! {0, 1, 0, 0, 0, 0, 0}, \ ! {~0, ~0, ~0, ~0, ~0, ~ 0xfffe0000, 0}, \ ! {0, 0, 0, 0, 0, 0x20000, 0}, \ ! {0, 0, 0, 0, 0, 0x40000, 0}, \ ! {0, 0, 0, 0, 0, 0x80000, 0}, \ ! {0, 0, 0, 0, 0, 0x100000, 0}, \ ! {0, 0, 0, 0, 0, 0xfffe0000, 0xff}, \ ! {0, 0, 0, 0, 0, 0, 0x100}, \ ! {0, 0, 0, 0, 0, 0, 0xf00}, \ ! {~0, ~0, ~0, ~0, ~0, ~ 0xfffe0000, 0xf00}, \ ! {~0, ~0, ~0, ~0, ~0, ~0, ~0} } /* The same information, inverted: --- 533,548 ---- #define REG_CLASS_CONTENTS \ ! { {0, 0, 0, 0, 0, 0, 0, 0}, \ ! {0, 1, 0, 0, 0, 0, 0, 0}, \ ! {~0, ~0, ~0, ~0, ~0, ~ 0xfffe0000, ~ 0xfff, 0xfffff}, \ ! {0, 0, 0, 0, 0, 0x20000, 0, 0}, \ ! {0, 0, 0, 0, 0, 0x40000, 0, 0}, \ ! {0, 0, 0, 0, 0, 0x80000, 0, 0}, \ ! {0, 0, 0, 0, 0, 0x100000, 0, 0}, \ ! {0, 0, 0, 0, 0, 0xfffe0000, 0xff, 0}, \ ! {0, 0, 0, 0, 0, 0, 0x100, 0}, \ ! {0, 0, 0, 0, 0, 0, 0xf00, 0}, \ ! {~0, ~0, ~0, ~0, ~0, ~ 0xfffe0000, ~ 0xff, ~0}, \ ! {~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0} } /* The same information, inverted: *************** *** 537,540 **** --- 558,562 ---- : (REGNO) > R_BP && (REGNO) <= R_EXO ? SPECIAL_REGS \ : (REGNO) == R_ACC (0) ? ACCUM0_REGS \ + : (REGNO) >= R_KR (0) ? GENERAL_REGS \ : (REGNO) > R_ACC (0) ? ACCUM_REGS \ : (REGNO) == R_LR (0) ? LR0_REGS \ *************** *** 564,582 **** On the 29k, we use this to change the register names for kernel mapping. */ ! #define CONDITIONAL_REGISTER_USAGE \ ! { \ ! static char *kernel_names[] = {"gr64", "gr65", "gr66", "gr67", \ ! "gr68", "gr69", "gr70", "gr71", \ ! "gr72", "gr73", "gr74", "gr75", \ ! "gr76", "gr77", "gr78", "gr79", \ ! "gr80", "gr81", "gr82", "gr83", \ ! "gr84", "gr85", "gr86", "gr87", \ ! "gr88", "gr89", "gr90", "gr91", \ ! "gr92", "gr93", "gr94", "gr95"}; \ ! int i; \ ! \ ! if (TARGET_KERNEL_REGISTERS) \ ! for (i = 0; i < 32; i++) \ ! reg_names[i] = kernel_names[i]; \ } --- 586,601 ---- On the 29k, we use this to change the register names for kernel mapping. */ ! #define CONDITIONAL_REGISTER_USAGE \ ! { \ ! char *p; \ ! int i; \ ! \ ! if (TARGET_KERNEL_REGISTERS) \ ! for (i = 0; i < 32; i++) \ ! { \ ! p = reg_names[i]; \ ! reg_names[i] = reg_names[R_KR (i)]; \ ! reg_names[R_KR (i)] = p; \ ! } \ } *************** *** 878,882 **** (R_AR (0) + first_reg_offset, \ gen_rtx (MEM, BLKmode, virtual_incoming_args_rtx), \ ! 16 - first_reg_offset); \ PRETEND_SIZE = (16 - first_reg_offset) * UNITS_PER_WORD; \ } \ --- 897,901 ---- (R_AR (0) + first_reg_offset, \ gen_rtx (MEM, BLKmode, virtual_incoming_args_rtx), \ ! 16 - first_reg_offset, (16 - first_reg_offset) * UNITS_PER_WORD); \ PRETEND_SIZE = (16 - first_reg_offset) * UNITS_PER_WORD; \ } \ *************** *** 1205,1211 **** #define SLOW_BYTE_ACCESS 0 ! /* Define if normal loads of shorter-than-word items from memory clears ! the rest of the bigs in the register. */ ! #define BYTE_LOADS_ZERO_EXTEND /* Define if the object format being used is COFF or a superset. */ --- 1224,1236 ---- #define SLOW_BYTE_ACCESS 0 ! /* Define if operations between registers always perform the operation ! on the full register even if a narrower mode is specified. */ ! #define WORD_REGISTER_OPERATIONS ! ! /* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD ! will either zero-extend or sign-extend. The value of this macro should ! be the code that says which one of the two operations is implicitly ! done, NIL if none. */ ! #define LOAD_EXTEND_OP(MODE) ZERO_EXTEND /* Define if the object format being used is COFF or a superset. */ *************** *** 1252,1258 **** #define NO_FUNCTION_CSE ! /* Define this if shift instructions ignore all but the low-order few bits. */ ! #define SHIFT_COUNT_TRUNCATED /* Compute the cost of computing a constant rtl expression RTX --- 1277,1283 ---- #define NO_FUNCTION_CSE ! /* Define this to be nonzero if shift instructions ignore all but the low-order few bits. */ ! #define SHIFT_COUNT_TRUNCATED 1 /* Compute the cost of computing a constant rtl expression RTX *************** *** 1306,1310 **** if (*p == '/') \ after_dir = p + 1; \ ! fprintf (FILE, "\t.file \"%s\"\n", after_dir); \ fprintf (FILE, "\t.sect .lit,lit\n"); } --- 1331,1337 ---- if (*p == '/') \ after_dir = p + 1; \ ! fprintf (FILE, "\t.file "); \ ! output_quoted_string (FILE, after_dir); \ ! fprintf (FILE, "\n"); \ fprintf (FILE, "\t.sect .lit,lit\n"); } *************** *** 1352,1355 **** --- 1379,1392 ---- #define READONLY_DATA_SECTION literal_section + /* If we are referencing a function that is static or is known to be + in this file, make the SYMBOL_REF special. We can use this to indicate + that we can branch to this function without emitting a no-op after the + call. */ + + #define ENCODE_SECTION_INFO(DECL) \ + if (TREE_CODE (DECL) == FUNCTION_DECL \ + && (TREE_ASM_WRITTEN (DECL) || ! TREE_PUBLIC (DECL))) \ + SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1; + /* How to refer to registers in assembler output. This sequence is indexed by compiler's hard-register-number (see above). */ *************** *** 1380,1384 **** "vab", "ops", "cps", "cfg", "cha", "chd", "chc", "rbp", "tmc", "tmr", \ "pc0", "pc1", "pc2", "mmu", "lru", "fpe", "int", "fps", "exo", \ ! "0", "1", "2", "3" } /* How to renumber registers for dbx and gdb. */ --- 1417,1425 ---- "vab", "ops", "cps", "cfg", "cha", "chd", "chc", "rbp", "tmc", "tmr", \ "pc0", "pc1", "pc2", "mmu", "lru", "fpe", "int", "fps", "exo", \ ! "0", "1", "2", "3", \ ! "gr64", "gr65", "gr66", "gr67", "gr68", "gr69", "gr70", "gr71", \ ! "gr72", "gr73", "gr74", "gr75", "gr76", "gr77", "gr78", "gr79", \ ! "gr80", "gr81", "gr82", "gr83", "gr84", "gr85", "gr86", "gr87", \ ! "gr88", "gr89", "gr90", "gr91", "gr92", "gr93", "gr94", "gr95" } /* How to renumber registers for dbx and gdb. */ *************** *** 1569,1576 **** LABEL_REF, SYMBOL_REF}}, \ {"shift_constant_operand", {CONST_INT, ASHIFT}}, \ ! {"const_0__operand", {CONST_INT, ASHIFT}}, \ ! {"const_8__operand", {CONST_INT, ASHIFT}}, \ ! {"const_16__operand", {CONST_INT, ASHIFT}}, \ ! {"const_24__operand", {CONST_INT, ASHIFT}}, \ {"float_const_operand", {CONST_DOUBLE}}, \ {"gpc_reg_operand", {SUBREG, REG}}, \ --- 1610,1617 ---- LABEL_REF, SYMBOL_REF}}, \ {"shift_constant_operand", {CONST_INT, ASHIFT}}, \ ! {"const_0_operand", {CONST_INT, ASHIFT}}, \ ! {"const_8_operand", {CONST_INT, ASHIFT}}, \ ! {"const_16_operand", {CONST_INT, ASHIFT}}, \ ! {"const_24_operand", {CONST_INT, ASHIFT}}, \ {"float_const_operand", {CONST_DOUBLE}}, \ {"gpc_reg_operand", {SUBREG, REG}}, \ *************** *** 1578,1581 **** --- 1619,1625 ---- {"gpc_reg_or_integer_constant_operand", {SUBREG, REG, \ CONST_INT, CONST_DOUBLE}}, \ + {"gpc_reg_or_immediate_operand", {SUBREG, REG, CONST_INT, \ + CONST_DOUBLE, CONST, \ + SYMBOL_REF, LABEL_REF}}, \ {"spec_reg_operand", {REG}}, \ {"accum_reg_operand", {REG}}, \ *************** *** 1593,1595 **** --- 1637,1641 ---- {"fp_comparison_operator", {EQ, GT, GE}}, \ {"branch_operator", {GE, LT}}, \ + {"load_multiple_operation", {PARALLEL}}, \ + {"store_multiple_operation", {PARALLEL}}, \ {"epilogue_operand", {CODE_LABEL}}, diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/a29k/unix.h gcc-2.5.0/config/a29k/unix.h *** gcc-2.4.5/config/a29k/unix.h Wed Jan 27 06:42:07 1993 --- gcc-2.5.0/config/a29k/unix.h Sat Oct 2 04:17:21 1993 *************** *** 32,36 **** #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dam29k -Da29k -Dam29000" #undef CPP_SPEC --- 32,36 ---- #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dam29k -Da29k -Dam29000 -Asystem(unix) -Acpu(a29k) -Amachine(a29k)" #undef CPP_SPEC *************** *** 62,66 **** if (*p == '/') \ after_dir = p + 1; \ ! fprintf (FILE, "\t.file \"%s\"\n", after_dir); \ if (flag_shared_data) \ fprintf (FILE, "\t.sect .shdata,data\n"); \ --- 62,68 ---- if (*p == '/') \ after_dir = p + 1; \ ! fprintf (FILE, "\t.file "); \ ! output_quoted_string (FILE, after_dir); \ ! fprintf (FILE, "\n"); \ if (flag_shared_data) \ fprintf (FILE, "\t.sect .shdata,data\n"); \ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/a29k/xm-a29k.h gcc-2.5.0/config/a29k/xm-a29k.h *** gcc-2.4.5/config/a29k/xm-a29k.h Sat Dec 26 17:19:39 1992 --- gcc-2.5.0/config/a29k/xm-a29k.h Sat Jun 26 11:43:29 1993 *************** *** 1,4 **** /* Configuration for GNU C-compiler for AMD Am29000 processor. ! Copyright (C) 1987, 1988 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,4 ---- /* Configuration for GNU C-compiler for AMD Am29000 processor. ! Copyright (C) 1987, 1988, 1993 Free Software Foundation, Inc. This file is part of GNU CC. *************** *** 39,45 **** #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 --- 39,40 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/a29k/xm-unix.h gcc-2.5.0/config/a29k/xm-unix.h *** gcc-2.4.5/config/a29k/xm-unix.h Sat Dec 26 17:19:43 1992 --- gcc-2.5.0/config/a29k/xm-unix.h Sat Jun 26 11:43:06 1993 *************** *** 1,4 **** /* Configuration for GNU C-compiler for AMD Am29000 processor. ! Copyright (C) 1987, 1988 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,4 ---- /* Configuration for GNU C-compiler for AMD Am29000 processor. ! Copyright (C) 1987, 1988, 1993 Free Software Foundation, Inc. This file is part of GNU CC. *************** *** 38,46 **** #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 /* Ultra is V7, which is closest to USG. */ --- 38,41 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/alpha/alpha-gdb.h gcc-2.5.0/config/alpha/alpha-gdb.h *** gcc-2.4.5/config/alpha/alpha-gdb.h --- gcc-2.5.0/config/alpha/alpha-gdb.h Tue Oct 12 18:37:40 1993 *************** *** 0 **** --- 1,25 ---- + /* Definitions of target machine for GNU compiler, for DEC Alpha, using + encapsulated stabs. + Copyright (C) 1992, 1993 Free Software Foundation, Inc. + Contributed by Peter Schauer (pes@regent.e-technik.tu-muenchen.de). + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + #include "alpha/alpha.h" + + #undef PREFERRED_DEBUGGING_TYPE + #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/alpha/alpha.c gcc-2.5.0/config/alpha/alpha.c *** gcc-2.4.5/config/alpha/alpha.c Tue May 18 00:45:50 1993 --- gcc-2.5.0/config/alpha/alpha.c Wed Oct 13 18:00:12 1993 *************** *** 49,52 **** --- 49,57 ---- char *alpha_function_name; + /* Non-zero if inside of a function, because the Alpha asm can't + handle .files inside of functions. */ + + static int inside_function = FALSE; + /* Nonzero if the current function needs gp. */ *************** *** 82,85 **** --- 87,104 ---- } + /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or + any register. */ + + int + reg_or_6bit_operand (op, mode) + register rtx op; + enum machine_mode mode; + { + return ((GET_CODE (op) == CONST_INT + && (unsigned HOST_WIDE_INT) INTVAL (op) < 64) + || register_operand (op, mode)); + } + + /* Return 1 if OP is an 8-bit constant or any register. */ *************** *** 1107,1110 **** --- 1126,1179 ---- #endif } + + /* Write code to add constant C to register number IN_REG (possibly 31) + and put the result into OUT_REG. Write the code to FILE. */ + + static void + add_long_const (file, c, in_reg, out_reg) + HOST_WIDE_INT c; + int in_reg, out_reg; + FILE *file; + { + HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000); + HOST_WIDE_INT tmp1 = c - low; + HOST_WIDE_INT high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000); + HOST_WIDE_INT extra = 0; + + /* We don't have code to write out constants larger than 32 bits. */ + #if HOST_BITS_PER_LONG_INT == 64 + if ((unsigned HOST_WIDE_INT) c >> 32 != 0) + abort (); + #endif + + /* If HIGH will be interpreted as negative, we must adjust it to do two + ldha insns. Note that we will never be building a negative constant + here. */ + + if (high & 0x8000) + { + extra = 0x4000; + tmp1 -= 0x40000000; + high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000); + } + + if (low != 0) + { + if (low >= 0 && low < 255) + fprintf (file, "\taddq $%d,%d,$%d\n", in_reg, low, out_reg); + else + fprintf (file, "\tlda $%d,%d($%d)\n", out_reg, low, in_reg); + in_reg = out_reg; + } + + if (extra) + { + fprintf (file, "\tldah $%d,%d($%d)\n", out_reg, extra, in_reg); + in_reg = out_reg; + } + + if (high) + fprintf (file, "\tldah $%d,%d($%d)\n", out_reg, high, in_reg); + } /* Write function prologue. */ *************** *** 1118,1127 **** + current_function_pretend_args_size + alpha_sa_size () + 15) & ~15); ! int reg_offset = size + current_function_outgoing_args_size; rtx insn; ! int start_reg_offset = reg_offset; unsigned reg_mask = 0; int i; /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first. Even if we are a static function, we still need to do this in case --- 1187,1227 ---- + current_function_pretend_args_size + alpha_sa_size () + 15) & ~15); ! HOST_WIDE_INT reg_offset = size + current_function_outgoing_args_size; ! HOST_WIDE_INT start_reg_offset = reg_offset; ! HOST_WIDE_INT actual_start_reg_offset = start_reg_offset; rtx insn; ! int reg_offset_base_reg = 30; unsigned reg_mask = 0; int i; + /* Ecoff can handle multiple .file directives, put out file and lineno. + We have to do that before the .ent directive as we cannot switch + files within procedures with native ecoff because line numbers are + linked to procedure descriptors. + Outputting the lineno helps debugging of one line functions as they + would otherwise get no line number at all. Please note that we would + like to put out last_linenum from final.c, but it is not accesible. */ + + if (write_symbols == SDB_DEBUG) + { + ASM_OUTPUT_SOURCE_FILENAME (file, + DECL_SOURCE_FILE (current_function_decl)); + if (debug_info_level != DINFO_LEVEL_TERSE) + ASM_OUTPUT_SOURCE_LINE (file, DECL_SOURCE_LINE (current_function_decl)); + } + + /* The assembly language programmer's guide states that the second argument + to the .ent directive, the lex_level, is ignored by the assembler, + so we might as well omit it. */ + + fprintf (file, "\t.ent %s\n", alpha_function_name); + ASM_OUTPUT_LABEL (file, alpha_function_name); + inside_function = TRUE; + + /* Set up offsets to alpha virtual arg/local debugging pointer. */ + + alpha_auto_offset = -frame_size + current_function_pretend_args_size; + alpha_arg_offset = -frame_size + 48; + /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first. Even if we are a static function, we still need to do this in case *************** *** 1182,1228 **** number of 8192 byte blocks to probe. We then probe each block in the loop and then set SP to the proper location. If the ! amount remaining is > 4096, we have to do one more probe. ! ! This is complicated by the code we would generate if ! the number of blocks > 32767. */ HOST_WIDE_INT blocks = (frame_size + 4096) / 8192; HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192; - HOST_WIDE_INT low = (blocks & 0xffff) - 2 * (blocks & 0x8000); - HOST_WIDE_INT tmp1 = blocks - low; - HOST_WIDE_INT high - = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000); - HOST_WIDE_INT extra = 0; - int in_reg = 31; - - /* If HIGH will be interpreted as negative, we must adjust it to - do two ldha insns. Note that we will never be building a negative - constant here. */ - - if (high & 0x8000) - { - extra = 0x4000; - tmp1 -= 0x40000000; - high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000); - } - - if (low != 0) - { - if (low < 255) - fprintf (file, "\tbis $31,%d,$5\n", low); - else - fprintf (file, "\tlda $5,%d($31)\n", low); - in_reg = 5; - } ! if (extra) ! { ! fprintf (file, "\tldah $5,%d($%d)\n", extra, in_reg); ! in_reg = 5; ! } - if (high) - fprintf (file, "\tldah $5,%d($%d)\n", high, in_reg); - fprintf (file, "\tlda $4,4096($30)\n"); fprintf (file, "%s..sc:\n", alpha_function_name); --- 1282,1292 ---- number of 8192 byte blocks to probe. We then probe each block in the loop and then set SP to the proper location. If the ! amount remaining is > 4096, we have to do one more probe. */ HOST_WIDE_INT blocks = (frame_size + 4096) / 8192; HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192; ! add_long_const (file, blocks, 31, 5); fprintf (file, "\tlda $4,4096($30)\n"); fprintf (file, "%s..sc:\n", alpha_function_name); *************** *** 1242,1245 **** --- 1306,1319 ---- frame_size, current_function_pretend_args_size); + /* If reg_offset is "close enough" to 2**15 that one of the offsets would + overflow a store instruction, compute the base of the register save + area into $28. */ + if (reg_offset >= 32768 - alpha_sa_size () && alpha_sa_size () != 0) + { + add_long_const (file, reg_offset, 30, 28); + reg_offset_base_reg = 28; + reg_offset = start_reg_offset = 0; + } + /* Save register 26 if it is used or if any other register needs to be saved. */ *************** *** 1247,1251 **** { reg_mask |= 1 << 26; ! fprintf (file, "\tstq $26,%d($30)\n", reg_offset); reg_offset += 8; } --- 1321,1325 ---- { reg_mask |= 1 << 26; ! fprintf (file, "\tstq $26,%d($%d)\n", reg_offset, reg_offset_base_reg); reg_offset += 8; } *************** *** 1256,1260 **** { reg_mask |= 1 << i; ! fprintf (file, "\tstq $%d,%d($30)\n", i, reg_offset); reg_offset += 8; } --- 1330,1335 ---- { reg_mask |= 1 << i; ! fprintf (file, "\tstq $%d,%d($%d)\n", ! i, reg_offset, reg_offset_base_reg); reg_offset += 8; } *************** *** 1263,1267 **** if (reg_mask) fprintf (file, "\t.mask 0x%x,%d\n", reg_mask, ! start_reg_offset - frame_size); start_reg_offset = reg_offset; --- 1338,1342 ---- if (reg_mask) fprintf (file, "\t.mask 0x%x,%d\n", reg_mask, ! actual_start_reg_offset - frame_size); start_reg_offset = reg_offset; *************** *** 1273,1277 **** { reg_mask |= 1 << i; ! fprintf (file, "\tstt $f%d,%d($30)\n", i, reg_offset); reg_offset += 8; } --- 1348,1353 ---- { reg_mask |= 1 << i; ! fprintf (file, "\tstt $f%d,%d($%d)\n", ! i, reg_offset, reg_offset_base_reg); reg_offset += 8; } *************** *** 1279,1283 **** /* Print the floating-point mask, if we've saved any fp register. */ if (reg_mask) ! fprintf (file, "\t.fmask 0x%x,%d\n", reg_mask, start_reg_offset); /* If we need a frame pointer, set it from the stack pointer. Note that --- 1355,1359 ---- /* Print the floating-point mask, if we've saved any fp register. */ if (reg_mask) ! fprintf (file, "\t.fmask 0x%x,%d\n", reg_mask, actual_start_reg_offset); /* If we need a frame pointer, set it from the stack pointer. Note that *************** *** 1301,1305 **** + current_function_pretend_args_size + alpha_sa_size () + 15) & ~15); ! int reg_offset = size + current_function_outgoing_args_size; int i; --- 1377,1383 ---- + current_function_pretend_args_size + alpha_sa_size () + 15) & ~15); ! HOST_WIDE_INT reg_offset = size + current_function_outgoing_args_size; ! HOST_WIDE_INT frame_size_from_reg_save = frame_size - reg_offset; ! int reg_offset_base_reg = 30; int i; *************** *** 1316,1319 **** --- 1394,1406 ---- fprintf (file, "\tbis $15,$15,$30\n"); + /* If the register save area is out of range, put its address into + $28. */ + if (reg_offset >= 32768 - alpha_sa_size () && alpha_sa_size () != 0) + { + add_long_const (file, reg_offset, 30, 28); + reg_offset_base_reg = 28; + reg_offset = 0; + } + /* Restore all the registers, starting with the return address register. */ *************** *** 1320,1324 **** if (regs_ever_live[26] || alpha_sa_size () != 0) { ! fprintf (file, "\tldq $26,%d($30)\n", reg_offset); reg_offset += 8; } --- 1407,1412 ---- if (regs_ever_live[26] || alpha_sa_size () != 0) { ! fprintf (file, "\tldq $26,%d($%d)\n", ! reg_offset, reg_offset_base_reg); reg_offset += 8; } *************** *** 1335,1339 **** fp_offset = reg_offset; else ! fprintf (file, "\tldq $%d,%d($30)\n", i, reg_offset); reg_offset += 8; } --- 1423,1428 ---- fp_offset = reg_offset; else ! fprintf (file, "\tldq $%d,%d($%d)\n", ! i, reg_offset, reg_offset_base_reg); reg_offset += 8; } *************** *** 1343,1347 **** && regs_ever_live[i + 32]) { ! fprintf (file, "\tldt $f%d,%d($30)\n", i, reg_offset); reg_offset += 8; } --- 1432,1437 ---- && regs_ever_live[i + 32]) { ! fprintf (file, "\tldt $f%d,%d($%d)\n", ! i, reg_offset, reg_offset_base_reg); reg_offset += 8; } *************** *** 1349,1400 **** /* If the stack size is large, compute the size of the stack into a register because the old FP restore, stack pointer adjust, ! and return are required to be consecutive instructions. */ ! if (frame_size > 32767) ! { ! HOST_WIDE_INT low ! = (frame_size & 0xffff) - 2 * (frame_size & 0x8000); ! HOST_WIDE_INT tmp1 = frame_size - low; ! HOST_WIDE_INT high ! = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000); ! HOST_WIDE_INT extra = 0; ! int in_reg = 31; ! ! /* We haven't written code to handle frames > 4GB. */ ! #if HOST_BITS_PER_LONG_INT == 64 ! if ((unsigned HOST_WIDE_INT) frame_size >> 32 != 0) ! abort (); ! #endif ! ! /* If HIGH will be interpreted as negative, we must adjust it to ! do two ldha insns. Note that we will never be building a negative ! constant here. */ ! ! if (high & 0x8000) ! { ! extra = 0x4000; ! tmp1 -= 0x40000000; ! high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000); ! } ! ! if (low != 0) ! { ! fprintf (file, "\tlda $28,%d($%d)\n", low, in_reg); ! in_reg = 28; ! } ! ! if (extra) ! { ! fprintf (file, "\tldah $28,%d($%d)\n", extra, in_reg); ! in_reg = 28; ! } ! ! fprintf (file, "\tldah $28,%d($%d)\n", high, in_reg); ! } /* If we needed a frame pointer and we have to restore it, do it ! now. */ ! if (frame_pointer_needed && regs_ever_live[FRAME_POINTER_REGNUM]) ! fprintf (file, "\tldq $15,%d($30)\n", fp_offset); /* Now update the stack pointer, if needed. This must be done in --- 1439,1456 ---- /* If the stack size is large, compute the size of the stack into a register because the old FP restore, stack pointer adjust, ! and return are required to be consecutive instructions. ! However, if the new stack pointer can be computed by adding the ! a constant to the start of the register save area, we can do ! it that way. */ ! if (frame_size > 32767 ! && ! (reg_offset_base_reg != 30 ! && frame_size_from_reg_save < 32768)) ! add_long_const (file, frame_size, 31, 1); /* If we needed a frame pointer and we have to restore it, do it ! now. This must be done in one instruction immediately ! before the SP update. */ if (frame_pointer_needed && regs_ever_live[FRAME_POINTER_REGNUM]) ! fprintf (file, "\tldq $15,%d($%d)\n", fp_offset, reg_offset_base_reg); /* Now update the stack pointer, if needed. This must be done in *************** *** 1401,1405 **** one, stylized, instruction. */ if (frame_size > 32768) ! fprintf (file, "\taddq $28,$30,$30\n"); else if (frame_size != 0) fprintf (file, "\tlda $30,%d($30)\n", frame_size); --- 1457,1474 ---- one, stylized, instruction. */ if (frame_size > 32768) ! { ! if (reg_offset_base_reg != 30 ! && frame_size_from_reg_save < 32768) ! { ! if (frame_size_from_reg_save < 255) ! fprintf (file, "\taddq $%d,%d,$30\n", ! reg_offset_base_reg, frame_size_from_reg_save); ! else ! fprintf (file, "\tlda %30,%d($%d)\n", ! frame_size_from_reg_save, reg_offset_base_reg); ! } ! else ! fprintf (file, "\taddq $1,$30,$30\n"); ! } else if (frame_size != 0) fprintf (file, "\tlda $30,%d($30)\n", frame_size); *************** *** 1411,1416 **** --- 1480,1577 ---- /* End the function. */ fprintf (file, "\t.end %s\n", alpha_function_name); + inside_function = FALSE; /* Show that we know this function if it is called again. */ SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1; + } + + /* Debugging support. */ + + #include "gstab.h" + + /* Count the number of sdb related labels are generated (to find block + start and end boundaries). */ + + int sdb_label_count = 0; + + /* Next label # for each statement. */ + + static int sym_lineno = 0; + + /* Count the number of .file directives, so that .loc is up to date. */ + + static int num_source_filenames = 0; + + /* Name of the file containing the current function. */ + + static char *current_function_file = ""; + + /* Offsets to alpha virtual arg/local debugging pointers. */ + + long alpha_arg_offset; + long alpha_auto_offset; + + /* Emit a new filename to a stream. */ + + void + alpha_output_filename (stream, name) + FILE *stream; + char *name; + { + static int first_time = TRUE; + char ltext_label_name[100]; + + if (first_time) + { + first_time = FALSE; + ++num_source_filenames; + current_function_file = name; + fprintf (stream, "\t.file\t%d ", num_source_filenames); + output_quoted_string (stream, name); + fprintf (stream, "\n"); + if (!TARGET_GAS && write_symbols == DBX_DEBUG) + fprintf (stream, "\t#@stabs\n"); + } + + else if (!TARGET_GAS && write_symbols == DBX_DEBUG) + { + ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0); + fprintf (stream, "%s ", ASM_STABS_OP); + output_quoted_string (stream, name); + fprintf (stream, ",%d,0,0,%s\n", N_SOL, <ext_label_name[1]); + } + + else if (name != current_function_file + && strcmp (name, current_function_file) != 0) + { + if (inside_function && ! TARGET_GAS) + fprintf (stream, "\t#.file\t%d ", num_source_filenames); + else + { + ++num_source_filenames; + current_function_file = name; + fprintf (stream, "\t.file\t%d ", num_source_filenames); + } + + output_quoted_string (stream, name); + fprintf (stream, "\n"); + } + } + + /* Emit a linenumber to a stream. */ + + void + alpha_output_lineno (stream, line) + FILE *stream; + int line; + { + if (! TARGET_GAS && write_symbols == DBX_DEBUG) + { + /* mips-tfile doesn't understand .stabd directives. */ + ++sym_lineno; + fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n", + sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno); + } + else + fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line); } diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/alpha/alpha.h gcc-2.5.0/config/alpha/alpha.h *** gcc-2.4.5/config/alpha/alpha.h Sat May 22 15:42:59 1993 --- gcc-2.5.0/config/alpha/alpha.h Wed Oct 20 19:35:11 1993 *************** *** 24,28 **** #define CPP_PREDEFINES "\ -Dunix -D__osf__ -D__alpha -D__alpha__ -D_LONGLONG -DSYSTYPE_BSD \ ! -D_SYSTYPE_BSD" /* Write out the correct language type definition for the header files. */ --- 24,28 ---- #define CPP_PREDEFINES "\ -Dunix -D__osf__ -D__alpha -D__alpha__ -D_LONGLONG -DSYSTYPE_BSD \ ! -D_SYSTYPE_BSD -Asystem(unix) -Asystem(xpg4) -Acpu(alpha) -Amachine(alpha)" /* Write out the correct language type definition for the header files. */ *************** *** 45,58 **** #define ASM_SPEC "-nocpp" ! /* Right now Alpha OSF/1 doesn't seem to have debugging or profiled ! libraries. */ ! #define LIB_SPEC "-lc" ! /* Pass "-G 8" to ld because Alpha's CC does. Pass -O2 if we are optimizing, -O1 if we are not. Pass -non_shared or -call_shared as appropriate. */ - /* Disable -O2 to ld; it seems to have problems. */ #define LINK_SPEC \ ! "-G 8 %{O*:-O1} %{!O*:-O1} %{static:-non_shared} %{!static:-call_shared}" /* Print subsidiary information on the compiler version in use. */ --- 45,56 ---- #define ASM_SPEC "-nocpp" ! /* Right now Alpha OSF/1 doesn't seem to have debugging libraries. */ ! #define LIB_SPEC "%{p:-lprof1} -lc" ! /* Pass "-G 8" to ld because Alpha's CC does. Pass -O3 if we are optimizing, -O1 if we are not. Pass -non_shared or -call_shared as appropriate. */ #define LINK_SPEC \ ! "-G 8 %{O*:-O3} %{!O*:-O1} %{static:-non_shared} %{!static:-call_shared}" /* Print subsidiary information on the compiler version in use. */ *************** *** 76,81 **** provide the FP registers. */ ! #define TARGET_FPREGS (target_flags & 2) /* Macro to define tables used to set the flags. This is a list in braces of pairs in braces, --- 74,84 ---- provide the FP registers. */ ! #define TARGET_FPREGS (target_flags & 2) + /* This means that gas is used to process the assembler file. */ + + #define MASK_GAS 4 + #define TARGET_GAS (target_flags & MASK_GAS) + /* Macro to define tables used to set the flags. This is a list in braces of pairs in braces, *************** *** 89,92 **** --- 92,97 ---- {"fp-regs", 2}, \ {"no-fp-regs", -3}, \ + {"alpha-as", -MASK_GAS}, \ + {"gas", MASK_GAS}, \ {"", TARGET_DEFAULT} } *************** *** 216,223 **** #define PCC_BITFIELD_TYPE_MATTERS 1 ! /* Align loop starts for optimal branching. */ #define ASM_OUTPUT_LOOP_ALIGN(FILE) \ ! ASM_OUTPUT_ALIGN (FILE, 5) /* This is how to align an instruction for optimal branching. --- 221,233 ---- #define PCC_BITFIELD_TYPE_MATTERS 1 ! /* Align loop starts for optimal branching. + ??? Kludge this and the next macro for the moment by not doing anything if + we don't optimize and also if we are writing ECOFF symbols to work around + a bug in DEC's assembler. */ + #define ASM_OUTPUT_LOOP_ALIGN(FILE) \ ! if (optimize > 0 && write_symbols != SDB_DEBUG) \ ! ASM_OUTPUT_ALIGN (FILE, 5) /* This is how to align an instruction for optimal branching. *************** *** 226,230 **** #define ASM_OUTPUT_ALIGN_CODE(FILE) \ ! ASM_OUTPUT_ALIGN ((FILE), 4) /* No data type wants to be aligned rounder than this. */ --- 236,241 ---- #define ASM_OUTPUT_ALIGN_CODE(FILE) \ ! if (optimize > 0 && write_symbols != SDB_DEBUG) \ ! ASM_OUTPUT_ALIGN ((FILE), 4) /* No data type wants to be aligned rounder than this. */ *************** *** 320,324 **** #define REG_ALLOC_ORDER \ {33, \ ! 42, 43, 44, 45, \ 54, 55, 56, 57, 58, 59, 60, 61, 62, \ 53, 52, 51, 50, 49, 48, \ --- 331,335 ---- #define REG_ALLOC_ORDER \ {33, \ ! 42, 43, 44, 45, 46, 47, \ 54, 55, 56, 57, 58, 59, 60, 61, 62, \ 53, 52, 51, 50, 49, 48, \ *************** *** 795,799 **** This is not only because we won't need the space, but because AP includes the current_pretend_args_size and we don't want to mess up any ! ap-relative addresses already made. */ #define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \ --- 806,817 ---- This is not only because we won't need the space, but because AP includes the current_pretend_args_size and we don't want to mess up any ! ap-relative addresses already made. ! ! If we are not to use the floating-point registers, save the integer ! registers where we would put the floating-point registers. This is ! not the most efficient way to implement varargs with just one register ! class, but it isn't worth doing anything more efficient in this rare ! case. */ ! #define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \ *************** *** 807,817 **** plus_constant (virtual_incoming_args_rtx, \ ((CUM) + 6)* UNITS_PER_WORD)), \ ! 6 - (CUM)); \ move_block_from_reg \ ! (16 + 32 + CUM, \ gen_rtx (MEM, BLKmode, \ plus_constant (virtual_incoming_args_rtx, \ (CUM) * UNITS_PER_WORD)), \ ! 6 - (CUM)); \ } \ PRETEND_SIZE = 12 * UNITS_PER_WORD; \ --- 825,835 ---- plus_constant (virtual_incoming_args_rtx, \ ((CUM) + 6)* UNITS_PER_WORD)), \ ! 6 - (CUM), (6 - (CUM)) * UNITS_PER_WORD); \ move_block_from_reg \ ! (16 + (TARGET_FPREGS ? 32 : 0) + CUM, \ gen_rtx (MEM, BLKmode, \ plus_constant (virtual_incoming_args_rtx, \ (CUM) * UNITS_PER_WORD)), \ ! 6 - (CUM), (6 - (CUM)) * UNITS_PER_WORD); \ } \ PRETEND_SIZE = 12 * UNITS_PER_WORD; \ *************** *** 832,836 **** /* This macro produces the initial definition of a function name. On the ! Alpha, we need to save the function name for the epilogue. */ extern char *alpha_function_name; --- 850,854 ---- /* This macro produces the initial definition of a function name. On the ! Alpha, we need to save the function name for the prologue and epilogue. */ extern char *alpha_function_name; *************** *** 837,847 **** #define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL) \ ! { int _level; \ ! tree _context; \ ! for (_level = -1, _context = (DECL); _context; \ ! _context = DECL_CONTEXT (_context), _level++) \ ! ; \ ! fprintf (FILE, "\t.ent %s %d\n", NAME, _level); \ ! ASM_OUTPUT_LABEL (FILE, NAME); \ alpha_function_name = NAME; \ } --- 855,859 ---- #define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL) \ ! { \ alpha_function_name = NAME; \ } *************** *** 1222,1232 **** #define SLOW_BYTE_ACCESS 1 ! /* Define if normal loads of shorter-than-word items from memory clears ! the rest of the bits in the register. */ ! /* #define BYTE_LOADS_ZERO_EXTEND */ ! ! /* Define if normal loads of shorter-than-word items from memory sign-extends ! the rest of the bits in the register. */ ! #define BYTE_LOADS_SIGN_EXTEND /* Define if loading short immediate values into registers sign extends. */ --- 1234,1246 ---- #define SLOW_BYTE_ACCESS 1 ! /* Define if operations between registers always perform the operation ! on the full register even if a narrower mode is specified. */ ! #define WORD_REGISTER_OPERATIONS ! ! /* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD ! will either zero-extend or sign-extend. The value of this macro should ! be the code that says which one of the two operations is implicitly ! done, NIL if none. */ ! #define LOAD_EXTEND_OP(MODE) SIGN_EXTEND /* Define if loading short immediate values into registers sign extends. */ *************** *** 1233,1247 **** #define SHORT_IMMEDIATES_SIGN_EXTEND - /* We aren't doing ANYTHING about debugging for now. */ - /* #define SDB_DEBUGGING_INFO */ - - /* Do not break .stabs pseudos into continuations. */ - #define DBX_CONTIN_LENGTH 0 - - /* Don't try to use the `x' type-cross-reference character in DBX data. - Also has the consequence of putting each struct, union or enum - into a separate .stabs, containing only cross-refs to the others. */ - #define DBX_NO_XREFS - /* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits is done just by pretending it is already truncated. */ --- 1247,1250 ---- *************** *** 1278,1284 **** #define NO_FUNCTION_CSE ! /* Define this if shift instructions ignore all but the low-order few bits. */ ! #define SHIFT_COUNT_TRUNCATED /* Compute the cost of computing a constant rtl expression RTX --- 1281,1291 ---- #define NO_FUNCTION_CSE ! /* Define this to be nonzero if shift instructions ignore all but the low-order few bits. */ ! #define SHIFT_COUNT_TRUNCATED 1 ! ! /* Use atexit for static constructors/destructors, instead of defining ! our own exit function. */ ! #define HAVE_ATEXIT /* Compute the cost of computing a constant rtl expression RTX *************** *** 1309,1313 **** else if (GET_CODE (XEXP (X, 0)) == MULT \ && const48_operand (XEXP (XEXP (X, 0), 1), VOIDmode)) \ ! return 2 + rtx_cost (XEXP (XEXP (X, 0), 0)) + rtx_cost (XEXP (X, 1)); \ break; \ case MULT: \ --- 1316,1321 ---- else if (GET_CODE (XEXP (X, 0)) == MULT \ && const48_operand (XEXP (XEXP (X, 0), 1), VOIDmode)) \ ! return (2 + rtx_cost (XEXP (XEXP (X, 0), 0), OUTER_CODE) \ ! + rtx_cost (XEXP (X, 1), OUTER_CODE)); \ break; \ case MULT: \ *************** *** 1345,1357 **** #define ASM_FILE_START(FILE) \ ! { char *p, *after_dir = main_input_filename; \ ! \ alpha_write_verstamp (FILE); \ fprintf (FILE, "\t.set noreorder\n"); \ fprintf (FILE, "\t.set noat\n"); \ ! for (p = main_input_filename; *p; p++) \ ! if (*p == '/') \ ! after_dir = p + 1; \ ! fprintf (FILE, "\n\t.file 2 \"%s\"\n", after_dir); \ } --- 1353,1361 ---- #define ASM_FILE_START(FILE) \ ! { \ alpha_write_verstamp (FILE); \ fprintf (FILE, "\t.set noreorder\n"); \ fprintf (FILE, "\t.set noat\n"); \ ! ASM_OUTPUT_SOURCE_FILENAME (FILE, main_input_filename); \ } *************** *** 1698,1701 **** --- 1702,1706 ---- #define PREDICATE_CODES \ {"reg_or_0_operand", {SUBREG, REG, CONST_INT}}, \ + {"reg_or_6bit_operand", {SUBREG, REG, CONST_INT}}, \ {"reg_or_8bit_operand", {SUBREG, REG, CONST_INT}}, \ {"reg_or_cint_operand", {SUBREG, REG, CONST_INT}}, \ *************** *** 1710,1714 **** --- 1715,1721 ---- {"alpha_comparison_operator", {EQ, LE, LT, LEU, LTU}}, \ {"signed_comparison_operator", {EQ, NE, LE, LT, GE, GT}}, \ + {"divmod_operator", {DIV, MOD, UDIV, UMOD}}, \ {"fp0_operand", {CONST_DOUBLE}}, \ + {"current_file_function_operand", {SYMBOL_REF}}, \ {"input_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE, \ SYMBOL_REF, CONST, LABEL_REF}}, \ *************** *** 1716,1717 **** --- 1723,1881 ---- {"unaligned_memory_operand", {MEM}}, \ {"any_memory_operand", {MEM}}, + + /* Definitions for debugging. */ + + #define SDB_DEBUGGING_INFO /* generate info for mips-tfile */ + #define DBX_DEBUGGING_INFO /* generate embedded stabs */ + #define MIPS_DEBUGGING_INFO /* MIPS specific debugging info */ + + #ifndef PREFERRED_DEBUGGING_TYPE /* assume SDB_DEBUGGING_INFO */ + #define PREFERRED_DEBUGGING_TYPE ((len > 1 && !strncmp (str, "ggdb", len)) ? DBX_DEBUG : SDB_DEBUG) + #endif + + + /* Correct the offset of automatic variables and arguments. Note that + the Alpha debug format wants all automatic variables and arguments + to be in terms of two different offsets from the virtual frame pointer, + which is the stack pointer before any adjustment in the function. + The offset for the argument pointer is fixed for the native compiler, + it is either zero (for the no arguments case) or large enough to hold + all argument registers. + The offset for the auto pointer is the fourth argument to the .frame + directive (local_offset). + To stay compatible with the native tools we use the same offsets + from the virtual frame pointer and adjust the debugger arg/auto offsets + accordingly. These debugger offsets are set up in output_prolog. */ + + long alpha_arg_offset; + long alpha_auto_offset; + #define DEBUGGER_AUTO_OFFSET(X) \ + ((GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0) + alpha_auto_offset) + #define DEBUGGER_ARG_OFFSET(OFFSET, X) (OFFSET + alpha_arg_offset) + + + #define ASM_OUTPUT_SOURCE_LINE(STREAM, LINE) \ + alpha_output_lineno (STREAM, LINE) + extern void alpha_output_lineno (); + + #define ASM_OUTPUT_SOURCE_FILENAME(STREAM, NAME) \ + alpha_output_filename (STREAM, NAME) + extern void alpha_output_filename (); + + + /* mips-tfile.c limits us to strings of one page. */ + #define DBX_CONTIN_LENGTH 4000 + + /* By default, turn on GDB extensions. */ + #define DEFAULT_GDB_EXTENSIONS 1 + + /* If we are smuggling stabs through the ALPHA ECOFF object + format, put a comment in front of the .stab operation so + that the ALPHA assembler does not choke. The mips-tfile program + will correctly put the stab into the object file. */ + + #define ASM_STABS_OP ((TARGET_GAS) ? ".stabs" : " #.stabs") + #define ASM_STABN_OP ((TARGET_GAS) ? ".stabn" : " #.stabn") + #define ASM_STABD_OP ((TARGET_GAS) ? ".stabd" : " #.stabd") + + /* Forward references to tags are allowed. */ + #define SDB_ALLOW_FORWARD_REFERENCES + + /* Unknown tags are also allowed. */ + #define SDB_ALLOW_UNKNOWN_REFERENCES + + #define PUT_SDB_DEF(a) \ + do { \ + fprintf (asm_out_file, "\t%s.def\t", \ + (TARGET_GAS) ? "" : "#"); \ + ASM_OUTPUT_LABELREF (asm_out_file, a); \ + fputc (';', asm_out_file); \ + } while (0) + + #define PUT_SDB_PLAIN_DEF(a) \ + do { \ + fprintf (asm_out_file, "\t%s.def\t.%s;", \ + (TARGET_GAS) ? "" : "#", (a)); \ + } while (0) + + #define PUT_SDB_TYPE(a) \ + do { \ + fprintf (asm_out_file, "\t.type\t0x%x;", (a)); \ + } while (0) + + /* For block start and end, we create labels, so that + later we can figure out where the correct offset is. + The normal .ent/.end serve well enough for functions, + so those are just commented out. */ + + extern int sdb_label_count; /* block start/end next label # */ + + #define PUT_SDB_BLOCK_START(LINE) \ + do { \ + fprintf (asm_out_file, \ + "$Lb%d:\n\t%s.begin\t$Lb%d\t%d\n", \ + sdb_label_count, \ + (TARGET_GAS) ? "" : "#", \ + sdb_label_count, \ + (LINE)); \ + sdb_label_count++; \ + } while (0) + + #define PUT_SDB_BLOCK_END(LINE) \ + do { \ + fprintf (asm_out_file, \ + "$Le%d:\n\t%s.bend\t$Le%d\t%d\n", \ + sdb_label_count, \ + (TARGET_GAS) ? "" : "#", \ + sdb_label_count, \ + (LINE)); \ + sdb_label_count++; \ + } while (0) + + #define PUT_SDB_FUNCTION_START(LINE) + + #define PUT_SDB_FUNCTION_END(LINE) + + #define PUT_SDB_EPILOGUE_END(NAME) + + /* Specify to run a post-processor, mips-tfile after the assembler + has run to stuff the ecoff debug information into the object file. + This is needed because the Alpha assembler provides no way + of specifying such information in the assembly file. */ + + #if (TARGET_DEFAULT & MASK_GAS) != 0 + + #define ASM_FINAL_SPEC "\ + %{malpha-as: %{!mno-mips-tfile: \ + \n mips-tfile %{v*: -v} \ + %{K: -I %b.o~} \ + %{!K: %{save-temps: -I %b.o~}} \ + %{c:%W{o*}%{!o*:-o %b.o}}%{!c:-o %U.o} \ + %{.s:%i} %{!.s:%g.s}}}" + + #else + #define ASM_FINAL_SPEC "\ + %{!mgas: %{!mno-mips-tfile: \ + \n mips-tfile %{v*: -v} \ + %{K: -I %b.o~} \ + %{!K: %{save-temps: -I %b.o~}} \ + %{c:%W{o*}%{!o*:-o %b.o}}%{!c:-o %U.o} \ + %{.s:%i} %{!.s:%g.s}}}" + + #endif + + /* Macros for mips-tfile.c to encapsulate stabs in ECOFF, and for + mips-tdump.c to print them out. + + These must match the corresponding definitions in gdb/mipsread.c. + Unfortunately, gcc and gdb do not currently share any directories. */ + + #define CODE_MASK 0x8F300 + #define MIPS_IS_STAB(sym) (((sym)->index & 0xFFF00) == CODE_MASK) + #define MIPS_MARK_STAB(code) ((code)+CODE_MASK) + #define MIPS_UNMARK_STAB(code) ((code)-CODE_MASK) + + /* Override some mips-tfile definitions. */ + + #define SHASH_SIZE 511 + #define THASH_SIZE 55 diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/alpha/alpha.md gcc-2.5.0/config/alpha/alpha.md *** gcc-2.4.5/config/alpha/alpha.md Tue Jun 1 18:48:11 1993 --- gcc-2.5.0/config/alpha/alpha.md Thu Oct 7 08:53:51 1993 *************** *** 88,92 **** (define_insn "addsi3" [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") ! (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,%rJ,%rJ,%rJ") (match_operand:SI 2 "add_operand" "rI,O,K,L")))] "" --- 88,92 ---- (define_insn "addsi3" [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") ! (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ") (match_operand:SI 2 "add_operand" "rI,O,K,L")))] "" *************** *** 152,156 **** (define_insn "adddi3" [(set (match_operand:DI 0 "register_operand" "=r,r,r,r") ! (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,%rJ,%rJ,%rJ") (match_operand:DI 2 "add_operand" "rI,O,K,L")))] "" --- 152,156 ---- (define_insn "adddi3" [(set (match_operand:DI 0 "register_operand" "=r,r,r,r") ! (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ") (match_operand:DI 2 "add_operand" "rI,O,K,L")))] "" *************** *** 634,638 **** (define_insn "xordi3" [(set (match_operand:DI 0 "register_operand" "=r") ! (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") (match_operand:DI 2 "reg_or_8bit_operand" "rI")))] "" --- 634,638 ---- (define_insn "xordi3" [(set (match_operand:DI 0 "register_operand" "=r") ! (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ") (match_operand:DI 2 "reg_or_8bit_operand" "rI")))] "" *************** *** 642,646 **** (define_insn "" [(set (match_operand:DI 0 "register_operand" "=r") ! (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") (match_operand:DI 2 "reg_or_8bit_operand" "rI"))))] "" --- 642,646 ---- (define_insn "" [(set (match_operand:DI 0 "register_operand" "=r") ! (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ") (match_operand:DI 2 "reg_or_8bit_operand" "rI"))))] "" *************** *** 653,657 **** [(set (match_operand:DI 0 "register_operand" "=r,r") (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ") ! (match_operand:DI 2 "reg_or_8bit_operand" "P,rI")))] "" "* --- 653,657 ---- [(set (match_operand:DI 0 "register_operand" "=r,r") (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ") ! (match_operand:DI 2 "reg_or_6bit_operand" "P,rI")))] "" "* *************** *** 696,700 **** [(set (match_operand:DI 0 "register_operand" "=r") (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ! (match_operand:DI 2 "reg_or_8bit_operand" "rI")))] "" "srl %r1,%2,%0") --- 696,700 ---- [(set (match_operand:DI 0 "register_operand" "=r") (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ! (match_operand:DI 2 "reg_or_6bit_operand" "rI")))] "" "srl %r1,%2,%0") *************** *** 703,707 **** [(set (match_operand:DI 0 "register_operand" "=r") (ashiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ! (match_operand:DI 2 "reg_or_8bit_operand" "rI")))] "" "sra %r1,%2,%0") --- 703,707 ---- [(set (match_operand:DI 0 "register_operand" "=r") (ashiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ! (match_operand:DI 2 "reg_or_6bit_operand" "rI")))] "" "sra %r1,%2,%0") *************** *** 972,976 **** [(set (match_operand:DF 0 "register_operand" "=f") (plus:DF (float_extend:DF ! (match_operand:SF 1 "reg_or_fp0_operand" "%fG")) (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] "TARGET_FP" --- 972,976 ---- [(set (match_operand:DF 0 "register_operand" "=f") (plus:DF (float_extend:DF ! (match_operand:SF 1 "reg_or_fp0_operand" "fG")) (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] "TARGET_FP" *************** *** 1076,1080 **** (define_insn "mulsf3" [(set (match_operand:SF 0 "register_operand" "=f") ! (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG") (match_operand:SF 2 "reg_or_fp0_operand" "fG")))] "TARGET_FP" --- 1076,1080 ---- (define_insn "mulsf3" [(set (match_operand:SF 0 "register_operand" "=f") ! (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG") (match_operand:SF 2 "reg_or_fp0_operand" "fG")))] "TARGET_FP" *************** *** 1084,1088 **** (define_insn "muldf3" [(set (match_operand:DF 0 "register_operand" "=f") ! (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG") (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] "TARGET_FP" --- 1084,1088 ---- (define_insn "muldf3" [(set (match_operand:DF 0 "register_operand" "=f") ! (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG") (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] "TARGET_FP" *************** *** 1102,1106 **** [(set (match_operand:DF 0 "register_operand" "=f") (mult:DF (float_extend:DF ! (match_operand:SF 1 "reg_or_fp0_operand" "fG")) (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))] --- 1102,1106 ---- [(set (match_operand:DF 0 "register_operand" "=f") (mult:DF (float_extend:DF ! (match_operand:SF 1 "reg_or_fp0_operand" "%fG")) (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))] *************** *** 1111,1115 **** (define_insn "subsf3" [(set (match_operand:SF 0 "register_operand" "=f") ! (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG") (match_operand:SF 2 "reg_or_fp0_operand" "fG")))] "TARGET_FP" --- 1111,1115 ---- (define_insn "subsf3" [(set (match_operand:SF 0 "register_operand" "=f") ! (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG") (match_operand:SF 2 "reg_or_fp0_operand" "fG")))] "TARGET_FP" *************** *** 1119,1123 **** (define_insn "subdf3" [(set (match_operand:DF 0 "register_operand" "=f") ! (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG") (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] "TARGET_FP" --- 1119,1123 ---- (define_insn "subdf3" [(set (match_operand:DF 0 "register_operand" "=f") ! (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG") (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] "TARGET_FP" *************** *** 1128,1132 **** [(set (match_operand:DF 0 "register_operand" "=f") (minus:DF (float_extend:DF ! (match_operand:SF 1 "reg_or_fp0_operand" "%fG")) (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] "TARGET_FP" --- 1128,1132 ---- [(set (match_operand:DF 0 "register_operand" "=f") (minus:DF (float_extend:DF ! (match_operand:SF 1 "reg_or_fp0_operand" "fG")) (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] "TARGET_FP" *************** *** 1136,1140 **** (define_insn "" [(set (match_operand:DF 0 "register_operand" "=f") ! (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG") (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))] --- 1136,1140 ---- (define_insn "" [(set (match_operand:DF 0 "register_operand" "=f") ! (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG") (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))] *************** *** 1146,1150 **** [(set (match_operand:DF 0 "register_operand" "=f") (minus:DF (float_extend:DF ! (match_operand:SF 1 "reg_or_fp0_operand" "%fG")) (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))] --- 1146,1150 ---- [(set (match_operand:DF 0 "register_operand" "=f") (minus:DF (float_extend:DF ! (match_operand:SF 1 "reg_or_fp0_operand" "fG")) (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))] Only in gcc-2.4.5/config/alpha: x-alpha diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/alpha/xm-alpha.h gcc-2.5.0/config/alpha/xm-alpha.h *** gcc-2.4.5/config/alpha/xm-alpha.h Mon Apr 26 19:07:38 1993 --- gcc-2.5.0/config/alpha/xm-alpha.h Thu Oct 7 17:24:19 1993 *************** *** 1,4 **** /* Configuration for GNU C-compiler for DEC Alpha. ! Copyright (C) 1990, 192, 1993 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@nyu.edu). --- 1,4 ---- /* Configuration for GNU C-compiler for DEC Alpha. ! Copyright (C) 1990, 1992, 1993 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@nyu.edu). *************** *** 42,49 **** #define FATAL_EXIT_CODE 3 ! /* If compiled with GNU C, use the built-in alloca. */ ! #ifdef __GNUC__ ! #define alloca __builtin_alloca ! #else #define USE_C_ALLOCA #endif --- 42,47 ---- #define FATAL_EXIT_CODE 3 ! /* If not compiled with GNU C, use the C alloca. */ ! #ifndef __GNUC__ #define USE_C_ALLOCA #endif *************** *** 60,68 **** differently. */ ! #ifdef __STDC__ ! extern void *malloc (), *realloc (), *sbrk (), *calloc (); ! #else ! extern char *malloc (), *realloc (), *sbrk (), *calloc (); ! #endif #include "string.h" --- 58,62 ---- differently. */ ! extern void *malloc (), *realloc (), *sbrk (), *calloc (), *alloca (); #include "string.h" diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/arm/arm.c gcc-2.5.0/config/arm/arm.c *** gcc-2.4.5/config/arm/arm.c Thu Oct 29 05:47:35 1992 --- gcc-2.5.0/config/arm/arm.c Tue Oct 19 17:33:50 1993 *************** *** 1,6 **** /* Output routines for GCC for ARM/RISCiX. ! Copyright (C) 1991 Free Software Foundation, Inc. Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) and Martin Simmons (@harleqn.co.uk). This file is part of GNU CC. --- 1,7 ---- /* Output routines for GCC for ARM/RISCiX. ! Copyright (C) 1991, 1993 Free Software Foundation, Inc. Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) and Martin Simmons (@harleqn.co.uk). + More major hacks by Richard Earnshaw (rwe11@cl.cam.ac.uk) This file is part of GNU CC. *************** *** 19,23 **** along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! #include #include "assert.h" --- 20,24 ---- along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! #include #include "assert.h" *************** *** 33,36 **** --- 34,38 ---- #include "insn-attr.h" #include "flags.h" + #include "reload.h" /* The maximum number of insns skipped which will be conditionalised if *************** *** 44,47 **** --- 46,59 ---- extern void arm_increase_location (); + /* Define the information needed to generate branch insns. This is + stored from the compare operation. */ + + rtx arm_compare_op0, arm_compare_op1; + int arm_compare_fp; + + /* What type of cpu are we compiling for? */ + + enum processor_type arm_cpu; + /* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference, we must report the mode of the memory reference from PRINT_OPERAND to *************** *** 55,58 **** --- 67,74 ---- int arm_text_location = 0; + /* Set to one if we think that lr is only saved because of subroutine calls, + but all of these can be `put after' return insns */ + int lr_save_eliminated; + /* A hash table is used to store text segment labels and their associated offset from the start of the text segment. */ *************** *** 68,71 **** --- 84,92 ---- static struct label_offset *offset_table[LABEL_HASH_SIZE]; + /* Set to 1 when a return insn is output, this means that the epilogue + is not needed. */ + + static int return_used_this_function; + /* For an explanation of these variables, see final_prescan_insn below. */ int arm_ccfsm_state; *************** *** 73,78 **** rtx arm_target_insn; int arm_target_label; - char *arm_condition_codes[]; /* Return the number of mov instructions needed to get the constant VALUE into a register. */ --- 94,119 ---- rtx arm_target_insn; int arm_target_label; + /* Return 1 if it is possible to return using a single instruction */ + + int + use_return_insn () + { + int regno; + + if (!reload_completed ||current_function_pretend_args_size + || current_function_anonymous_args + || (get_frame_size () && !(TARGET_APCS || frame_pointer_needed))) + return 0; + + /* Can't be done if any of the FPU regs are pushed, since this also + requires an insn */ + for (regno = 20; regno < 24; regno++) + if (regs_ever_live[regno]) + return 0; + + return 1; + } + /* Return the number of mov instructions needed to get the constant VALUE into a register. */ *************** *** 97,109 **** int const_ok_for_arm (i) ! int i; { ! unsigned int mask = ~0xFF; do { ! if ((i & mask) == 0) ! return(TRUE); ! mask = (mask << 2) | (mask >> (32 - 2)); } while (mask != ~0xFF); --- 138,152 ---- int const_ok_for_arm (i) ! HOST_WIDE_INT i; { ! unsigned HOST_WIDE_INT mask = ~0xFF; do { ! if ((i & mask & (unsigned HOST_WIDE_INT) 0xffffffff) == 0) ! return(TRUE); ! mask = ! (mask << 2) | ((mask & (unsigned HOST_WIDE_INT) 0xffffffff) ! >> (32 - 2)) | ~((unsigned HOST_WIDE_INT) 0xffffffff); } while (mask != ~0xFF); *************** *** 111,114 **** --- 154,188 ---- } /* const_ok_for_arm */ + /* This code has been fixed for cross compilation. */ + + static int fpa_consts_inited = 0; + + char *strings_fpa[8] = { + "0.0", + "1.0", + "2.0", + "3.0", + "4.0", + "5.0", + "0.5", + "10.0" + }; + + static REAL_VALUE_TYPE values_fpa[8]; + + static void + init_fpa_table () + { + int i; + REAL_VALUE_TYPE r; + + for (i = 0; i < 8; i++) + { + r = REAL_VALUE_ATOF (strings_fpa[i], DFmode); + values_fpa[i] = r; + } + fpa_consts_inited = 1; + } + /* Return TRUE if rtx X is a valid immediate FPU constant. */ *************** *** 117,132 **** rtx x; { ! double d; ! union real_extract u; ! u.i[0] = CONST_DOUBLE_LOW(x); ! u.i[1] = CONST_DOUBLE_HIGH(x); ! d = u.d; ! ! return (d == 0.0 || d == 1.0 || d == 2.0 || d == 3.0 ! || d == 4.0 || d == 5.0 || d == 0.5 || d == 10.0); } /* const_double_rtx_ok_for_fpu */ /* Predicates for `match_operand' and `match_operator'. */ /* Return TRUE for valid operands for the rhs of an ARM instruction. */ --- 191,271 ---- rtx x; { ! REAL_VALUE_TYPE r; ! int i; ! ! if (!fpa_consts_inited) ! init_fpa_table (); ! ! REAL_VALUE_FROM_CONST_DOUBLE (r, x); ! if (REAL_VALUE_MINUS_ZERO (r)) ! return 0; ! for (i = 0; i < 8; i++) ! if (REAL_VALUES_EQUAL (r, values_fpa[i])) ! return 1; ! return 0; } /* const_double_rtx_ok_for_fpu */ + + /* Return TRUE if rtx X is a valid immediate FPU constant. */ + + int + neg_const_double_rtx_ok_for_fpu (x) + rtx x; + { + REAL_VALUE_TYPE r; + int i; + + if (!fpa_consts_inited) + init_fpa_table (); + + REAL_VALUE_FROM_CONST_DOUBLE (r, x); + r = REAL_VALUE_NEGATE (r); + if (REAL_VALUE_MINUS_ZERO (r)) + return 0; + for (i = 0; i < 8; i++) + if (REAL_VALUES_EQUAL (r, values_fpa[i])) + return 1; + return 0; + } /* neg_const_double_rtx_ok_for_fpu */ /* Predicates for `match_operand' and `match_operator'. */ + /* s_register_operand is the same as register_operand, but it doesn't accept + (SUBREG (MEM)...). */ + + int + s_register_operand (op, mode) + register rtx op; + enum machine_mode mode; + { + if (GET_MODE (op) != mode && mode != VOIDmode) + return 0; + + if (GET_CODE (op) == SUBREG) + { + op = SUBREG_REG (op); + } + + /* We don't consider registers whose class is NO_REGS + to be a register operand. */ + return (GET_CODE (op) == REG + && (REGNO (op) >= FIRST_PSEUDO_REGISTER + || REGNO_REG_CLASS (REGNO (op)) != NO_REGS)); + } + + /* Return 1 if OP is an item in memory, given that we are in reload. */ + + int + reload_memory_operand (op, mode) + rtx op; + enum machine_mode mode; + { + int regno = true_regnum (op); + + return (! CONSTANT_P (op) + && (regno == -1 + || (GET_CODE (op) == REG + && REGNO (op) >= FIRST_PSEUDO_REGISTER))); + } + /* Return TRUE for valid operands for the rhs of an ARM instruction. */ *************** *** 136,143 **** enum machine_mode mode; { ! return (register_operand (op, mode) || (GET_CODE (op) == CONST_INT && const_ok_for_arm (INTVAL (op)))); } /* arm_rhs_operand */ /* Return TRUE for valid operands for the rhs of an FPU instruction. */ --- 275,320 ---- enum machine_mode mode; { ! return (s_register_operand (op, mode) || (GET_CODE (op) == CONST_INT && const_ok_for_arm (INTVAL (op)))); } /* arm_rhs_operand */ + /* Return TRUE for valid operands for the rhs of an ARM instruction, or a load. + */ + + int + arm_rhsm_operand (op, mode) + rtx op; + enum machine_mode mode; + { + return (s_register_operand (op, mode) + || (GET_CODE (op) == CONST_INT && const_ok_for_arm (INTVAL (op))) + || memory_operand (op, mode)); + } /* arm_rhs_operand */ + + /* Return TRUE for valid operands for the rhs of an ARM instruction, or if a + constant that is valid when negated. */ + + int + arm_add_operand (op, mode) + rtx op; + enum machine_mode mode; + { + return (s_register_operand (op, mode) + || (GET_CODE (op) == CONST_INT + && (const_ok_for_arm (INTVAL (op)) + || const_ok_for_arm (-INTVAL (op))))); + } /* arm_rhs_operand */ + + int + arm_not_operand (op, mode) + rtx op; + enum machine_mode mode; + { + return (s_register_operand (op, mode) + || (GET_CODE (op) == CONST_INT + && (const_ok_for_arm (INTVAL (op)) + || const_ok_for_arm (~INTVAL (op))))); + } /* arm_rhs_operand */ + /* Return TRUE for valid operands for the rhs of an FPU instruction. */ *************** *** 147,151 **** enum machine_mode mode; { ! if (register_operand (op, mode)) return(TRUE); else if (GET_CODE (op) == CONST_DOUBLE) --- 324,328 ---- enum machine_mode mode; { ! if (s_register_operand (op, mode)) return(TRUE); else if (GET_CODE (op) == CONST_DOUBLE) *************** *** 154,157 **** --- 331,347 ---- } /* fpu_rhs_operand */ + int + fpu_add_operand (op, mode) + rtx op; + enum machine_mode mode; + { + if (s_register_operand (op, mode)) + return(TRUE); + else if (GET_CODE (op) == CONST_DOUBLE) + return const_double_rtx_ok_for_fpu (op) + || neg_const_double_rtx_ok_for_fpu (op); + return (FALSE); + } + /* Return nonzero if OP is a constant power of two. */ *************** *** 170,175 **** /* Return TRUE for a valid operand of a DImode operation. ! Either: REG, CONST_DOUBLE or MEM(offsettable). ! Note that this disallows MEM(REG+REG). */ int --- 360,366 ---- /* Return TRUE for a valid operand of a DImode operation. ! Either: REG, CONST_DOUBLE or MEM(DImode_address). ! Note that this disallows MEM(REG+REG), but allows ! MEM(PRE/POST_INC/DEC(REG)). */ int *************** *** 178,182 **** enum machine_mode mode; { ! if (register_operand (op, mode)) return (TRUE); --- 369,373 ---- enum machine_mode mode; { ! if (s_register_operand (op, mode)) return (TRUE); *************** *** 187,192 **** return (TRUE); case MEM: ! return (memory_address_p (DImode, XEXP (op, 0)) ! && offsettable_address_p (FALSE, DImode, XEXP (op, 0))); default: return (FALSE); --- 378,382 ---- return (TRUE); case MEM: ! return (memory_address_p (DImode, XEXP (op, 0))); default: return (FALSE); *************** *** 201,208 **** enum machine_mode mode; { ! return (register_operand(op, mode) ! || (immediate_operand (op, mode) && abs (INTVAL (op)) < 4096)); } /* index_operand */ /* Return TRUE for arithmetic operators which can be combined with a multiply (shift). */ --- 391,413 ---- enum machine_mode mode; { ! return (s_register_operand(op, mode) ! || (immediate_operand (op, mode) ! && INTVAL (op) < 4096 && INTVAL (op) > -4096)); } /* index_operand */ + /* Return TRUE for valid shifts by a constant. This also accepts any + power of two on the (somewhat overly relaxed) assumption that the + shift operator in this case was a mult. */ + + int + const_shift_operand (op, mode) + rtx op; + enum machine_mode mode; + { + return (power_of_two_operand (op, mode) + || (immediate_operand (op, mode) + && (INTVAL (op) < 32 && INTVAL (op) > 0))); + } /* const_shift_operand */ + /* Return TRUE for arithmetic operators which can be combined with a multiply (shift). */ *************** *** 237,240 **** --- 442,447 ---- enum rtx_code code = GET_CODE (x); + if (code == MULT) + return power_of_two_operand (XEXP (x, 1)); return (code == ASHIFT || code == LSHIFT || code == ASHIFTRT || code == LSHIFTRT); *************** *** 241,247 **** --- 448,840 ---- } } /* shift_operator */ + + int equality_operator (x, mode) + rtx x; + enum machine_mode mode; + { + return (GET_CODE (x) == EQ || GET_CODE (x) == NE); + } + + /* Return TRUE for SMIN SMAX UMIN UMAX operators. */ + + int + minmax_operator (x, mode) + rtx x; + enum machine_mode mode; + { + enum rtx_code code = GET_CODE (x); + + if (GET_MODE (x) != mode) + return FALSE; + return code == SMIN || code == SMAX || code == UMIN || code == UMAX; + } /* minmax_operator */ + + /* return TRUE if x is EQ or NE */ + + /* Return TRUE if this is the condition code register, if we aren't given + a mode, accept any class CCmode register */ + + int + cc_register (x, mode) + rtx x; + enum machine_mode mode; + { + if (mode == VOIDmode) + { + mode = GET_MODE (x); + if (GET_MODE_CLASS (mode) != MODE_CC) + return FALSE; + } + if (mode == GET_MODE (x) && GET_CODE (x) == REG && REGNO (x) == 24) + return TRUE; + return FALSE; + } + + enum rtx_code + minmax_code (x) + rtx x; + { + enum rtx_code code = GET_CODE (x); + + if (code == SMAX) + return GE; + if (code == SMIN) + return LE; + if (code == UMIN) + return LEU; + if (code == UMAX) + return GEU; + abort (); + } + + /* Return 1 if memory locations are adjacent */ + + adjacent_mem_locations (a, b) + rtx a, b; + { + int val0 = 0, val1 = 0; + int reg0, reg1; + + if ((GET_CODE (XEXP (a, 0)) == REG + || (GET_CODE (XEXP (a, 0)) == PLUS + && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT)) + && (GET_CODE (XEXP (b, 0)) == REG + || (GET_CODE (XEXP (b, 0)) == PLUS + && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT))) + { + if (GET_CODE (XEXP (a, 0)) == PLUS) + { + reg0 = REGNO (XEXP (XEXP (a, 0), 0)); + val0 = INTVAL (XEXP (XEXP (a, 0), 1)); + } + else + reg0 = REGNO (XEXP (a, 0)); + if (GET_CODE (XEXP (b, 0)) == PLUS) + { + reg1 = REGNO (XEXP (XEXP (b, 0), 0)); + val1 = INTVAL (XEXP (XEXP (b, 0), 1)); + } + else + reg1 = REGNO (XEXP (b, 0)); + return (reg0 == reg1) && ((val1 - val0) == 4 || (val0 - val1) == 4); + } + return 0; + } + + /* Return 1 if OP is a load multiple operation. It is known to be + parallel and the first section will be tested. */ + + load_multiple_operation (op, mode) + rtx op; + enum machine_mode mode; + { + int count = XVECLEN (op, 0); + int dest_regno; + rtx src_addr; + int i = 1, base = 0; + rtx elt; + + if (count <= 1 + || GET_CODE (XVECEXP (op, 0, 0)) != SET) + return 0; + + /* Check to see if this might be a write-back */ + if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS) + { + i++; + base = 1; + + /* Now check it more carefully */ + if (GET_CODE (SET_DEST (elt)) != REG + || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG + || REGNO (XEXP (SET_SRC (elt), 0)) != REGNO (SET_DEST (elt)) + || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT + || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 2) * 4 + || GET_CODE (XVECEXP (op, 0, count - 1)) != CLOBBER + || GET_CODE (XEXP (XVECEXP (op, 0, count - 1), 0)) != REG + || REGNO (XEXP (XVECEXP (op, 0, count - 1), 0)) + != REGNO (SET_DEST (elt))) + return 0; + count--; + } + + /* Perform a quick check so we don't blow up below. */ + if (count <= i + || GET_CODE (XVECEXP (op, 0, i - 1)) != SET + || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != REG + || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != MEM) + return 0; + + dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, i - 1))); + src_addr = XEXP (SET_SRC (XVECEXP (op, 0, i - 1)), 0); + + for (; i < count; i++) + { + rtx elt = XVECEXP (op, 0, i); + + if (GET_CODE (elt) != SET + || GET_CODE (SET_DEST (elt)) != REG + || GET_MODE (SET_DEST (elt)) != SImode + || REGNO (SET_DEST (elt)) != dest_regno + i - base + || GET_CODE (SET_SRC (elt)) != MEM + || GET_MODE (SET_SRC (elt)) != SImode + || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS + || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr) + || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT + || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != (i - base) * 4) + return 0; + } + + return 1; + } + + /* Return 1 if OP is a store multiple operation. It is known to be + parallel and the first section will be tested. */ + + store_multiple_operation (op, mode) + rtx op; + enum machine_mode mode; + { + int count = XVECLEN (op, 0); + int src_regno; + rtx dest_addr; + int i = 1, base = 0; + rtx elt; + + if (count <= 1 + || GET_CODE (XVECEXP (op, 0, 0)) != SET) + return 0; + + /* Check to see if this might be a write-back */ + if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS) + { + i++; + base = 1; + + /* Now check it more carefully */ + if (GET_CODE (SET_DEST (elt)) != REG + || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG + || REGNO (XEXP (SET_SRC (elt), 0)) != REGNO (SET_DEST (elt)) + || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT + || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 2) * 4 + || GET_CODE (XVECEXP (op, 0, count - 1)) != CLOBBER + || GET_CODE (XEXP (XVECEXP (op, 0, count - 1), 0)) != REG + || REGNO (XEXP (XVECEXP (op, 0, count - 1), 0)) + != REGNO (SET_DEST (elt))) + return 0; + count--; + } + + /* Perform a quick check so we don't blow up below. */ + if (count <= i + || GET_CODE (XVECEXP (op, 0, i - 1)) != SET + || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != MEM + || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != REG) + return 0; + + src_regno = REGNO (SET_SRC (XVECEXP (op, 0, i - 1))); + dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, i - 1)), 0); + + for (; i < count; i++) + { + elt = XVECEXP (op, 0, i); + + if (GET_CODE (elt) != SET + || GET_CODE (SET_SRC (elt)) != REG + || GET_MODE (SET_SRC (elt)) != SImode + || REGNO (SET_SRC (elt)) != src_regno + i - base + || GET_CODE (SET_DEST (elt)) != MEM + || GET_MODE (SET_DEST (elt)) != SImode + || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS + || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr) + || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT + || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != (i - base) * 4) + return 0; + } + + return 1; + } + + /* Routines for use in generating RTL */ + + rtx arm_gen_load_multiple (base_regno, count, from, up, write_back) + int base_regno; + int count; + rtx from; + int up; + int write_back; + { + int i = 0, j; + rtx result; + int sign = up ? 1 : -1; + + result = gen_rtx (PARALLEL, VOIDmode, + rtvec_alloc (count + (write_back ? 2 : 0))); + if (write_back) + { + XVECEXP (result, 0, 0) + = gen_rtx (SET, GET_MODE (from), from, + plus_constant (from, count * 4 * sign)); + i = 1; + count++; + } + for (j = 0; i < count; i++, j++) + { + XVECEXP (result, 0, i) + = gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, base_regno + j), + gen_rtx (MEM, SImode, + plus_constant (from, j * 4 * sign))); + } + if (write_back) + XVECEXP (result, 0, i) = gen_rtx (CLOBBER, SImode, from); + + return result; + } + + rtx arm_gen_store_multiple (base_regno, count, to, up, write_back) + int base_regno; + int count; + rtx to; + int up; + int write_back; + { + int i = 0, j; + rtx result; + int sign = up ? 1 : -1; + + result = gen_rtx (PARALLEL, VOIDmode, + rtvec_alloc (count + (write_back ? 2 : 0))); + if (write_back) + { + XVECEXP (result, 0, 0) + = gen_rtx (SET, GET_MODE (to), to, + plus_constant (to, count * 4 * sign)); + i = 1; + count++; + } + for (j = 0; i < count; i++, j++) + { + XVECEXP (result, 0, i) + = gen_rtx (SET, VOIDmode, + gen_rtx (MEM, SImode, plus_constant (to, j * 4 * sign)), + gen_rtx (REG, SImode, base_regno + j)); + } + if (write_back) + XVECEXP (result, 0, i) = gen_rtx (CLOBBER, SImode, to); + + return result; + } + + /* X and Y are two things to compare using CODE. Emit the compare insn and + return the rtx for register 0 in the proper mode. FP means this is a + floating point compare: I don't think that it is needed on the arm. */ + + rtx + gen_compare_reg (code, x, y, fp) + enum rtx_code code; + rtx x, y; + { + enum machine_mode mode = SELECT_CC_MODE (code, x, y); + rtx cc_reg = gen_rtx (REG, mode, 24); + + emit_insn (gen_rtx (SET, VOIDmode, cc_reg, + gen_rtx (COMPARE, mode, x, y))); + + return cc_reg; + } + + arm_reload_out_hi (operands) + rtx operands[]; + { + rtx base = find_replacement (&XEXP (operands[0], 0)); + + emit_insn (gen_rtx (SET, VOIDmode, + gen_rtx (MEM, QImode, base), + gen_rtx (SUBREG, QImode, operands[1], 0))); + emit_insn (gen_rtx (SET, VOIDmode, operands[2], + gen_rtx (LSHIFTRT, SImode, + gen_rtx (SUBREG, SImode, operands[1], 0), + GEN_INT (8)))); + emit_insn (gen_rtx (SET, VOIDmode, + gen_rtx (MEM, QImode, + plus_constant (base, 1)), + gen_rtx (SUBREG, QImode, operands[2], 0))); + } + + /* Check to see if a branch is forwards or backwards. Return TRUE if it + is backwards. */ + + int + arm_backwards_branch (from, to) + int from, to; + { + return (insn_addresses[to] < insn_addresses[from]); + } + + /* Check to see if a branch is within the distance that can be done using + an arithmetic expression. */ + int + short_branch (from, to) + int from, to; + { + int delta = insn_addresses[from] + 2 - insn_addresses[to]; + + return abs (delta) < 245; /* A small margin for safety */ + } + + /* Check to see that the insn isn't the target of the conditionalizing + code */ + int + arm_insn_not_targeted (insn) + rtx insn; + { + return insn != arm_target_insn; + } + /* Routines to output assembly language. */ + /* fp_immediate_constant + if the rtx is the correct value then return the string of the number. + In this way we can ensure that valid double constants are generated even + when cross compiling. */ + char * + fp_immediate_constant (x) + rtx (x); + { + REAL_VALUE_TYPE r; + int i; + + if (!fpa_consts_inited) + init_fpa_table (); + + REAL_VALUE_FROM_CONST_DOUBLE (r, x); + for (i = 0; i < 8; i++) + if (REAL_VALUES_EQUAL (r, values_fpa[i])) + return strings_fpa[i]; + abort (); + } + + /* Output the operands of a LDM/STM instruction to STREAM. MASK is the ARM register set mask of which only bits 0-15 are important. *************** *** 276,281 **** rtx operands[]; { - operands[0] = XEXP (operands[0], 0); - /* Handle calls to lr using ip (which may be clobbered in subr anyway). */ --- 869,872 ---- *************** *** 290,293 **** --- 881,1012 ---- } /* output_call */ + static int + eliminate_lr2ip (x) + rtx *x; + { + int something_changed = 0; + rtx x0 = *x; + int code = GET_CODE (x0); + register int i, j; + register char *fmt; + + switch (code) + { + case REG: + if (REGNO (x0) == 14) + { + *x = gen_rtx (REG, SImode, 12); + return 1; + } + return 0; + default: + /* Scan through the sub-elements and change any references there */ + fmt = GET_RTX_FORMAT (code); + for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) + if (fmt[i] == 'e') + something_changed |= eliminate_lr2ip (&XEXP (x0, i)); + else if (fmt[i] == 'E') + for (j = 0; j < XVECLEN (x0, i); j++) + something_changed |= eliminate_lr2ip (&XVECEXP (x0, i, j)); + return something_changed; + } + } + + /* Output a 'call' insn that is a reference in memory. */ + + char * + output_call_mem (operands) + rtx operands[]; + { + operands[0] = copy_rtx (operands[0]); /* Be ultra careful */ + /* Handle calls using lr by using ip (which may be clobbered in subr anyway). + */ + if (eliminate_lr2ip (&operands[0])) + arm_output_asm_insn ("mov\tip, lr", operands); + arm_output_asm_insn ("mov\tlr, pc", operands); + arm_output_asm_insn ("ldr\tpc, %0", operands); + return (""); + } /* output_call */ + + + /* Output a move from arm registers to an fpu registers. + OPERANDS[0] is an fpu register. + OPERANDS[1] is the first registers of an arm register pair. */ + + char * + output_mov_long_double_fpu_from_arm (operands) + rtx operands[]; + { + int arm_reg0 = REGNO (operands[1]); + rtx ops[3]; + + if (arm_reg0 == 12) + abort(); + ops[0] = gen_rtx (REG, SImode, arm_reg0); + ops[1] = gen_rtx (REG, SImode, 1 + arm_reg0); + ops[2] = gen_rtx (REG, SImode, 2 + arm_reg0); + + arm_output_asm_insn ("stmfd\tsp!, {%0, %1, %2}", ops); + arm_output_asm_insn ("ldfe\t%0, [sp], #12", operands); + return (""); + } /* output_mov_long_double_fpu_from_arm */ + + /* Output a move from an fpu register to arm registers. + OPERANDS[0] is the first registers of an arm register pair. + OPERANDS[1] is an fpu register. */ + + char * + output_mov_long_double_arm_from_fpu (operands) + rtx operands[]; + { + int arm_reg0 = REGNO (operands[0]); + rtx ops[3]; + + if (arm_reg0 == 12) + abort(); + ops[0] = gen_rtx (REG, SImode, arm_reg0); + ops[1] = gen_rtx (REG, SImode, 1 + arm_reg0); + ops[2] = gen_rtx (REG, SImode, 2 + arm_reg0); + + arm_output_asm_insn ("stfe\t%1, [sp, #-12]!", operands); + arm_output_asm_insn ("ldmfd\tsp!, {%0, %1, %2}", ops); + return(""); + } /* output_mov_long_double_arm_from_fpu */ + + /* Output a move from arm registers to arm registers of a long double + OPERANDS[0] is the destination. + OPERANDS[1] is the source. */ + char * + output_mov_long_double_arm_from_arm (operands) + rtx operands[]; + { + /* We have to be careful here because the two might overlap */ + int dest_start = REGNO (operands[0]); + int src_start = REGNO (operands[1]); + rtx ops[2]; + int i; + + if (dest_start < src_start) + { + for (i = 0; i < 3; i++) + { + ops[0] = gen_rtx (REG, SImode, dest_start + i); + ops[1] = gen_rtx (REG, SImode, src_start + i); + arm_output_asm_insn ("mov\t%0, %1", ops); + } + } + else + { + for (i = 2; i >= 0; i--) + { + ops[0] = gen_rtx (REG, SImode, dest_start + i); + ops[1] = gen_rtx (REG, SImode, src_start + i); + arm_output_asm_insn ("mov\t%0, %1", ops); + } + } + return ""; + } + + /* Output a move from arm registers to an fpu registers. OPERANDS[0] is an fpu register. *************** *** 372,377 **** operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[1])); ! arm_output_asm_insn ("mov\t%0, %1", operands); ! arm_output_asm_insn ("mov\t%0, %1", otherops); } else if (code1 == CONST_INT) --- 1091,1096 ---- operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[1])); ! output_mov_immediate (operands, FALSE, ""); ! output_mov_immediate (otherops, FALSE, ""); } else if (code1 == CONST_INT) *************** *** 378,388 **** { otherops[1] = const0_rtx; ! arm_output_asm_insn ("mov\t%0, %1", operands); ! arm_output_asm_insn ("mov\t%0, %1", otherops); } else if (code1 == MEM) { ! if (GET_CODE (XEXP (operands[1], 0)) == REG) { /* Handle the simple case where address is [r, #0] more efficient. */ --- 1097,1114 ---- { otherops[1] = const0_rtx; ! /* sign extend the intval into the high-order word */ ! /* Note: output_mov_immediate may clobber operands[1], so we ! put this out first */ ! if (INTVAL (operands[1]) < 0) ! arm_output_asm_insn ("mvn\t%0, %1", otherops); ! else ! arm_output_asm_insn ("mov\t%0, %1", otherops); ! output_mov_immediate (operands, FALSE, ""); } else if (code1 == MEM) { ! switch (GET_CODE (XEXP (operands[1], 0))) { + case REG: /* Handle the simple case where address is [r, #0] more efficient. */ *************** *** 389,395 **** operands[1] = XEXP (operands[1], 0); arm_output_asm_insn ("ldmia\t%1, %M0", operands); ! } ! else ! { otherops[1] = adj_offsettable_operand (operands[1], 4); /* Take care of overlapping base/data reg. */ --- 1115,1139 ---- operands[1] = XEXP (operands[1], 0); arm_output_asm_insn ("ldmia\t%1, %M0", operands); ! break; ! case PRE_INC: ! operands[1] = XEXP (XEXP (operands[1], 0), 0); ! arm_output_asm_insn ("add\t%1, %1, #8", operands); ! arm_output_asm_insn ("ldmia\t%1, %M0", operands); ! break; ! case PRE_DEC: ! operands[1] = XEXP (XEXP (operands[1], 0), 0); ! arm_output_asm_insn ("sub\t%1, %1, #8", operands); ! arm_output_asm_insn ("ldmia\t%1, %M0", operands); ! break; ! case POST_INC: ! operands[1] = XEXP (XEXP (operands[1], 0), 0); ! arm_output_asm_insn ("ldmia\t%1!, %M0", operands); ! break; ! case POST_DEC: ! operands[1] = XEXP (XEXP (operands[1], 0), 0); ! arm_output_asm_insn ("ldmia\t%1, %M0", operands); ! arm_output_asm_insn ("sub\t%1, %1, #8", operands); ! break; ! default: otherops[1] = adj_offsettable_operand (operands[1], 4); /* Take care of overlapping base/data reg. */ *************** *** 412,423 **** if (REGNO (operands[1]) == 12) abort(); ! ! if (GET_CODE (XEXP (operands[0], 0)) == REG) ! { operands[0] = XEXP (operands[0], 0); arm_output_asm_insn ("stmia\t%0, %M1", operands); ! } ! else ! { otherops[0] = adj_offsettable_operand (operands[0], 4); otherops[1] = gen_rtx (REG, SImode, 1 + REGNO (operands[1])); --- 1156,1185 ---- if (REGNO (operands[1]) == 12) abort(); ! switch (GET_CODE (XEXP (operands[0], 0))) ! { ! case REG: operands[0] = XEXP (operands[0], 0); arm_output_asm_insn ("stmia\t%0, %M1", operands); ! break; ! case PRE_INC: ! operands[0] = XEXP (XEXP (operands[0], 0), 0); ! arm_output_asm_insn ("add\t%0, %0, #8", operands); ! arm_output_asm_insn ("stmia\t%0, %M1", operands); ! break; ! case PRE_DEC: ! operands[0] = XEXP (XEXP (operands[0], 0), 0); ! arm_output_asm_insn ("sub\t%0, %0, #8", operands); ! arm_output_asm_insn ("stmia\t%0, %M1", operands); ! break; ! case POST_INC: ! operands[0] = XEXP (XEXP (operands[0], 0), 0); ! arm_output_asm_insn ("stmia\t%0!, %M1", operands); ! break; ! case POST_DEC: ! operands[0] = XEXP (XEXP (operands[0], 0), 0); ! arm_output_asm_insn ("stmia\t%0, %M1", operands); ! arm_output_asm_insn ("sub\t%0, %0, #8", operands); ! break; ! default: otherops[0] = adj_offsettable_operand (operands[0], 4); otherops[1] = gen_rtx (REG, SImode, 1 + REGNO (operands[1])); *************** *** 594,597 **** --- 1356,1363 ---- max_shift = 32; break; + case MULT: + *shift_ptr = gen_rtx (CONST_INT, VOIDmode, + int_log2 (INTVAL (*shift_ptr))); + return ("asl"); default: abort(); *************** *** 720,723 **** --- 1486,1504 ---- } /* output_shifted_move */ + char * + output_shift_compare (operands, neg) + rtx *operands; + int neg; + { + char buf[80]; + + if (neg) + sprintf (buf, "cmn\t%%1, %%3, %s %%4", shift_instr (GET_CODE (operands[2]), + &operands[4])); + else + sprintf (buf, "cmp\t%%1, %%3, %s %%4", shift_instr (GET_CODE (operands[2]), + &operands[4])); + return arm_output_asm_insn (buf, operands); + } /* output_shift_compare */ /* Output a .ascii pseudo-op, keeping track of lengths. This is because *************** *** 769,772 **** --- 1550,1737 ---- } /* output_ascii_pseudo_op */ + + /* Try to determine whether a pattern really clobbers the link register. + This information is useful when peepholing, so that lr need not be pushed + if we combine a call followed by a return */ + + static int + pattern_really_clobbers_lr (x) + rtx x; + { + int i; + + switch (GET_CODE (x)) + { + case SET: + switch (GET_CODE (SET_DEST (x))) + { + case REG: + return REGNO (SET_DEST (x)) == 14; + case SUBREG: + if (GET_CODE (XEXP (SET_DEST (x), 0)) == REG) + return REGNO (XEXP (SET_DEST (x), 0)) == 14; + abort (); + default: + return 0; + } + case PARALLEL: + for (i = 0; i < XVECLEN (x, 0); i++) + if (pattern_really_clobbers_lr (XVECEXP (x, 0, i))) + return 1; + return 0; + case CLOBBER: + switch (GET_CODE (XEXP (x, 0))) + { + case REG: + return REGNO (XEXP (x, 0)) == 14; + case SUBREG: + if (GET_CODE (XEXP (XEXP (x, 0), 0)) == REG) + return REGNO (XEXP (XEXP (x, 0), 0)) == 14; + abort (); + default: + return 0; + } + case UNSPEC: + return 1; + default: + return 0; + } + } + + static int + function_really_clobbers_lr (first) + rtx first; + { + rtx insn, next; + + for (insn = first; insn; insn = next_nonnote_insn (insn)) + { + switch (GET_CODE (insn)) + { + case BARRIER: + case NOTE: + case CODE_LABEL: + case JUMP_INSN: /* Jump insns only change the PC (and conds) */ + case INLINE_HEADER: + break; + case INSN: + if (pattern_really_clobbers_lr (PATTERN (insn))) + return 1; + break; + case CALL_INSN: + /* Don't yet know how to handle those calls that are not to a + SYMBOL_REF */ + if (GET_CODE (PATTERN (insn)) != PARALLEL) + abort (); + switch (GET_CODE (XVECEXP (PATTERN (insn), 0, 0))) + { + case CALL: + if (GET_CODE (XEXP (XEXP (XVECEXP (PATTERN (insn), 0, 0), 0), 0)) + != SYMBOL_REF) + return 1; + break; + case SET: + if (GET_CODE (XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn), + 0, 0)), 0), 0)) + != SYMBOL_REF) + return 1; + break; + default: /* Don't recognize it, be safe */ + return 1; + } + /* A call can be made (by peepholing) not to clobber lr iff it is + followed by a return. There may, however, be a use insn iff + we are returning the result of the call. + If we run off the end of the insn chain, then that means the + call was at the end of the function. Unfortunately we don't + have a return insn for the peephole to recognize, so we + must reject this. (Can this be fixed by adding our own insn?) */ + if ((next = next_nonnote_insn (insn)) == NULL) + return 1; + if (GET_CODE (next) == INSN && GET_CODE (PATTERN (next)) == USE + && (GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET) + && (REGNO (SET_DEST (XVECEXP (PATTERN (insn), 0, 0))) + == REGNO (XEXP (PATTERN (next), 0)))) + if ((next = next_nonnote_insn (next)) == NULL) + return 1; + if (GET_CODE (next) == JUMP_INSN + && GET_CODE (PATTERN (next)) == RETURN) + break; + return 1; + default: + abort (); + } + } + /* We have reached the end of the chain so lr was _not_ clobbered */ + return 0; + } + + char * + output_return_instruction (operand, really_return) + rtx operand; + int really_return; + { + char instr[100]; + int reg, live_regs = 0; + + if (current_function_calls_alloca && !really_return) + abort(); + + for (reg = 4; reg < 10; reg++) + if (regs_ever_live[reg]) + live_regs++; + + if (live_regs || (regs_ever_live[14] && !lr_save_eliminated)) + live_regs++; + + if (frame_pointer_needed) + live_regs += 4; + + if (live_regs) + { + if (lr_save_eliminated || !regs_ever_live[14]) + live_regs++; + if (frame_pointer_needed) + strcpy (instr, "ldm%d0ea\tfp, {"); + else + strcpy (instr, "ldm%d0fd\tsp!, {"); + for (reg = 4; reg < 10; reg++) + if (regs_ever_live[reg]) + { + strcat (instr, reg_names[reg]); + if (--live_regs) + strcat (instr, ", "); + } + if (frame_pointer_needed) + { + strcat (instr, reg_names[11]); + strcat (instr, ", "); + strcat (instr, reg_names[13]); + strcat (instr, ", "); + strcat (instr, really_return ? reg_names[15] : reg_names[14]); + } + else + strcat (instr, really_return ? reg_names[15] : reg_names[14]); + strcat (instr, (TARGET_6 || !really_return) ? "}" : "}^"); + arm_output_asm_insn (instr, &operand); + } + else if (really_return) + { + strcpy (instr, TARGET_6 ? "mov%d0\tpc, lr" : "mov%d0s\tpc, lr"); + arm_output_asm_insn (instr, &operand); + } + return_used_this_function = 1; + return ""; + } + + /* The amount of stack adjustment that happens here, in output_return and in + output_epilogue must be exactly the same as was calculated during reload, + or things will point to the wrong place. The only time we can safely + ignore this constraint is when a function has no arguments on the stack, + no stack frame requirement and no live registers execpt for `lr'. If we + can guarantee that by making all function calls into tail calls and that + lr is not clobbered in any other way, then there is no need to push lr + onto the stack. */ + void output_prologue (f, frame_size) *************** *** 774,784 **** int frame_size; { - int reg, live_regs_mask = 0, code_size = 0; rtx operands[3]; - /* Nonzero if the `fp' (argument pointer) register is needed. */ - int fp_needed = 0; - /* Nonzero if we must stuff some register arguments onto the stack as if they were passed there. */ --- 1739,1745 ---- *************** *** 785,797 **** int store_arg_regs = 0; fprintf (f, "\t@ args = %d, pretend = %d, frame = %d\n", ! current_function_args_size, current_function_pretend_args_size, frame_size); ! fprintf (f, "\t@ frame_pointer_needed = %d, current_function_anonymous_args = %d\n", frame_pointer_needed, current_function_anonymous_args); - if (current_function_pretend_args_size || current_function_args_size - || frame_pointer_needed || current_function_anonymous_args || TARGET_APCS) - fp_needed = 1; - if (current_function_anonymous_args && current_function_pretend_args_size) store_arg_regs = 1; --- 1746,1761 ---- int store_arg_regs = 0; + if (arm_ccfsm_state || arm_target_insn) + abort (); /* Sanity check */ + + return_used_this_function = 0; + lr_save_eliminated = 0; + fprintf (f, "\t@ args = %d, pretend = %d, frame = %d\n", ! current_function_args_size, current_function_pretend_args_size, ! frame_size); ! fprintf (f, "\t@ frame_needed = %d, current_function_anonymous_args = %d\n", frame_pointer_needed, current_function_anonymous_args); if (current_function_anonymous_args && current_function_pretend_args_size) store_arg_regs = 1; *************** *** 801,811 **** live_regs_mask |= (1 << reg); ! if (fp_needed) { live_regs_mask |= 0xD800; - /* The following statement is probably redundant now - because the frame pointer is recorded in regs_ever_live. */ - if (frame_pointer_needed) - live_regs_mask |= (1 << FRAME_POINTER_REGNUM); fputs ("\tmov\tip, sp\n", f); code_size += 4; --- 1765,1771 ---- live_regs_mask |= (1 << reg); ! if (frame_pointer_needed) { live_regs_mask |= 0xD800; fputs ("\tmov\tip, sp\n", f); code_size += 4; *************** *** 812,816 **** } else if (regs_ever_live[14]) ! live_regs_mask |= 0x4000; /* If CURRENT_FUNCTION_PRETEND_ARGS_SIZE, adjust the stack pointer to make --- 1772,1785 ---- } else if (regs_ever_live[14]) ! { ! if (! current_function_args_size ! && !function_really_clobbers_lr (get_insns ())) ! { ! fprintf (f,"\t@ I don't think this function clobbers lr\n"); ! lr_save_eliminated = 1; ! } ! else ! live_regs_mask |= 0x4000; ! } /* If CURRENT_FUNCTION_PRETEND_ARGS_SIZE, adjust the stack pointer to make *************** *** 828,831 **** --- 1797,1801 ---- mask |= (1 << reg); print_multi_reg (f, "stmfd\tsp!", mask, FALSE); + code_size += 4; } else *************** *** 840,843 **** --- 1810,1820 ---- if (live_regs_mask) { + /* if a di mode load/store multiple is used, and the base register + is r3, then r4 can become an ever live register without lr + doing so, in this case we need to push lr as well, or we + will fail to get a proper return. */ + + live_regs_mask |= 0x4000; + lr_save_eliminated = 0; print_multi_reg (f, "stmfd\tsp!", live_regs_mask, FALSE); code_size += 4; *************** *** 851,859 **** } ! if (fp_needed) { /* Make `fp' point to saved value of `pc'. */ ! operands[0] = arg_pointer_rtx; operands[1] = gen_rtx (REG, SImode, 12); operands[2] = gen_rtx (CONST_INT, VOIDmode, --- 1828,1836 ---- } ! if (frame_pointer_needed) { /* Make `fp' point to saved value of `pc'. */ ! operands[0] = gen_rtx (REG, SImode, HARD_FRAME_POINTER_REGNUM); operands[1] = gen_rtx (REG, SImode, 12); operands[2] = gen_rtx (CONST_INT, VOIDmode, *************** *** 862,871 **** } - if (frame_pointer_needed) - { - fprintf (f, "\tmov\trfp, sp\n"); - code_size += 4; - } - if (frame_size) { --- 1839,1842 ---- *************** *** 884,918 **** int frame_size; { ! int reg, live_regs_mask = 0, code_size = 0, fp_needed = 0; rtx operands[3]; ! if (current_function_pretend_args_size || current_function_args_size ! || frame_pointer_needed || current_function_anonymous_args || TARGET_APCS) ! fp_needed = 1; ! ! for (reg = 4; reg < 10; reg++) ! if (regs_ever_live[reg]) ! live_regs_mask |= (1 << reg); ! ! if (fp_needed) { ! live_regs_mask |= 0xA800; ! if (frame_pointer_needed) ! live_regs_mask |= (1 << FRAME_POINTER_REGNUM); } - else if (regs_ever_live[14]) - live_regs_mask |= 0x4000; ! for (reg = 20; reg < 24; reg++) if (regs_ever_live[reg]) { ! fprintf (f, "\tldfe\t%s, [%s], #12\n", reg_names[reg], ! frame_pointer_needed ? "rfp" : "sp"); ! code_size += 4; } ! if (fp_needed) { ! print_multi_reg (f, "ldmea\tfp", live_regs_mask, TRUE); code_size += 4; } --- 1855,1894 ---- int frame_size; { ! int reg, live_regs_mask = 0, code_size = 0; ! /* If we need this then it will always be at lesat this much */ ! int floats_offset = 24; rtx operands[3]; ! if (use_return_insn() && return_used_this_function) { ! if (frame_size && !(frame_pointer_needed || TARGET_APCS)) ! { ! abort (); ! } ! return; } ! for (reg = 4; reg <= 10; reg++) if (regs_ever_live[reg]) { ! live_regs_mask |= (1 << reg); ! floats_offset += 4; } ! ! if (frame_pointer_needed) { ! for (reg = 23; reg >= 20; reg--) ! if (regs_ever_live[reg]) ! { ! fprintf (f, "\tldfe\t%s, [fp, #-%d]\n", reg_names[reg], ! floats_offset); ! floats_offset += 12; ! code_size += 4; ! } ! ! live_regs_mask |= 0xA800; ! print_multi_reg (f, "ldmea\tfp", live_regs_mask, ! TARGET_6 ? FALSE : TRUE); code_size += 4; } *************** *** 927,934 **** } if (current_function_pretend_args_size == 0 && regs_ever_live[14]) { ! print_multi_reg (f, "ldmfd\tsp!", ! (live_regs_mask & ~0x4000) | 0x8000, TRUE); code_size += 4; } --- 1903,1916 ---- } + for (reg = 20; reg < 24; reg++) + if (regs_ever_live[reg]) + { + fprintf (f, "\tldfe\t%s, [sp], #12\n", reg_names[reg]); + code_size += 4; + } if (current_function_pretend_args_size == 0 && regs_ever_live[14]) { ! print_multi_reg (f, "ldmfd\tsp!", live_regs_mask | 0x8000, ! TARGET_6 ? FALSE : TRUE); code_size += 4; } *************** *** 935,940 **** else { ! if (live_regs_mask) { print_multi_reg (f, "ldmfd\tsp!", live_regs_mask, FALSE); code_size += 4; --- 1917,1923 ---- else { ! if (live_regs_mask || regs_ever_live[14]) { + live_regs_mask |= 0x4000; print_multi_reg (f, "ldmfd\tsp!", live_regs_mask, FALSE); code_size += 4; *************** *** 947,951 **** output_add_immediate (operands); } ! fputs ("\tmovs\tpc, lr\n", f); code_size += 4; } --- 1930,1934 ---- output_add_immediate (operands); } ! fputs (TARGET_6 ? "\tmov\tpc, lr\n" : "\tmovs\tpc, lr\n", f); code_size += 4; } *************** *** 1087,1090 **** --- 2070,2139 ---- } /* arm_output_llc */ + /* output_load_symbol () + load a symbol that is known to be in the text segment into a register */ + + char * + output_load_symbol (operands) + rtx *operands; + { + char *s, *name = XSTR (operands[1], 0); + struct label_offset *he; + int hash = 0; + int offset; + + if (*name != '*') + abort (); + + for (s = &name[1]; *s; s++) + hash += *s; + hash = hash % LABEL_HASH_SIZE; + he = offset_table[hash]; + while (he && strcmp (he->name, &name[1])) + he = he->cdr; + + if (!he) + abort (); + + offset = (arm_text_location + 8 - he->offset); + if (offset < 0) + abort (); + + /* If the symbol is word aligned then we might be able to reduce the + number of loads */ + if ((offset & 3) == 0) + { + arm_output_asm_insn ("sub\t%0, pc, #(8 + . -%a1) & 1023", operands); + if (offset > 0x3ff) + { + arm_output_asm_insn ("sub\t%0, %0, #(4 + . -%a1) & 261120", + operands); + if (offset > 0x3ffff) + { + arm_output_asm_insn ("sub\t%0, %0, #(. -%a1) & 66846720", + operands); + if (offset > 0x3ffffff) + arm_output_asm_insn ("sub\t%0, %0, #(. - 4 -%a1) & -67108864", + operands); + } + } + } + else + { + arm_output_asm_insn ("sub\t%0, pc, #(8 + . -%a1) & 255", operands); + if (offset > 0x0ff) + { + arm_output_asm_insn ("sub\t%0, %0, #(4 + . -%a1) & 65280", operands); + if (offset > 0x0ffff) + { + arm_output_asm_insn ("sub\t%0, %0, #(. -%a1) & 16711680", + operands); + if (offset > 0x0ffffff) + arm_output_asm_insn ("sub\t%0, %0, #(. - 4 -%a1) & -16777216", + operands); + } + } + } + return ""; + } /* Output code resembling an .lcomm directive. /bin/as doesn't have this *************** *** 1132,1135 **** --- 2181,2188 ---- (the target insn is arm_target_insn). + If the jump clobbers the conditions then we use states 2 and 4. + + A similar thing can be done with conditional return insns. + XXX In case the `target' is an unconditional branch, this conditionalising of the instructions always reduces code size, but not always execution *************** *** 1186,1189 **** --- 2239,2251 ---- int reverse = 0; + /* JUMP_CLOBBERS will be one implies that the conditions if a branch is + taken are clobbered, even if the rtl suggests otherwise. It also + means that we have to grub around within the jump expression to find + out what the conditions are when the jump isn't taken. */ + int jump_clobbers = 0; + + /* If we start with a return insn, we only succeed if we find another one. */ + int seeking_return = 0; + /* START_INSN will hold the insn from where we start looking. This is the first insn after the following code_label if REVERSE is true. */ *************** *** 1195,1199 **** --- 2257,2264 ---- { if (insn == arm_target_insn) + { + arm_target_insn = NULL; arm_ccfsm_state = 0; + } return; } *************** *** 1220,1223 **** --- 2285,2303 ---- return; } + else if (GET_CODE (body) == RETURN) + { + start_insn = next_nonnote_insn (start_insn); + if (GET_CODE (start_insn) == BARRIER) + start_insn = next_nonnote_insn (start_insn); + if (GET_CODE (start_insn) == CODE_LABEL + && CODE_LABEL_NUMBER (start_insn) == arm_target_label + && LABEL_NUSES (start_insn) == 1) + { + reverse = TRUE; + seeking_return = 1; + } + else + return; + } else return; *************** *** 1229,1232 **** --- 2309,2326 ---- return; + /* This jump might be paralled with a clobber of the condition codes + the jump should always come first */ + if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0) + body = XVECEXP (body, 0, 0); + + #if 0 + /* If this is a conditional return then we don't want to know */ + if (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC + && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE + && (GET_CODE (XEXP (SET_SRC (body), 1)) == RETURN + || GET_CODE (XEXP (SET_SRC (body), 2)) == RETURN)) + return; + #endif + if (reverse || (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC *************** *** 1236,1244 **** /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */ int then_not_else = TRUE; ! rtx this_insn = start_insn, label; /* Register the insn jumped to. */ if (reverse) ! label = XEXP (SET_SRC (body), 0); else if (GET_CODE (XEXP (SET_SRC (body), 1)) == LABEL_REF) label = XEXP (XEXP (SET_SRC (body), 1), 0); --- 2330,2344 ---- /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */ int then_not_else = TRUE; ! rtx this_insn = start_insn, label = 0; + if (get_attr_conds (insn) == CONDS_JUMP_CLOB) + jump_clobbers = 1; + /* Register the insn jumped to. */ if (reverse) ! { ! if (!seeking_return) ! label = XEXP (SET_SRC (body), 0); ! } else if (GET_CODE (XEXP (SET_SRC (body), 1)) == LABEL_REF) label = XEXP (XEXP (SET_SRC (body), 1), 0); *************** *** 1248,1251 **** --- 2348,2358 ---- then_not_else = FALSE; } + else if (GET_CODE (XEXP (SET_SRC (body), 1)) == RETURN) + seeking_return = 1; + else if (GET_CODE (XEXP (SET_SRC (body), 2)) == RETURN) + { + seeking_return = 1; + then_not_else = FALSE; + } else abort (); *************** *** 1273,1277 **** if (this_insn == label) { ! arm_ccfsm_state = 1; succeed = TRUE; } --- 2380,2390 ---- if (this_insn == label) { ! if (jump_clobbers) ! { ! arm_ccfsm_state = 2; ! this_insn = next_nonnote_insn (this_insn); ! } ! else ! arm_ccfsm_state = 1; succeed = TRUE; } *************** *** 1280,1290 **** break; ! case BARRIER: /* XXX Is this case necessary? */ /* Succeed if the following insn is the target label. ! Otherwise fail. */ this_insn = next_nonnote_insn (this_insn); ! if (this_insn == label) { ! arm_ccfsm_state = 1; succeed = TRUE; } --- 2393,2411 ---- break; ! case BARRIER: /* Succeed if the following insn is the target label. ! Otherwise fail. ! If return insns are used then the last insn in a function ! will be a barrier. */ this_insn = next_nonnote_insn (this_insn); ! if (this_insn && this_insn == label) { ! if (jump_clobbers) ! { ! arm_ccfsm_state = 2; ! this_insn = next_nonnote_insn (this_insn); ! } ! else ! arm_ccfsm_state = 1; succeed = TRUE; } *************** *** 1293,1296 **** --- 2414,2423 ---- break; + case CALL_INSN: + /* The arm 6xx uses full 32 bit addresses so the cc is not + preserved over calls */ + if (TARGET_6) + fail = TRUE; + break; case JUMP_INSN: /* If this is an unconditional branch to the same label, succeed. *************** *** 1299,1303 **** /* XXX Probably, the test for the SET and the PC are unnecessary. */ ! if (GET_CODE (scanbody) == SET && GET_CODE (SET_DEST (scanbody)) == PC) { if (GET_CODE (SET_SRC (scanbody)) == LABEL_REF --- 2426,2431 ---- /* XXX Probably, the test for the SET and the PC are unnecessary. */ ! if (GET_CODE (scanbody) == SET ! && GET_CODE (SET_DEST (scanbody)) == PC) { if (GET_CODE (SET_SRC (scanbody)) == LABEL_REF *************** *** 1310,1318 **** fail = TRUE; } break; case INSN: ! /* Instructions affecting the condition codes make it fail. */ ! if (sets_cc0_p (scanbody)) fail = TRUE; break; --- 2438,2466 ---- fail = TRUE; } + else if (GET_CODE (scanbody) == RETURN + && seeking_return) + { + arm_ccfsm_state = 2; + succeed = TRUE; + } + else if (GET_CODE (scanbody) == PARALLEL) + { + switch (get_attr_conds (this_insn)) + { + case CONDS_NOCOND: + break; + default: + fail = TRUE; + break; + } + } break; case INSN: ! /* Instructions using or affecting the condition codes make it ! fail. */ ! if ((GET_CODE (scanbody) == SET ! || GET_CODE (scanbody) == PARALLEL) ! && get_attr_conds (this_insn) != CONDS_NOCOND) fail = TRUE; break; *************** *** 1324,1341 **** if (succeed) { ! if (arm_ccfsm_state == 1 || reverse) arm_target_label = CODE_LABEL_NUMBER (label); ! else if (arm_ccfsm_state == 2) ! arm_target_insn = this_insn; else abort (); - /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from what - it was. */ - if (!reverse) - arm_current_cc = get_arm_condition_code (XEXP (SET_SRC (body), 0)); if (reverse || then_not_else) arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc); } } } /* final_prescan_insn */ --- 2472,2527 ---- if (succeed) { ! if ((!seeking_return) && (arm_ccfsm_state == 1 || reverse)) arm_target_label = CODE_LABEL_NUMBER (label); ! else if (seeking_return || arm_ccfsm_state == 2) ! { ! while (this_insn && GET_CODE (PATTERN (this_insn)) == USE) ! { ! this_insn = next_nonnote_insn (this_insn); ! if (this_insn && (GET_CODE (this_insn) == BARRIER ! || GET_CODE (this_insn) == CODE_LABEL)) ! abort (); ! } ! if (!this_insn) ! { ! /* Oh, dear! we ran off the end.. give up */ ! recog (PATTERN (insn), insn, NULL_PTR); ! arm_ccfsm_state = 0; ! arm_target_insn = NULL; ! return; ! } ! arm_target_insn = this_insn; ! } else abort (); + if (jump_clobbers) + { + if (reverse) + abort (); + arm_current_cc = + get_arm_condition_code (XEXP (XEXP (XEXP (SET_SRC (body), + 0), 0), 1)); + if (GET_CODE (XEXP (XEXP (SET_SRC (body), 0), 0)) == AND) + arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc); + if (GET_CODE (XEXP (SET_SRC (body), 0)) == NE) + arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc); + } + else + { + /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from + what it was. */ + if (!reverse) + arm_current_cc = get_arm_condition_code (XEXP (SET_SRC (body), + 0)); + } if (reverse || then_not_else) arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc); } + /* restore recog_operand (getting the attributes of other insns can + destroy this array, but final.c assumes that it remains intact + accross this call; since the insn has been recognized already we + call recog direct). */ + recog (PATTERN (insn), insn, NULL_PTR); } } /* final_prescan_insn */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/arm/arm.h gcc-2.5.0/config/arm/arm.h *** gcc-2.4.5/config/arm/arm.h Fri May 28 15:01:14 1993 --- gcc-2.5.0/config/arm/arm.h Tue Oct 19 17:34:03 1993 *************** *** 1,7 **** /* Definitions of target machine for GNU compiler, for Acorn RISC Machine. ! Copyright (C) 1991 Free Software Foundation, Inc. Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) and Martin Simmons (@harleqn.co.uk). ! This file is part of GNU CC. --- 1,8 ---- /* Definitions of target machine for GNU compiler, for Acorn RISC Machine. ! Copyright (C) 1991, 1993 Free Software Foundation, Inc. Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) and Martin Simmons (@harleqn.co.uk). ! More major hacks by Richard Earnshaw (rwe11@cl.cam.ac.uk) ! This file is part of GNU CC. *************** *** 28,55 **** extern char *arm_output_asm_insn (); extern char *arm_output_llc (); extern char *output_add_immediate (); extern char *output_call (); extern char *output_move_double (); extern char *output_mov_double_fpu_from_arm (); extern char *output_mov_double_arm_from_fpu (); extern char *output_mov_immediate (); extern char *output_multi_immediate (); extern char *output_shifted_move (); extern char *output_arithmetic_with_immediate_multiply (); ! /* Translation to find startup files. On RISCiX boxes, gcrt0.o is in ! /usr/lib. */ ! #define STARTFILE_SPEC \ ! "%{pg:/usr/lib/gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}" ! #ifdef riscos ! #define CPP_PREDEFINES "-Darm -Driscos" ! #else ! #define CPP_PREDEFINES "-Darm -Driscix -Dunix" #endif /* Run-time Target Specification. */ #define TARGET_VERSION \ ! fputs (" (ARM/RISCiX)", stderr); /* Run-time compilation parameters selecting different hardware subsets. --- 29,75 ---- extern char *arm_output_asm_insn (); extern char *arm_output_llc (); + extern char *arithmetic_instr (); extern char *output_add_immediate (); extern char *output_call (); + extern char *output_call_mem (); extern char *output_move_double (); extern char *output_mov_double_fpu_from_arm (); extern char *output_mov_double_arm_from_fpu (); + extern char *output_mov_long_double_fpu_from_arm (); + extern char *output_mov_long_double_arm_from_fpu (); + extern char *output_mov_long_double_arm_from_arm (); extern char *output_mov_immediate (); extern char *output_multi_immediate (); extern char *output_shifted_move (); + extern char *output_shift_compare (); extern char *output_arithmetic_with_immediate_multiply (); + extern char *output_arithmetic_with_shift (); + extern char *output_return_instruction (); + extern char *output_load_symbol (); + extern char *fp_immediate_constant (); + extern char *shift_instr (); + extern struct rtx_def *gen_compare_reg (); + extern struct rtx_def *arm_gen_store_multiple (); + extern struct rtx_def *arm_gen_load_multiple (); + + extern char *arm_condition_codes[]; + + /* This is needed by the tail-calling peepholes */ + extern int frame_pointer_needed; + ! #ifndef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Darm -Acpu(arm) -Amachine(arm)" ! #endif ! #ifndef CPP_SPEC ! #define CPP_SPEC "%{m6:-D__arm6__}" #endif /* Run-time Target Specification. */ + #ifndef TARGET_VERSION #define TARGET_VERSION \ ! fputs (" (ARM/generic)", stderr); ! #endif /* Run-time compilation parameters selecting different hardware subsets. *************** *** 71,74 **** --- 91,108 ---- #define TARGET_FPE (target_flags & 4) + /* Nonzero if destined for an ARM6xx. Takes out bits that assume restoration + of condition flags when returning from a branch & link (ie. a function) */ + #define TARGET_6 (target_flags & 8) + + /* ARM_EXTRA_TARGET_SWITCHES is used in riscix.h to define some options which + are passed to the preprocessor and the assembler post-processor. They + aren't needed in the main pass of the compiler, but if we don't define + them in target switches cc1 complains about them. For the sake of + argument lets allocate bit 31 of target flags for such options. */ + + #ifndef ARM_EXTRA_TARGET_SWITCHES + #define ARM_EXTRA_TARGET_SWITCHES + #endif + #define TARGET_SWITCHES \ { \ *************** *** 76,82 **** --- 110,138 ---- {"poke-function-name", 2}, \ {"fpe", 4}, \ + {"6", 8}, \ + {"2", -8}, \ + {"3", -8}, \ + ARM_EXTRA_TARGET_SWITCHES \ {"", TARGET_DEFAULT } \ } + /* Which processor we are running on. Currently this is only used to + get the condition code clobbering attribute right when we are running on + an arm 6 */ + + enum processor_type + { + PROCESSOR_ARM2, + PROCESSOR_ARM3, + PROCESSOR_ARM6 + }; + + /* Recast the cpu class to be the cpu attribute. */ + + /* Recast the cpu class to be the cpu attribute. */ + #define arm_cpu_attr ((enum attr_cpu)arm_cpu) + + extern enum processor_type arm_cpu; + #define TARGET_DEFAULT 0 *************** *** 89,95 **** scheduling. Note that this only saves compilation time; it doesn't matter for the final code. */ ! #ifdef riscos ! #define TARGET_WHEN_DEBUGGING 3 ! #else #define TARGET_WHEN_DEBUGGING 1 #endif --- 145,149 ---- scheduling. Note that this only saves compilation time; it doesn't matter for the final code. */ ! #ifndef TARGET_WHEN_DEBUGGING #define TARGET_WHEN_DEBUGGING 1 #endif *************** *** 97,106 **** #define OVERRIDE_OPTIONS \ { \ ! if (write_symbols != NO_DEBUG) \ ! target_flags |= TARGET_WHEN_DEBUGGING; \ ! else if (TARGET_POKE_FUNCTION_NAME) \ target_flags |= 1; \ if (TARGET_FPE) \ flag_schedule_insns = flag_schedule_insns_after_reload = 0; \ } --- 151,161 ---- #define OVERRIDE_OPTIONS \ { \ ! if (write_symbols != NO_DEBUG && flag_omit_frame_pointer) \ ! warning ("-g without a frame pointer may not give sensible debugging");\ ! if (TARGET_POKE_FUNCTION_NAME) \ target_flags |= 1; \ if (TARGET_FPE) \ flag_schedule_insns = flag_schedule_insns_after_reload = 0; \ + arm_cpu = TARGET_6 ? PROCESSOR_ARM6: PROCESSOR_ARM2; \ } *************** *** 107,115 **** /* Omitting the frame pointer is a very good idea on the ARM, especially if not TARGET_APCS, in which case all that pushing on function entry isn't ! mandatory anymore. */ #define OPTIMIZATION_OPTIONS(OPTIMIZE) \ { \ if (OPTIMIZE) \ ! flag_omit_frame_pointer = 1; \ } --- 162,174 ---- /* Omitting the frame pointer is a very good idea on the ARM, especially if not TARGET_APCS, in which case all that pushing on function entry isn't ! mandatory anymore. Unfortunately this is not permitted since we mustn't ! change the flags when -g is enabled and without a frame pointer debugging ! using dbx is impossible. ! Forcing loads to be explicit allows cse to work better */ ! #define OPTIMIZATION_OPTIONS(OPTIMIZE) \ { \ if (OPTIMIZE) \ ! flag_force_mem = 1; \ } *************** *** 116,119 **** --- 175,218 ---- /* Target machine storage Layout. */ + + /* Define this macro if it is advisable to hold scalars in registers + in a wider mode than that declared by the program. In such cases, + the value is constrained to be within the bounds of the declared + type, but kept valid in the wider mode. The signedness of the + extension may differ from that of the type. */ + + /* It is far faster to zero extend chars than to sign extend them */ + + #define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \ + if (GET_MODE_CLASS (MODE) == MODE_INT \ + && GET_MODE_SIZE (MODE) < 4) \ + { \ + if (MODE == QImode) \ + UNSIGNEDP = 1; \ + (MODE) = SImode; \ + } + + /* Define for XFmode extended real floating point support. + This will automatically cause REAL_ARITHMETIC to be defined. */ + /* For the ARM: + I think I have added all the code to make this work. Unfortunately, + early releases of the floating point emulation code on RISCiX used a + different format for extended precision numbers. On my RISCiX box there + is a bug somewhere which causes the machine to lock up when running enquire + with long doubles. There is the additional aspect that Norcroft C + treats long doubles as doubles and we ought to remain compatible. + Perhaps someone with an FPA coprocessor and not running RISCiX would like + to try this someday. */ + /* #define LONG_DOUBLE_TYPE_SIZE 96 */ + + /* Disable XFmode patterns in md file */ + #define ENABLE_XF_PATTERNS 0 + + /* Define if you don't want extended real, but do want to use the + software floating point emulator for REAL_ARITHMETIC and + decimal <-> binary conversion. */ + /* See comment above */ + #define REAL_ARITHMETIC + /* Define this if most significant bit is lowest numbered in instructions that operate on numbered bit-fields. */ *************** *** 127,130 **** --- 226,232 ---- #define WORDS_BIG_ENDIAN 0 + /* Define this if most significant word of doubles is the lowest numbered */ + #define FLOAT_WORDS_BIG_ENDIAN 1 + /* Number of bits in an addressable storage unit */ #define BITS_PER_UNIT 8 *************** *** 146,154 **** --- 248,265 ---- #define BIGGEST_ALIGNMENT 32 + /* Make strings word-aligned so strcpy from constants will be faster. */ + #define CONSTANT_ALIGNMENT(EXP, ALIGN) \ + (TREE_CODE (EXP) == STRING_CST \ + && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN)) + /* Every structures size must be a multiple of 32 bits. */ #define STRUCTURE_SIZE_BOUNDARY 32 + /* Non-zero if move instructions will actually fail to work + when given unaligned data. */ #define STRICT_ALIGNMENT 1 + #define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT + /* Define number of bits in most basic integer type. (If undefined, default is BITS_PER_WORD). */ *************** *** 178,185 **** f4-f7 S floating point variable *: See CONDITIONAL_REGISTER_USAGE */ ! /* The number of hard registers is 16 ARM + 8 FPU. */ ! #define FIRST_PSEUDO_REGISTER 24 /* 1 for registers that have pervasive standard uses --- 289,329 ---- f4-f7 S floating point variable + cc This is NOT a real register, but is used internally + to represent things that use or set the condition + codes. + sfp This isn't either. It is used during rtl generation + since the offset between the frame pointer and the + auto's isn't known until after register allocation. + afp Nor this, we only need this because of non-local + goto. Without it fp appears to be used and the + elimination code won't get rid of sfp. It tracks + fp exactly at all times. + *: See CONDITIONAL_REGISTER_USAGE */ ! /* The stack backtrace structure is as follows: ! fp points to here: | save code pointer | [fp] ! | return link value | [fp, #-4] ! | return sp value | [fp, #-8] ! | return fp value | [fp, #-12] ! [| saved r10 value |] ! [| saved r9 value |] ! [| saved r8 value |] ! [| saved r7 value |] ! [| saved r6 value |] ! [| saved r5 value |] ! [| saved r4 value |] ! [| saved r3 value |] ! [| saved r2 value |] ! [| saved r1 value |] ! [| saved r0 value |] ! [| saved f7 value |] three words ! [| saved f6 value |] three words ! [| saved f5 value |] three words ! [| saved f4 value |] three words ! r0-r3 are not normally saved in a C function. */ ! ! /* The number of hard registers is 16 ARM + 8 FPU + 1 CC + 1 SFP. */ ! #define FIRST_PSEUDO_REGISTER 27 /* 1 for registers that have pervasive standard uses *************** *** 189,193 **** 0,0,0,0,0,0,0,0, \ 0,0,1,1,0,1,0,1, \ ! 0,0,0,0,0,0,0,0 \ } --- 333,338 ---- 0,0,0,0,0,0,0,0, \ 0,0,1,1,0,1,0,1, \ ! 0,0,0,0,0,0,0,0, \ ! 1,1,1 \ } *************** *** 197,201 **** 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 \ { \ --- 342,348 ---- 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 CC is not preserved over function calls on the ARM 6, so it is ! easier to assume this for all. SFP is preserved, since FP is. */ #define CALL_USED_REGISTERS \ { \ *************** *** 202,206 **** 1,1,1,1,0,0,0,0, \ 0,0,1,1,1,1,1,1, \ ! 1,1,1,1,0,0,0,0 \ } --- 349,354 ---- 1,1,1,1,0,0,0,0, \ 0,0,1,1,1,1,1,1, \ ! 1,1,1,1,0,0,0,0, \ ! 1,1,1 \ } *************** *** 222,227 **** On the ARM regs are UNITS_PER_WORD bits wide; FPU regs can hold any FP mode. */ ! #define HARD_REGNO_NREGS(REGNO, MODE) \ ! ((REGNO) >= 16 ? 1 \ : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) --- 370,376 ---- On the ARM regs are UNITS_PER_WORD bits wide; FPU regs can hold any FP mode. */ ! #define HARD_REGNO_NREGS(REGNO, MODE) \ ! (((REGNO) >= 16 && REGNO != FRAME_POINTER_REGNUM \ ! && (REGNO) != ARG_POINTER_REGNUM) ? 1 \ : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) *************** *** 229,234 **** This is TRUE for ARM regs since they can hold anything, and TRUE for FPU regs holding FP. */ ! #define HARD_REGNO_MODE_OK(REGNO, MODE) \ ! ((REGNO) < 16 || GET_MODE_CLASS (MODE) == MODE_FLOAT) /* Value is 1 if it is a good idea to tie two pseudo registers --- 378,386 ---- This is TRUE for ARM regs since they can hold anything, and TRUE for FPU regs holding FP. */ ! #define HARD_REGNO_MODE_OK(REGNO, MODE) \ ! ((GET_MODE_CLASS (MODE) == MODE_CC) ? (REGNO == CC_REGNUM) : \ ! ((REGNO) < 16 || REGNO == FRAME_POINTER_REGNUM \ ! || REGNO == ARG_POINTER_REGNUM \ ! || GET_MODE_CLASS (MODE) == MODE_FLOAT)) /* Value is 1 if it is a good idea to tie two pseudo registers *************** *** 250,262 **** /* Base register for access to local variables of the function. */ ! #define FRAME_POINTER_REGNUM 9 /* 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. */ ! #define FRAME_POINTER_REQUIRED 0 /* Base register for access to arguments of the function. */ ! #define ARG_POINTER_REGNUM 11 /* The native (Norcroft) Pascal compiler for the ARM passes the static chain --- 402,423 ---- /* Base register for access to local variables of the function. */ ! #define FRAME_POINTER_REGNUM 25 ! ! /* Define this to be where the real frame pointer is if it is not possible to ! work out the offset between the frame pointer and the automatic variables ! until after register allocation has taken place. FRAME_POINTER_REGNUM ! should point to a special register that we will make sure is eliminated. */ ! #define HARD_FRAME_POINTER_REGNUM 11 /* 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. ! If we have to have a frame pointer we might as well make use of it. ! APCS says that the frame pointer does not need to be pushed in leaf ! functions. */ ! #define FRAME_POINTER_REQUIRED (TARGET_APCS && !leaf_function_p ()) /* Base register for access to arguments of the function. */ ! #define ARG_POINTER_REGNUM 26 /* The native (Norcroft) Pascal compiler for the ARM passes the static chain *************** *** 269,280 **** #define STRUCT_VALUE_REGNUM 0 /* The order in which register should be allocated. It is good to use ip ! since no saving is required (though calls clobber it). It is quite good to ! use lr since other calls may clobber it anyway. */ #define REG_ALLOC_ORDER \ { \ ! 0, 1, 2, 3, 12, 14, 4, 5, \ 6, 7, 8, 10, 9, 11, 13, 15, \ ! 16, 17, 18, 19, 20, 21, 22, 23 \ } --- 430,449 ---- #define STRUCT_VALUE_REGNUM 0 + /* Internal, so that we don't need to refer to a raw number */ + #define CC_REGNUM 24 + /* The order in which register should be allocated. It is good to use ip ! since no saving is required (though calls clobber it) and it never contains ! function parameters. It is quite good to use lr since other calls may ! clobber it anyway. Allocate r0 through r3 in reverse order since r3 is ! least likely to contain a function parameter; in addition results are ! returned in r0. ! */ #define REG_ALLOC_ORDER \ { \ ! 3, 2, 1, 0, 12, 14, 4, 5, \ 6, 7, 8, 10, 9, 11, 13, 15, \ ! 16, 17, 18, 19, 20, 21, 22, 23, \ ! 24, 25 \ } *************** *** 307,314 **** #define REG_CLASS_CONTENTS \ { \ ! 0x000000, /* NO_REGS */ \ ! 0xFF0000, /* FPU_REGS */ \ ! 0x00FFFF, /* GENERAL_REGS */ \ ! 0xFFFFFF /* ALL_REGS */ \ } --- 476,483 ---- #define REG_CLASS_CONTENTS \ { \ ! 0x0000000, /* NO_REGS */ \ ! 0x0FF0000, /* FPU_REGS */ \ ! 0x200FFFF, /* GENERAL_REGS */ \ ! 0x2FFFFFF /* ALL_REGS */ \ } *************** *** 317,322 **** reg number REGNO. This could be a conditional expression or could index an array. */ ! #define REGNO_REG_CLASS(REGNO) \ ! ((REGNO) < 16 ? GENERAL_REGS : FPU_REGS) /* The class value for index registers, and the one for base regs. */ --- 486,494 ---- reg number REGNO. This could be a conditional expression or could index an array. */ ! #define REGNO_REG_CLASS(REGNO) \ ! (((REGNO) < 16 || REGNO == FRAME_POINTER_REGNUM \ ! || REGNO == ARG_POINTER_REGNUM) \ ! ? GENERAL_REGS : (REGNO) == CC_REGNUM \ ! ? NO_REGS : FPU_REGS) /* The class value for index registers, and the one for base regs. */ *************** *** 335,346 **** Return 1 if VALUE is in the range specified by C. I: immediate arithmetic operand (i.e. 8 bits shifted as required). ! J: valid indexing constants. */ ! #define CONST_OK_FOR_LETTER_P(VALUE, C) \ ! ((C) == 'I' ? const_ok_for_arm (VALUE) : \ ! (C) == 'J' ? (abs (VALUE) < 4096) : 0) ! ! /* Constant letter 'G' for the FPU immediate constants. */ ! #define CONST_DOUBLE_OK_FOR_LETTER_P(X,C) \ ! ((C) == 'G' ? const_double_rtx_ok_for_fpu (X) : 0) /* Given an rtx X being reloaded into a reg required to be --- 507,534 ---- Return 1 if VALUE is in the range specified by C. I: immediate arithmetic operand (i.e. 8 bits shifted as required). ! J: valid indexing constants. ! K: as I but also (not (value)) ok. ! L: as I but also (neg (value)) ok.*/ ! #define CONST_OK_FOR_LETTER_P(VALUE, C) \ ! ((C) == 'I' ? const_ok_for_arm (VALUE) : \ ! (C) == 'J' ? ((VALUE) < 4096 && (VALUE) > -4096) : \ ! (C) == 'K' ? (const_ok_for_arm (VALUE) || const_ok_for_arm (~(VALUE))) : \ ! (C) == 'L' ? (const_ok_for_arm (VALUE) || const_ok_for_arm (-(VALUE))) : 0) ! ! /* For the ARM, `Q' means that this is a memory operand that is just ! an offset from a register. ! `S' means any symbol that has the SYMBOL_REF_FLAG set or a CONSTANT_POOL ! address. This means that the symbol is in the text segment and can be ! accessed without using a load. */ ! ! #define EXTRA_CONSTRAINT(OP, C) \ ! ((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG \ ! : (C) == 'S' ? CONSTANT_ADDRESS_P (OP) : 0) ! ! /* Constant letter 'G' for the FPU immediate constants. ! 'H' means the same constant negated. */ ! #define CONST_DOUBLE_OK_FOR_LETTER_P(X,C) \ ! ((C) == 'G' ? const_double_rtx_ok_for_fpu (X) \ ! : (C) == 'H' ? neg_const_double_rtx_ok_for_fpu (X) : 0) /* Given an rtx X being reloaded into a reg required to be *************** *** 350,353 **** --- 538,549 ---- #define PREFERRED_RELOAD_CLASS(X, CLASS) (CLASS) + /* Return the register class of a scratch register needed to copy IN into + or out of a register in CLASS in MODE. If it can be done directly, + NO_REGS is returned. */ + #define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS,MODE,X) \ + (((MODE) == DFmode && (CLASS) == GENERAL_REGS \ + && true_regnum (X) == -1) ? GENERAL_REGS \ + : ((MODE) == HImode && true_regnum (X) == -1) ? GENERAL_REGS : NO_REGS) + /* Return the maximum number of consecutive registers needed to represent mode MODE in a register of class CLASS. *************** *** 357,365 **** : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) ! /* Moves between FPU_REGS and GENERAL_REGS are two insns. */ #define REGISTER_MOVE_COST(CLASS1, CLASS2) \ ((((CLASS1) == FPU_REGS && (CLASS2) != FPU_REGS) \ || ((CLASS2) == FPU_REGS && (CLASS1) != FPU_REGS)) \ ! ? 4 : 2) /* Stack layout; function entry, exit and calling. */ --- 553,561 ---- : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) ! /* Moves between FPU_REGS and GENERAL_REGS are two memory insns. */ #define REGISTER_MOVE_COST(CLASS1, CLASS2) \ ((((CLASS1) == FPU_REGS && (CLASS2) != FPU_REGS) \ || ((CLASS2) == FPU_REGS && (CLASS1) != FPU_REGS)) \ ! ? 20 : 2) /* Stack layout; function entry, exit and calling. */ *************** *** 463,467 **** On the ARM, the offset starts at 0. */ #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME) \ ! ((CUM) = (((FNTYPE) && aggregate_value_p (FNTYPE)) ? 4 : 0)) /* Update the data in CUM to advance over an argument --- 659,663 ---- On the ARM, the offset starts at 0. */ #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME) \ ! ((CUM) = (((FNTYPE) && aggregate_value_p (TREE_TYPE ((FNTYPE)))) ? 4 : 0)) /* Update the data in CUM to advance over an argument *************** *** 530,535 **** /* Determine if the epilogue should be output as RTL. You should override this if you define FUNCTION_EXTRA_EPILOGUE. */ ! /* #define USE_RETURN_INSN use_return_insn () */ /* Store in the variable DEPTH the initial difference between the frame pointer reg contents and the stack pointer reg contents, as of the start of --- 726,793 ---- /* Determine if the epilogue should be output as RTL. You should override this if you define FUNCTION_EXTRA_EPILOGUE. */ ! #define USE_RETURN_INSN use_return_insn () ! ! /* Definitions for register eliminations. ! ! This is an array of structures. Each structure initializes one pair ! of eliminable registers. The "from" register number is given first, ! followed by "to". Eliminations of the same "from" register are listed ! in order of preference. ! ! We have two registers that can be eliminated on the ARM. First, the ! arg pointer register can often be eliminated in favor of the stack ! pointer register. Secondly, the pseudo frame pointer register can always ! be eliminated; it is replaced with either the stack or the real frame ! pointer. */ ! ! #define ELIMINABLE_REGS \ ! {{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ ! {ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \ ! {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ ! {FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}} ! ! /* Given FROM and TO register numbers, say whether this elimination is allowed. ! Frame pointer elimination is automatically handled. ! ! All eliminations are permissible. Note that ARG_POINTER_REGNUM and ! HARD_FRAME_POINTER_REGNUM are infact the same thing. If we need a frame ! pointer, we must eliminate FRAME_POINTER_REGNUM into ! HARD_FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM. */ ! #define CAN_ELIMINATE(FROM, TO) \ ! (((TO) == STACK_POINTER_REGNUM && frame_pointer_needed) ? 0 : 1) ! ! /* Define the offset between two registers, one to be eliminated, and the other ! its replacement, at the start of a routine. */ ! #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ ! { \ ! if ((FROM) == ARG_POINTER_REGNUM && (TO) == HARD_FRAME_POINTER_REGNUM)\ ! (OFFSET) = 0; \ ! else if ((FROM) == FRAME_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM)\ ! (OFFSET) = (get_frame_size () + 3 & ~3); \ ! else \ ! { \ ! int regno; \ ! int offset = 12; \ ! \ ! for (regno = 4; regno <= 10; regno++) \ ! if (regs_ever_live[regno]) \ ! offset += 4; \ ! for (regno = 20; regno <=23; regno++) \ ! if (regs_ever_live[regno]) \ ! offset += 12; \ ! if ((FROM) == FRAME_POINTER_REGNUM) \ ! (OFFSET) = -offset; \ ! else \ ! { \ ! if (! regs_ever_live[HARD_FRAME_POINTER_REGNUM]) \ ! offset -= 16; \ ! if (regs_ever_live[14]) \ ! offset += 4; \ ! (OFFSET) = (get_frame_size () + 3 & ~3) + offset; \ ! } \ ! } \ ! } + #if 0 /* Store in the variable DEPTH the initial difference between the frame pointer reg contents and the stack pointer reg contents, as of the start of *************** *** 536,542 **** the function body. This depends on the layout of the fixed parts of the stack frame and on how registers are saved. */ #define INITIAL_FRAME_POINTER_OFFSET(DEPTH) \ (DEPTH) = (get_frame_size () + 3) & ~3; ! /* Output assembler code for a block containing the constant parts of a trampoline, leaving space for the variable parts. --- 794,814 ---- the function body. This depends on the layout of the fixed parts of the stack frame and on how registers are saved. */ + #define INITIAL_FRAME_POINTER_OFFSET(DEPTH) \ + { \ + int regno; \ + int offset = 12; \ + \ + for (regno = 0; regno < FRAME_POINTER_REGNUM; regno++) \ + if (regs_ever_live[regno]) \ + offset += 4; \ + for (regno = 20; regno < 24; regno++) \ + if (regs_ever_live[regno]) \ + offset += 12; \ + (DEPTH) = offset + (get_frame_size () + 3 & ~3); \ + } + #define INITIAL_FRAME_POINTER_OFFSET(DEPTH) \ (DEPTH) = (get_frame_size () + 3) & ~3; ! #endif /* Output assembler code for a block containing the constant parts of a trampoline, leaving space for the variable parts. *************** *** 601,613 **** On the ARM, don't allow the pc to be used. */ ! #define REGNO_OK_FOR_BASE_P(REGNO) \ ! ((REGNO) < 15 || (unsigned) reg_renumber[(REGNO)] < 15) ! #define REGNO_OK_FOR_INDEX_P(REGNO) \ REGNO_OK_FOR_BASE_P(REGNO) /* Maximum number of registers that can appear in a valid memory address. ! The addressing mode [ra,rb, rc] uses the greatest number of ! registers. */ ! #define MAX_REGS_PER_ADDRESS 3 /* Recognize any constant value that is a valid address. */ --- 873,889 ---- On the ARM, don't allow the pc to be used. */ ! #define REGNO_OK_FOR_BASE_P(REGNO) \ ! ((REGNO) < 15 || (REGNO) == FRAME_POINTER_REGNUM \ ! || (REGNO) == ARG_POINTER_REGNUM \ ! || (unsigned) reg_renumber[(REGNO)] < 15 \ ! || (unsigned) reg_renumber[(REGNO)] == FRAME_POINTER_REGNUM \ ! || (unsigned) reg_renumber[(REGNO)] == ARG_POINTER_REGNUM) ! #define REGNO_OK_FOR_INDEX_P(REGNO) \ REGNO_OK_FOR_BASE_P(REGNO) /* Maximum number of registers that can appear in a valid memory address. ! Shifts in addresses can't be by a register. */ ! ! #define MAX_REGS_PER_ADDRESS 2 /* Recognize any constant value that is a valid address. */ *************** *** 621,626 **** #endif ! #define CONSTANT_ADDRESS_P(X) \ ! (GET_CODE (X) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (X)) /* Nonzero if the constant value X is a legitimate general operand. --- 897,903 ---- #endif ! #define CONSTANT_ADDRESS_P(X) \ ! (GET_CODE (X) == SYMBOL_REF \ ! && (CONSTANT_POOL_ADDRESS_P (X) || SYMBOL_REF_FLAG (X))) /* Nonzero if the constant value X is a legitimate general operand. *************** *** 633,640 **** (GET_CODE (X) == CONST_INT \ || (GET_CODE (X) == CONST_DOUBLE \ ! && const_double_rtx_ok_for_fpu (X))) ! #if 0 ! || GET_CODE(X) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P(X)) ! #endif /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx --- 910,927 ---- (GET_CODE (X) == CONST_INT \ || (GET_CODE (X) == CONST_DOUBLE \ ! && (const_double_rtx_ok_for_fpu (X) \ ! || neg_const_double_rtx_ok_for_fpu (X))) \ ! || CONSTANT_ADDRESS_P (X)) ! ! /* Symbols in the text segment can be accessed without indirecting via the ! constant pool; it may take an extra binary operation, but this is still ! faster than indirecting via memory. */ ! ! #define ENCODE_SECTION_INFO(decl) \ ! { \ ! if (TREE_CONSTANT (decl) \ ! && (!flag_writable_strings || TREE_CODE (decl) != STRING_CST)) \ ! SYMBOL_REF_FLAG (XEXP (TREE_CST_RTL (decl), 0)) = 1; \ ! } /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx *************** *** 645,652 **** The symbol REG_OK_STRICT causes the latter definition to be used. */ #ifndef REG_OK_STRICT /* 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) \ ! (REGNO (X) < 16 || REGNO (X) >= 24) /* Nonzero if X is a hard reg that can be used as an index or if it is a pseudo reg. */ --- 932,942 ---- The symbol REG_OK_STRICT causes the latter definition to be used. */ #ifndef REG_OK_STRICT + /* 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) \ ! (REGNO (X) < 16 || REGNO (X) >= FIRST_PSEUDO_REGISTER \ ! || REGNO (X) == FRAME_POINTER_REGNUM || REGNO (X) == ARG_POINTER_REGNUM) ! /* Nonzero if X is a hard reg that can be used as an index or if it is a pseudo reg. */ *************** *** 653,665 **** #define REG_OK_FOR_INDEX_P(X) \ REG_OK_FOR_BASE_P(X) ! #define REG_OK_FOR_PRE_POST_P(X) \ ! (REGNO (X) < 16 || REGNO (X) >= FIRST_PSEUDO_REGISTER) #else /* 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)) /* 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)) ! #define REG_OK_FOR_PRE_POST_P(X) \ ! (REGNO (X) < 16 || (unsigned) reg_renumber[REGNO (X)] < 16) #endif --- 943,965 ---- #define REG_OK_FOR_INDEX_P(X) \ REG_OK_FOR_BASE_P(X) ! ! #define REG_OK_FOR_PRE_POST_P(X) \ ! (REGNO (X) < 16 || REGNO (X) >= FIRST_PSEUDO_REGISTER \ ! || REGNO (X) == FRAME_POINTER_REGNUM || REGNO (X) == ARG_POINTER_REGNUM) ! #else + /* 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)) + /* 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)) ! ! #define REG_OK_FOR_PRE_POST_P(X) \ ! (REGNO (X) < 16 || (unsigned) reg_renumber[REGNO (X)] < 16 \ ! || REGNO (X) == FRAME_POINTER_REGNUM || REGNO (X) == ARG_POINTER_REGNUM \ ! || (unsigned) reg_renumber[REGNO (X)] == FRAME_POINTER_REGNUM \ ! || (unsigned) reg_renumber[REGNO (X)] == ARG_POINTER_REGNUM) ! #endif *************** *** 679,694 **** used by the macro GO_IF_LEGITIMATE_ADDRESS. Floating point indices can only be small constants. */ ! #define GO_IF_LEGITIMATE_INDEX(MODE, BASE_REGNO, INDEX, LABEL) \ do \ { \ int range; \ \ if (GET_MODE_CLASS (MODE) == MODE_FLOAT) \ ! range = 1024; \ else \ { \ ! if (INDEX_REGISTER_RTX_P (INDEX)) \ goto LABEL; \ ! if (GET_MODE_SIZE (MODE) <= 4 && GET_CODE (INDEX) == MULT) \ { \ rtx xiop0 = XEXP (INDEX, 0); \ --- 979,1000 ---- used by the macro GO_IF_LEGITIMATE_ADDRESS. Floating point indices can only be small constants. */ ! #define GO_IF_LEGITIMATE_INDEX(MODE, BASE_REGNO, INDEX, LABEL) \ do \ { \ int range; \ + int code = GET_CODE (INDEX); \ \ if (GET_MODE_CLASS (MODE) == MODE_FLOAT) \ ! { \ ! if (code == CONST_INT && INTVAL (INDEX) < 1024 \ ! && INTVAL (INDEX) > -1024 \ ! && (INTVAL (INDEX) & 3) == 0) \ ! goto LABEL; \ ! } \ else \ { \ ! if (INDEX_REGISTER_RTX_P (INDEX) && GET_MODE_SIZE (MODE) <= 4) \ goto LABEL; \ ! if (GET_MODE_SIZE (MODE) <= 4 && code == MULT) \ { \ rtx xiop0 = XEXP (INDEX, 0); \ *************** *** 701,710 **** goto LABEL; \ } \ ! range = 4096; \ } \ - \ - if (GET_CODE (INDEX) == CONST_INT && INTVAL (INDEX) < range \ - && INTVAL (INDEX) > -range) \ - goto LABEL; \ } while (0) --- 1007,1025 ---- goto LABEL; \ } \ ! if (GET_MODE_SIZE (MODE) <= 4 \ ! && (code == LSHIFTRT || code == ASHIFTRT || code == LSHIFT \ ! || code == ASHIFT || code == ROTATERT)) \ ! { \ ! rtx op = XEXP (INDEX, 1); \ ! if (INDEX_REGISTER_RTX_P (XEXP (INDEX, 0)) \ ! && GET_CODE (op) == CONST_INT && INTVAL (op) > 0 \ ! && INTVAL (op) <= 31) \ ! goto LABEL; \ ! } \ ! range = (MODE) == HImode ? 4095 : 4096; \ ! if (code == CONST_INT && INTVAL (INDEX) < range \ ! && INTVAL (INDEX) > -range) \ ! goto LABEL; \ } \ } while (0) *************** *** 713,718 **** the above macros so we are in luck. Allow REG, REG+REG, REG+INDEX, INDEX+REG, REG-INDEX, and non floating SYMBOL_REF to the constant pool. ! Allow REG-only and AUTINC-REG if handling TImode. Other symbol refs must ! be forced though a static cell to ensure addressability. */ #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \ { \ --- 1028,1033 ---- the above macros so we are in luck. Allow REG, REG+REG, REG+INDEX, INDEX+REG, REG-INDEX, and non floating SYMBOL_REF to the constant pool. ! Allow REG-only and AUTINC-REG if handling TImode or HImode. Other symbol ! refs must be forced though a static cell to ensure addressability. */ #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \ { \ *************** *** 835,842 **** #define EASY_DIV_EXPR TRUNC_DIV_EXPR ! /* 'char' is signed by default on RISCiX, unsigned on RISCOS. */ ! #ifdef riscos ! #define DEFAULT_SIGNED_CHAR 0 ! #else #define DEFAULT_SIGNED_CHAR 1 #endif --- 1150,1156 ---- #define EASY_DIV_EXPR TRUNC_DIV_EXPR ! /* signed 'char' is most compatible, but RISC OS wants it unsigned. ! unsigned is probably best, but may break some code. */ ! #ifndef DEFAULT_SIGNED_CHAR #define DEFAULT_SIGNED_CHAR 1 #endif *************** *** 849,856 **** #define MOVE_MAX 4 ! /* Define if normal loads of shorter-than-word items from memory clears ! the rest of the bigs in the register. ! On the ARM, movhi does a garbage extend. */ ! /* #define BYTE_LOADS_ZERO_EXTEND */ /* Define this if zero-extension is slow (more than one real instruction). --- 1163,1176 ---- #define MOVE_MAX 4 ! /* Define if operations between registers always perform the operation ! on the full register even if a narrower mode is specified. */ ! #define WORD_REGISTER_OPERATIONS ! ! /* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD ! will either zero-extend or sign-extend. The value of this macro should ! be the code that says which one of the two operations is implicitly ! done, NIL if none. */ ! #define LOAD_EXTEND_OP(MODE) \ ! ((MODE) == QImode ? ZERO_EXTEND : NIL) /* Define this if zero-extension is slow (more than one real instruction). *************** *** 867,875 **** into a register and shifts by the register, letting the ARM decide what to do instead of doing that itself. */ ! #define SHIFT_COUNT_TRUNCATED 1 - /* We have the vprintf function. */ - #define HAVE_VPRINTF 1 - /* XX This is not true, is it? */ /* All integers have the same format so truncation is easy. */ --- 1187,1196 ---- into a register and shifts by the register, letting the ARM decide what to do instead of doing that itself. */ ! /* This is all wrong. Defining SHIFT_COUNT_TRUNCATED tells combine that ! code like (X << (Y % 32)) for register X, Y is equivalent to (X << Y). ! On the arm, Y in a register is used modulo 256 for the shift. Only for ! rotates is modulo 32 used. */ ! /* #define SHIFT_COUNT_TRUNCATED 1 */ /* XX This is not true, is it? */ /* All integers have the same format so truncation is easy. */ *************** *** 892,960 **** /* The relative costs of various types of constants. Note that cse.c defines REG = 1, SUBREG = 2, any node = (2 + sum of subnodes). */ ! #define CONST_COSTS(RTX, CODE, OUTER_CODE) \ ! case CONST_INT: \ ! if (const_ok_for_arm (INTVAL (RTX))) \ ! return (2); \ ! else \ ! return (5); \ ! \ ! case CONST: \ ! case LABEL_REF: \ ! case SYMBOL_REF: \ ! return (6); \ ! \ ! case CONST_DOUBLE: \ ! if (const_double_rtx_ok_for_fpu (RTX)) \ ! return(2); \ ! else \ ! return(7); ! /* Condition code information. */ - /* 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 ARM nothing sets the condition code implicitly---apart from DImode - operations excluding moves---but we have to watch for registers in the - condition code value being clobbered. This clobbering includes (alas) - function calls. XXX They could just be considered to clobber regs 0-3 and - 10-15 with extra work. */ - #define NOTICE_UPDATE_CC(EXP, INSN) \ - { \ - if (GET_MODE (EXP) == DImode \ - && GET_CODE (EXP) == SET \ - && GET_CODE (SET_SRC (EXP)) != REG \ - && GET_CODE (SET_SRC (EXP)) != MEM \ - && GET_CODE (SET_SRC (EXP)) != CONST_INT) \ - CC_STATUS_INIT; \ - else if (GET_CODE (EXP) == SET) \ - { \ - rtx dest = SET_DEST (EXP); \ - if (dest == cc0_rtx) \ - { \ - cc_status.flags = 0; \ - cc_status.value1 = SET_DEST (EXP); \ - cc_status.value2 = SET_SRC (EXP); \ - } \ - if (BASE_REGISTER_RTX_P (dest)) \ - { \ - if (cc_status.value1 \ - && reg_overlap_mentioned_p (dest, cc_status.value1)) \ - cc_status.value1 = 0; \ - if (cc_status.value2 \ - && reg_overlap_mentioned_p (dest, cc_status.value2)) \ - cc_status.value2 = 0; \ - } \ - } \ - else if (GET_CODE (INSN) != JUMP_INSN && GET_CODE (EXP) == PARALLEL) \ - { \ - CC_STATUS_INIT; \ - } \ - } /* Assembler output control */ /* The text to go at the start of the assembler file */ #define ASM_FILE_START(STREAM) \ --- 1213,1397 ---- /* The relative costs of various types of constants. Note that cse.c defines REG = 1, SUBREG = 2, any node = (2 + sum of subnodes). */ ! #define CONST_COSTS(RTX, CODE, OUTER_CODE) \ ! case CONST_INT: \ ! if (const_ok_for_arm (INTVAL (RTX))) \ ! return (OUTER_CODE) == SET ? 2 : -1; \ ! else if (OUTER_CODE == AND \ ! && const_ok_for_arm (~INTVAL (RTX))) \ ! return -1; \ ! else if ((OUTER_CODE == COMPARE \ ! || OUTER_CODE == PLUS || OUTER_CODE == MINUS) \ ! && const_ok_for_arm (-INTVAL (RTX))) \ ! return -1; \ ! else \ ! return 5; \ ! case CONST: \ ! case LABEL_REF: \ ! case SYMBOL_REF: \ ! return 6; \ ! case CONST_DOUBLE: \ ! if (const_double_rtx_ok_for_fpu (RTX)) \ ! return (OUTER_CODE) == SET ? 2 : -1; \ ! else if (((OUTER_CODE) == COMPARE || (OUTER_CODE) == PLUS) \ ! && neg_const_double_rtx_ok_for_fpu (RTX)) \ ! return -1; \ ! return(7); ! ! #define RTX_COSTS(X,CODE,OUTER_CODE) \ ! case MEM: \ ! { \ ! int num_words = (GET_MODE_SIZE (GET_MODE (X)) > UNITS_PER_WORD) ? 2 : 1;\ ! return (COSTS_N_INSNS (10*num_words)); \ ! } \ ! case MULT: \ ! if (GET_CODE (XEXP (X, 1)) == CONST_INT \ ! && exact_log2 (INTVAL (XEXP (X, 1))) >= 0) \ ! return rtx_cost (XEXP (X, 0), GET_CODE (X))+1; \ ! return COSTS_N_INSNS (9); \ ! case LSHIFT: \ ! case ASHIFT: \ ! case LSHIFTRT: \ ! case ASHIFTRT: \ ! if (GET_CODE (XEXP (X, 1)) == CONST_INT) \ ! return rtx_cost (XEXP (X, 0), GET_CODE (X))+1; \ ! break; \ ! case MINUS: \ ! { \ ! enum rtx_code code = GET_CODE (XEXP (X, 1)); \ ! if (code == MULT) \ ! { \ ! if (GET_CODE (XEXP (XEXP (X, 1), 1)) == CONST_INT \ ! && exact_log2 (INTVAL (XEXP (XEXP (X, 0), 1))) >= 0) \ ! return COSTS_N_INSNS (1); \ ! break; \ ! } \ ! else if (code == ASHIFT || code == LSHIFT || code == ASHIFTRT \ ! || code == LSHIFTRT) \ ! return COSTS_N_INSNS (1); \ ! } /* fall through */ \ ! case PLUS: \ ! case IOR: \ ! case XOR: \ ! case AND: \ ! { \ ! enum rtx_code code = GET_CODE (XEXP (X, 0)); \ ! if (code == MULT) \ ! { \ ! if (GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \ ! && exact_log2 (INTVAL (XEXP (XEXP (X, 0), 1))) >= 0) \ ! return COSTS_N_INSNS (1); \ ! if (GET_CODE (X) == PLUS) \ ! return COSTS_N_INSNS (12); \ ! break; \ ! } \ ! else if (code == ASHIFT || code == LSHIFT || code == ASHIFTRT \ ! || code == LSHIFTRT) \ ! return COSTS_N_INSNS (1); \ ! break; \ ! } \ ! case NOT: \ ! return rtx_cost (XEXP (X, 0), GET_CODE (XEXP (X, 0))); \ ! case IF_THEN_ELSE: \ ! { \ ! if (GET_CODE (XEXP(X,1)) == PC || GET_CODE (XEXP(X,2)) == PC) \ ! return COSTS_N_INSNS (4); \ ! return COSTS_N_INSNS (1); \ ! } \ ! case SIGN_EXTEND: \ ! return COSTS_N_INSNS (2); \ ! case ZERO_EXTEND: \ ! if (GET_MODE (XEXP (X, 0)) == QImode) \ ! { \ ! if (GET_CODE (XEXP (X, 0)) == MEM) \ ! return COSTS_N_INSNS (10); \ ! return COSTS_N_INSNS (1); \ ! } \ ! break; \ ! case COMPARE: \ ! if (GET_CODE (XEXP (X, 1)) == REG) \ ! return 4; \ ! case SMIN: \ ! case SMAX: \ ! case UMIN: \ ! case UMAX: \ ! return COSTS_N_INSNS (3); \ ! case ABS: \ ! if (GET_MODE (X) == SImode) \ ! return COSTS_N_INSNS (2); \ ! return COSTS_N_INSNS (1); ! ! /* Moves to and from memory are quite expensive */ ! #define MEMORY_MOVE_COST(MODE) 10 ! ! /* All address computations that can be done are free */ ! #define ADDRESS_COST(x) 2 ! ! /* Try to generate sequences that don't involve branches, we can then use ! conditional instructions */ ! #define BRANCH_COST 4 ! /* Condition code information. */ ! /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE, ! return the mode to be used for the comparison. ! CCFPEmode should be used with floating inequalites, ! CCFPmode should be used with floating equalities. ! CC_NOOVmode should be used with SImode integer equalites ! CCmode should be used otherwise. */ ! ! #define EXTRA_CC_MODES CC_NOOVmode, CCFPmode, CCFPEmode ! ! #define EXTRA_CC_NAMES "CC_NOOV", "CCFP", "CCFPE" ! ! #define SELECT_CC_MODE(OP,X,Y) \ ! (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \ ! ? ((OP == EQ || OP == NE) ? CCFPmode : CCFPEmode) \ ! : ((GET_MODE (X) == SImode) \ ! && ((OP) == EQ || (OP) == NE) \ ! && (GET_CODE (X) == PLUS || GET_CODE (X) == MINUS \ ! || GET_CODE (X) == AND || GET_CODE (X) == IOR \ ! || GET_CODE (X) == XOR || GET_CODE (X) == MULT \ ! || GET_CODE (X) == NOT || GET_CODE (X) == NEG \ ! || GET_CODE (X) == LSHIFT || GET_CODE (X) == LSHIFTRT \ ! || GET_CODE (X) == ASHIFT || GET_CODE (X) == ASHIFTRT \ ! || GET_CODE (X) == ROTATERT || GET_CODE (X) == ZERO_EXTRACT) \ ! ? CC_NOOVmode \ ! : GET_MODE (X) == QImode ? CC_NOOVmode : CCmode)) ! ! #define STORE_FLAG_VALUE 1 ! ! /* Define the information needed to generate branch insns. This is ! stored from the compare operation. Note that we can't use "rtx" here ! since it hasn't been defined! */ ! ! extern struct rtx_def *arm_compare_op0, *arm_compare_op1; ! extern int arm_compare_fp; ! ! /* Define the codes that are matched by predicates in arm.c */ ! #define PREDICATE_CODES \ ! {"s_register_operand", {SUBREG, REG}}, \ ! {"arm_add_operand", {SUBREG, REG, CONST_INT}}, \ ! {"fpu_add_operand", {SUBREG, REG, CONST_DOUBLE}}, \ ! {"arm_rhs_operand", {SUBREG, REG, CONST_INT}}, \ ! {"fpu_rhs_operand", {SUBREG, REG, CONST_DOUBLE}}, \ ! {"arm_not_operand", {SUBREG, REG, CONST_INT}}, \ ! {"shiftable_operator", {PLUS, MINUS, AND, IOR, XOR}}, \ ! {"minmax_operator", {SMIN, SMAX, UMIN, UMAX}}, \ ! {"shift_operator", {ASHIFT, LSHIFT, ASHIFTRT, LSHIFTRT, MULT}}, \ ! {"di_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE, MEM}}, \ ! {"load_multiple_operation", {PARALLEL}}, \ ! {"store_multiple_operation", {PARALLEL}}, \ ! {"equality_operator", {EQ, NE}}, \ ! {"arm_rhsm_operand", {SUBREG, REG, CONST_INT, MEM}}, \ ! {"const_shift_operand", {CONST_INT}}, \ ! {"index_operand", {SUBREG, REG, CONST_INT}}, \ ! {"cc_register", {REG}}, /* Assembler output control */ + #ifndef ARM_OS_NAME + #define ARM_OS_NAME "(generic)" + #endif + /* The text to go at the start of the assembler file */ #define ASM_FILE_START(STREAM) \ *************** *** 961,966 **** { \ extern char *version_string; \ ! \ ! fprintf (STREAM,"@ Generated by gcc %s for ARM/RISCiX\n", version_string); \ fprintf (STREAM,"rfp\t.req\tr9\n"); \ fprintf (STREAM,"fp\t.req\tr11\n"); \ --- 1398,1404 ---- { \ extern char *version_string; \ ! \ ! fprintf (STREAM,"@ Generated by gcc %s for ARM/%s\n", version_string, \ ! ARM_OS_NAME); \ fprintf (STREAM,"rfp\t.req\tr9\n"); \ fprintf (STREAM,"fp\t.req\tr11\n"); \ *************** *** 986,996 **** "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ "r8","rfp", "sl", "fp", "ip", "sp", "lr", "pc", \ ! "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7" \ } /* DBX register number for a given compiler register number */ #define DBX_REGISTER_NUMBER(REGNO) (REGNO) ! /* Generate DBX debugging information. */ #define DBX_DEBUGGING_INFO 1 --- 1424,1441 ---- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ "r8","rfp", "sl", "fp", "ip", "sp", "lr", "pc", \ ! "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ ! "cc", "sfp", "afp" \ } + /* Arm Assembler barfs on dollars */ + #define DOLLARS_IN_IDENTIFIERS 0 + + #define NO_DOLLAR_IN_LABEL + /* DBX register number for a given compiler register number */ #define DBX_REGISTER_NUMBER(REGNO) (REGNO) ! /* Generate DBX debugging information. riscix.h will undefine this because ! the native assembler does not support stabs. */ #define DBX_DEBUGGING_INFO 1 *************** *** 998,1001 **** --- 1443,1456 ---- #define DBX_CONTIN_LENGTH 0 + /* Output a source filename for the debugger. RISCiX dbx insists that the + ``desc'' field is set to compiler version number >= 315 (sic). */ + #define DBX_OUTPUT_MAIN_SOURCE_FILENAME(STREAM,NAME) \ + do { \ + fprintf (STREAM, ".stabs \"%s\",%d,0,315,%s\n", (NAME), N_SO, \ + <ext_label_name[1]); \ + text_section (); \ + ASM_OUTPUT_INTERNAL_LABEL (STREAM, "Ltext", 0); \ + } while (0) + /* Output a label definition. */ #define ASM_OUTPUT_LABEL(STREAM,NAME) \ *************** *** 1026,1035 **** char *s = (char *) alloca (11 + strlen (PREFIX)); \ extern int arm_target_label, arm_ccfsm_state; \ \ ! if (arm_ccfsm_state == 3 && arm_target_label == (NUM)) \ ! arm_ccfsm_state = 0; \ ! strcpy (s, "*"); \ ! sprintf (&s[strlen (s)], "%s%d", (PREFIX), (NUM)); \ ! arm_asm_output_label (STREAM, s); \ } while (0) --- 1481,1495 ---- char *s = (char *) alloca (11 + strlen (PREFIX)); \ extern int arm_target_label, arm_ccfsm_state; \ + extern rtx arm_target_insn; \ \ ! if (arm_ccfsm_state == 3 && arm_target_label == (NUM) \ ! && !strcmp (PREFIX, "L")) \ ! { \ ! arm_ccfsm_state = 0; \ ! arm_target_insn = NULL; \ ! } \ ! strcpy (s, "*"); \ ! sprintf (&s[strlen (s)], "%s%d", (PREFIX), (NUM)); \ ! arm_asm_output_label (STREAM, s); \ } while (0) *************** *** 1062,1078 **** , fprintf (STREAM, "\t.word\tL%d\n", VALUE)) ! /* Output various types of constants. */ ! #define ASM_OUTPUT_DOUBLE(STREAM, VALUE) \ ! (arm_increase_location (sizeof (double)) \ ! , fprintf (STREAM, "\t.double\t%20.20f\n", VALUE)) ! ! #define ASM_OUTPUT_FLOAT(STREAM, VALUE) \ ! (arm_increase_location (sizeof (float)) \ ! , fprintf (STREAM, "\t.float\t%20.20f\n", VALUE)) ! ! #define ASM_OUTPUT_INT(STREAM, EXP) \ ! (fprintf (STREAM, "\t.word\t"), \ ! output_addr_const (STREAM, (EXP)), \ ! arm_increase_location (4), \ fputc ('\n', STREAM)) --- 1522,1575 ---- , fprintf (STREAM, "\t.word\tL%d\n", VALUE)) ! /* Output various types of constants. For real numbers we output hex, with ! a comment containing the "human" value, this allows us to pass NaN's which ! the riscix assembler doesn't understand (it also makes cross-assembling ! less likely to fail). */ ! ! #define ASM_OUTPUT_LONG_DOUBLE(STREAM,VALUE) \ ! do { char dstr[30]; \ ! long l[3]; \ ! arm_increase_location (12); \ ! REAL_VALUE_TO_TARGET_LONG_DOUBLE (VALUE, l); \ ! REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr); \ ! if (sizeof (int) == sizeof (long)) \ ! fprintf (STREAM, "\t.long 0x%x,0x%x,0x%x\t@ long double %s\n", \ ! l[2], l[1], l[0], dstr); \ ! else \ ! fprintf (STREAM, "\t.long 0x%lx,0x%lx,0x%lx\t@ long double %s\n",\ ! l[0], l[1], l[2], dstr); \ ! } while (0) ! ! ! #define ASM_OUTPUT_DOUBLE(STREAM, VALUE) \ ! do { char dstr[30]; \ ! long l[2]; \ ! arm_increase_location (8); \ ! REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l); \ ! REAL_VALUE_TO_DECIMAL (VALUE, "%.14g", dstr); \ ! if (sizeof (int) == sizeof (long)) \ ! fprintf (STREAM, "\t.long 0x%x, 0x%x\t@ double %s\n", l[0], l[1],\ ! dstr); \ ! else \ ! fprintf (STREAM, "\t.long 0x%lx, 0x%lx\t@ double %s\n", l[0], \ ! l[1], dstr); \ ! } while (0) ! ! #define ASM_OUTPUT_FLOAT(STREAM, VALUE) \ ! do { char dstr[30]; \ ! long l; \ ! arm_increase_location (4); \ ! REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \ ! REAL_VALUE_TO_DECIMAL (VALUE, "%.7g", dstr); \ ! if (sizeof (int) == sizeof (long)) \ ! fprintf (STREAM, "\t.word 0x%x\t@ float %s\n", l, dstr); \ ! else \ ! fprintf (STREAM, "\t.word 0x%lx\t@ float %s\n", l, dstr); \ ! } while (0); ! ! #define ASM_OUTPUT_INT(STREAM, EXP) \ ! (fprintf (STREAM, "\t.word\t"), \ ! output_addr_const (STREAM, (EXP)), \ ! arm_increase_location (4), \ fputc ('\n', STREAM)) *************** *** 1160,1164 **** instructions conditional. Suffixes like s (affect flags) and b (bytewise load/store) need to stay suffixes, so the possible condition code comes ! before these suffixes. */ #define ASM_OUTPUT_OPCODE(STREAM, PTR) \ { \ --- 1657,1663 ---- instructions conditional. Suffixes like s (affect flags) and b (bytewise load/store) need to stay suffixes, so the possible condition code comes ! before these suffixes. %d or %D may appear in the opcode if ! it can take a condition; a null rtx will cause no condition to be added, ! this is what we expect to happen if arm_ccfsm_state is non-zero. */ #define ASM_OUTPUT_OPCODE(STREAM, PTR) \ { \ *************** *** 1168,1182 **** \ fflush (STREAM); /* XXX for debugging only. */ \ ! if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) \ ! { \ ! fprintf (STREAM, "@ \t"); \ ! arm_ccfsm_state += 2; \ ! } \ ! else if (arm_ccfsm_state == 3 || arm_ccfsm_state == 4) \ { \ ! for (i = 0; *(PTR) != ' ' && *(PTR) != '\t' && i < 3; i++, (PTR)++) \ putc (*(PTR), STREAM); \ fprintf (STREAM, "%s", arm_condition_codes[arm_current_cc]); \ ! for (; *(PTR) != ' ' && *(PTR) != '\t'; (PTR)++) \ putc (*(PTR), STREAM); \ } \ --- 1667,1677 ---- \ fflush (STREAM); /* XXX for debugging only. */ \ ! if (arm_ccfsm_state == 3 || arm_ccfsm_state == 4) \ { \ ! for (i = 0; *(PTR) != ' ' && *(PTR) != '\t' && *(PTR) != '%' && i < 3;\ ! i++, (PTR)++) \ putc (*(PTR), STREAM); \ fprintf (STREAM, "%s", arm_condition_codes[arm_current_cc]); \ ! for (; *(PTR) != ' ' && *(PTR) != '\t' && *(PTR) != '%'; (PTR)++) \ putc (*(PTR), STREAM); \ } \ *************** *** 1192,1233 **** a ldm/stm style multi-reg. */ #define PRINT_OPERAND(STREAM, X, CODE) \ ! { \ ! if ((CODE) == 'R') \ ! fputs (reg_names[REGNO (X) + 1], (STREAM)); \ ! else if (GET_CODE (X) == REG) \ ! { \ ! if ((CODE) != 'M') \ ! fputs (reg_names[REGNO (X)], (STREAM)); \ ! else \ ! fprintf ((STREAM), "{%s-%s}", \ ! reg_names[REGNO (X)], \ ! reg_names[REGNO (X) - 1 \ ! + ((GET_MODE_SIZE (GET_MODE (X)) \ ! + GET_MODE_SIZE (SImode) - 1) \ ! / GET_MODE_SIZE (SImode))]); \ ! } \ ! else if (GET_CODE (X) == MEM) \ ! { \ ! extern int output_memory_reference_mode; \ ! output_memory_reference_mode = GET_MODE (X); \ ! output_address (XEXP (X, 0)); \ ! } \ ! else if (GET_CODE(X) == CONST_DOUBLE) \ ! { \ ! union real_extract u; \ ! u.i[0] = CONST_DOUBLE_LOW (X); \ ! u.i[1] = CONST_DOUBLE_HIGH (X); \ ! fprintf(STREAM,"#%20.20f",u.d); \ ! } \ ! else if (GET_CODE (X) == NEG) \ ! { \ ! fputc ('-', (STREAM)); \ ! output_operand ((X), 0); \ ! } \ ! else \ ! { \ ! fputc('#', STREAM); \ ! output_addr_const(STREAM, X); \ ! } \ } --- 1687,1735 ---- a ldm/stm style multi-reg. */ #define PRINT_OPERAND(STREAM, X, CODE) \ ! { \ ! if ((CODE) == 'd') \ ! { \ ! if (X) \ ! fputs (arm_condition_codes[get_arm_condition_code (X)], \ ! (STREAM)); \ ! } \ ! else if ((CODE) == 'D') \ ! { \ ! if (X) \ ! fputs (arm_condition_codes[get_arm_condition_code (X) ^ 1], \ ! (STREAM)); \ ! } \ ! else if ((CODE) == 'R') \ ! fputs (reg_names[REGNO (X) + 1], (STREAM)); \ ! else if (GET_CODE (X) == REG) \ ! { \ ! if ((CODE) != 'M') \ ! fputs (reg_names[REGNO (X)], (STREAM)); \ ! else \ ! fprintf ((STREAM), "{%s-%s}", \ ! reg_names[REGNO (X)], \ ! reg_names[REGNO (X) - 1 \ ! + ((GET_MODE_SIZE (GET_MODE (X)) \ ! + GET_MODE_SIZE (SImode) - 1) \ ! / GET_MODE_SIZE (SImode))]); \ ! } \ ! else if (GET_CODE (X) == MEM) \ ! { \ ! extern int output_memory_reference_mode; \ ! output_memory_reference_mode = GET_MODE (X); \ ! output_address (XEXP (X, 0)); \ ! } \ ! else if (GET_CODE(X) == CONST_DOUBLE) \ ! fprintf(STREAM,"#%s", fp_immediate_constant(X)); \ ! else if (GET_CODE (X) == NEG) \ ! { \ ! fputc ('-', (STREAM)); \ ! output_operand ((X), 0); \ ! } \ ! else \ ! { \ ! fputc('#', STREAM); \ ! output_addr_const(STREAM, X); \ ! } \ } *************** *** 1281,1288 **** else \ abort(); \ ! fprintf (STREAM, "[%s, %s%s, asl#%d]", base_reg_name, \ is_minus ? "-" : "", reg_names[REGNO (index)], \ shift); \ break; \ \ default: \ --- 1783,1805 ---- else \ abort(); \ ! fprintf (STREAM, "[%s, %s%s, asl #%d]", base_reg_name, \ is_minus ? "-" : "", reg_names[REGNO (index)], \ shift); \ break; \ + case ASHIFTRT: \ + case LSHIFTRT: \ + case ASHIFT: \ + case LSHIFT: \ + case ROTATERT: \ + { \ + char *shift_type = shift_instr (GET_CODE (index), \ + &XEXP (index, 1)); \ + shift = INTVAL (XEXP (index, 1)); \ + index = XEXP (index, 0); \ + fprintf (STREAM, "[%s, %s%s, %s #%d]", base_reg_name, \ + is_minus ? "-" : "", reg_names[REGNO (index)], \ + shift_type, shift); \ + break; \ + } \ \ default: \ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/arm/arm.md gcc-2.5.0/config/arm/arm.md *** gcc-2.4.5/config/arm/arm.md Tue May 18 18:07:32 1993 --- gcc-2.5.0/config/arm/arm.md Tue Oct 19 17:34:39 1993 *************** *** 1,6 **** ;;- Machine description Acorn RISC Machine for GNU compiler ! ;; Copyright (C) 1991 Free Software Foundation, Inc. ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) ;; and Martin Simmons (@harleqn.co.uk). ;; This file is part of GNU CC. --- 1,7 ---- ;;- Machine description Acorn RISC Machine for GNU compiler ! ;; Copyright (C) 1991, 1993 Free Software Foundation, Inc. ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) ;; and Martin Simmons (@harleqn.co.uk). + ;; More major hacks by Richard Earnshaw (rwe11@cl.cam.ac.uk) ;; This file is part of GNU CC. *************** *** 27,37 **** ;; function's constant pool, since different instructions are needed when the ;; constant pool is more than 4095 bytes away from the PC. ;; Addition insns. (define_insn "adddi3" ! [(set (match_operand:DI 0 "di_operand" "=&r") ! (plus:DI (match_operand:DI 1 "di_operand" "%r") ! (match_operand:DI 2 "di_operand" "r")))] "" "* --- 28,152 ---- ;; function's constant pool, since different instructions are needed when the ;; constant pool is more than 4095 bytes away from the PC. + + ;; There are patterns in this file to support XFmode arithmetic. + ;; Unfortunately RISCiX doesn't work well with these so they are disabled. + ;; (See arm.h) + + ;; UNSPEC Usage: + ;; 0 `sin' operation: operand 0 is the result, operand 1 the parameter, + ;; the mode is MODE_FLOAT + ;; 1 `cos' operation: operand 0 is the result, operand 1 the parameter, + ;; the mode is MODE_FLOAT + + ;; Attributes + + ; condition codes: this one is used by final_prescan_insn to speed up + ; conditionalizing instructions. It saves having to scan the rtl to see if + ; it uses or alters the condition codes. + + ; USE means that the condition codes are used by the insn in the process of + ; outputting code, this means (at present) that we can't use the insn in + ; inlined branches + + ; SET means that the purpose of the insn is to set the condition codes in a + ; well defined manner. + + ; CLOB means that the condition codes are altered in an undefined manner, if + ; they are altered at all + + ; JUMP_CLOB is used when the conditions are not defined if a branch is taken, + ; but are if the branch wasn't taken; the effect is to limit the branch + ; elimination scanning. + + ; NOCOND means that the condition codes are niether altered nor affect the + ; output of this insn + + (define_attr "conds" "use,set,clob,jump_clob,nocond" + (const_string "nocond")) + + ; CPU attribute is used to determine whether condition codes are clobbered + ; by a call insn: on the arm6 they are if in 32-bit addressing mode; on the + ; arm2 and arm3 the condition codes are restored by the return. + + (define_attr "cpu" "arm2,arm3,arm6" (const (symbol_ref "arm_cpu_attr"))) + + ; LENGTH, all instructions are 4 bytes + (define_attr "length" "" (const_int 1)) + + ; An assembler sequence may clobber the condition codes without us knowing + (define_asm_attributes + [(set_attr "conds" "clob") + (set_attr "length" "1")]) + + ; TYPE attribute is used to detect floating point instructions which, if + ; running on a co-processor can run in parallel with other, basic instructions + ; If write-buffer scheduling is enabled then it can also be used in the + ; scheduling of writes. + + ; Classification of each insn + ; normal any data instruction that doesn't hit memory or fp regs + ; block blockage insn, this blocks all functional units + ; float a floating point arithmetic operation (subject to expansion) + ; float_em a floating point arithmetic operation that is normally emulated + ; f_load a floating point load from memory + ; f_store a floating point store to memory + ; f_mem_r a transfer of a floating point register to a real reg via mem + ; r_mem_f the reverse of f_mem_r + ; f_2_r fast transfer float to arm (no memory needed) + ; r_2_f fast transfer arm to float + ; call a subroutine call + ; load any load from memory + ; store1 store 1 word to memory from arm registers + ; store2 store 2 words + ; store3 store 3 words + ; store4 store 4 words + ; + (define_attr "type" + "normal,block,float,float_em,f_load,f_store,f_mem_r,r_mem_f,f_2_r,r_2_f,call,load,store1,store2,store3,store4" + (const_string "normal")) + + (define_attr "write_conflict" "no,yes" + (if_then_else (eq_attr "type" + "block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load") + (const_string "yes") + (const_string "no"))) + + ; The write buffer on some of the arm6 processors is hard to model exactly. + ; There is room in the buffer for up to two addresses and up to eight words + ; of memory, but the two needn't be split evenly. When writing the two + ; addresses are fully pipelined. However, a read from memory that is not + ; currently in the cache will block until the writes have completed. + ; It is normally the case that FCLK and MCLK will be in the ratio 2:1, so + ; writes will take 2 FCLK cycles per word, if FCLK and MCLK are asynchronous + ; (they aren't allowed to be at present) then there is a startup cost of 1MCLK + ; cycle to add as well. + + ;; (define_function_unit {name} {num-units} {n-users} {test} + ;; {ready-delay} {issue-delay} [{conflict-list}]) + ;; This is not well tuned, but I don't have all the details. + (define_function_unit "fpa" 1 1 (eq_attr "type" "float") 5 0) + + (define_function_unit "write_buf" 1 2 (eq_attr "type" "store1") 3 3 + [(eq_attr "write_conflict" "yes")]) + (define_function_unit "write_buf" 1 2 (eq_attr "type" "store2") 5 5 + [(eq_attr "write_conflict" "yes")]) + (define_function_unit "write_buf" 1 2 (eq_attr "type" "store3") 7 7 + [(eq_attr "write_conflict" "yes")]) + (define_function_unit "write_buf" 1 2 (eq_attr "type" "store4") 9 9 + [(eq_attr "write_conflict" "yes")]) + (define_function_unit "write_buf" 1 2 (eq_attr "type" "r_mem_f") 3 3 + [(eq_attr "write_conflict" "yes")]) + ;; Note: For DImode insns, there is normally no reason why operands should + ;; not be in the same register, what we don't want is for something being + ;; written to partially overlap something that is an input. + ;; Addition insns. (define_insn "adddi3" ! [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! (plus:DI (match_operand:DI 1 "s_register_operand" "%0,0") ! (match_operand:DI 2 "s_register_operand" "r,0"))) ! (clobber (reg:CC 24))] "" "* *************** *** 38,80 **** arm_output_asm_insn (\"adds\\t%0, %1, %2\", operands); return (arm_output_asm_insn (\"adc\\t%R0, %R1, %R2\", operands)); ! ") (define_insn "addsi3" ! [(set (match_operand:SI 0 "register_operand" "=r,r") ! (plus:SI (match_operand:SI 1 "register_operand" "r,r") ! (match_operand:SI 2 "general_operand" "r,n")))] "" "* ! switch (which_alternative) { ! case 0: ! return (arm_output_asm_insn (\"add\\t%0, %1, %2\", operands)); ! case 1: ! return (output_add_immediate (operands)); } ") ! (define_insn "addsf3" ! [(set (match_operand:SF 0 "register_operand" "=f") ! (plus:SF (match_operand:SF 1 "register_operand" "f") ! (match_operand:SF 2 "fpu_rhs_operand" "fG")))] "" "* ! return (arm_output_asm_insn (\"adfs\\t%0, %1, %2\", operands)); ") (define_insn "adddf3" ! [(set (match_operand:DF 0 "register_operand" "=f") ! (plus:DF (match_operand:DF 1 "register_operand" "f") ! (match_operand:DF 2 "fpu_rhs_operand" "fG")))] "" "* return (arm_output_asm_insn (\"adfd\\t%0, %1, %2\", operands)); ! ") (define_insn "subdi3" ! [(set (match_operand:DI 0 "di_operand" "=&r") ! (minus:DI (match_operand:DI 1 "di_operand" "%r") ! (match_operand:DI 2 "di_operand" "r")))] "" "* --- 153,431 ---- arm_output_asm_insn (\"adds\\t%0, %1, %2\", operands); return (arm_output_asm_insn (\"adc\\t%R0, %R1, %R2\", operands)); ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "2")]) ! ! (define_insn "" ! [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! (plus:DI (sign_extend:DI ! (match_operand:SI 1 "s_register_operand" "r,r")) ! (match_operand:DI 2 "s_register_operand" "r,0"))) ! (clobber (reg:CC 24))] ! "" ! "* ! arm_output_asm_insn (\"adds\\t%0, %2, %1\", operands); ! return (arm_output_asm_insn (\"adc\\t%R0, %R2, %1, asr #31\", operands)); ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "2")]) ! ! (define_insn "" ! [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! (plus:DI (zero_extend:DI ! (match_operand:SI 1 "s_register_operand" "r,r")) ! (match_operand:DI 2 "s_register_operand" "r,0"))) ! (clobber (reg:CC 24))] ! "" ! "* ! arm_output_asm_insn (\"adds\\t%0, %2, %1\", operands); ! return (arm_output_asm_insn (\"adc\\t%R0, %R2, #0\", operands)); ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "2")]) (define_insn "addsi3" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (plus:SI (match_operand:SI 1 "s_register_operand" "r") ! (match_operand:SI 2 "arm_add_operand" "rL")))] "" "* ! if (GET_CODE (operands[2]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[2]))) { ! operands[2] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[2])); ! return arm_output_asm_insn (\"sub\\t%0, %1, %2\", operands); } + return arm_output_asm_insn (\"add\\t%0, %1, %2\", operands); ") ! (define_insn "" ! [(set (reg:CC_NOOV 24) ! (compare:CC_NOOV (plus:SI (match_operand:SI 1 "s_register_operand" "r") ! (match_operand:SI 2 "arm_add_operand" "rL")) ! (const_int 0))) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (plus:SI (match_dup 1) (match_dup 2)))] ! "" ! "* ! if (GET_CODE (operands[2]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[2]))) ! { ! operands[2] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[2])); ! return arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands); ! } ! return (arm_output_asm_insn (\"adds\\t%0, %1, %2\", operands)); ! " ! [(set_attr "conds" "set")]) ! ! (define_insn "" ! [(set (reg:CC 24) ! (compare:CC (match_operand:SI 1 "s_register_operand" "r") ! (neg:SI (match_operand:SI 2 "arm_add_operand" "rL")))) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (plus:SI (match_dup 1) (match_dup 2)))] "" "* ! if (GET_CODE (operands[2]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[2]))) ! { ! operands[2] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[2])); ! return arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands); ! } ! return (arm_output_asm_insn (\"adds\\t%0, %1, %2\", operands)); ! " ! [(set_attr "conds" "set")]) ! ! (define_insn "incscc" ! [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! (plus:SI (match_operator:SI 2 "comparison_operator" ! [(reg 24) (const_int 0)]) ! (match_operand:SI 1 "s_register_operand" "0,?r")))] ! "" ! "* ! if (which_alternative == 1) ! arm_output_asm_insn (\"mov%D2\\t%0, %1\", operands); ! return arm_output_asm_insn (\"add%d2\\t%0, %1, #1\", operands); ! " ! [(set_attr "conds" "use") ! (set_attr "length" "*,2")]) ! ! ; If a constant is too big to fit in a single instruction then the constant ! ; will be pre-loaded into a register taking at least two insns, we might be ! ; able to merge it with an add, but it depends on the exact value. ! ! (define_split ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (plus:SI (match_operand:SI 1 "s_register_operand" "r") ! (match_operand:SI 2 "immediate_operand" "n")))] ! "!(const_ok_for_arm (INTVAL (operands[2])) ! || const_ok_for_arm (-INTVAL (operands[2])))" ! [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2))) ! (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))] ! " ! { ! unsigned int val = (unsigned) INTVAL (operands[2]); ! int i; ! unsigned int temp; ! ! /* this code is similar to the approach followed in movsi, but it must ! generate exactly two insns */ ! ! for (i = 30; i >= 0; i -= 2) ! { ! if (val & (3 << i)) ! { ! i -= 6; ! if (i < 0) i = 0; ! if (const_ok_for_arm (temp = (val & ~(255 << i)))) ! { ! val &= 255 << i; ! break; ! } ! /* we might be able to do this as (larger number - small number) */ ! temp = ((val >> i) & 255) + 1; ! if (temp > 255 && i < 24) ! { ! i += 2; ! temp = ((val >> i) & 255) + 1; ! } ! if (const_ok_for_arm ((temp << i) - val)) ! { ! i = temp << i; ! temp = (unsigned) - (int) (i - val); ! val = i; ! break; ! } ! FAIL; ! } ! } ! /* if we got here, we have found a way of doing it in two instructions. ! the two constants are in val and temp */ ! operands[2] = GEN_INT ((int)val); ! operands[3] = GEN_INT ((int)temp); ! } ") + (define_insn "addsf3" + [(set (match_operand:SF 0 "s_register_operand" "=f,f") + (plus:SF (match_operand:SF 1 "s_register_operand" "f,f") + (match_operand:SF 2 "fpu_add_operand" "fG,H")))] + "" + "* + { + REAL_VALUE_TYPE r; + + switch (which_alternative) + { + case 0: + return arm_output_asm_insn (\"adfs\\t%0, %1, %2\", operands); + case 1: + REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]); + r = REAL_VALUE_NEGATE (r); + operands[2] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[2])); + return arm_output_asm_insn (\"sufs\\t%0, %1, %2\", operands); + } + } + " + [(set_attr "type" "float")]) + (define_insn "adddf3" ! [(set (match_operand:DF 0 "s_register_operand" "=f,f") ! (plus:DF (match_operand:DF 1 "s_register_operand" "f,f") ! (match_operand:DF 2 "fpu_add_operand" "fG,H")))] ! "" ! "* ! { ! REAL_VALUE_TYPE r; ! ! switch (which_alternative) ! { ! case 0: ! return (arm_output_asm_insn (\"adfd\\t%0, %1, %2\", operands)); ! case 1: ! REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]); ! r = REAL_VALUE_NEGATE (r); ! operands[2] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[2])); ! return arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands); ! } ! } ! " ! [(set_attr "type" "float")]) ! ! (define_insn "" ! [(set (match_operand:DF 0 "s_register_operand" "=f,f") ! (plus:DF (float_extend:DF ! (match_operand:SF 1 "s_register_operand" "f,f")) ! (match_operand:DF 2 "fpu_add_operand" "fG,H")))] ! "" ! "* ! { ! REAL_VALUE_TYPE r; ! ! switch (which_alternative) ! { ! case 0: ! return (arm_output_asm_insn (\"adfd\\t%0, %1, %2\", operands)); ! case 1: ! REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]); ! r = REAL_VALUE_NEGATE (r); ! operands[2] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[2])); ! return arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands); ! } ! } ! " ! [(set_attr "type" "float")]) ! ! (define_insn "" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (plus:DF (match_operand:DF 1 "s_register_operand" "f") ! (float_extend:DF ! (match_operand:SF 2 "s_register_operand" "f"))))] "" "* return (arm_output_asm_insn (\"adfd\\t%0, %1, %2\", operands)); ! " ! [(set_attr "type" "float")]) ! ! (define_insn "" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (plus:DF (float_extend:DF ! (match_operand:SF 1 "s_register_operand" "f")) ! (float_extend:DF ! (match_operand:SF 2 "s_register_operand" "f"))))] ! "" ! "* ! return (arm_output_asm_insn (\"adfd\\t%0, %1, %2\", operands)); ! " ! [(set_attr "type" "float")]) ! ! (define_insn "addxf3" ! [(set (match_operand:XF 0 "s_register_operand" "=f,f") ! (plus:XF (match_operand:XF 1 "s_register_operand" "f,f") ! (match_operand:XF 2 "fpu_add_operand" "fG,H")))] ! "ENABLE_XF_PATTERNS" ! "* ! { ! REAL_VALUE_TYPE r; + switch (which_alternative) + { + case 0: + return (arm_output_asm_insn (\"adfe\\t%0, %1, %2\", operands)); + case 1: + REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]); + r = REAL_VALUE_NEGATE (r); + operands[2] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[2])); + return arm_output_asm_insn (\"sufe\\t%0, %1, %2\", operands); + } + } + " + [(set_attr "type" "float")]) + (define_insn "subdi3" ! [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r") ! (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0") ! (match_operand:DI 2 "s_register_operand" "r,0,0"))) ! (clobber (reg:CC 24))] "" "* *************** *** 81,90 **** arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands); return (arm_output_asm_insn (\"sbc\\t%R0, %R1, %R2\", operands)); ! ") (define_insn "subsi3" ! [(set (match_operand:SI 0 "register_operand" "=r,r,r") ! (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I") ! (match_operand:SI 2 "general_operand" "r,n,r")))] "" "* --- 432,515 ---- arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands); return (arm_output_asm_insn (\"sbc\\t%R0, %R1, %R2\", operands)); ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "2")]) ! ! (define_insn "" ! [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! (minus:DI (match_operand:DI 1 "s_register_operand" "?r,0") ! (zero_extend:DI ! (match_operand:SI 2 "s_register_operand" "r,r")))) ! (clobber (reg:CC 24))] ! "" ! "* ! arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands); ! return (arm_output_asm_insn (\"sbc\\t%R0, %R1, #0\", operands)); ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "2")]) ! ! (define_insn "" ! [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! (minus:DI (match_operand:DI 1 "s_register_operand" "r,0") ! (sign_extend:DI ! (match_operand:SI 2 "s_register_operand" "r,r")))) ! (clobber (reg:CC 24))] ! "" ! "* ! arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands); ! return (arm_output_asm_insn (\"sbc\\t%R0, %R1, %2, asr #31\", operands)); ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "2")]) ! ! (define_insn "" ! [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! (minus:DI (zero_extend:DI ! (match_operand:SI 2 "s_register_operand" "r,r")) ! (match_operand:DI 1 "s_register_operand" "?r,0"))) ! (clobber (reg:CC 24))] ! "" ! "* ! arm_output_asm_insn (\"rsbs\\t%0, %1, %2\", operands); ! return (arm_output_asm_insn (\"rsc\\t%R0, %R1, #0\", operands)); ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "2")]) + (define_insn "" + [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") + (minus:DI (sign_extend:DI + (match_operand:SI 2 "s_register_operand" "r,r")) + (match_operand:DI 1 "s_register_operand" "?r,0"))) + (clobber (reg:CC 24))] + "" + "* + arm_output_asm_insn (\"rsbs\\t%0, %1, %2\", operands); + return (arm_output_asm_insn (\"rsc\\t%R0, %R1, %2, asr #31\", operands)); + " + [(set_attr "conds" "clob") + (set_attr "length" "2")]) + + (define_insn "" + [(set (match_operand:DI 0 "s_register_operand" "=r") + (minus:DI (zero_extend:DI + (match_operand:SI 1 "s_register_operand" "r")) + (zero_extend:DI + (match_operand:SI 2 "s_register_operand" "r")))) + (clobber (reg:CC 24))] + "" + "* + arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands); + return (arm_output_asm_insn (\"rsc\\t%R0, %1, %1 @ extend carry\", + operands)); + " + [(set_attr "conds" "clob") + (set_attr "length" "2")]) + (define_insn "subsi3" ! [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I") ! (match_operand:SI 2 "arm_rhs_operand" "rI,r")))] "" "* *************** *** 94,100 **** return (arm_output_asm_insn (\"sub\\t%0, %1, %2\", operands)); case 1: - operands[2] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[2])); - return (output_add_immediate (operands)); - case 2: return (arm_output_asm_insn (\"rsb\\t%0, %2, %1\", operands)); } --- 519,522 ---- *************** *** 101,106 **** ") (define_insn "subsf3" ! [(set (match_operand:SF 0 "register_operand" "=f,f") (minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G") (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))] --- 523,561 ---- ") + (define_insn "" + [(set (reg:CC_NOOV 24) + (compare:CC_NOOV (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I") + (match_operand:SI 2 "arm_rhs_operand" "rI,r")) + (const_int 0))) + (set (match_operand:SI 0 "s_register_operand" "=r,r") + (minus:SI (match_dup 1) (match_dup 2)))] + "" + "* + switch (which_alternative) + { + case 0: + return arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands); + case 1: + return arm_output_asm_insn (\"rsbs\\t%0, %2, %1\", operands); + } + " + [(set_attr "conds" "set")]) + + (define_insn "decscc" + [(set (match_operand:SI 0 "s_register_operand" "=r,r") + (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r") + (match_operator:SI 2 "comparison_operator" + [(reg 24) (const_int 0)])))] + "" + "* + if (which_alternative == 1) + arm_output_asm_insn (\"mov%D2\\t%0, %1\", operands); + return arm_output_asm_insn (\"sub%d2\\t%0, %1, #1\", operands); + " + [(set_attr "conds" "use") + (set_attr "length" "*,2")]) + (define_insn "subsf3" ! [(set (match_operand:SF 0 "s_register_operand" "=f,f") (minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G") (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))] *************** *** 114,123 **** return (arm_output_asm_insn (\"rsfs\\t%0, %2, %1\", operands)); } ! ") (define_insn "subdf3" ! [(set (match_operand:DF 0 "register_operand" "=f,f") (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G") ! (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))] "" "* --- 569,579 ---- return (arm_output_asm_insn (\"rsfs\\t%0, %2, %1\", operands)); } ! " ! [(set_attr "type" "float")]) (define_insn "subdf3" ! [(set (match_operand:DF 0 "s_register_operand" "=f,f") (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G") ! (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))] "" "* *************** *** 126,189 **** case 0: return (arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands)); ! case 2: return (arm_output_asm_insn (\"rsfd\\t%0, %2, %1\", operands)); } ! ") ;; Multiplication insns ! ;; The `&' is too strict, but at least generates correct code. (define_insn "mulsi3" ! [(set (match_operand:SI 0 "register_operand" "=&r") ! (mult:SI (match_operand:SI 1 "register_operand" "%r") ! (match_operand:SI 2 "register_operand" "r")))] "" "* ! if (REGNO (operands[0]) == REGNO (operands[1])) ! return (arm_output_asm_insn (\"mul\\t%0, %2, %1\", operands)); ! else ! return (arm_output_asm_insn (\"mul\\t%0, %1, %2\", operands)); ") ;; Unnamed templates to match MLA instruction. (define_insn "" ! [(set (match_operand:SI 0 "register_operand" "=&r") (plus:SI ! (mult:SI (match_operand:SI 1 "register_operand" "%r") ! (match_operand:SI 2 "register_operand" "r")) ! (match_operand:SI 3 "register_operand" "r")))] "" "* ! if (REGNO (operands[0]) == REGNO (operands[1])) ! return (arm_output_asm_insn (\"mla\\t%0, %2, %1, %3\", operands)); ! else ! return (arm_output_asm_insn (\"mla\\t%0, %1, %2, %3\", operands)); ") (define_insn "" ! [(set (match_operand:SI 0 "register_operand" "=&r") ! (plus:SI ! (match_operand:SI 3 "register_operand" "r") ! (mult:SI (match_operand:SI 1 "register_operand" "%r") ! (match_operand:SI 2 "register_operand" "r"))))] "" "* ! if (REGNO (operands[0]) == REGNO (operands[1])) ! return (arm_output_asm_insn (\"mla\\t%0, %2, %1, %3\", operands)); ! else ! return (arm_output_asm_insn (\"mla\\t%0, %1, %2, %3\", operands)); ! ") (define_insn "mulsf3" ! [(set (match_operand:SF 0 "register_operand" "=f") ! (mult:SF (match_operand:SF 1 "register_operand" "f") (match_operand:SF 2 "fpu_rhs_operand" "fG")))] "" ! "*return (arm_output_asm_insn (\"mufs\\t%0, %1, %2\", operands));") (define_insn "muldf3" ! [(set (match_operand:DF 0 "register_operand" "=f") ! (mult:DF (match_operand:DF 1 "register_operand" "f") (match_operand:DF 2 "fpu_rhs_operand" "fG")))] "" --- 582,744 ---- case 0: return (arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands)); ! case 1: return (arm_output_asm_insn (\"rsfd\\t%0, %2, %1\", operands)); } ! " ! [(set_attr "type" "float")]) ! ! (define_insn "" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (minus:DF (float_extend:DF ! (match_operand:SF 1 "s_register_operand" "f")) ! (match_operand:DF 2 "fpu_rhs_operand" "fG")))] ! "" ! "* ! return arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands); ! " ! [(set_attr "type" "float")]) ! ! (define_insn "" ! [(set (match_operand:DF 0 "s_register_operand" "=f,f") ! (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G") ! (float_extend:DF ! (match_operand:SF 2 "s_register_operand" "f,f"))))] ! "" ! "* ! switch (which_alternative) ! { ! case 0: ! return (arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands)); ! case 1: ! return (arm_output_asm_insn (\"rsfd\\t%0, %2, %1\", operands)); ! } ! " ! [(set_attr "type" "float")]) ! ! (define_insn "" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (minus:DF (float_extend:DF ! (match_operand:SF 1 "s_register_operand" "f")) ! (float_extend:DF ! (match_operand:SF 2 "s_register_operand" "f"))))] ! "" ! "* ! return arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands); ! " ! [(set_attr "type" "float")]) ! ! (define_insn "subxf3" ! [(set (match_operand:XF 0 "s_register_operand" "=f,f") ! (minus:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G") ! (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))] ! "ENABLE_XF_PATTERNS" ! "* ! switch (which_alternative) ! { ! case 0: ! return (arm_output_asm_insn (\"sufe\\t%0, %1, %2\", operands)); ! case 1: ! return (arm_output_asm_insn (\"rsfe\\t%0, %2, %1\", operands)); ! } ! " ! [(set_attr "type" "float")]) ;; Multiplication insns ! ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same (define_insn "mulsi3" ! [(set (match_operand:SI 0 "s_register_operand" "=&r,&r") ! (mult:SI (match_operand:SI 2 "s_register_operand" "r,r") ! (match_operand:SI 1 "s_register_operand" "%?r,0")))] "" "* ! return (arm_output_asm_insn (\"mul\\t%0, %2, %1\", operands)); ") + (define_insn "" + [(set (reg:CC_NOOV 24) + (compare:CC_NOOV (mult:SI + (match_operand:SI 2 "s_register_operand" "r,r") + (match_operand:SI 1 "s_register_operand" "%?r,0")) + (const_int 0))) + (set (match_operand:SI 0 "s_register_operand" "=&r,&r") + (mult:SI (match_dup 2) (match_dup 1)))] + "" + "* + return (arm_output_asm_insn (\"muls\\t%0, %2, %1\", operands)); + " + [(set_attr "conds" "set")]) + + (define_insn "" + [(set (reg:CC_NOOV 24) + (compare:CC_NOOV (mult:SI + (match_operand:SI 2 "s_register_operand" "r,r") + (match_operand:SI 1 "s_register_operand" "%?r,0")) + (const_int 0))) + (clobber (match_scratch:SI 0 "=&r,&r"))] + "" + "* + return (arm_output_asm_insn (\"muls\\t%0, %2, %1\", operands)); + " + [(set_attr "conds" "set")]) + ;; Unnamed templates to match MLA instruction. (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r") (plus:SI ! (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r") ! (match_operand:SI 1 "s_register_operand" "%r,0,r,0")) ! (match_operand:SI 3 "s_register_operand" "?r,r,0,0")))] "" "* ! return (arm_output_asm_insn (\"mla\\t%0, %2, %1, %3\", operands)); ") (define_insn "" ! [(set (reg:CC_NOOV 24) ! (compare:CC_NOOV (plus:SI ! (mult:SI ! (match_operand:SI 2 "s_register_operand" "r,r,r,r") ! (match_operand:SI 1 "s_register_operand" "%r,0,r,0")) ! (match_operand:SI 3 "s_register_operand" "?r,r,0,0")) ! (const_int 0))) ! (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r") ! (plus:SI (mult:SI (match_dup 2) (match_dup 1)) ! (match_dup 3)))] "" "* ! return (arm_output_asm_insn (\"mlas\\t%0, %2, %1, %3\", operands)); ! " ! [(set_attr "conds" "set")]) ! ! (define_insn "" ! [(set (reg:CC_NOOV 24) ! (compare:CC_NOOV (plus:SI ! (mult:SI ! (match_operand:SI 2 "s_register_operand" "r,r,r,r") ! (match_operand:SI 1 "s_register_operand" "%r,0,r,0")) ! (match_operand:SI 3 "s_register_operand" "?r,r,0,0")) ! (const_int 0))) ! (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))] ! "" ! "* ! return (arm_output_asm_insn (\"mlas\\t%0, %2, %1, %3\", operands)); ! " ! [(set_attr "conds" "set")]) (define_insn "mulsf3" ! [(set (match_operand:SF 0 "s_register_operand" "=f") ! (mult:SF (match_operand:SF 1 "s_register_operand" "f") (match_operand:SF 2 "fpu_rhs_operand" "fG")))] "" ! "* ! return (arm_output_asm_insn (\"fmls\\t%0, %1, %2\", operands)); ! " ! [(set_attr "type" "float")]) (define_insn "muldf3" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (mult:DF (match_operand:DF 1 "s_register_operand" "f") (match_operand:DF 2 "fpu_rhs_operand" "fG")))] "" *************** *** 190,194 **** "* return (arm_output_asm_insn (\"mufd\\t%0, %1, %2\", operands)); ! ") ;; Division insns --- 745,794 ---- "* return (arm_output_asm_insn (\"mufd\\t%0, %1, %2\", operands)); ! " ! [(set_attr "type" "float")]) ! ! (define_insn "" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (mult:DF (float_extend:DF ! (match_operand:SF 1 "s_register_operand" "f")) ! (match_operand:DF 2 "fpu_rhs_operand" "fG")))] ! "" ! "* ! return (arm_output_asm_insn (\"mufd\\t%0, %1, %2\", operands)); ! " ! [(set_attr "type" "float")]) ! ! (define_insn "" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (mult:DF (match_operand:DF 1 "s_register_operand" "f") ! (float_extend:DF ! (match_operand:SF 2 "s_register_operand" "f"))))] ! "" ! "* ! return (arm_output_asm_insn (\"mufd\\t%0, %1, %2\", operands)); ! " ! [(set_attr "type" "float")]) ! ! (define_insn "" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (mult:DF (float_extend:DF ! (match_operand:SF 1 "s_register_operand" "f")) ! (float_extend:DF ! (match_operand:SF 2 "s_register_operand" "f"))))] ! "" ! "* ! return (arm_output_asm_insn (\"mufd\\t%0, %1, %2\", operands)); ! " ! [(set_attr "type" "float")]) ! ! (define_insn "mulxf3" ! [(set (match_operand:XF 0 "s_register_operand" "=f") ! (mult:XF (match_operand:XF 1 "s_register_operand" "f") ! (match_operand:XF 2 "fpu_rhs_operand" "fG")))] ! "ENABLE_XF_PATTERNS" ! "* ! return (arm_output_asm_insn (\"mufe\\t%0, %1, %2\", operands)); ! " ! [(set_attr "type" "float")]) ;; Division insns *************** *** 195,199 **** (define_insn "divsf3" ! [(set (match_operand:SF 0 "register_operand" "=f,f") (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G") (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))] --- 795,799 ---- (define_insn "divsf3" ! [(set (match_operand:SF 0 "s_register_operand" "=f,f") (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G") (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))] *************** *** 203,214 **** { case 0: ! return (arm_output_asm_insn (\"dvfs\\t%0, %1, %2\", operands)); case 1: ! return (arm_output_asm_insn (\"rdfs\\t%0, %2, %1\", operands)); } ! ") (define_insn "divdf3" ! [(set (match_operand:DF 0 "register_operand" "=f,f") (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G") (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))] --- 803,815 ---- { case 0: ! return (arm_output_asm_insn (\"fdvs\\t%0, %1, %2\", operands)); case 1: ! return (arm_output_asm_insn (\"frds\\t%0, %2, %1\", operands)); } ! " ! [(set_attr "type" "float")]) (define_insn "divdf3" ! [(set (match_operand:DF 0 "s_register_operand" "=f,f") (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G") (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))] *************** *** 222,226 **** return (arm_output_asm_insn (\"rdfd\\t%0, %2, %1\", operands)); } ! ") ;; Modulo insns --- 823,878 ---- return (arm_output_asm_insn (\"rdfd\\t%0, %2, %1\", operands)); } ! " ! [(set_attr "type" "float")]) ! ! (define_insn "" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (div:DF (float_extend:DF ! (match_operand:SF 1 "s_register_operand" "f")) ! (match_operand:DF 2 "fpu_rhs_operand" "fG")))] ! "" ! "* ! return (arm_output_asm_insn (\"dvfd\\t%0, %1, %2\", operands)); ! " ! [(set_attr "type" "float")]) ! ! (define_insn "" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (div:DF (match_operand:DF 1 "fpu_rhs_operand" "fG") ! (float_extend:DF ! (match_operand:SF 2 "s_register_operand" "f"))))] ! "" ! "* ! return (arm_output_asm_insn (\"rdfd\\t%0, %2, %1\", operands)); ! " ! [(set_attr "type" "float")]) ! ! (define_insn "" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (div:DF (float_extend:DF ! (match_operand:SF 1 "s_register_operand" "f")) ! (float_extend:DF ! (match_operand:SF 2 "s_register_operand" "f"))))] ! "" ! "* ! return (arm_output_asm_insn (\"dvfd\\t%0, %1, %2\", operands)); ! " ! [(set_attr "type" "float")]) ! ! (define_insn "divxf3" ! [(set (match_operand:XF 0 "s_register_operand" "=f,f") ! (div:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G") ! (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))] ! "ENABLE_XF_PATTERNS" ! "* ! switch (which_alternative) ! { ! case 0: ! return (arm_output_asm_insn (\"dvfe\\t%0, %1, %2\", operands)); ! case 1: ! return (arm_output_asm_insn (\"rdfe\\t%0, %2, %1\", operands)); ! } ! " ! [(set_attr "type" "float")]) ;; Modulo insns *************** *** 227,232 **** (define_insn "modsf3" ! [(set (match_operand:SF 0 "register_operand" "=f") ! (mod:SF (match_operand:SF 1 "register_operand" "f") (match_operand:SF 2 "fpu_rhs_operand" "fG")))] "" --- 879,884 ---- (define_insn "modsf3" ! [(set (match_operand:SF 0 "s_register_operand" "=f") ! (mod:SF (match_operand:SF 1 "s_register_operand" "f") (match_operand:SF 2 "fpu_rhs_operand" "fG")))] "" *************** *** 233,241 **** "* return (arm_output_asm_insn (\"rmfs\\t%0, %1, %2\", operands)); ! ") (define_insn "moddf3" ! [(set (match_operand:DF 0 "register_operand" "=f") ! (mod:DF (match_operand:DF 1 "register_operand" "f") (match_operand:DF 2 "fpu_rhs_operand" "fG")))] "" --- 885,894 ---- "* return (arm_output_asm_insn (\"rmfs\\t%0, %1, %2\", operands)); ! " ! [(set_attr "type" "float")]) (define_insn "moddf3" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (mod:DF (match_operand:DF 1 "s_register_operand" "f") (match_operand:DF 2 "fpu_rhs_operand" "fG")))] "" *************** *** 242,246 **** "* return (arm_output_asm_insn (\"rmfd\\t%0, %1, %2\", operands)); ! ") ;; Boolean and,ior,xor insns --- 895,944 ---- "* return (arm_output_asm_insn (\"rmfd\\t%0, %1, %2\", operands)); ! " ! [(set_attr "type" "float")]) ! ! (define_insn "" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (mod:DF (float_extend:DF ! (match_operand:SF 1 "s_register_operand" "f")) ! (match_operand:DF 2 "fpu_rhs_operand" "fG")))] ! "" ! "* ! return (arm_output_asm_insn (\"rmfd\\t%0, %1, %2\", operands)); ! " ! [(set_attr "type" "float")]) ! ! (define_insn "" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (mod:DF (match_operand:DF 1 "s_register_operand" "f") ! (float_extend:DF ! (match_operand:SF 2 "s_register_operand" "f"))))] ! "" ! "* ! return (arm_output_asm_insn (\"rmfd\\t%0, %1, %2\", operands)); ! " ! [(set_attr "type" "float")]) ! ! (define_insn "" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (mod:DF (float_extend:DF ! (match_operand:SF 1 "s_register_operand" "f")) ! (float_extend:DF ! (match_operand:SF 2 "s_register_operand" "f"))))] ! "" ! "* ! return (arm_output_asm_insn (\"rmfd\\t%0, %1, %2\", operands)); ! " ! [(set_attr "type" "float")]) ! ! (define_insn "modxf3" ! [(set (match_operand:XF 0 "s_register_operand" "=f") ! (mod:XF (match_operand:XF 1 "s_register_operand" "f") ! (match_operand:XF 2 "fpu_rhs_operand" "fG")))] ! "ENABLE_XF_PATTERNS" ! "* ! return (arm_output_asm_insn (\"rmfe\\t%0, %1, %2\", operands)); ! " ! [(set_attr "type" "float")]) ;; Boolean and,ior,xor insns *************** *** 247,253 **** (define_insn "anddi3" ! [(set (match_operand:DI 0 "di_operand" "=&r") ! (and:DI (match_operand:DI 1 "di_operand" "%r") ! (match_operand:DI 2 "di_operand" "r")))] "" "* --- 945,951 ---- (define_insn "anddi3" ! [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! (and:DI (match_operand:DI 1 "s_register_operand" "%0,0") ! (match_operand:DI 2 "s_register_operand" "r,0")))] "" "* *************** *** 254,272 **** arm_output_asm_insn (\"and\\t%0, %1, %2\", operands); return (arm_output_asm_insn (\"and\\t%R0, %R1, %R2\", operands)); ! ") (define_insn "andsi3" ! [(set (match_operand:SI 0 "register_operand" "=r") ! (and:SI (match_operand:SI 1 "register_operand" "r") ! (match_operand:SI 2 "arm_rhs_operand" "rI")))] "" "* ! return (arm_output_asm_insn (\"and\\t%0, %1, %2\", operands)); ") ! (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 "arm_rhs_operand" "rI"))))] "" "* --- 952,1131 ---- arm_output_asm_insn (\"and\\t%0, %1, %2\", operands); return (arm_output_asm_insn (\"and\\t%R0, %R1, %R2\", operands)); ! " ! [(set_attr "length" "2")]) ! ! (define_insn "" ! [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! (and:DI (zero_extend:DI ! (match_operand:SI 2 "s_register_operand" "r,r")) ! (match_operand:DI 1 "s_register_operand" "?r,0")))] ! "" ! "* ! arm_output_asm_insn (\"and\\t%0, %1, %2\", operands); ! return arm_output_asm_insn (\"mov\\t%R0, #0\", operands); ! " ! [(set_attr "length" "2")]) ! ! (define_insn "" ! [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! (and:DI (sign_extend:DI ! (match_operand:SI 2 "s_register_operand" "r,r")) ! (match_operand:DI 1 "s_register_operand" "?r,0")))] ! "" ! "* ! arm_output_asm_insn (\"and\\t%0, %1, %2\", operands); ! return arm_output_asm_insn (\"and\\t%R0, %R1, %2, asr #31\", operands); ! " ! [(set_attr "length" "2")]) (define_insn "andsi3" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (and:SI (match_operand:SI 1 "s_register_operand" "r") ! (match_operand:SI 2 "arm_not_operand" "rK")))] "" "* ! if (GET_CODE (operands[2]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[2]))) ! { ! operands[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2])); ! return arm_output_asm_insn (\"bic\\t%0, %1, %2\", operands); ! } ! return arm_output_asm_insn (\"and\\t%0, %1, %2\", operands); ") ! (define_insn "" ! [(set (reg:CC_NOOV 24) ! (compare:CC_NOOV (and:SI (match_operand:SI 1 "s_register_operand" "r") ! (match_operand:SI 2 "arm_not_operand" "rK")) ! (const_int 0))) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (and:SI (match_dup 1) (match_dup 2)))] ! "" ! "* ! if (GET_CODE (operands[2]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[2]))) ! { ! operands[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2])); ! return arm_output_asm_insn (\"bics\\t%0, %1, %2\", operands); ! } ! return arm_output_asm_insn (\"ands\\t%0, %1, %2\", operands); ! " ! [(set_attr "conds" "set")]) ! ! (define_insn "" ! [(set (reg:CC_NOOV 24) ! (compare:CC_NOOV (and:SI (match_operand:SI 0 "s_register_operand" "r") ! (match_operand:SI 1 "arm_rhs_operand" "rI")) ! (const_int 0)))] ! "" ! "* ! return arm_output_asm_insn (\"tst\\t%0, %1\", operands); ! " ! [(set_attr "conds" "set")]) ! ! (define_insn "" ! [(set (reg:CC_NOOV 24) ! (compare:CC_NOOV (and:SI (match_operand:SI 0 "s_register_operand" "r") ! (match_operand:SI 1 "immediate_operand" "K")) ! (const_int 0))) ! (clobber (match_scratch:SI 3 "=r"))] ! "const_ok_for_arm (~INTVAL (operands[1]))" ! "* ! operands[1] = GEN_INT (~INTVAL (operands[1])); ! return arm_output_asm_insn (\"bics\\t%3, %0, %1\", operands); ! " ! [(set_attr "conds" "set")]) ! ! (define_insn "" ! [(set (reg:CC_NOOV 24) ! (compare:CC_NOOV (zero_extract:SI ! (match_operand:SI 0 "s_register_operand" "r") ! (match_operand:SI 1 "immediate_operand" "n") ! (match_operand:SI 2 "immediate_operand" "n")) ! (const_int 0)))] ! "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32 ! && INTVAL (operands[1]) > 0 ! && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8 ! && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32" ! "* ! { ! unsigned int mask = 0; ! int cnt = INTVAL (operands[1]); ! ! while (cnt--) ! mask = (mask << 1) | 1; ! operands[1] = gen_rtx (CONST_INT, VOIDmode, mask << INTVAL (operands[2])); ! return arm_output_asm_insn (\"tst\\t%0, %1\", operands); ! } ! " ! [(set_attr "conds" "set")]) ! ! (define_insn "" ! [(set (reg:CC_NOOV 24) ! (compare:CC_NOOV (zero_extract:SI ! (match_operand:QI 0 "memory_operand" "m") ! (match_operand 1 "immediate_operand" "n") ! (match_operand 2 "immediate_operand" "n")) ! (const_int 0))) ! (clobber (match_scratch:QI 3 "=r"))] ! "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 8 ! && INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8" ! "* ! { ! unsigned int mask = 0; ! int cnt = INTVAL (operands[1]); ! ! while (cnt--) ! mask = (mask << 1) | 1; ! operands[1] = gen_rtx (CONST_INT, VOIDmode, mask << INTVAL (operands[2])); ! arm_output_asm_insn (\"ldrb\\t%3, %0\", operands); ! return arm_output_asm_insn (\"tst\\t%3, %1\", operands); ! } ! " ! [(set_attr "conds" "set") ! (set_attr "length" "2")]) ! ! ;; constants for op 2 will never be given to these patterns. ! (define_insn "" ! [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r,0")) ! (match_operand:DI 1 "s_register_operand" "0,r")))] ! "" ! "* ! arm_output_asm_insn (\"bic\\t%0, %1, %2\", operands); ! return arm_output_asm_insn (\"bic\\t%R0, %R1, %R2\", operands); ! " ! [(set_attr "length" "2")]) ! ! (define_insn "" ! [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! (and:DI (not:DI (zero_extend:DI ! (match_operand:SI 2 "s_register_operand" "r,r"))) ! (match_operand:DI 1 "s_register_operand" "?r,0")))] ! "" ! "* ! arm_output_asm_insn (\"bic\\t%0, %1, %2\", operands); ! if (REGNO (operands[1]) != REGNO (operands[0])) ! return arm_output_asm_insn (\"mov\\t%R0, %R1\", operands); ! return \"\"; ! " ! [(set_attr "length" "2,1")]) ! ! (define_insn "" ! [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! (and:DI (not:DI (sign_extend:DI ! (match_operand:SI 2 "s_register_operand" "r,r"))) ! (match_operand:DI 1 "s_register_operand" "?r,0")))] ! "" ! "* ! arm_output_asm_insn (\"bic\\t%0, %1, %2\", operands); ! return arm_output_asm_insn (\"bic\\t%R0, %R1, %2, asr #31\", operands); ! " ! [(set_attr "length" "2")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r")) ! (match_operand:SI 1 "s_register_operand" "r")))] "" "* *************** *** 274,281 **** ") (define_insn "iordi3" ! [(set (match_operand:DI 0 "di_operand" "=&r") ! (ior:DI (match_operand:DI 1 "di_operand" "%r") ! (match_operand:DI 2 "di_operand" "r")))] "" "* --- 1133,1167 ---- ") + (define_insn "" + [(set (reg:CC_NOOV 24) + (compare:CC_NOOV (and:SI + (not:SI (match_operand:SI 2 "s_register_operand" "r")) + (match_operand:SI 1 "s_register_operand" "r")) + (const_int 0))) + (set (match_operand:SI 0 "s_register_operand" "=r") + (and:SI (not:SI (match_dup 2)) (match_dup 1)))] + "" + "* + return (arm_output_asm_insn (\"bics\\t%0, %1, %2\", operands)); + " + [(set_attr "conds" "set")]) + + (define_insn "" + [(set (reg:CC_NOOV 24) + (compare:CC_NOOV (and:SI + (not:SI (match_operand:SI 2 "s_register_operand" "r")) + (match_operand:SI 1 "s_register_operand" "r")) + (const_int 0))) + (clobber (match_scratch:SI 0 "=r"))] + "" + "* + return (arm_output_asm_insn (\"bics\\t%0, %1, %2\", operands)); + " + [(set_attr "conds" "set")]) + (define_insn "iordi3" ! [(set (match_operand:DI 0 "s_register_operand" "=&r") ! (ior:DI (match_operand:DI 1 "s_register_operand" "%0") ! (match_operand:DI 2 "s_register_operand" "r")))] "" "* *************** *** 282,320 **** arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands); return (arm_output_asm_insn (\"orr\\t%R0, %R1, %R2\", operands)); ! ") (define_insn "iorsi3" ! [(set (match_operand:SI 0 "register_operand" "=r,r") ! (ior:SI (match_operand:SI 1 "register_operand" "r,r") ! (match_operand:SI 2 "nonmemory_operand" "r,n")))] "" "* ! switch (which_alternative) ! { ! case 0: ! return (arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands)); ! case 1: ! return (output_multi_immediate (operands, ! \"orr\\t%0, %1, %2\", \"orr\\t%0, %0, %2\", ! 2, INTVAL (operands[2]))); ! } ") (define_insn "xorsi3" ! [(set (match_operand:SI 0 "register_operand" "=r,r") ! (xor:SI (match_operand:SI 1 "register_operand" "r,r") ! (match_operand:SI 2 "nonmemory_operand" "r,n")))] "" "* ! switch (which_alternative) ! { ! case 0: ! return (arm_output_asm_insn (\"eor\\t%0, %1, %2\", operands)); ! case 1: ! return (output_multi_immediate (operands, ! \"eor\\t%0, %1, %2\", \"eor\\t%0, %0, %2\", ! 2, INTVAL (operands[2]))); ! } ") ;; Shift and rotation insns --- 1168,1455 ---- arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands); return (arm_output_asm_insn (\"orr\\t%R0, %R1, %R2\", operands)); ! " ! [(set_attr "length" "2")]) ! ! (define_insn "" ! [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! (ior:DI (zero_extend:DI ! (match_operand:SI 2 "s_register_operand" "r,r")) ! (match_operand:DI 1 "s_register_operand" "?r,0")))] ! "" ! "* ! arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands); ! if (REGNO (operands[0]) != REGNO (operands[1])) ! return (arm_output_asm_insn (\"mov\\t%R0, %R1\", operands)); ! return \"\"; ! " ! [(set_attr "length" "2,1")]) ! ! (define_insn "" ! [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! (ior:DI (sign_extend:DI ! (match_operand:SI 2 "s_register_operand" "r,r")) ! (match_operand:DI 1 "s_register_operand" "?r,0")))] ! "" ! "* ! arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands); ! return (arm_output_asm_insn (\"orr\\t%R0, %R1, %2, asr #31\", operands)); ! " ! [(set_attr "length" "2")]) (define_insn "iorsi3" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (ior:SI (match_operand:SI 1 "s_register_operand" "r") ! (match_operand:SI 2 "arm_rhs_operand" "rI")))] "" "* ! return (arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands)); ") + (define_insn "" + [(set (reg:CC_NOOV 24) + (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r") + (match_operand:SI 2 "arm_rhs_operand" "rI")) + (const_int 0))) + (set (match_operand:SI 0 "s_register_operand" "=r") + (ior:SI (match_dup 1) (match_dup 2)))] + "" + "* + return arm_output_asm_insn (\"orrs\\t%0, %1, %2\", operands); + " + [(set_attr "conds" "set")]) + + (define_insn "" + [(set (reg:CC_NOOV 24) + (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r") + (match_operand:SI 2 "arm_rhs_operand" "rI")) + (const_int 0))) + (clobber (match_scratch:SI 0 "=r"))] + "" + "* + return arm_output_asm_insn (\"orrs\\t%0, %1, %2\", operands); + " + [(set_attr "conds" "set")]) + + (define_insn "xordi3" + [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") + (xor:DI (match_operand:DI 1 "s_register_operand" "%0,0") + (match_operand:DI 2 "s_register_operand" "r,0")))] + "" + "* + arm_output_asm_insn (\"eor\\t%0, %1, %2\", operands); + return arm_output_asm_insn (\"eor\\t%R0, %R1, %R2\", operands); + " + [(set_attr "length" "2")]) + + (define_insn "" + [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") + (xor:DI (zero_extend:DI + (match_operand:SI 2 "s_register_operand" "r,r")) + (match_operand:DI 1 "s_register_operand" "?r,0")))] + "" + "* + arm_output_asm_insn (\"eor\\t%0, %1, %2\", operands); + if (REGNO (operands[0]) != REGNO (operands[1])) + return arm_output_asm_insn (\"mov\\t%R0, %R1\", operands); + return \"\"; + " + [(set_attr "length" "2,1")]) + + (define_insn "" + [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") + (xor:DI (sign_extend:DI + (match_operand:SI 2 "s_register_operand" "r,r")) + (match_operand:DI 1 "s_register_operand" "?r,0")))] + "" + "* + arm_output_asm_insn (\"eor\\t%0, %1, %2\", operands); + return arm_output_asm_insn (\"eor\\t%R0, %R1, %2, asr #31\", operands); + " + [(set_attr "length" "2")]) + (define_insn "xorsi3" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (xor:SI (match_operand:SI 1 "s_register_operand" "r") ! (match_operand:SI 2 "arm_rhs_operand" "rI")))] "" "* ! return (arm_output_asm_insn (\"eor\\t%0, %1, %2\", operands)); ") + + (define_insn "" + [(set (reg:CC_NOOV 24) + (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r") + (match_operand:SI 2 "arm_rhs_operand" "rI")) + (const_int 0))) + (set (match_operand:SI 0 "s_register_operand" "=r") + (xor:SI (match_dup 1) (match_dup 2)))] + "" + "* + return arm_output_asm_insn (\"eors\\t%0, %1, %2\", operands); + " + [(set_attr "conds" "set")]) + + (define_insn "" + [(set (reg:CC_NOOV 24) + (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r") + (match_operand:SI 1 "arm_rhs_operand" "rI")) + (const_int 0)))] + "" + "* + return arm_output_asm_insn (\"teq\\t%0, %1\", operands); + " + [(set_attr "conds" "set")]) + + ;; by splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C), + ;; (NOT D) we can sometimes merge the final NOT into one of the following + ;; insns + + (define_split + [(set (match_operand:SI 0 "s_register_operand" "=r") + (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" "r")) + (not:SI (match_operand:SI 2 "arm_rhs_operand" "rI"))) + (match_operand:SI 3 "arm_rhs_operand" "rI"))) + (clobber (match_operand:SI 4 "s_register_operand" "=r"))] + "" + [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2)) + (not:SI (match_dup 3)))) + (set (match_dup 0) (not:SI (match_dup 4)))] + "" + ) + + (define_insn "" + [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r") + (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,0") + (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")) + (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))] + "" + "* + arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands); + return arm_output_asm_insn (\"bic\\t%0, %0, %3\", operands); + " + [(set_attr "length" "2")]) + + + + ;; Minimum and maximum insns + + (define_insn "smaxsi3" + [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") + (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r") + (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) + (clobber (reg:CC 24))] + "" + "* + arm_output_asm_insn (\"cmp\\t%1, %2\", operands); + if (which_alternative != 0) + arm_output_asm_insn (\"movge\\t%0, %1\", operands); + if (which_alternative != 1) + return arm_output_asm_insn (\"movlt\\t%0, %2\", operands); + return \"\"; + " + [(set_attr "conds" "clob") + (set_attr "length" "2,2,3")]) + + (define_insn "sminsi3" + [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") + (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r") + (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) + (clobber (reg:CC 24))] + "" + "* + arm_output_asm_insn (\"cmp\\t%1, %2\", operands); + if (which_alternative != 0) + arm_output_asm_insn (\"movle\\t%0, %1\", operands); + if (which_alternative != 1) + return arm_output_asm_insn (\"movgt\\t%0, %2\", operands); + return \"\"; + " + [(set_attr "conds" "clob") + (set_attr "length" "2,2,3")]) + + (define_insn "umaxsi3" + [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") + (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r") + (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) + (clobber (reg:CC 24))] + "" + "* + arm_output_asm_insn (\"cmp\\t%1, %2\", operands); + if (which_alternative != 0) + arm_output_asm_insn (\"movcs\\t%0, %1\", operands); + if (which_alternative != 1) + return arm_output_asm_insn (\"movcc\\t%0, %2\", operands); + return \"\"; + " + [(set_attr "conds" "clob") + (set_attr "length" "2,2,3")]) + + (define_insn "uminsi3" + [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") + (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r") + (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) + (clobber (reg:CC 24))] + "" + "* + arm_output_asm_insn (\"cmp\\t%1, %2\", operands); + if (which_alternative != 0) + arm_output_asm_insn (\"movcc\\t%0, %1\", operands); + if (which_alternative != 1) + return arm_output_asm_insn (\"movcs\\t%0, %2\", operands); + return \"\"; + " + [(set_attr "conds" "clob") + (set_attr "length" "2,2,3")]) + + (define_insn "" + [(set (match_operand:SI 0 "memory_operand" "=m") + (match_operator:SI 3 "minmax_operator" + [(match_operand:SI 1 "s_register_operand" "r") + (match_operand:SI 2 "s_register_operand" "r")])) + (clobber (reg:CC 24))] + "" + "* + operands[3] = gen_rtx (minmax_code (operands[3]), SImode, operands[1], + operands[2]); + arm_output_asm_insn (\"cmp\\t%1, %2\", operands); + arm_output_asm_insn (\"str%d3\\t%1, %0\", operands); + return arm_output_asm_insn (\"str%D3\\t%2, %0\", operands); + " + [(set_attr "conds" "clob") + (set_attr "length" "3") + (set_attr "type" "store1")]) + + (define_insn "" + [(set (match_operand:SI 0 "s_register_operand" "=r,r") + (match_operator:SI 4 "shiftable_operator" + [(match_operator:SI 5 "minmax_operator" + [(match_operand:SI 2 "s_register_operand" "r,r") + (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]) + (match_operand:SI 1 "s_register_operand" "0,?r")])) + (clobber (reg:CC 24))] + "" + "* + { + char buf[100]; + enum rtx_code code = GET_CODE (operands[4]); + char *inst = arithmetic_instr (operands[4], TRUE); + + operands[5] = gen_rtx (minmax_code (operands[5]), SImode, operands[2], + operands[3]); + arm_output_asm_insn (\"cmp\\t%2, %3\", operands); + sprintf (buf, \"%s%%d5\\t%%0, %%1, %%2\", inst); + arm_output_asm_insn (buf, operands); + if (which_alternative != 0 || operands[3] != const0_rtx + || (code != PLUS && code != MINUS && code != IOR && code != XOR)) + { + sprintf (buf, \"%s%%D5\\t%%0, %%1, %%3\", inst); + return arm_output_asm_insn (buf, operands); + } + return \"\"; + } + " + [(set_attr "conds" "clob") + (set_attr "length" "3")]) + ;; Shift and rotation insns *************** *** 321,327 **** (define_insn "ashlsi3" ! [(set (match_operand:SI 0 "register_operand" "=r") ! (ashift:SI (match_operand:SI 1 "register_operand" "r") ! (match_operand:SI 2 "general_operand" "rn")))] "" "* --- 1456,1462 ---- (define_insn "ashlsi3" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (ashift:SI (match_operand:SI 1 "s_register_operand" "r") ! (match_operand:SI 2 "arm_rhs_operand" "rn")))] "" "* *************** *** 330,336 **** (define_insn "ashrsi3" ! [(set (match_operand:SI 0 "register_operand" "=r") ! (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") ! (match_operand:SI 2 "general_operand" "rn")))] "" "* --- 1465,1471 ---- (define_insn "ashrsi3" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "r") ! (match_operand:SI 2 "arm_rhs_operand" "rn")))] "" "* *************** *** 342,348 **** (define_insn "" ! [(set (match_operand:SI 0 "register_operand" "=r") ! (lshift:SI (match_operand:SI 1 "register_operand" "r") ! (match_operand:SI 2 "general_operand" "rn")))] "" "* --- 1477,1483 ---- (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (lshift:SI (match_operand:SI 1 "s_register_operand" "r") ! (match_operand:SI 2 "arm_rhs_operand" "rn")))] "" "* *************** *** 351,357 **** (define_insn "lshrsi3" ! [(set (match_operand:SI 0 "register_operand" "=r") ! (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") ! (match_operand:SI 2 "general_operand" "rn")))] "" "* --- 1486,1492 ---- (define_insn "lshrsi3" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "r") ! (match_operand:SI 2 "arm_rhs_operand" "rn")))] "" "* *************** *** 362,368 **** (define_insn "rotrsi3" ! [(set (match_operand:SI 0 "register_operand" "=r,r") ! (rotatert:SI (match_operand:SI 1 "register_operand" "r,r") ! (match_operand:SI 2 "general_operand" "r,n")))] "" "* --- 1497,1503 ---- (define_insn "rotrsi3" ! [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! (rotatert:SI (match_operand:SI 1 "s_register_operand" "r,r") ! (match_operand:SI 2 "arm_rhs_operand" "r,n")))] "" "* *************** *** 370,380 **** { case 0: ! return (arm_output_asm_insn (\"mov\\t%0, %1,ror %2\", operands)); case 1: if (INTVAL(operands[2]) > 31) operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) % 32); ! return (arm_output_asm_insn (\"mov\\t%0, %1,ror%2\", operands)); } ") ;; Unary arithmetic insns --- 1505,1607 ---- { case 0: ! return (arm_output_asm_insn (\"mov\\t%0, %1, ror %2\", operands)); case 1: if (INTVAL(operands[2]) > 31) operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) % 32); ! return (arm_output_asm_insn (\"mov\\t%0, %1, ror %2\", operands)); } ") + + (define_insn "" + [(set (reg:CC_NOOV 24) + (compare:CC_NOOV (match_operator:SI 1 "shift_operator" + [(match_operand:SI 2 "s_register_operand" "r") + (match_operand:SI 3 "arm_rhs_operand" "rn")]) + (const_int 0))) + (set (match_operand:SI 0 "s_register_operand" "=r") + (match_op_dup 1 [(match_dup 2) (match_dup 3)]))] + "" + "* + { + char buf[100]; + + sprintf (buf, \"movs\\t%%0, %%2, %s %%3\", + shift_instr (GET_CODE (operands[1]), &operands[3])); + return arm_output_asm_insn (buf, operands); + } + " + [(set_attr "conds" "set")]) + + (define_insn "" + [(set (reg:CC_NOOV 24) + (compare:CC_NOOV (match_operator:SI 1 "shift_operator" + [(match_operand:SI 2 "s_register_operand" "r") + (match_operand:SI 3 "arm_rhs_operand" "rn")]) + (const_int 0))) + (clobber (match_scratch:SI 0 "=r"))] + "" + "* + { + char buf[100]; + + sprintf (buf, \"movs\\t%%0, %%2, %s %%3\", + shift_instr (GET_CODE (operands[1]), &operands[3])); + return arm_output_asm_insn (buf, operands); + } + " + [(set_attr "conds" "set")]) + + (define_insn "" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (not:SI (match_operator:SI 1 "shift_operator" + [(match_operand:SI 2 "s_register_operand" "r") + (match_operand:SI 3 "arm_rhs_operand" "rn")])))] + "" + "* + { + char buf[100]; + sprintf (buf, \"mvn\\t%%0, %%2, %s %%3\", + shift_instr (GET_CODE (operands[1]), &operands[3])); + return arm_output_asm_insn (buf, operands); + } + ") + + (define_insn "" + [(set (reg:CC_NOOV 24) + (compare:CC_NOOV (not:SI (match_operator:SI 1 "shift_operator" + [(match_operand:SI 2 "s_register_operand" "r") + (match_operand:SI 3 "arm_rhs_operand" "rn")])) + (const_int 0))) + (set (match_operand:SI 0 "s_register_operand" "=r") + (not:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])))] + "" + "* + { + char buf[100]; + sprintf (buf, \"mvns\\t%%0, %%2, %s %%3\", + shift_instr (GET_CODE (operands[1]), &operands[3])); + return arm_output_asm_insn (buf, operands); + } + " + [(set_attr "conds" "set")]) + + (define_insn "" + [(set (reg:CC_NOOV 24) + (compare:CC_NOOV (not:SI (match_operator:SI 1 "shift_operator" + [(match_operand:SI 2 "s_register_operand" "r") + (match_operand:SI 3 "arm_rhs_operand" "rn")])) + (const_int 0))) + (clobber (match_scratch:SI 0 "=r"))] + "" + "* + { + char buf[100]; + sprintf (buf, \"mvns\\t%%0, %%2, %s %%3\", + shift_instr (GET_CODE (operands[1]), &operands[3])); + return arm_output_asm_insn (buf, operands); + } + " + [(set_attr "conds" "set")]) + ;; Unary arithmetic insns *************** *** 381,395 **** (define_insn "negdi2" ! [(set (match_operand:DI 0 "di_operand" "=&r") ! (neg:DI (match_operand:DI 1 "di_operand" "r")))] "" "* ! arm_output_asm_insn (\"rsb\\t%0, %1, #0\", operands); return (arm_output_asm_insn (\"rsc\\t%R0, %R1, #0\", operands)); ! ") (define_insn "negsi2" ! [(set (match_operand:SI 0 "register_operand" "=r") ! (neg:SI (match_operand:SI 1 "register_operand" "r")))] "" "* --- 1608,1624 ---- (define_insn "negdi2" ! [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0")))] "" "* ! arm_output_asm_insn (\"rsbs\\t%0, %1, #0\", operands); return (arm_output_asm_insn (\"rsc\\t%R0, %R1, #0\", operands)); ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "2")]) (define_insn "negsi2" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (neg:SI (match_operand:SI 1 "s_register_operand" "r")))] "" "* *************** *** 398,451 **** (define_insn "negsf2" ! [(set (match_operand:SF 0 "register_operand" "=f") ! (neg:SF (match_operand:SF 1 "register_operand" "f")))] "" "* return (arm_output_asm_insn (\"mnfs\\t%0, %1\", operands)); ! ") (define_insn "negdf2" ! [(set (match_operand:DF 0 "register_operand" "=f") ! (neg:DF (match_operand:DF 1 "register_operand" "f")))] "" "* return (arm_output_asm_insn (\"mnfd\\t%0, %1\", operands)); ! ") (define_insn "abssf2" ! [(set (match_operand:SF 0 "register_operand" "=f") ! (abs:SF (match_operand:SF 1 "register_operand" "f")))] "" "* return (arm_output_asm_insn (\"abss\\t%0, %1\", operands)); ! ") (define_insn "absdf2" ! [(set (match_operand:DF 0 "register_operand" "=f") ! (abs:DF (match_operand:DF 1 "register_operand" "f")))] "" "* return (arm_output_asm_insn (\"absd\\t%0, %1\", operands)); ! ") (define_insn "sqrtsf2" ! [(set (match_operand:SF 0 "register_operand" "=f") ! (sqrt:SF (match_operand:SF 1 "register_operand" "f")))] "" "* return (arm_output_asm_insn (\"sqts\\t%0, %1\", operands)); ! ") (define_insn "sqrtdf2" ! [(set (match_operand:DF 0 "register_operand" "=f") ! (sqrt:DF (match_operand:DF 1 "register_operand" "f")))] "" "* return (arm_output_asm_insn (\"sqtd\\t%0, %1\", operands)); ! ") (define_insn "one_cmplsi2" ! [(set (match_operand:SI 0 "register_operand" "=r") ! (not:SI (match_operand:SI 1 "register_operand" "r")))] "" "* --- 1627,1870 ---- (define_insn "negsf2" ! [(set (match_operand:SF 0 "s_register_operand" "=f") ! (neg:SF (match_operand:SF 1 "s_register_operand" "f")))] "" "* return (arm_output_asm_insn (\"mnfs\\t%0, %1\", operands)); ! " ! [(set_attr "type" "float")]) (define_insn "negdf2" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (neg:DF (match_operand:DF 1 "s_register_operand" "f")))] "" "* return (arm_output_asm_insn (\"mnfd\\t%0, %1\", operands)); ! " ! [(set_attr "type" "float")]) ! ! (define_insn "" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (neg:DF (float_extend:DF ! (match_operand:SF 1 "s_register_operand" "f"))))] ! "" ! "* ! return (arm_output_asm_insn (\"mnfd\\t%0, %1\", operands)); ! " ! [(set_attr "type" "float")]) ! ! (define_insn "negxf2" ! [(set (match_operand:XF 0 "s_register_operand" "=f") ! (neg:XF (match_operand:XF 1 "s_register_operand" "f")))] ! "ENABLE_XF_PATTERNS" ! "* ! return (arm_output_asm_insn (\"mnfe\\t%0, %1\", operands)); ! " ! [(set_attr "type" "float")]) ! ! ;; abssi2 doesn't really clobber the condition codes if a different register ! ;; is being set. To keep things simple, assume during rtl manipulations that ! ;; it does, but tell the final scan operator the truth. Similarly for ! ;; (neg (abs...)) ! ! (define_insn "abssi2" ! [(set (match_operand:SI 0 "s_register_operand" "=r,&r") ! (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))) ! (clobber (reg 24))] ! "" ! "* ! switch (which_alternative) ! { ! case 0: ! arm_output_asm_insn (\"cmp\\t%0, #0\", operands); ! return arm_output_asm_insn (\"rsblt\\t%0, %0, #0\", operands); ! case 1: ! arm_output_asm_insn (\"eor\\t%0, %1, %1, asr #31\", operands); ! return arm_output_asm_insn (\"sub\\t%0, %0, %1, asr #31\", operands); ! } ! " ! [(set_attr "conds" "clob,*") ! (set_attr "length" "2")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r,&r") ! (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))) ! (clobber (reg 24))] ! "" ! "* ! switch (which_alternative) ! { ! case 0: ! arm_output_asm_insn (\"cmp\\t%0, #0\", operands); ! return arm_output_asm_insn (\"rsbgt\\t%0, %0, #0\", operands); ! case 1: ! arm_output_asm_insn (\"eor\\t%0, %1, %1, asr #31\", operands); ! return arm_output_asm_insn (\"rsb\\t%0, %0, %1, asr #31\", operands); ! } ! " ! [(set_attr "conds" "clob,*") ! (set_attr "length" "2")]) (define_insn "abssf2" ! [(set (match_operand:SF 0 "s_register_operand" "=f") ! (abs:SF (match_operand:SF 1 "s_register_operand" "f")))] "" "* return (arm_output_asm_insn (\"abss\\t%0, %1\", operands)); ! " ! [(set_attr "type" "float")]) (define_insn "absdf2" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (abs:DF (match_operand:DF 1 "s_register_operand" "f")))] "" "* return (arm_output_asm_insn (\"absd\\t%0, %1\", operands)); ! " ! [(set_attr "type" "float")]) ! ! (define_insn "" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (abs:DF (float_extend:DF ! (match_operand:SF 1 "s_register_operand" "f"))))] ! "" ! "* ! return (arm_output_asm_insn (\"absd\\t%0, %1\", operands)); ! " ! [(set_attr "type" "float")]) ! ! (define_insn "absxf2" ! [(set (match_operand:XF 0 "s_register_operand" "=f") ! (abs:XF (match_operand:XF 1 "s_register_operand" "f")))] ! "ENABLE_XF_PATTERNS" ! "* ! return (arm_output_asm_insn (\"abse\\t%0, %1\", operands)); ! " ! [(set_attr "type" "float")]) (define_insn "sqrtsf2" ! [(set (match_operand:SF 0 "s_register_operand" "=f") ! (sqrt:SF (match_operand:SF 1 "s_register_operand" "f")))] "" "* return (arm_output_asm_insn (\"sqts\\t%0, %1\", operands)); ! " ! [(set_attr "type" "float_em")]) (define_insn "sqrtdf2" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (sqrt:DF (match_operand:DF 1 "s_register_operand" "f")))] "" "* return (arm_output_asm_insn (\"sqtd\\t%0, %1\", operands)); ! " ! [(set_attr "type" "float_em")]) ! ! (define_insn "" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (sqrt:DF (float_extend:DF ! (match_operand:SF 1 "s_register_operand" "f"))))] ! "" ! "* ! return (arm_output_asm_insn (\"sqtd\\t%0, %1\", operands)); ! " ! [(set_attr "type" "float_em")]) ! ! (define_insn "sqrtxf2" ! [(set (match_operand:XF 0 "s_register_operand" "=f") ! (sqrt:XF (match_operand:XF 1 "s_register_operand" "f")))] ! "ENABLE_XF_PATTERNS" ! "* ! return (arm_output_asm_insn (\"sqte\\t%0, %1\", operands)); ! " ! [(set_attr "type" "float_em")]) ! ! (define_insn "sinsf2" ! [(set (match_operand:SF 0 "s_register_operand" "=f") ! (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 0))] ! "" ! "* ! return arm_output_asm_insn (\"sins\\t%0, %1\", operands); ! " ! [(set_attr "type" "float_em")]) ! ! (define_insn "sindf2" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 0))] ! "" ! "* ! return arm_output_asm_insn (\"sind\\t%0, %1\", operands); ! " ! [(set_attr "type" "float_em")]) ! ! (define_insn "" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (unspec:DF [(float_extend:DF ! (match_operand:SF 1 "s_register_operand" "f"))] 0))] ! "" ! "* ! return arm_output_asm_insn (\"sind\\t%0, %1\", operands); ! " ! [(set_attr "type" "float_em")]) ! ! (define_insn "sinxf2" ! [(set (match_operand:XF 0 "s_register_operand" "=f") ! (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 0))] ! "ENABLE_XF_PATTERNS" ! "* ! return arm_output_asm_insn (\"sine\\t%0, %1\", operands); ! " ! [(set_attr "type" "float_em")]) ! ! (define_insn "cossf2" ! [(set (match_operand:SF 0 "s_register_operand" "=f") ! (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 1))] ! "" ! "* ! return arm_output_asm_insn (\"coss\\t%0, %1\", operands); ! " ! [(set_attr "type" "float_em")]) ! ! (define_insn "cosdf2" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 1))] ! "" ! "* ! return arm_output_asm_insn (\"cosd\\t%0, %1\", operands); ! " ! [(set_attr "type" "float_em")]) ! ! (define_insn "" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (unspec:DF [(float_extend:DF ! (match_operand:SF 1 "s_register_operand" "f"))] 1))] ! "" ! "* ! return arm_output_asm_insn (\"cosd\\t%0, %1\", operands); ! " ! [(set_attr "type" "float_em")]) ! ! (define_insn "cosxf2" ! [(set (match_operand:XF 0 "s_register_operand" "=f") ! (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 1))] ! "ENABLE_XF_PATTERNS" ! "* ! return arm_output_asm_insn (\"cose\\t%0, %1\", operands); ! " ! [(set_attr "type" "float_em")]) + (define_insn "one_cmpldi2" + [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") + (not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))] + "" + "* + arm_output_asm_insn (\"mvn\\t%0, %1\", operands); + return arm_output_asm_insn (\"mvn\\t%R0, %R1\", operands); + " + [(set_attr "length" "2")]) + (define_insn "one_cmplsi2" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (not:SI (match_operand:SI 1 "s_register_operand" "r")))] "" "* *************** *** 452,455 **** --- 1871,1897 ---- return (arm_output_asm_insn (\"mvn\\t%0, %1\", operands)); ") + + (define_insn "" + [(set (reg:CC_NOOV 24) + (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r")) + (const_int 0))) + (set (match_operand:SI 0 "s_register_operand" "=r") + (not:SI (match_dup 1)))] + "" + "* + return (arm_output_asm_insn (\"mvns\\t%0, %1\", operands)); + " + [(set_attr "conds" "set")]) + + (define_insn "" + [(set (reg:CC_NOOV 24) + (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r")) + (const_int 0))) + (clobber (match_scratch:SI 0 "=r"))] + "" + "* + return (arm_output_asm_insn (\"mvns\\t%0, %1\", operands)); + " + [(set_attr "conds" "set")]) ;; Fixed <--> Floating conversion insns *************** *** 456,473 **** (define_insn "floatsisf2" ! [(set (match_operand:SF 0 "register_operand" "=f") ! (float:SF (match_operand:SI 1 "register_operand" "r")))] "" "* return (arm_output_asm_insn (\"flts\\t%0, %1\", operands)); ! ") (define_insn "floatsidf2" ! [(set (match_operand:DF 0 "register_operand" "=f") ! (float:DF (match_operand:SI 1 "register_operand" "r")))] "" "* return (arm_output_asm_insn (\"fltd\\t%0, %1\", operands)); ! ") ;; Truncation insns --- 1898,1953 ---- (define_insn "floatsisf2" ! [(set (match_operand:SF 0 "s_register_operand" "=f") ! (float:SF (match_operand:SI 1 "s_register_operand" "r")))] "" "* return (arm_output_asm_insn (\"flts\\t%0, %1\", operands)); ! " ! [(set_attr "type" "r_2_f")]) (define_insn "floatsidf2" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (float:DF (match_operand:SI 1 "s_register_operand" "r")))] "" "* return (arm_output_asm_insn (\"fltd\\t%0, %1\", operands)); ! " ! [(set_attr "type" "r_2_f")]) ! ! (define_insn "floatsixf2" ! [(set (match_operand:XF 0 "s_register_operand" "=f") ! (float:XF (match_operand:SI 1 "s_register_operand" "r")))] ! "ENABLE_XF_PATTERNS" ! "* ! return (arm_output_asm_insn (\"flte\\t%0, %1\", operands)); ! " ! [(set_attr "type" "r_2_f")]) ! ! (define_insn "fix_truncsfsi2" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (fix:SI (match_operand:SF 1 "s_register_operand" "f")))] ! "" ! "* ! return arm_output_asm_insn (\"fixz\\t%0, %1\", operands); ! " ! [(set_attr "type" "f_2_r")]) ! ! (define_insn "fix_truncdfsi2" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (fix:SI (match_operand:DF 1 "s_register_operand" "f")))] ! "" ! "* ! return arm_output_asm_insn (\"fixz\\t%0, %1\", operands); ! " ! [(set_attr "type" "f_2_r")]) ! ! (define_insn "fix_truncxfsi2" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (fix:SI (match_operand:XF 1 "s_register_operand" "f")))] ! "ENABLE_XF_PATTERNS" ! "* ! return arm_output_asm_insn (\"fixz\\t%0, %1\", operands); ! " ! [(set_attr "type" "f_2_r")]) ;; Truncation insns *************** *** 474,492 **** (define_insn "truncdfsf2" ! [(set (match_operand:SF 0 "register_operand" "=f") (float_truncate:SF ! (match_operand:DF 1 "register_operand" "f")))] "" "* return (arm_output_asm_insn (\"mvfs\\t%0, %1\", operands)); ! ") ! ;; Zero extension instructions. (define_expand "zero_extendhisi2" [(set (match_dup 2) ! (ashift:SI (match_operand:HI 1 "register_operand" "") (const_int 16))) ! (set (match_operand:SI 0 "register_operand" "") (lshiftrt:SI (match_dup 2) (const_int 16)))] --- 1954,2034 ---- (define_insn "truncdfsf2" ! [(set (match_operand:SF 0 "s_register_operand" "=f") (float_truncate:SF ! (match_operand:DF 1 "s_register_operand" "f")))] "" "* return (arm_output_asm_insn (\"mvfs\\t%0, %1\", operands)); ! " ! [(set_attr "type" "float")]) ! ! (define_insn "truncxfsf2" ! [(set (match_operand:SF 0 "s_register_operand" "=f") ! (float_truncate:SF ! (match_operand:XF 1 "s_register_operand" "f")))] ! "ENABLE_XF_PATTERNS" ! "* ! return (arm_output_asm_insn (\"mvfs\\t%0, %1\", operands)); ! " ! [(set_attr "type" "float")]) ! ! (define_insn "truncxfdf2" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (float_truncate:DF ! (match_operand:XF 1 "s_register_operand" "f")))] ! "ENABLE_XF_PATTERNS" ! "* ! return (arm_output_asm_insn (\"mvfd\\t%0, %1\", operands)); ! " ! [(set_attr "type" "float")]) ! ;; Zero and sign extension instructions. ! ! (define_insn "zero_extendsidi2" ! [(set (match_operand:DI 0 "s_register_operand" "=r") ! (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))] ! "" ! "* ! if (REGNO (operands[1]) != REGNO (operands[0])) ! arm_output_asm_insn (\"mov\\t%0, %1\", operands); ! return arm_output_asm_insn (\"mov\\t%R0, #0\", operands); ! " ! [(set_attr "length" "2")]) ! ! (define_insn "zero_extendqidi2" ! [(set (match_operand:DI 0 "s_register_operand" "=r,r") ! (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))] ! "" ! "* ! switch (which_alternative) ! { ! case 0: ! arm_output_asm_insn (\"and\\t%0, %1, #255\", operands); ! break; ! case 1: ! arm_output_asm_insn (\"ldrb\\t%0, %1\",operands); ! break; ! } ! return arm_output_asm_insn (\"mov\\t%R0, #0\", operands); ! " ! [(set_attr "length" "2") ! (set_attr "type" "*,load")]) ! ! (define_insn "extendsidi2" ! [(set (match_operand:DI 0 "s_register_operand" "=r") ! (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))] ! "" ! "* ! if (REGNO (operands[1]) != REGNO (operands[0])) ! arm_output_asm_insn (\"mov\\t%0, %1\", operands); ! return arm_output_asm_insn (\"mov\\t%R0, %0, asr #31\", operands); ! " ! [(set_attr "length" "2")]) (define_expand "zero_extendhisi2" [(set (match_dup 2) ! (ashift:SI (match_operand:HI 1 "s_register_operand" "") (const_int 16))) ! (set (match_operand:SI 0 "s_register_operand" "") (lshiftrt:SI (match_dup 2) (const_int 16)))] *************** *** 497,503 **** (define_insn "zero_extendqihi2" ! [(set (match_operand:HI 0 "register_operand" "=r") (zero_extend:HI ! (match_operand:QI 1 "register_operand" "r")))] "" "* --- 2039,2045 ---- (define_insn "zero_extendqihi2" ! [(set (match_operand:HI 0 "s_register_operand" "=r") (zero_extend:HI ! (match_operand:QI 1 "s_register_operand" "r")))] "" "* *************** *** 505,510 **** ") (define_insn "zero_extendqisi2" ! [(set (match_operand:SI 0 "register_operand" "=r,r") (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))] --- 2047,2074 ---- ") + (define_insn "" + [(set (reg:CC_NOOV 24) + (compare:CC_NOOV (match_operand:QI 1 "s_register_operand" "r") + (const_int 0))) + (set (match_operand:SI 0 "s_register_operand" "=r") + (zero_extend:HI (match_dup 1)))] + "" + "* + return arm_output_asm_insn (\"ands\\t%0, %1, #255\", operands); + " + [(set_attr "conds" "set")]) + + (define_insn "" + [(set (reg:CC_NOOV 24) + (compare:CC_NOOV (match_operand:QI 0 "s_register_operand" "r") + (const_int 0)))] + "" + "* + return arm_output_asm_insn (\"tst\\t%0, #255\", operands); + " + [(set_attr "conds" "set")]) + (define_insn "zero_extendqisi2" ! [(set (match_operand:SI 0 "s_register_operand" "=r,r") (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))] *************** *** 518,528 **** return (arm_output_asm_insn (\"ldrb\\t%0, %1\\t@ zero_extendqisi2\", operands)); } ! ") (define_expand "extendhisi2" [(set (match_dup 2) ! (ashift:SI (match_operand:HI 1 "register_operand" "") (const_int 16))) ! (set (match_operand:SI 0 "register_operand" "") (ashiftrt:SI (match_dup 2) (const_int 16)))] --- 2082,2117 ---- return (arm_output_asm_insn (\"ldrb\\t%0, %1\\t@ zero_extendqisi2\", operands)); } ! " ! [(set_attr "type" "*,load")]) ! ! (define_insn "" ! [(set (reg:CC_NOOV 24) ! (compare:CC_NOOV (match_operand:QI 1 "s_register_operand" "r") ! (const_int 0))) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (zero_extend:SI (match_dup 1)))] ! "" ! "* ! return arm_output_asm_insn (\"ands\\t%0, %1, #255\", operands); ! " ! [(set_attr "conds" "set")]) ! ! (define_insn "" ! [(set (reg:CC_NOOV 24) ! (compare:CC_NOOV (match_operand:QI 1 "s_register_operand" "r") ! (const_int 0))) ! (set (match_operand:QI 0 "s_register_operand" "=r") ! (match_dup 1))] ! "" ! "* ! return arm_output_asm_insn (\"ands\\t%0, %1, #255\", operands); ! " ! [(set_attr "conds" "set")]) (define_expand "extendhisi2" [(set (match_dup 2) ! (ashift:SI (match_operand:HI 1 "s_register_operand" "") (const_int 16))) ! (set (match_operand:SI 0 "s_register_operand" "") (ashiftrt:SI (match_dup 2) (const_int 16)))] *************** *** 534,540 **** (define_expand "extendqihi2" [(set (match_dup 2) ! (ashift:SI (match_operand:QI 1 "register_operand" "") (const_int 24))) ! (set (match_operand:HI 0 "register_operand" "") (ashiftrt:SI (match_dup 2) (const_int 24)))] --- 2123,2129 ---- (define_expand "extendqihi2" [(set (match_dup 2) ! (ashift:SI (match_operand:QI 1 "s_register_operand" "") (const_int 24))) ! (set (match_operand:HI 0 "s_register_operand" "") (ashiftrt:SI (match_dup 2) (const_int 24)))] *************** *** 547,553 **** (define_expand "extendqisi2" [(set (match_dup 2) ! (ashift:SI (match_operand:QI 1 "register_operand" "") (const_int 24))) ! (set (match_operand:SI 0 "register_operand" "") (ashiftrt:SI (match_dup 2) (const_int 24)))] --- 2136,2142 ---- (define_expand "extendqisi2" [(set (match_dup 2) ! (ashift:SI (match_operand:QI 1 "s_register_operand" "") (const_int 24))) ! (set (match_operand:SI 0 "s_register_operand" "") (ashiftrt:SI (match_dup 2) (const_int 24)))] *************** *** 558,567 **** (define_insn "extendsfdf2" ! [(set (match_operand:DF 0 "register_operand" "=f") ! (float_extend:DF (match_operand:SF 1 "register_operand" "f")))] "" "* return (arm_output_asm_insn (\"mvfd\\t%0, %1\", operands)); ") ;; Move insns (including loads and stores) --- 2147,2175 ---- (define_insn "extendsfdf2" ! [(set (match_operand:DF 0 "s_register_operand" "=f") ! (float_extend:DF (match_operand:SF 1 "s_register_operand" "f")))] "" "* return (arm_output_asm_insn (\"mvfd\\t%0, %1\", operands)); + " + [(set_attr "type" "float")]) + + (define_insn "extendsfxf2" + [(set (match_operand:XF 0 "s_register_operand" "=f") + (float_extend:XF (match_operand:SF 1 "s_register_operand" "f")))] + "ENABLE_XF_PATTERNS" + "* + return (arm_output_asm_insn (\"mvfe\\t%0, %1\", operands)); ") + + (define_insn "extenddfxf2" + [(set (match_operand:XF 0 "s_register_operand" "=f") + (float_extend:XF (match_operand:DF 1 "s_register_operand" "f")))] + "ENABLE_XF_PATTERNS" + "* + return (arm_output_asm_insn (\"mvfe\\t%0, %1\", operands)); + " + [(set_attr "type" "float")]) + ;; Move insns (including loads and stores) *************** *** 568,574 **** ;; XXX Just some ideas about movti. ! ;;(define_expand "loadti" ! ;; [(set (match_operand:TI 0 "register_operand" "") ;; (mem:TI (match_operand:SI 1 "address_operand" "")))] ;; "" "") --- 2176,2183 ---- ;; XXX Just some ideas about movti. ! ;; I don't think these are a good idea on the arm, there just aren't enough ! ;; registers ;;(define_expand "loadti" ! ;; [(set (match_operand:TI 0 "s_register_operand" "") ;; (mem:TI (match_operand:SI 1 "address_operand" "")))] ;; "" "") *************** *** 576,580 **** ;;(define_expand "storeti" ;; [(set (mem:TI (match_operand:TI 0 "address_operand" "")) ! ;; (match_operand:TI 1 "register_operand" ""))] ;; "" "") --- 2185,2189 ---- ;;(define_expand "storeti" ;; [(set (mem:TI (match_operand:TI 0 "address_operand" "")) ! ;; (match_operand:TI 1 "s_register_operand" ""))] ;; "" "") *************** *** 626,648 **** (define_insn "movdi" ! [(set (match_operand:DI 0 "di_operand" "=r,r,r,o,r") ! (match_operand:DI 1 "di_operand" "r,n,o,r,F"))] "" "* return (output_move_double (operands)); ") ! (define_insn "movsi" ! [(set (match_operand:SI 0 "general_operand" "=r,r,r,m") ! (match_operand:SI 1 "general_operand" "r,n,m,r"))] ! "" "* switch (which_alternative) { ! case 0: return (arm_output_asm_insn (\"mov\\t%0, %1\", operands)); case 1: ! return (output_mov_immediate (operands)); ! case 2: if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))) --- 2235,2383 ---- (define_insn "movdi" ! [(set (match_operand:DI 0 "di_operand" "=r,r,r,o<>,r") ! (match_operand:DI 1 "di_operand" "rK,n,o<>,r,F"))] "" "* return (output_move_double (operands)); + " + [(set_attr "length" "2,8,2,2,8") + (set_attr "type" "*,*,load,store2,*")]) + + (define_expand "movsi" + [(set (match_operand:SI 0 "general_operand" "") + (match_operand:SI 1 "general_operand" ""))] + "" + " + /* Everything except mem = const or mem = mem can be done easily */ + if (GET_CODE (operands[0]) == MEM) + operands[1] = force_reg (SImode, operands[1]); + if (GET_CODE (operands[1]) == CONST_INT + && !(const_ok_for_arm (INTVAL (operands[1])) + || const_ok_for_arm (~INTVAL (operands[1])))) + { + int n = INTVAL (operands[1]); + rtx tmpreg, tmpreg2; + int i, n_ones = 0, first = 1, last = 0; + + if (GET_CODE (operands[0]) != REG + && GET_CODE (operands[0]) != SUBREG) + abort (); + for (i = 0; i < 32; i++) + if (n & 1 << i) + n_ones++; + /* These loops go the opposite way around to those in arm.c so that + the last constant may be more likely to be eliminted into the + next instruction */ + + if (n_ones > 16) + { + n = (~n) & 0xffffffff; + for (i = 30; i >= 0; i -= 2) + { + if (n & (3 << i)) + { + i -= 6; + if (i < 0) + i = 0; + if ((n & (255 << i)) == n) + last = 1; + if (first) + { + rtx equal; + rtx insn = + emit_insn (gen_movsi (tmpreg = (reload_in_progress + || reload_completed) + ? operands[0] + : gen_reg_rtx (SImode), + equal = gen_rtx (CONST_INT, VOIDmode, + ~(n & (255 << i))))); + first = 0; + } + else + { + rtx constant; + rtx insn = + emit_insn (gen_subsi3 (tmpreg2 = (reload_in_progress + || reload_completed + || last) + ? operands[0] + : gen_reg_rtx (SImode), + tmpreg, + constant = gen_rtx (CONST_INT, VOIDmode, + n & (255 << i)))); + tmpreg = tmpreg2; + } + n &= ~(255 << i); + } + } + } + else + { + for (i = 30; i >= 0; i -= 2) + { + if (n & (3 << i)) + { + i -= 6; + if (i < 0) + i = 0; + if ((n & (255 << i)) == n) + last = 1; + if (first) + { + rtx equal; + rtx insn = + emit_insn (gen_movsi (tmpreg = (reload_in_progress + || reload_completed) + ? operands[0] + : gen_reg_rtx (SImode), + equal = gen_rtx (CONST_INT, VOIDmode, + n & (255 << i)))); + first = 0; + } + else + { + rtx constant; + rtx insn = + emit_insn (gen_addsi3 (tmpreg2 = (reload_in_progress + || reload_completed + || last) + ? operands[0] + : gen_reg_rtx (SImode), + tmpreg, + constant = gen_rtx (CONST_INT, VOIDmode, + n & (255 << i)))); + tmpreg = tmpreg2; + } + n &= ~(255 << i); + } + } + } + DONE; + } ") ! (define_insn "" ! [(set (match_operand:SI 0 "general_operand" "=r,r,r,m,r") ! (match_operand:SI 1 "general_operand" "m,K,r,r,S"))] ! "(register_operand (operands[0], SImode) ! && (GET_CODE (operands[1]) != CONST_INT ! || const_ok_for_arm (INTVAL (operands[1])) ! || const_ok_for_arm (~INTVAL (operands[1]))) ! && (GET_CODE (operands[1]) != SYMBOL_REF ! || CONSTANT_ADDRESS_P (operands[1]))) ! || register_operand (operands[1], SImode)" "* switch (which_alternative) { ! case 2: return (arm_output_asm_insn (\"mov\\t%0, %1\", operands)); case 1: ! if (!const_ok_for_arm (INTVAL (operands[1]))) ! { ! operands[1] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[1])); ! return arm_output_asm_insn (\"mvn\\t%0, %1\", operands); ! } ! return arm_output_asm_insn (\"mov\\t%0, %1\", operands); ! case 0: if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))) *************** *** 652,702 **** case 3: return (arm_output_asm_insn (\"str\\t%1, %0\", operands)); } ! ") ! ! ;; XXX The movhi stuff isn't as correct or as nice as it could be... ! ! ;; Subroutine to load a half word into a register from memory. ! ;; Operand 0 is the destination register (HImode). ! ;; Operand 1 is the source address (SImode). ! ;; Operand 2 is a temporary (SImode). ! ! ;;(define_expand "loadhi" ! ;; [;; load the whole word (ARM realigns it if not on word boundary) ! ;; (set (match_operand:SI 2 "register_operand" "") ! ;; (mem:SI (match_operand:SI 1 "address_operand" ""))) ! ;; ;; quietly forget the upper 16 bits ! ;; (set (match_operand:HI 0 "register_operand" "") ! ;; (subreg:HI (match_dup 2) 0))] ! ;; "" ! ;; "" ! ;;) ! ;; Load op0 from mem:op1. Subroutine in case we're reloading and the normal ! ;; loadhi is not allowed. ! ! ;;(define_expand "reloadhi" ! ;; [(set (reg:SI 10) ! ;; (mem:SI (match_operand:SI 1 "address_operand" ""))) ! ;; (set (match_operand:HI 0 "register_operand" "") ! ;; (subreg:HI (reg:SI 10) 0))] ! ;; "" "") ! ! ;; Store op0 into mem:op1. Subroutine in case we're reloading and the normal ! ;; storehi is not allowed. ! ! (define_expand "restorehi" ! [(set (mem:QI (match_operand:SI 1 "" "")) ! (match_dup 2)) ! (set (reg:SI 10) ! (ashiftrt:SI (match_operand 0 "" "") (const_int 8))) ! (set (mem:QI (plus:SI (match_dup 1) (const_int 1))) ! (reg:QI 10))] "" ! " ! { ! operands[2] = gen_lowpart (QImode, operands[0]); ! operands[0] = gen_lowpart (SImode, operands[0]); ! }") ;; Subroutine to store a half word from a register into memory. --- 2387,2413 ---- case 3: return (arm_output_asm_insn (\"str\\t%1, %0\", operands)); + case 4: + return output_load_symbol (operands); } ! " ! [(set_attr "length" "2,*,*,*,4") ! (set_attr "type" "load,*,*,store1,*")]) ! ! ;; If copying one reg to another we can set the condition codes according to ! ;; its value. Such a move is common after a return from subroutine and the ! ;; result is being tested against zero. ! (define_insn "" ! [(set (reg:CC 24) (compare (match_operand:SI 1 "s_register_operand" "r") ! (const_int 0))) ! (set (match_operand:SI 0 "s_register_operand" "=r") (match_dup 1))] "" ! "* ! if (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG ! && REGNO (operands[0]) == REGNO (operands[1])) ! return arm_output_asm_insn (\"cmp\\t%0, #0\", operands); ! return arm_output_asm_insn (\"subs\\t%0, %1, #0\", operands); ! " ! [(set_attr "conds" "set")]) ;; Subroutine to store a half word from a register into memory. *************** *** 704,707 **** --- 2415,2422 ---- ;; Operand 1 is the destination address in a register (SImode) + ;; In both this routine and the next, we must be careful not to spill + ;; a memory address of reg+large_const into a seperate PLUS insn, since this + ;; can generate unrecognizable rtl. + (define_expand "storehi" [;; store the low byte *************** *** 711,721 **** (ashiftrt:SI (match_operand 0 "" "") (const_int 8))) ;; store the high byte ! (set (mem:QI (plus:SI (match_dup 1) (const_int 1))) (subreg:QI (match_dup 2) 0))] ;explicit subreg safe "" " ! { operands[3] = gen_lowpart (QImode, operands[0]); operands[0] = gen_lowpart (SImode, operands[0]); ! operands[2] = gen_reg_rtx (SImode); }") ;; Subroutine to store a half word integer constant into memory. --- 2426,2446 ---- (ashiftrt:SI (match_operand 0 "" "") (const_int 8))) ;; store the high byte ! (set (mem:QI (match_dup 4)) (subreg:QI (match_dup 2) 0))] ;explicit subreg safe "" " ! { ! enum rtx_code code = GET_CODE (operands[1]); ! ! if ((code == PLUS || code == MINUS) ! && (GET_CODE (XEXP (operands[1], 1)) == REG ! || GET_CODE (XEXP (operands[1], 0)) != REG)) ! operands[1] = force_reg (SImode, operands[1]); ! operands[4] = plus_constant (operands[1], 1); ! operands[3] = gen_lowpart (QImode, operands[0]); operands[0] = gen_lowpart (SImode, operands[0]); ! operands[2] = gen_reg_rtx (SImode); ! } ! ") ;; Subroutine to store a half word integer constant into memory. *************** *** 727,740 **** (set (mem:QI (match_operand:SI 1 "" "")) (match_operand 0 "" "")) ;; store the high byte ! (set (mem:QI (plus:SI (match_dup 1) (const_int 1))) ! (match_dup 2))] "" " ! { ! int value = INTVAL (operands[0]); ! operands[0] = force_reg (QImode, gen_rtx (CONST_INT, VOIDmode, value & 255)); ! operands[2] = force_reg (QImode, gen_rtx (CONST_INT, VOIDmode,(value>>8) & 255)); ! } ") --- 2452,2472 ---- (set (mem:QI (match_operand:SI 1 "" "")) (match_operand 0 "" "")) ;; store the high byte ! (set (mem:QI (match_dup 3)) (match_dup 2))] "" " ! { ! int value = INTVAL (operands[0]); ! enum rtx_code code = GET_CODE (operands[1]); ! if ((code == PLUS || code == MINUS) ! && (GET_CODE (XEXP (operands[1], 1)) == REG ! || GET_CODE (XEXP (operands[1], 0)) != REG)) ! operands[1] = force_reg (SImode, operands[1]); ! ! operands[0] = force_reg (QImode, gen_rtx (CONST_INT, VOIDmode, value & 255)); ! operands[2] = force_reg (QImode, ! gen_rtx (CONST_INT, VOIDmode,(value>>8) & 255)); ! operands[3] = plus_constant (operands[1], 1); ! } ") *************** *** 748,757 **** if (reload_in_progress || reload_completed) ! { ! if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == REG) ! insn = gen_restorehi (operands[1], XEXP (operands[0], 0)); ! else ! insn = gen_rtx (SET, VOIDmode, operands[0], operands[1]); ! } else { --- 2480,2484 ---- if (reload_in_progress || reload_completed) ! insn = gen_rtx (SET, VOIDmode, operands[0], operands[1]); else { *************** *** 760,764 **** if (GET_CODE (operands[1]) == CONST_INT) { ! insn = gen_storeinthi (operands[1], force_reg (SImode, XEXP (operands[0], 0))); } else --- 2487,2491 ---- if (GET_CODE (operands[1]) == CONST_INT) { ! insn = gen_storeinthi (operands[1], XEXP (operands[0],0)); } else *************** *** 765,779 **** { if (GET_CODE (operands[1]) == MEM) ! operands[1] = copy_to_reg (operands[1]); ! insn = gen_storehi (operands[1], force_reg (SImode, XEXP (operands[0], 0))); } } ! #if 0 ! else if (GET_CODE (operands[1]) == MEM) { ! insn = gen_loadhi (operands[0], XEXP (operands[1], 0), ! gen_reg_rtx (SImode)); } - #endif else insn = gen_rtx (SET, VOIDmode, operands[0], operands[1]); --- 2492,2526 ---- { if (GET_CODE (operands[1]) == MEM) ! operands[1] = force_reg (HImode, operands[1]); ! insn = gen_storehi (operands[1], XEXP (operands[0], 0)); } } ! else if (GET_CODE (operands[1]) == CONST_INT ! && !(const_ok_for_arm (INTVAL (operands[1])) ! || const_ok_for_arm (~INTVAL (operands[1])))) { ! rtx reg, reg2; ! ! /* no need to be clever, this will always take two insns. ! The top sixteen bits should be all zeros or all ones. */ ! if (INTVAL (operands[1]) < 0) ! { ! emit_insn (gen_movsi (reg = gen_reg_rtx (SImode), ! GEN_INT (INTVAL (operands[1]) ! | ~(0x0ff00)))); ! emit_insn (gen_addsi3 (reg2 = gen_reg_rtx (SImode), reg, ! GEN_INT (-((~INTVAL (operands[1])) ! & 0xff)))); ! } ! else ! { ! emit_insn (gen_movsi (reg = gen_reg_rtx (SImode), ! GEN_INT (INTVAL (operands[1]) & 0xff00))); ! emit_insn (gen_addsi3 (reg2 = gen_reg_rtx (SImode), reg, ! GEN_INT (INTVAL (operands[1]) & 0x00ff))); ! } ! insn = gen_rtx (SET, HImode, operands[0], ! gen_rtx (SUBREG, HImode, reg2, 0)); } else insn = gen_rtx (SET, VOIDmode, operands[0], operands[1]); *************** *** 788,814 **** (define_insn "" [(set (match_operand:HI 0 "general_operand" "=r,r,r,m") ! (match_operand:HI 1 "general_operand" "r,n,m,r"))] ! "" "* switch (which_alternative) { ! case 0: return (arm_output_asm_insn (\"mov\\t%0, %1\\t@movhi\", operands)); ! case 1: return (output_mov_immediate (operands)); ! case 2: return (arm_output_asm_insn (\"ldr\\t%0, %1\\t@movhi\", operands)); ! case 3: return (arm_output_asm_insn (\"str\\t%1, %0\\t@movhi\", operands)); } ") ! (define_insn "movqi" ! [(set (match_operand:QI 0 "general_operand" "=r,r,r,m") ! (match_operand:QI 1 "general_operand" "r,n,m,r"))] "" "* switch (which_alternative) { case 0: return (arm_output_asm_insn (\"mov\\t%0, %1\", operands)); - case 1: - return (output_mov_immediate (operands)); case 2: return (arm_output_asm_insn (\"ldrb\\t%0, %1\", operands)); --- 2535,2611 ---- (define_insn "" [(set (match_operand:HI 0 "general_operand" "=r,r,r,m") ! (match_operand:HI 1 "general_operand" "r,K,m,r"))] ! "(register_operand (operands[0], HImode) ! && (GET_CODE (operands[1]) != CONST_INT ! || const_ok_for_arm (INTVAL (operands[1])) ! || const_ok_for_arm (~INTVAL (operands[1])))) ! || register_operand (operands[1], HImode)" "* switch (which_alternative) { ! case 1: ! if (!const_ok_for_arm (INTVAL (operands[1]))) ! { ! operands[1] = GEN_INT (~INTVAL (operands[1])); ! return arm_output_asm_insn (\"mvn\\t%0, %1\", operands); ! } ! /* fall through */ ! case 0: ! return arm_output_asm_insn (\"mov\\t%0, %1\\t@movhi\", operands); ! case 2: ! return arm_output_asm_insn (\"ldr\\t%0, %1\\t@movhi\", operands); ! case 3: ! return arm_output_asm_insn (\"str\\t%1, %0\\t@movhi\", operands); } + " + [(set_attr "type" "*,*,load,store1")]) + + (define_expand "reload_outhi" + [(parallel [(match_operand:HI 0 "reload_memory_operand" "=o") + (match_operand:HI 1 "s_register_operand" "r") + (match_operand:SI 2 "s_register_operand" "=&r")])] + "" + " + arm_reload_out_hi (operands); + DONE; ") ! (define_expand "movqi" ! [(set (match_operand:QI 0 "general_operand" "") ! (match_operand:QI 1 "general_operand" ""))] "" + " + /* Everything except mem = const or mem = mem can be done easily */ + + if (!(reload_in_progress || reload_completed)) + { + rtx reg; + if (GET_CODE (operands[1]) == CONST_INT) + { + emit_insn (gen_movsi (reg = gen_reg_rtx (SImode), operands[1])); + operands[1] = gen_rtx (SUBREG, QImode, reg, 0); + } + } + if (GET_CODE (operands[0]) == MEM) + operands[1] = force_reg (QImode, operands[1]); + ") + + + (define_insn "" + [(set (match_operand:QI 0 "general_operand" "=r,r,r,m") + (match_operand:QI 1 "general_operand" "r,K,m,r"))] + "register_operand (operands[0], QImode) + || register_operand (operands[1], QImode)" "* switch (which_alternative) { + case 1: + if (INTVAL (operands[1]) < 0) + { + operands[1] = GEN_INT (~INTVAL (operands[1])); + return arm_output_asm_insn (\"mvn\\t%0, %1\", operands); + } case 0: return (arm_output_asm_insn (\"mov\\t%0, %1\", operands)); case 2: return (arm_output_asm_insn (\"ldrb\\t%0, %1\", operands)); *************** *** 816,1023 **** return (arm_output_asm_insn (\"strb\\t%1, %0\", operands)); } ! ") (define_insn "movsf" ! [(set (match_operand:SF 0 "general_operand" "=f,f,m,f,r,r") ! (match_operand:SF 1 "general_operand" "fG,m,f,r,f,r"))] "" "* switch (which_alternative) { case 0: ! return (arm_output_asm_insn (\"mvfs\\t%0, %1\", operands)); case 1: ! return (arm_output_asm_insn (\"ldfs\\t%0, %1\", operands)); case 2: ! return (arm_output_asm_insn (\"stfs\\t%1, %0\", operands)); case 3: ! arm_output_asm_insn(\"stmfd\\tsp!, {%1}\", operands); ! return (arm_output_asm_insn (\"ldfs\\t%0, [sp],#4\", operands)); case 4: ! arm_output_asm_insn(\"stfs\\t%1, [sp,#-4]!\", operands); ! return (arm_output_asm_insn (\"ldmfd\\tsp!, {%0}\", operands)); case 5: ! return (arm_output_asm_insn (\"mov\\t%0, %1\", operands)); } ") ! (define_insn "movdf" ! [(set (match_operand:DF 0 "general_operand" "=f,f,m,f,r,r") ! (match_operand:DF 1 "general_operand" "fG,m,f,r,f,r"))] "" "* switch (which_alternative) { ! case 0: return (arm_output_asm_insn (\"mvfd\\t%0, %1\", operands)); ! case 1: return (arm_output_asm_insn (\"ldfd\\t%0, %1\", operands)); ! case 2: return (arm_output_asm_insn (\"stfd\\t%1, %0\", operands)); ! case 3: return (output_mov_double_fpu_from_arm (operands)); ! case 4: return (output_mov_double_arm_from_fpu (operands)); ! case 5: return (output_move_double (operands)); } ! ") - ;; Comparison and test insns ! (define_insn "cmpsi" ! [(set (cc0) ! (compare (match_operand:SI 0 "register_operand" "r") ! (match_operand:SI 1 "arm_rhs_operand" "rI")))] "" ! "* ! return (arm_output_asm_insn (\"cmp\\t%0, %1\", operands)); ") ! (define_insn "tstsi" ! [(set (cc0) (match_operand:SI 0 "register_operand" "r"))] "" "* ! return (arm_output_asm_insn (\"cmp\\t%0, #0\", operands)); ") (define_insn "" ! [(set (cc0) ! (compare (match_operand:SI 0 "register_operand" "r") ! (neg:SI (match_operand:SI 1 "arm_rhs_operand" "rI"))))] "" "* ! return (arm_output_asm_insn (\"cmn\\t%0, %1\", operands)); ") ! (define_insn "cmpsf" ! [(set (cc0) ! (compare (match_operand:SF 0 "register_operand" "f") ! (match_operand:SF 1 "fpu_rhs_operand" "fG")))] "" ! "* ! return (arm_output_asm_insn (\"cmf\\t%0, %1\", operands)); ") ! (define_insn "cmpdf" ! [(set (cc0) ! (compare (match_operand:DF 0 "register_operand" "f") ! (match_operand:DF 1 "fpu_rhs_operand" "fG")))] "" ! "* ! return (arm_output_asm_insn (\"cmf\\t%0, %1\", operands)); ") ;; Conditional branch insns ! (define_insn "beq" [(set (pc) ! (if_then_else (eq (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" ! "* ! return (arm_output_asm_insn (\"beq\\t%l0\", operands)); ") ! (define_insn "bne" [(set (pc) ! (if_then_else (ne (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" ! "* ! return (arm_output_asm_insn (\"bne\\t%l0\", operands)); ") ! (define_insn "bgt" [(set (pc) ! (if_then_else (gt (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" ! "* ! return (arm_output_asm_insn (\"bgt\\t%l0\", operands)); ") ! (define_insn "ble" [(set (pc) ! (if_then_else (le (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" ! "* ! return (arm_output_asm_insn (\"ble\\t%l0\", operands)); ") ! (define_insn "bge" [(set (pc) ! (if_then_else (ge (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" ! "* ! return (arm_output_asm_insn (\"bge\\t%l0\", operands)); ") ! (define_insn "blt" [(set (pc) ! (if_then_else (lt (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" ! "* ! return (arm_output_asm_insn (\"blt\\t%l0\", operands)); ") ! (define_insn "bgtu" [(set (pc) ! (if_then_else (gtu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" ! "* ! return (arm_output_asm_insn (\"bhi\\t%l0\", operands)); ") ! (define_insn "bleu" [(set (pc) ! (if_then_else (leu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" ! "* ! return (arm_output_asm_insn (\"bls\\t%l0\", operands)); ") ! (define_insn "bgeu" [(set (pc) ! (if_then_else (geu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" ! "* ! return (arm_output_asm_insn (\"bhs\\t%l0\", operands)); ") ! (define_insn "bltu" [(set (pc) ! (if_then_else (ltu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" ! "* ! return (arm_output_asm_insn (\"blo\\t%l0\", operands)); ") ! ! ;; Inverted conditional branch insns (define_insn "" [(set (pc) ! (if_then_else (eq (cc0) (const_int 0)) ! (pc) ! (label_ref (match_operand 0 "" ""))))] "" "* ! return (arm_output_asm_insn (\"bne\\t%l0\", operands)); ! ") (define_insn "" [(set (pc) ! (if_then_else (ne (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] --- 2613,3504 ---- return (arm_output_asm_insn (\"strb\\t%1, %0\", operands)); } ! " ! [(set_attr "type" "*,*,load,store1")]) (define_insn "movsf" ! [(set (match_operand:SF 0 "general_operand" "=f,f,f,m,f,r,r,r,m") ! (match_operand:SF 1 "general_operand" "fG,H,m,f,r,f,r,m,r"))] "" "* + { + REAL_VALUE_TYPE r; + switch (which_alternative) { case 0: ! return arm_output_asm_insn (\"mvfs\\t%0, %1\", operands); case 1: ! REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); ! r = REAL_VALUE_NEGATE (r); ! operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1])); ! return arm_output_asm_insn (\"mnfs\\t%0, %1\", operands); case 2: ! return arm_output_asm_insn (\"ldfs\\t%0, %1\", operands); case 3: ! return arm_output_asm_insn (\"stfs\\t%1, %0\", operands); case 4: ! arm_output_asm_insn(\"stmfd\\tsp!, {%1}\", operands); ! return arm_output_asm_insn (\"ldfs\\t%0, [sp],#4\", operands); case 5: ! arm_output_asm_insn(\"stfs\\t%1, [sp,#-4]!\", operands); ! return arm_output_asm_insn (\"ldmfd\\tsp!, {%0}\", operands); ! case 6: ! return arm_output_asm_insn (\"mov\\t%0, %1\", operands); ! case 7: ! return arm_output_asm_insn (\"ldr\\t%0, %1\\t@ float\", operands); ! case 8: ! return arm_output_asm_insn (\"str\\t%1, %0\\t@ float\", operands); } + } + " + [(set_attr "length" "1,1,1,1,2,2,1,1,1") + (set_attr "type" "float,float,f_load,f_store,r_mem_f,f_mem_r,*,load,store1")]) + + (define_expand "movdf" + [(parallel [(set (match_operand:DF 0 "general_operand" "") + (match_operand:DF 1 "general_operand" "")) + (clobber (match_scratch:SI 2 ""))])] + "" + " + if (GET_CODE (operands[0]) == MEM) + operands[1] = force_reg (DFmode, operands[1]); ") ! ;; Reloading a df mode value stored in integer regs to memory can require a ! ;; scratch reg. ! (define_expand "reload_outdf" ! [(parallel [(set (match_operand:DF 0 "reload_memory_operand" "=o") ! (match_operand:DF 1 "s_register_operand" "r")) ! (clobber (match_operand:SI 2 "s_register_operand" "=&r"))])] "" + "") + + (define_insn "" + [(set (match_operand:DF 0 "general_operand" "=r,Q,r,o,f,f,f,f,m,!f,!r,r") + (match_operand:DF 1 "general_operand" + "Q,r,?o,?r,?f,!G,!H,m,f,r,f,??r")) + (clobber (match_scratch:SI 2 "=X,X,X,&r,X,X,X,X,X,X,X,X"))] + "GET_CODE (operands[0]) != MEM || register_operand (operands[1], DFmode)" + "* + { + REAL_VALUE_TYPE r; + rtx ops[3]; + + switch (which_alternative) + { + case 0: + operands[1] = XEXP (operands[1], 0); + return arm_output_asm_insn (\"ldmia\\t%1, {%0, %R0}\\t@ double\", + operands); + case 1: + operands[0] = XEXP (operands[0], 0); + return arm_output_asm_insn (\"stmia\\t%0, {%1, %R1}\\t@ double\", + operands); + case 2: + ops[0] = operands[0]; + ops[1] = XEXP (XEXP (operands[1], 0), 0); + ops[2] = XEXP (XEXP (operands[1], 0), 1); + if (!INTVAL (ops[2]) || const_ok_for_arm (INTVAL (ops[2]))) + arm_output_asm_insn (\"add\\t%0, %1, %2\", ops); + else + arm_output_asm_insn (\"sub\\t%0, %1, #%n2\", ops); + return arm_output_asm_insn (\"ldmia\\t%0, {%0, %R0}\\t@ double\", + operands); + case 3: + + ops[0] = operands[2]; + ops[1] = XEXP (XEXP (operands[0], 0), 0); + ops[2] = XEXP (XEXP (operands[0], 0), 1); + if (!INTVAL (ops[2]) || const_ok_for_arm (INTVAL (ops[2]))) + arm_output_asm_insn (\"add\\t%0, %1, %2\", ops); + else + arm_output_asm_insn (\"sub\\t%0, %1, #%n2\", ops); + return arm_output_asm_insn (\"stmia\\t%2, {%1, %R1}\\t@ double\", + operands); + case 4: + case 5: + return arm_output_asm_insn (\"mvfd\\t%0, %1\", operands); + case 6: + REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); + r = REAL_VALUE_NEGATE (r); + operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1])); + return arm_output_asm_insn (\"mnfd\\t%0, %1\", operands); + case 7: return arm_output_asm_insn (\"ldfd\\t%0, %1\", operands); + case 8: return arm_output_asm_insn (\"stfd\\t%1, %0\", operands); + case 9: return output_mov_double_fpu_from_arm (operands); + case 10: return output_mov_double_arm_from_fpu (operands); + case 11: return output_move_double (operands); + } + } + " + [(set_attr "length" "1,1,2,2,1,1,1,1,1,2,2,2") + (set_attr "type" + "load,store2,load,store2,float,float,float,f_load,f_store,r_mem_f,f_mem_r,*")]) + + (define_insn "movxf" + [(set (match_operand:XF 0 "general_operand" "=f,f,f,m,f,r,r") + (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))] + "ENABLE_XF_PATTERNS" "* + { + REAL_VALUE_TYPE r; + switch (which_alternative) { ! case 0: return arm_output_asm_insn (\"mvfe\\t%0, %1\", operands); ! case 1: ! REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); ! r = REAL_VALUE_NEGATE (r); ! operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1])); ! return arm_output_asm_insn (\"mnfe\\t%0, %1\", operands); ! case 2: return arm_output_asm_insn (\"ldfe\\t%0, %1\", operands); ! case 3: return arm_output_asm_insn (\"stfe\\t%1, %0\", operands); ! case 4: return output_mov_long_double_fpu_from_arm (operands); ! case 5: return output_mov_long_double_arm_from_fpu (operands); ! case 6: return output_mov_long_double_arm_from_arm (operands); } ! } ! " ! [(set_attr "length" "1,1,1,1,2,2,3") ! (set_attr "type" "float,float,f_load,f_store,r_mem_f,f_mem_r,*")]) ! ;; load- and store-multiple insns ! ;; The arm can load/store any set of registers, provided that they are in ! ;; ascending order; but that is beyond GCC so stick with what it knows. ! ! (define_expand "load_multiple" ! [(match_par_dup 3 [(set (match_operand:SI 0 "" "") ! (match_operand:SI 1 "" "")) ! (use (match_operand:SI 2 "" ""))])] "" ! " ! /* Support only fixed point registers */ ! if (GET_CODE (operands[2]) != CONST_INT ! || INTVAL (operands[2]) > 14 ! || INTVAL (operands[2]) < 2 ! || GET_CODE (operands[1]) != MEM ! || GET_CODE (operands[0]) != REG ! || REGNO (operands[0]) > 14 ! || REGNO (operands[0]) + INTVAL (operands[2]) > 15) ! FAIL; ! ! operands[3] ! = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]), ! force_reg (SImode, XEXP (operands[1], 0)), ! TRUE, FALSE); ") ! ;; Load multiple with write-back ! ! (define_insn "" ! [(match_parallel 0 "load_multiple_operation" ! [(set (match_operand:SI 1 "s_register_operand" "+r") ! (plus:SI (match_dup 1) ! (match_operand:SI 2 "immediate_operand" "n"))) ! (set (match_operand:SI 3 "s_register_operand" "=r") ! (mem:SI (match_dup 1)))])] ! "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))" ! "* ! { ! rtx ops[3]; ! int count = XVECLEN (operands[0], 0); ! ! ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0); ! ops[1] = SET_DEST (XVECEXP (operands[0], 0, 1)); ! ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 2)); ! ! return arm_output_asm_insn (\"ldmia\\t%0!, {%1-%2}\\t@ load multiple\", ops); ! } ! " ! [(set_attr "type" "load")]) ! ! ;; Ordinary load multiple ! ! (define_insn "" ! [(match_parallel 0 "load_multiple_operation" ! [(set (match_operand:SI 1 "s_register_operand" "=r") ! (match_operand:SI 2 "indirect_operand" "Q"))])] "" "* ! { ! rtx ops[3]; ! int count = XVECLEN (operands[0], 0); ! ! ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0); ! ops[1] = SET_DEST (XVECEXP (operands[0], 0, 0)); ! ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 1)); ! ! return arm_output_asm_insn (\"ldmia\\t%0, {%1-%2}\\t@ load multiple\", ops); ! } ! " ! [(set_attr "type" "load")]) ! ! (define_expand "store_multiple" ! [(match_par_dup 3 [(set (match_operand:SI 0 "" "") ! (match_operand:SI 1 "" "")) ! (use (match_operand:SI 2 "" ""))])] ! "" ! " ! /* Support only fixed point registers */ ! if (GET_CODE (operands[2]) != CONST_INT ! || INTVAL (operands[2]) > 14 ! || INTVAL (operands[2]) < 2 ! || GET_CODE (operands[1]) != REG ! || GET_CODE (operands[0]) != MEM ! || REGNO (operands[1]) > 14 ! || REGNO (operands[1]) + INTVAL (operands[2]) > 15) ! FAIL; ! ! operands[3] ! = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]), ! force_reg (SImode, XEXP (operands[0], 0)), ! TRUE, FALSE); ") + ;; Store multiple with write-back + + (define_insn "" + [(match_parallel 0 "store_multiple_operation" + [(set (match_operand:SI 1 "s_register_operand" "+r") + (plus:SI (match_dup 1) + (match_operand:SI 2 "immediate_operand" "n"))) + (set (mem:SI (match_dup 1)) + (match_operand:SI 3 "s_register_operand" "r"))])] + "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))" + "* + { + rtx ops[3]; + int count = XVECLEN (operands[0], 0); + + ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0); + ops[1] = SET_SRC (XVECEXP (operands[0], 0, 1)); + ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 2)); + + return arm_output_asm_insn (\"stmia\\t%0!, {%1-%2}\\t@ str multiple\", ops); + } + " + [(set (attr "type") + (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4)) + (const_string "store2") + (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 5)) + (const_string "store3")] + (const_string "store4")))]) + + ;; Ordinary store multiple + (define_insn "" ! [(match_parallel 0 "store_multiple_operation" ! [(set (match_operand:SI 2 "indirect_operand" "=Q") ! (match_operand:SI 1 "s_register_operand" "r"))])] "" "* ! { ! rtx ops[3]; ! int count = XVECLEN (operands[0], 0); ! ! ops[0] = XEXP (SET_DEST (XVECEXP (operands[0], 0, 0)), 0); ! ops[1] = SET_SRC (XVECEXP (operands[0], 0, 0)); ! ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 1)); ! ! return arm_output_asm_insn (\"stmia\\t%0, {%1-%2}\\t@ str multiple\", ops); ! } ! " ! [(set (attr "type") ! (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 3)) ! (const_string "store2") ! (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4)) ! (const_string "store3")] ! (const_string "store4")))]) ! ! ;; Move a block of memory if it is word aligned and MORE than 2 words long. ! ;; We could let this apply for blocks of less than this, but it clobbers so ! ;; many registers that there is then probably a better way. ! ! ;; If optimizing, output redundant moves with REG_NOTES on them, this ! ;; produces better code. ! ! (define_expand "movstrsi" ! [(set (match_operand:BLK 0 "general_operand" "=m") ! (match_operand:BLK 1 "general_operand" "m")) ! (use (match_operand:SI 2 "immediate_operand" "n")) ! (use (match_operand:SI 3 "immediate_operand" "n")) ! (clobber (reg:SI 0)) ! (clobber (reg:SI 1)) ! (clobber (reg:SI 2)) ! (clobber (reg:SI 3)) ! (clobber (match_scratch:SI 4 "=+r")) ! (clobber (match_scratch:SI 5 "=+r"))] ! "" ! " ! { ! int words_to_go; ! int i, r; ! rtx const_sxteen = gen_rtx (CONST_INT, SImode, 16); ! rtx src = gen_reg_rtx (SImode); ! rtx dst = gen_reg_rtx (SImode); ! rtx st_src, st_dst, end_src, end_dst, fin_src, fin_dst; ! extern int optimize; ! ! if (GET_CODE (operands[2]) != CONST_INT ! || GET_CODE (operands[3]) != CONST_INT ! || INTVAL (operands[2]) % 4 != 0 ! || INTVAL (operands[2]) < 4 ! || INTVAL (operands[2]) > 64 ! || INTVAL (operands[3]) < 4 ! || INTVAL (operands[3]) % 4 != 0) ! FAIL; ! emit_move_insn (dst, st_dst = force_reg (SImode, XEXP (operands[0], 0))); ! emit_move_insn (src, st_src = force_reg (SImode, XEXP (operands[1], 0))); ! fin_src = src; ! fin_dst = dst; ! ! for (i = 0, words_to_go = INTVAL (operands[2]) / 4; words_to_go >= 2; i+=4) ! { ! emit_insn (arm_gen_load_multiple (0, words_to_go > 4 ? 4 : words_to_go, ! src, TRUE, TRUE)); ! emit_insn (arm_gen_store_multiple (0, words_to_go > 4 ? 4 : words_to_go, ! dst, TRUE, TRUE)); ! if (optimize) ! for (r = (words_to_go > 4) ? 3 : words_to_go - 1; r >= 0; r--) ! { ! rtx note; ! note = emit_move_insn (gen_reg_rtx (SImode), ! gen_rtx (REG, SImode, r)); ! REG_NOTES (note) = gen_rtx (EXPR_LIST, REG_EQUIV, ! gen_rtx (MEM, SImode, ! plus_constant (st_src, 4*(i+r))), ! REG_NOTES (note)); ! REG_NOTES (note) = gen_rtx (EXPR_LIST, REG_EQUIV, ! gen_rtx (MEM, SImode, ! plus_constant (st_dst, 4*(i+r))), ! REG_NOTES (note)); ! } ! words_to_go -= words_to_go < 4 ? words_to_go : 4; ! } ! if (words_to_go) ! { ! rtx sreg; ! ! emit_move_insn (sreg = gen_reg_rtx (SImode), gen_rtx (MEM, SImode, src)); ! emit_move_insn (fin_src = gen_reg_rtx (SImode), plus_constant (src, 4)); ! emit_move_insn (gen_rtx (MEM, SImode, dst), sreg); ! emit_move_insn (fin_dst = gen_reg_rtx (SImode), plus_constant (dst, 4)); ! } ! if (optimize) ! { ! /* Insns for the REG_NOTES: These notes tell the optimiser where the ! index registers have got to so that consecutive block moves of ! contiguous data work efficiently */ ! ! end_src = emit_move_insn (fin_src, fin_src); ! REG_NOTES (end_src) = gen_rtx(EXPR_LIST, REG_EQUAL, ! plus_constant (st_src, INTVAL (operands[2])), ! REG_NOTES (end_src)); ! end_dst = emit_move_insn (fin_dst, fin_dst); ! REG_NOTES (end_dst) = gen_rtx(EXPR_LIST, REG_EQUAL, ! plus_constant (st_dst, INTVAL (operands[2])), ! REG_NOTES (end_dst)); ! } ! DONE; ! } ") + + + ;; Comparison and test insns ! (define_expand "cmpsi" ! [(set (reg:CC 24) ! (compare:CC (match_operand:SI 0 "s_register_operand" "") ! (match_operand:SI 1 "arm_add_operand" "")))] "" ! " ! { ! arm_compare_op0 = operands[0]; ! arm_compare_op1 = operands[1]; ! arm_compare_fp = 0; ! DONE; ! } ") ! (define_expand "cmpsf" ! [(set (reg:CC 24) ! (compare:CC (match_operand:SF 0 "s_register_operand" "") ! (match_operand:SF 1 "fpu_rhs_operand" "")))] "" ! " ! { ! arm_compare_op0 = operands[0]; ! arm_compare_op1 = operands[1]; ! arm_compare_fp = 1; ! DONE; ! } ! ") ! ! (define_expand "cmpdf" ! [(set (reg:CC 24) ! (compare:CC (match_operand:DF 0 "s_register_operand" "") ! (match_operand:DF 1 "fpu_rhs_operand" "")))] ! "" ! " ! { ! arm_compare_op0 = operands[0]; ! arm_compare_op1 = operands[1]; ! arm_compare_fp = 1; ! DONE; ! } ! ") ! ! (define_expand "cmpxf" ! [(set (reg:CC 24) ! (compare:CC (match_operand:XF 0 "s_register_operand" "") ! (match_operand:XF 1 "fpu_rhs_operand" "")))] ! "ENABLE_XF_PATTERNS" ! " ! { ! arm_compare_op0 = operands[0]; ! arm_compare_op1 = operands[1]; ! arm_compare_fp = 1; ! DONE; ! } ") + + (define_insn "" + [(set (match_operand 0 "cc_register" "") + (compare (match_operand:SI 1 "s_register_operand" "r") + (match_operand:SI 2 "arm_add_operand" "rL")))] + "" + "* + if (GET_CODE (operands[2]) == CONST_INT + && !const_ok_for_arm (INTVAL (operands[2]))) + return arm_output_asm_insn (\"cmn\\t%1, #%n2\", operands); + return arm_output_asm_insn (\"cmp\\t%1, %2\", operands); + " + [(set_attr "conds" "set")]) + + (define_insn "" + [(set (match_operand 0 "cc_register" "") + (compare (match_operand:SI 1 "s_register_operand" "r") + (neg:SI (match_operand:SI 2 "s_register_operand" "r"))))] + "" + "* + return arm_output_asm_insn (\"cmn\\t%1, %2\", operands); + " + [(set_attr "conds" "set")]) + + (define_insn "" + [(set (match_operand 0 "cc_register" "") + (compare (match_operand:SI 1 "s_register_operand" "r") + (match_operator:SI 2 "shift_operator" + [(match_operand:SI 3 "s_register_operand" "r") + (match_operand:SI 4 "arm_rhs_operand" "rn")])))] + "" + "* + return output_shift_compare (operands, FALSE); + " + [(set_attr "conds" "set")]) + + (define_insn "" + [(set (match_operand 0 "cc_register" "") + (compare (match_operand:SI 1 "s_register_operand" "r") + (neg:SI (match_operator:SI 2 "shift_operator" + [(match_operand:SI 3 "s_register_operand" "r") + (match_operand:SI 4 "arm_rhs_operand" "rn")]))))] + "" + "* + return output_shift_compare (operands, TRUE); + " + [(set_attr "conds" "set")]) + + (define_insn "" + [(set (reg:CCFP 24) + (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f") + (match_operand:SF 1 "fpu_add_operand" "fG,H")))] + "" + "* + { + REAL_VALUE_TYPE r; + + switch (which_alternative) + { + case 0: + return arm_output_asm_insn (\"cmf\\t%0, %1\", operands); + case 1: + REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); + r = REAL_VALUE_NEGATE (r); + operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1])); + return arm_output_asm_insn (\"cnf\\t%0, %1\", operands); + } + } + " + [(set_attr "conds" "set") + (set_attr "type" "f_2_r")]) + + (define_insn "" + [(set (reg:CCFP 24) + (compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f") + (match_operand:DF 1 "fpu_add_operand" "fG,H")))] + "" + "* + { + REAL_VALUE_TYPE r; + + switch (which_alternative) + { + case 0: + return arm_output_asm_insn (\"cmf\\t%0, %1\", operands); + case 1: + REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); + r = REAL_VALUE_NEGATE (r); + operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1])); + return arm_output_asm_insn (\"cnf\\t%0, %1\", operands); + } + } + " + [(set_attr "conds" "set") + (set_attr "type" "f_2_r")]) + + (define_insn "" + [(set (reg:CCFP 24) + (compare:CCFP (float_extend:DF + (match_operand:SF 0 "s_register_operand" "f,f")) + (match_operand:DF 1 "fpu_add_operand" "fG,H")))] + "" + "* + { + REAL_VALUE_TYPE r; + + switch (which_alternative) + { + case 0: + return arm_output_asm_insn (\"cmf\\t%0, %1\", operands); + case 1: + REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); + r = REAL_VALUE_NEGATE (r); + operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1])); + return arm_output_asm_insn (\"cnf\\t%0, %1\", operands); + } + } + " + [(set_attr "conds" "set") + (set_attr "type" "f_2_r")]) + + (define_insn "" + [(set (reg:CCFP 24) + (compare:CCFP (match_operand:DF 0 "s_register_operand" "f") + (float_extend:DF + (match_operand:SF 1 "s_register_operand" "f"))))] + "" + "* + return arm_output_asm_insn (\"cmf\\t%0, %1\", operands); + " + [(set_attr "conds" "set") + (set_attr "type" "f_2_r")]) + + (define_insn "" + [(set (reg:CCFP 24) + (compare:CCFP (match_operand:XF 0 "s_register_operand" "f,f") + (match_operand:XF 1 "fpu_add_operand" "fG,H")))] + "ENABLE_XF_PATTERNS" + "* + { + REAL_VALUE_TYPE r; + + switch (which_alternative) + { + case 0: + return arm_output_asm_insn (\"cmf\\t%0, %1\", operands); + case 1: + REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); + r = REAL_VALUE_NEGATE (r); + operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1])); + return arm_output_asm_insn (\"cnf\\t%0, %1\", operands); + } + } + " + [(set_attr "conds" "set") + (set_attr "type" "f_2_r")]) + + (define_insn "" + [(set (reg:CCFPE 24) + (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f") + (match_operand:SF 1 "fpu_add_operand" "fG,H")))] + "" + "* + { + REAL_VALUE_TYPE r; + + switch (which_alternative) + { + case 0: + return arm_output_asm_insn (\"cmfe\\t%0, %1\", operands); + case 1: + REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); + r = REAL_VALUE_NEGATE (r); + operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1])); + return arm_output_asm_insn (\"cnfe\\t%0, %1\", operands); + } + } + " + [(set_attr "conds" "set") + (set_attr "type" "f_2_r")]) + + (define_insn "" + [(set (reg:CCFPE 24) + (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f") + (match_operand:DF 1 "fpu_add_operand" "fG,H")))] + "" + "* + { + REAL_VALUE_TYPE r; + + switch (which_alternative) + { + case 0: + return arm_output_asm_insn (\"cmfe\\t%0, %1\", operands); + case 1: + REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); + r = REAL_VALUE_NEGATE (r); + operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1])); + return arm_output_asm_insn (\"cnfe\\t%0, %1\", operands); + } + } + " + [(set_attr "conds" "set") + (set_attr "type" "f_2_r")]) + + (define_insn "" + [(set (reg:CCFPE 24) + (compare:CCFPE (float_extend:DF + (match_operand:SF 0 "s_register_operand" "f,f")) + (match_operand:DF 1 "fpu_add_operand" "fG,H")))] + "" + "* + { + REAL_VALUE_TYPE r; + + switch (which_alternative) + { + case 0: + return arm_output_asm_insn (\"cmfe\\t%0, %1\", operands); + case 1: + REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); + r = REAL_VALUE_NEGATE (r); + operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1])); + return arm_output_asm_insn (\"cnfe\\t%0, %1\", operands); + } + } + " + [(set_attr "conds" "set") + (set_attr "type" "f_2_r")]) + + (define_insn "" + [(set (reg:CCFPE 24) + (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f") + (float_extend:DF + (match_operand:SF 1 "s_register_operand" "f"))))] + "" + "* + return arm_output_asm_insn (\"cmfe\\t%0, %1\", operands); + " + [(set_attr "conds" "set") + (set_attr "type" "f_2_r")]) + + (define_insn "" + [(set (reg:CCFPE 24) + (compare:CCFPE (match_operand:XF 0 "s_register_operand" "f,f") + (match_operand:XF 1 "fpu_add_operand" "fG,H")))] + "ENABLE_XF_PATTERNS" + "* + { + REAL_VALUE_TYPE r; + + switch (which_alternative) + { + case 0: + return arm_output_asm_insn (\"cmfe\\t%0, %1\", operands); + case 1: + REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); + r = REAL_VALUE_NEGATE (r); + operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1])); + return arm_output_asm_insn (\"cnfe\\t%0, %1\", operands); + } + } + " + [(set_attr "conds" "set") + (set_attr "type" "f_2_r")]) + + ; This insn allows redundant compares to be removed by cse, nothing should + ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that + ; is deleted later on. The match_dup will match the mode here, so that + ; mode changes of the condition codes aren't lost by this even though we don't + ; specify what they are. + + (define_insn "" + [(set (match_operand 0 "cc_register" "") (match_dup 0))] + "" + "\\t@ deleted compare" + [(set_attr "conds" "set") + (set_attr "length" "0")]) + ;; Conditional branch insns ! (define_expand "beq" [(set (pc) ! (if_then_else (eq (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" ! " ! { ! operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1, ! arm_compare_fp); ! } ") ! (define_expand "bne" [(set (pc) ! (if_then_else (ne (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" ! " ! { ! operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1, ! arm_compare_fp); ! } ") ! (define_expand "bgt" [(set (pc) ! (if_then_else (gt (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" ! " ! { ! operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1, ! arm_compare_fp); ! } ") ! (define_expand "ble" [(set (pc) ! (if_then_else (le (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" ! " ! { ! operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1, ! arm_compare_fp); ! } ") ! (define_expand "bge" [(set (pc) ! (if_then_else (ge (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" ! " ! { ! operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1, ! arm_compare_fp); ! } ") ! (define_expand "blt" [(set (pc) ! (if_then_else (lt (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" ! " ! { ! operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1, ! arm_compare_fp); ! } ") ! (define_expand "bgtu" [(set (pc) ! (if_then_else (gtu (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" ! " ! { ! operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1, ! arm_compare_fp); ! } ") ! (define_expand "bleu" [(set (pc) ! (if_then_else (leu (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" ! " ! { ! operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1, ! arm_compare_fp); ! } ") ! (define_expand "bgeu" [(set (pc) ! (if_then_else (geu (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" ! " ! { ! operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1, ! arm_compare_fp); ! } ") ! (define_expand "bltu" [(set (pc) ! (if_then_else (ltu (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" ! " ! { ! operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1, ! arm_compare_fp); ! } ") ! ! ;; patterns to match conditional branch insns (define_insn "" [(set (pc) ! (if_then_else (match_operator 1 "comparison_operator" ! [(reg 24) (const_int 0)]) ! (label_ref (match_operand 0 "" "")) ! (pc)))] "" "* ! { ! extern int arm_ccfsm_state; + if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) + { + arm_ccfsm_state += 2; + return \"\"; + } + return (arm_output_asm_insn (\"b%d1\\t%l0\", operands)); + }" + [(set_attr "conds" "use")]) + (define_insn "" [(set (pc) ! (if_then_else (match_operator 1 "comparison_operator" ! [(reg 24) (const_int 0)]) (pc) (label_ref (match_operand 0 "" ""))))] *************** *** 1024,1112 **** "" "* ! return (arm_output_asm_insn (\"beq\\t%l0\", operands)); ") ! (define_insn "" ! [(set (pc) ! (if_then_else (gt (cc0) (const_int 0)) ! (pc) ! (label_ref (match_operand 0 "" ""))))] "" ! "* ! return (arm_output_asm_insn (\"ble\\t%l0\", operands)); ") ! (define_insn "" ! [(set (pc) ! (if_then_else (le (cc0) (const_int 0)) ! (pc) ! (label_ref (match_operand 0 "" ""))))] "" ! "* ! return (arm_output_asm_insn (\"bgt\\t%l0\", operands)); ") ! (define_insn "" ! [(set (pc) ! (if_then_else (ge (cc0) (const_int 0)) ! (pc) ! (label_ref (match_operand 0 "" ""))))] "" ! "* ! return (arm_output_asm_insn (\"blt\\t%l0\", operands)); ") ! (define_insn "" ! [(set (pc) ! (if_then_else (lt (cc0) (const_int 0)) ! (pc) ! (label_ref (match_operand 0 "" ""))))] "" ! "* ! return (arm_output_asm_insn (\"bge\\t%l0\", operands)); ") ! (define_insn "" ! [(set (pc) ! (if_then_else (gtu (cc0) (const_int 0)) ! (pc) ! (label_ref (match_operand 0 "" ""))))] "" ! "* ! return (arm_output_asm_insn (\"bls\\t%l0\", operands)); ") (define_insn "" ! [(set (pc) ! (if_then_else (leu (cc0) (const_int 0)) ! (pc) ! (label_ref (match_operand 0 "" ""))))] "" "* ! return (arm_output_asm_insn (\"bhi\\t%l0\", operands)); ! ") (define_insn "" ! [(set (pc) ! (if_then_else (geu (cc0) (const_int 0)) ! (pc) ! (label_ref (match_operand 0 "" ""))))] "" "* ! return (arm_output_asm_insn (\"blo\\t%l0\", operands)); ! ") (define_insn "" ! [(set (pc) ! (if_then_else (ltu (cc0) (const_int 0)) ! (pc) ! (label_ref (match_operand 0 "" ""))))] "" "* ! return (arm_output_asm_insn (\"bhs\\t%l0\", operands)); ! ") ;; Jump and linkage insns - ;; `return' is still a jump-to-epilogue... (define_insn "jump" --- 3505,3670 ---- "" "* ! { ! extern int arm_ccfsm_state; ! ! if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) ! { ! arm_ccfsm_state += 2; ! return \"\"; ! } ! return (arm_output_asm_insn (\"b%D1\\t%l0\", operands)); ! }" ! [(set_attr "conds" "use")]) ! ! ! ; scc insns ! ! (define_expand "seq" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (eq:SI (match_dup 1) (const_int 0)))] ! "" ! " ! { ! operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1, ! arm_compare_fp); ! } ") ! (define_expand "sne" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (ne:SI (match_dup 1) (const_int 0)))] "" ! " ! { ! operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1, ! arm_compare_fp); ! } ") ! (define_expand "sgt" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (gt:SI (match_dup 1) (const_int 0)))] "" ! " ! { ! operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1, ! arm_compare_fp); ! } ") ! (define_expand "sle" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (le:SI (match_dup 1) (const_int 0)))] "" ! " ! { ! operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1, ! arm_compare_fp); ! } ") ! (define_expand "sge" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (ge:SI (match_dup 1) (const_int 0)))] "" ! " ! { ! operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1, ! arm_compare_fp); ! } ") ! (define_expand "slt" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (lt:SI (match_dup 1) (const_int 0)))] "" ! " ! { ! operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1, ! arm_compare_fp); ! } ! ") ! ! (define_expand "sgtu" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (gtu:SI (match_dup 1) (const_int 0)))] ! "" ! " ! { ! operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1, ! arm_compare_fp); ! } ! ") ! ! (define_expand "sleu" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (leu:SI (match_dup 1) (const_int 0)))] ! "" ! " ! { ! operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1, ! arm_compare_fp); ! } ! ") ! ! (define_expand "sgeu" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (geu:SI (match_dup 1) (const_int 0)))] ! "" ! " ! { ! operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1, ! arm_compare_fp); ! } ! ") ! ! (define_expand "sltu" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (ltu:SI (match_dup 1) (const_int 0)))] ! "" ! " ! { ! operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1, ! arm_compare_fp); ! } ") (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (match_operator:SI 1 "comparison_operator" [(reg 24) (const_int 0)]))] "" "* ! arm_output_asm_insn (\"mov%d1\\t%0, #1\", operands); ! return arm_output_asm_insn (\"mov%D1\\t%0, #0\", operands); ! " ! [(set_attr "conds" "use") ! (set_attr "length" "2")]) (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (neg:SI (match_operator:SI 1 "comparison_operator" ! [(reg 24) (const_int 0)])))] "" "* ! arm_output_asm_insn (\"mvn%d1\\t%0, #0\", operands); ! return arm_output_asm_insn (\"mov%D1\\t%0, #0\", operands); ! " ! [(set_attr "conds" "use") ! (set_attr "length" "2")]) (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (not:SI (match_operator:SI 1 "comparison_operator" ! [(reg 24) (const_int 0)])))] "" "* ! arm_output_asm_insn (\"mvn%d1\\t%0, #1\", operands); ! return arm_output_asm_insn (\"mov%D1\\t%0, #0\", operands); ! " ! [(set_attr "conds" "use") ! (set_attr "length" "2")]) ! ;; Jump and linkage insns (define_insn "jump" *************** *** 1115,1124 **** "" "* return (arm_output_asm_insn (\"b\\t%l0\", operands)); ! ") ! (define_insn "call" ! [(call (match_operand 0 "memory_operand" "m") ! (match_operand 1 "general_operand" "g")) (clobber (reg:SI 14))] "" --- 3673,3697 ---- "" "* + { + extern int arm_ccfsm_state; + + if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) + { + arm_ccfsm_state += 2; + return \"\"; + } return (arm_output_asm_insn (\"b\\t%l0\", operands)); ! }") ! (define_expand "call" ! [(parallel [(call (match_operand 0 "memory_operand" "") ! (match_operand 1 "general_operand" "")) ! (clobber (reg:SI 14))])] ! "" ! "") ! ! (define_insn "" ! [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r")) ! (match_operand 1 "" "g")) (clobber (reg:SI 14))] "" *************** *** 1125,1134 **** "* return (output_call (operands)); ! ") ! (define_insn "call_value" [(set (match_operand 0 "" "=rf") ! (call (match_operand 1 "memory_operand" "m") ! (match_operand 2 "general_operand" "g"))) (clobber (reg:SI 14))] "" --- 3698,3737 ---- "* return (output_call (operands)); ! " ! [(set (attr "conds") ! (if_then_else (eq_attr "cpu" "arm6") ! (const_string "clob") ! (const_string "nocond"))) ! ;; length is worst case, normally it is only two ! (set_attr "length" "3") ! (set_attr "type" "call")]) ! ! (define_insn "" ! [(call (mem:SI (match_operand 0 "memory_operand" "m")) ! (match_operand 1 "general_operand" "g")) ! (clobber (reg:SI 14))] ! "" ! "* ! return (output_call_mem (operands)); ! " ! [(set (attr "conds") ! (if_then_else (eq_attr "cpu" "arm6") ! (const_string "clob") ! (const_string "nocond"))) ! (set_attr "length" "3") ! (set_attr "type" "call")]) ! ! (define_expand "call_value" ! [(parallel [(set (match_operand 0 "" "=rf") ! (call (match_operand 1 "memory_operand" "m") ! (match_operand 2 "general_operand" "g"))) ! (clobber (reg:SI 14))])] ! "" ! "") ! (define_insn "" [(set (match_operand 0 "" "=rf") ! (call (mem:SI (match_operand:SI 1 "s_register_operand" "r")) ! (match_operand 2 "general_operand" "g"))) (clobber (reg:SI 14))] "" *************** *** 1135,1139 **** "* return (output_call (&operands[1])); ! ") ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses --- 3738,3764 ---- "* return (output_call (&operands[1])); ! " ! [(set (attr "conds") ! (if_then_else (eq_attr "cpu" "arm6") ! (const_string "clob") ! (const_string "nocond"))) ! (set_attr "length" "3") ! (set_attr "type" "call")]) ! ! (define_insn "" ! [(set (match_operand 0 "" "=rf") ! (call (mem:SI (match_operand 1 "memory_operand" "m")) ! (match_operand 2 "general_operand" "g"))) ! (clobber (reg:SI 14))] ! "! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))" ! "* ! return (output_call_mem (&operands[1])); ! " ! [(set (attr "conds") ! (if_then_else (eq_attr "cpu" "arm6") ! (const_string "clob") ! (const_string "nocond"))) ! (set_attr "length" "3") ! (set_attr "type" "call")]) ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses *************** *** 1147,1154 **** "* return (arm_output_asm_insn (\"bl\\t%a0\", operands)); ! ") (define_insn "" ! [(set (match_operand 0 "register_operand" "=rf") (call (mem:SI (match_operand:SI 1 "" "i")) (match_operand:SI 2 "general_operand" "g"))) --- 3772,3784 ---- "* return (arm_output_asm_insn (\"bl\\t%a0\", operands)); ! " ! [(set (attr "conds") ! (if_then_else (eq_attr "cpu" "arm6") ! (const_string "clob") ! (const_string "nocond"))) ! (set_attr "type" "call")]) (define_insn "" ! [(set (match_operand 0 "s_register_operand" "=rf") (call (mem:SI (match_operand:SI 1 "" "i")) (match_operand:SI 2 "general_operand" "g"))) *************** *** 1157,1162 **** "* return (arm_output_asm_insn (\"bl\\t%a1\", operands)); ! ") ;; Call subroutine returning any type. --- 3787,3860 ---- "* return (arm_output_asm_insn (\"bl\\t%a1\", operands)); ! " ! [(set (attr "conds") ! (if_then_else (eq_attr "cpu" "arm6") ! (const_string "clob") ! (const_string "nocond"))) ! (set_attr "type" "call")]) ! ! ;; Often the return insn will be the same as loading from memory, so set attr ! (define_insn "return" ! [(return)] ! "USE_RETURN_INSN" ! "* ! { ! extern int arm_ccfsm_state; + if (arm_ccfsm_state == 2) + { + arm_ccfsm_state += 2; + return \"\"; + } + return output_return_instruction (NULL, TRUE); + }" + [(set_attr "type" "load")]) + + (define_insn "" + [(set (pc) + (if_then_else (match_operator 0 "comparison_operator" + [(reg 24) (const_int 0)]) + (return) + (pc)))] + "USE_RETURN_INSN" + "* + { + extern int arm_ccfsm_state; + + if (arm_ccfsm_state == 2) + { + arm_ccfsm_state += 2; + return \"\"; + } + return output_return_instruction (operands[0], TRUE); + }" + [(set_attr "conds" "use") + (set_attr "type" "load")]) + + (define_insn "" + [(set (pc) + (if_then_else (match_operator 0 "comparison_operator" + [(reg 24) (const_int 0)]) + (pc) + (return)))] + "USE_RETURN_INSN" + "* + { + extern int arm_ccfsm_state; + + if (arm_ccfsm_state == 2) + { + arm_ccfsm_state += 2; + return \"\"; + } + return output_return_instruction + (gen_rtx (reverse_condition (GET_CODE (operands[0])), + GET_MODE (operands[0]), XEXP (operands[0], 0), + XEXP (operands[0], 1)), + TRUE); + }" + [(set_attr "conds" "use") + (set_attr "type" "load")]) + ;; Call subroutine returning any type. *************** *** 1194,1215 **** [(unspec_volatile [(const_int 0)] 0)] "" ! "") (define_insn "tablejump" [(set (pc) ! (match_operand:SI 0 "register_operand" "r")) (use (label_ref (match_operand 1 "" "")))] "" "* ! return (arm_output_asm_insn (\"mov\\tpc, %0\\t@ table jump, label %l1\", operands)); ") (define_insn "indirect_jump" [(set (pc) ! (match_operand:SI 0 "register_operand" "r"))] "" "* ! return (arm_output_asm_insn (\"mov\\tpc, %0\\t@ indirect jump\", operands)); ") ;; Misc insns --- 3892,3936 ---- [(unspec_volatile [(const_int 0)] 0)] "" ! "" ! [(set_attr "length" "0") ! (set_attr "type" "block")]) (define_insn "tablejump" [(set (pc) ! (match_operand:SI 0 "s_register_operand" "r")) (use (label_ref (match_operand 1 "" "")))] "" "* ! return arm_output_asm_insn (\"mov\\tpc, %0\\t@ table jump, label %l1\", ! operands); ") + (define_insn "" + [(set (pc) + (match_operand:SI 0 "memory_operand" "m")) + (use (label_ref (match_operand 1 "" "")))] + "" + "* + return arm_output_asm_insn (\"ldr\\tpc, %0\\t@ table jump, label %l1\", + operands); + " + [(set_attr "type" "load")]) + (define_insn "indirect_jump" [(set (pc) ! (match_operand:SI 0 "s_register_operand" "r"))] "" "* ! return arm_output_asm_insn (\"mov\\tpc, %0\\t@ indirect jump\", operands); ") + + (define_insn "" + [(set (pc) + (match_operand:SI 0 "memory_operand" "m"))] + "" + "* + return arm_output_asm_insn (\"ldr\\tpc, %0\\t@ indirect jump\", operands); + " + [(set_attr "type" "load")]) ;; Misc insns *************** *** 1219,1223 **** "" "* ! return (arm_output_asm_insn (\"mov\\tr0, r0\\t@ nop\", operands)); ") --- 3940,3944 ---- "" "* ! return arm_output_asm_insn (\"mov\\tr0, r0\\t@ nop\", operands); ") *************** *** 1224,1287 **** ;; Patterns to allow combination of arithmetic, cond code and shifts - ;(define_insn "" - ; [(set (match_operand:SI 0 "register_operand" "=r") - ; (match_operator:SI 1 "shiftable_operator" - ; [(match_operand:SI 2 "register_operand" "r") - ; (match_operator:SI 3 "shift_operator" - ; [(match_operand:SI 4 "register_operand" "r") - ; (match_operand:SI 5 "nonmemory_operand" "rn")])]))] - ; "" - ; "* - ; return (output_arithmetic_with_shift (operands, FALSE, FALSE)); - ; " - ;) - - ;(define_insn "" - ; [(set (match_operand:SI 0 "register_operand" "=r") - ; (match_operator:SI 1 "shiftable_operator" - ; [(match_operator:SI 3 "shift_operator" - ; [(match_operand:SI 4 "register_operand" "r") - ; (match_operand:SI 5 "nonmemory_operand" "rI")]) - ; (match_operand:SI 2 "register_operand" "r")]))] - ; "" - ; "* - ; return (output_arithmetic_with_shift (operands, TRUE, FALSE)); - ;") - - ;; Patterns to allow combination of arithmetic and left shift - - ;(define_insn "" - ; [(set (match_operand:SI 0 "register_operand" "=r") - ; (match_operator:SI 1 "shiftable_operator" - ; [(match_operand:SI 2 "register_operand" "r") - ; (mult:SI - ; (match_operand:SI 3 "register_operand" "r") - ; (match_operand:SI 4 "power_of_two_operand" "n"))]))] - ; "" - ; "* - ; return (output_arithmetic_with_immediate_multiply (operands, FALSE)); - ;") - (define_insn "" ! [(set (match_operand:SI 0 "register_operand" "=r") (match_operator:SI 1 "shiftable_operator" ! [(mult:SI ! (match_operand:SI 3 "register_operand" "r") ! (match_operand:SI 4 "power_of_two_operand" "n")) ! (match_operand:SI 2 "register_operand" "r")]))] "" "* ! return (output_arithmetic_with_immediate_multiply (operands, TRUE)); ") ! ;; This variant of the above insn can occur if the first operand is the ;; frame pointer and we eliminate that. This is a kludge, but there doesn't ! ;; seem to be a way around it. (define_insn "" ! [(set (match_operand:SI 0 "register_operand" "=&r") ! (plus:SI (plus:SI (mult:SI (match_operand:SI 3 "register_operand" "r") ! (match_operand:SI 4 "power_of_two_operand" "n")) ! (match_operand:SI 2 "register_operand" "r")) (match_operand:SI 1 "const_int_operand" "n")))] "reload_in_progress" --- 3945,4077 ---- ;; Patterns to allow combination of arithmetic, cond code and shifts (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r") (match_operator:SI 1 "shiftable_operator" ! [(match_operator:SI 3 "shift_operator" ! [(match_operand:SI 4 "s_register_operand" "r") ! (match_operand:SI 5 "nonmemory_operand" "rI")]) ! (match_operand:SI 2 "s_register_operand" "r")]))] ! "" ! "* ! return (output_arithmetic_with_shift (operands, TRUE, FALSE)); ! ") ! ! (define_insn "" ! [(set (reg:CC_NOOV 24) ! (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator" ! [(match_operator:SI 3 "shift_operator" ! [(match_operand:SI 4 "s_register_operand" "r") ! (match_operand:SI 5 "nonmemory_operand" "rI")]) ! (match_operand:SI 2 "s_register_operand" "r")]) ! (const_int 0))) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)]) ! (match_dup 2)]))] ! "" ! "* ! return (output_arithmetic_with_shift (operands, TRUE, TRUE)); ! " ! [(set_attr "conds" "set")]) ! ! (define_insn "" ! [(set (reg:CC_NOOV 24) ! (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator" ! [(match_operator:SI 3 "shift_operator" ! [(match_operand:SI 4 "s_register_operand" "r") ! (match_operand:SI 5 "nonmemory_operand" "rI")]) ! (match_operand:SI 2 "s_register_operand" "r")]) ! (const_int 0))) ! (clobber (match_scratch:SI 0 "=r"))] "" "* ! return (output_arithmetic_with_shift (operands, TRUE, TRUE)); ! " ! [(set_attr "conds" "set")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (minus:SI (match_operand:SI 1 "s_register_operand" "r") ! (match_operator:SI 2 "shift_operator" ! [(match_operand:SI 3 "s_register_operand" "r") ! (match_operand:SI 4 "nonmemory_operand" "rn")])))] ! "" ! "* ! { ! rtx ops[6]; ! ! ops[0] = operands[0]; ! ops[1] = gen_rtx (MINUS, SImode, operands[1], operands[2]); ! ops[2] = operands[1]; ! ops[3] = operands[2]; ! ops[4] = operands[3]; ! ops[5] = operands[4]; ! return output_arithmetic_with_shift (ops, FALSE, FALSE); ! } ") ! (define_insn "" ! [(set (reg:CC_NOOV 24) ! (compare:CC_NOOV (minus:SI (match_operand:SI 1 "s_register_operand" "r") ! (match_operator:SI 2 "shift_operator" ! [(match_operand:SI 3 "s_register_operand" "r") ! (match_operand:SI 4 "nonmemory_operand" "rn")])) ! (const_int 0))) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3) ! (match_dup 4)])))] ! "" ! "* ! { ! rtx ops[6]; ! ! ops[0] = operands[0]; ! ops[1] = gen_rtx (MINUS, SImode, operands[1], operands[2]); ! ops[2] = operands[1]; ! ops[3] = operands[2]; ! ops[4] = operands[3]; ! ops[5] = operands[4]; ! return output_arithmetic_with_shift (ops, FALSE, TRUE); ! } ! " ! [(set_attr "conds" "set")]) ! ! (define_insn "" ! [(set (reg:CC_NOOV 24) ! (compare:CC_NOOV (minus:SI (match_operand:SI 1 "s_register_operand" "r") ! (match_operator:SI 2 "shift_operator" ! [(match_operand:SI 3 "s_register_operand" "r") ! (match_operand:SI 4 "nonmemory_operand" "rn")])) ! (const_int 0))) ! (clobber (match_scratch:SI 0 "=r"))] ! "" ! "* ! { ! rtx ops[6]; ! ! ops[0] = operands[0]; ! ops[1] = gen_rtx (MINUS, SImode, operands[1], operands[2]); ! ops[2] = operands[1]; ! ops[3] = operands[2]; ! ops[4] = operands[3]; ! ops[5] = operands[4]; ! return output_arithmetic_with_shift (ops, FALSE, TRUE); ! } ! " ! [(set_attr "conds" "set")]) ! ! ;; These variants of the above insns can occur if the first operand is the ;; frame pointer and we eliminate that. This is a kludge, but there doesn't ! ;; seem to be a way around it. Most of the predicates have to be null ! ;; because the format can be generated part way through reload, so ! ;; if we don't match it as soon as it becomes available, reload doesn't know ! ;; how to reload pseudos that haven't got hard registers; the constraints will ! ;; sort everything out. (define_insn "" ! [(set (match_operand:SI 0 "" "=&r") ! (plus:SI (plus:SI (match_operator:SI 5 "shift_operator" ! [(match_operand:SI 3 "" "r") ! (match_operand:SI 4 "" "rn")]) ! (match_operand:SI 2 "" "r")) (match_operand:SI 1 "const_int_operand" "n")))] "reload_in_progress" *************** *** 1288,1362 **** "* { ! int shift = int_log2 (INTVAL (operands[4])); ! operands[4] = GEN_INT (shift); ! arm_output_asm_insn (\"add\\t%0, %2, %3, asl %4\", operands); operands[2] = operands[1]; operands[1] = operands[0]; return output_add_immediate (operands); ! }") - ;; Peephole optimizations. ! ;; When testing a bitset smaller than 9 bits for (un)equality, a ! ;; shift/and/cmp/b{eq,ne} sequence can be replaced by one tst and the same ! ;; branch sequence. ! ! ;;(define_peephole ! ;; [(set (match_operand:SI 0 "register_operand" "=r") ! ;; (lshiftrt:SI (match_dup 0) ! ;; (match_operand 1 "immediate_operand" ""))) ! ;; (set (match_dup 0) ! ;; (and:SI (match_dup 0) ! ;; (match_operand 2 "immediate_operand" ""))) ! ;; (set (cc0) (match_dup 0)) ! ;; (set (pc) ! ;; (if_then_else (ne (cc0) (const_int 0)) ! ;; (label_ref (match_operand 3 "" "")) ! ;; (pc)))] ! ;; "dead_or_set_p (PREV_INSN (insn), operands[0]) ! ;; && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[1]) == CONST_INT ! ;; && const_ok_for_arm (INTVAL (operands[2]) << INTVAL (operands[1]))" ! ;; "* ! ;; operands[2] = gen_rtx (CONST_INT, VOIDmode, ! ;; INTVAL (operands[2]) << INTVAL (operands[1])); ! ;; arm_output_asm_insn (\"tst\\t%0, %2\\t\\t@ ph test bitfield\", operands); ! ;; return (arm_output_asm_insn (\"bne\\t%l3\", operands)); ! ;;") ! ! ;;(define_peephole ! ;; [(set (match_operand:SI 0 "register_operand" "=r") ! ;; (lshiftrt:SI (match_dup 0) ! ;; (match_operand 1 "immediate_operand" ""))) ! ;; (set (match_dup 0) ! ;; (and:SI (match_dup 0) ! ;; (match_operand 2 "immediate_operand" ""))) ! ;; (set (cc0) (match_dup 0)) ! ;; (set (pc) ! ;; (if_then_else (ne (cc0) (const_int 0)) ! ;; (pc) ! ;; (label_ref (match_operand 3 "" ""))))] ! ;; "dead_or_set_p (prev_real_insn (insn), operands[0]) ! ;; && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[1]) == CONST_INT ! ;; && const_ok_for_arm (INTVAL (operands[2]) << INTVAL (operands[1]))" ! ;; "* ! ;; operands[2] = gen_rtx (CONST_INT, VOIDmode, ! ;; INTVAL (operands[2]) << INTVAL (operands[1])); ! ;; arm_output_asm_insn (\"tst\\t%0, %2\\t\\t@ ph test bitfield\", operands); ! ;; return (arm_output_asm_insn (\"beq\\t%l3\", operands)); ! ;;") ! ! ;; This allows negative constants to be compared since GCC appears not to try ! ;; converting them with a NEG. ! ! ;;(define_peephole ! ;; [(set (match_operand:SI 2 "register_operand" "=r") ! ;; (match_operand:SI 1 "immediate_operand" "n")) ! ;; (set (cc0) ! ;; (compare (match_operand:SI 0 "register_operand" "r") ! ;; (match_dup 1)))] ! ;; "const_ok_for_arm (-INTVAL (operands[1])) ! ;; && dead_or_set_p (prev_real_insn (insn), operands[0])" ! ;; "* ! ;; operands[1] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[1])); ! ;; return (arm_output_asm_insn (\"cmn\\t%0, %1\\t\\t@ ph negate comparison\", operands)); ! ;;") --- 4078,6232 ---- "* { ! char instr[100]; ! sprintf (instr, \"add\\t%%0, %%2, %%3, %s %%4\", ! shift_instr (GET_CODE (operands[5]), &operands[4])); ! arm_output_asm_insn (instr, operands); operands[2] = operands[1]; operands[1] = operands[0]; return output_add_immediate (operands); ! }" ! ; we have no idea how long the add_immediate is, it could be up to 4. ! [(set_attr "length" "5")]) ! ! (define_insn "" ! [(set (reg:CC_NOOV 24) ! (compare:CC_NOOV (plus:SI ! (plus:SI ! (match_operator:SI 5 "shift_operator" ! [(match_operand:SI 3 "" "r") ! (match_operand:SI 4 "" "rn")]) ! (match_operand:SI 1 "" "r")) ! (match_operand:SI 2 "const_int_operand" "n")) ! (const_int 0))) ! (set (match_operand:SI 0 "" "=&r") ! (plus:SI (plus:SI (match_op_dup 5 [(match_dup 3) (match_dup 4)]) ! (match_dup 1)) ! (match_dup 2)))] ! "reload_in_progress" ! "* ! { ! char instr[100]; ! sprintf (instr, \"adds\\t%%0, %%0, %%3, %s %%4\", ! shift_instr (GET_CODE (operands[5]), &operands[4])); ! output_add_immediate (operands); ! return arm_output_asm_insn (instr, operands); ! }" ! [(set_attr "conds" "set") ! (set_attr "length" "5")]) ! ! (define_insn "" ! [(set (reg:CC_NOOV 24) ! (compare:CC_NOOV (plus:SI ! (plus:SI ! (match_operator:SI 5 "shift_operator" ! [(match_operand:SI 3 "" "r") ! (match_operand:SI 4 "" "rn")]) ! (match_operand:SI 1 "" "r")) ! (match_operand:SI 2 "const_int_operand" "n")) ! (const_int 0))) ! (clobber (match_scratch:SI 0 "=&r"))] ! "reload_in_progress" ! "* ! { ! char instr[100]; ! sprintf (instr, \"adds\\t%%0, %%0, %%3, %s %%4\", ! shift_instr (GET_CODE (operands[5]), &operands[4])); ! output_add_immediate (operands); ! return arm_output_asm_insn (instr, operands); ! }" ! [(set_attr "conds" "set") ! (set_attr "length" "5")]) ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (and:SI (match_operator 1 "comparison_operator" ! [(reg 24) (const_int 0)]) ! (match_operand:SI 2 "s_register_operand" "r")))] ! "" ! "* ! arm_output_asm_insn (\"mov%D1\\t%0, #0\", operands); ! return arm_output_asm_insn (\"and%d1\\t%0, %2, #1\", operands); ! " ! [(set_attr "conds" "use") ! (set_attr "length" "2")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! (ior:SI (match_operator 2 "comparison_operator" ! [(reg 24) (const_int 0)]) ! (match_operand:SI 1 "s_register_operand" "0,?r")))] ! "" ! "* ! if (which_alternative != 0) ! arm_output_asm_insn (\"mov%D2\\t%0, %1\", operands); ! return arm_output_asm_insn (\"orr%d2\\t%0, %1, #1\", operands); ! " ! [(set_attr "conds" "use") ! (set_attr "length" "1,2")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (match_operator 1 "comparison_operator" ! [(match_operand:SI 2 "s_register_operand" "r") ! (match_operand:SI 3 "arm_add_operand" "rL")])) ! (clobber (reg 24))] ! "" ! "* ! if (GET_CODE (operands[1]) == LT) ! { ! if (operands[3] == const0_rtx) ! return arm_output_asm_insn (\"mov\\t%0, %2, lsr #31\", operands); ! if (GET_CODE (operands[3]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[3]))) ! arm_output_asm_insn (\"add\\t%0, %2, #%n3\", operands); ! else ! arm_output_asm_insn (\"sub\\t%0, %2, %3\", operands); ! return arm_output_asm_insn (\"mov\\t%0, %0, lsr #31\", operands); ! } ! if (GET_CODE (operands[1]) == GE && operands[3] == const0_rtx) ! { ! arm_output_asm_insn (\"mvn\\t%0, %2\", operands); ! return arm_output_asm_insn (\"mov\\t%0, %0, lsr #31\", operands); ! } ! if (GET_CODE (operands[1]) == NE) ! { ! if (GET_CODE (operands[3]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[3]))) ! arm_output_asm_insn (\"adds\\t%0, %2, #%n3\", operands); ! else ! arm_output_asm_insn (\"subs\\t%0, %2, %3\", operands); ! return arm_output_asm_insn (\"movne\\t%0, #1\", operands); ! } ! if (GET_CODE (operands[3]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[3]))) ! arm_output_asm_insn (\"cmn\\t%2, #%n3\", operands); ! else ! arm_output_asm_insn (\"cmp\\t%2, %3\", operands); ! arm_output_asm_insn (\"mov%D1\\t%0, #0\", operands); ! return arm_output_asm_insn (\"mov%d1\\t%0, #1\", operands); ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "3")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=&r") ! (ior:SI (match_operator 1 "comparison_operator" ! [(match_operand:SI 2 "s_register_operand" "r") ! (match_operand:SI 3 "arm_rhs_operand" "rI")]) ! (match_operator 4 "comparison_operator" ! [(match_operand:SI 5 "s_register_operand" "r") ! (match_operand:SI 6 "arm_rhs_operand" "rI")]))) ! (clobber (reg 24))] ! "" ! "* ! { ! int dominant = comparison_dominates_p (GET_CODE (operands[4]), ! GET_CODE (operands[1])); ! ! arm_output_asm_insn (dominant ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\", ! operands); ! arm_output_asm_insn (\"mov\\t%0, #0\", operands); ! if (GET_CODE (operands[1]) == GET_CODE (operands[4]) ! || comparison_dominates_p (GET_CODE (operands[1]), ! GET_CODE (operands[4])) ! || dominant) ! { ! arm_output_asm_insn (dominant ? \"cmp%D4\\t%2, %3\" : \"cmp%D1\\t%5,%6\", ! operands); ! } ! else ! { ! arm_output_asm_insn (\"mov%d1\\t%0, #1\", operands); ! arm_output_asm_insn (\"cmp\\t%5, %6\", operands); ! } ! return arm_output_asm_insn (dominant ? \"mov%d1\\t%0, #1\" ! : \"mov%d4\\t%0, #1\", operands); ! } ! " ! [(set_attr "conds" "clob") ! ; worst case length ! (set_attr "length" "5")]) ! ! (define_split ! [(set (pc) ! (if_then_else (match_operator 5 "equality_operator" ! [(ior:SI (match_operator 6 "comparison_operator" ! [(match_operand:SI 0 "s_register_operand" "r") ! (match_operand:SI 1 "arm_add_operand" "rL")]) ! (match_operator 7 "comparison_operator" ! [(match_operand:SI 2 "s_register_operand" "r") ! (match_operand:SI 3 "arm_add_operand" "rL")])) ! (const_int 0)]) ! (label_ref (match_operand 4 "" "")) ! (pc))) ! (clobber (reg 24))] ! "(GET_CODE (operands[6]) == GET_CODE (operands[7]) ! || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[7])) ! || comparison_dominates_p (GET_CODE (operands[7]), GET_CODE (operands[6])))" ! [(set (reg:CC 24) ! (compare:CC (ior:CC (match_op_dup 6 ! [(match_dup 0) (match_dup 1)]) ! (match_op_dup 7 ! [(match_dup 2) (match_dup 3)])) ! (const_int 0))) ! (set (pc) ! (if_then_else (match_op_dup 5 [(reg:CC 24) (const_int 0)]) ! (label_ref (match_dup 4)) ! (pc)))] ! " ! { ! enum rtx_code code = comparison_dominates_p (GET_CODE (operands[6]), ! GET_CODE (operands[7])) ! ? GET_CODE (operands[7]) : GET_CODE (operands[6]); ! ! if (GET_CODE (operands[5]) == NE) ! operands[5] = gen_rtx (code, CCmode, ! XEXP (operands[5], 0), XEXP (operands[5], 1)); ! else ! operands[5] = gen_rtx (reverse_condition (code), CCmode, ! XEXP (operands[5], 0), XEXP (operands[5], 1)); ! } ! ") ! ! ;; Don't match these patterns if we can use a conditional compare, since they ! ;; tell the final prescan branch elimator code that full branch inlining ! ;; can't be done. ! ! (define_insn "" ! [(set (pc) ! (if_then_else (ne ! (ior:SI (match_operator 5 "comparison_operator" ! [(match_operand:SI 0 "s_register_operand" "r") ! (match_operand:SI 1 "arm_add_operand" "rL")]) ! (match_operator 6 "comparison_operator" ! [(match_operand:SI 2 "s_register_operand" "r") ! (match_operand:SI 3 "arm_rhs_operand" "rL")])) ! (const_int 0)) ! (label_ref (match_operand 4 "" "")) ! (pc))) ! (clobber (reg 24))] ! "!(GET_CODE (operands[5]) == GET_CODE (operands[6]) ! || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[6])) ! || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[5])))" ! "* ! { ! extern int arm_ccfsm_state; ! ! if (GET_CODE (operands[1]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[1]))) ! arm_output_asm_insn (\"cmn\\t%0, #%n1\", operands); ! else ! arm_output_asm_insn (\"cmp\\t%0, %1\", operands); ! arm_output_asm_insn (\"b%d5\\t%l4\", operands); ! if (GET_CODE (operands[3]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[3]))) ! arm_output_asm_insn (\"cmn\\t%2, #%n3\", operands); ! else ! arm_output_asm_insn (\"cmp\\t%2, %3\", operands); ! if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) ! { ! arm_ccfsm_state += 2; ! return \"\"; ! } ! return arm_output_asm_insn (\"b%d6\\t%l4\", operands); ! }" ! [(set_attr "conds" "jump_clob") ! (set_attr "length" "4")]) ! ! (define_insn "" ! [(set (reg:CC 24) ! (compare:CC (ior:CC (match_operator 4 "comparison_operator" ! [(match_operand:SI 0 "s_register_operand" "r") ! (match_operand:SI 1 "arm_add_operand" "rL")]) ! (match_operator 5 "comparison_operator" ! [(match_operand:SI 2 "s_register_operand" "r") ! (match_operand:SI 3 "arm_add_operand" "rL")])) ! (const_int 0)))] ! "(GET_CODE (operands[4]) == GET_CODE (operands[5]) ! || comparison_dominates_p (GET_CODE (operands[4]), GET_CODE (operands[5])) ! || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))" ! "* ! if (comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]))) ! { ! if (GET_CODE (operands[3]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[3]))) ! arm_output_asm_insn (\"cmn\\t%2, #%n3\", operands); ! else ! arm_output_asm_insn (\"cmp\\t%2, %3\", operands); ! if (GET_CODE (operands[1]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[1]))) ! return arm_output_asm_insn (\"cmn%D5\\t%0, #%n1\", operands); ! return arm_output_asm_insn (\"cmp%D5\\t%0, %1\", operands); ! } ! if (GET_CODE (operands[1]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[1]))) ! arm_output_asm_insn (\"cmn\\t%0, #%n1\", operands); ! else ! arm_output_asm_insn (\"cmp\\t%0, %1\", operands); ! if (GET_CODE (operands[3]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[3]))) ! return arm_output_asm_insn (\"cmn%D4\\t%2, #%n3\", operands); ! return arm_output_asm_insn (\"cmp%D4\\t%2, %3\", operands); ! " ! [(set_attr "conds" "set") ! (set_attr "length" "2")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") ! (if_then_else (match_operator 3 "equality_operator" ! [(match_operator 4 "comparison_operator" ! [(reg 24) (const_int 0)]) ! (const_int 0)]) ! (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI") ! (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))] ! "" ! "* ! if (GET_CODE (operands[3]) == NE) ! { ! if (which_alternative != 0) ! arm_output_asm_insn (\"mov%d4\\t%0, %1\", operands); ! if (which_alternative != 1) ! arm_output_asm_insn (\"mov%D4\\t%0, %2\", operands); ! return \"\"; ! } ! if (which_alternative != 0) ! arm_output_asm_insn (\"mov%D4\\t%0, %1\", operands); ! if (which_alternative != 1) ! arm_output_asm_insn (\"mov%d4\\t%0, %2\", operands); ! return \"\"; ! " ! [(set_attr "conds" "use") ! (set_attr "length" "1,1,2")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! (match_operator:SI 5 "shiftable_operator" ! [(match_operator:SI 4 "comparison_operator" ! [(match_operand:SI 2 "s_register_operand" "r,r") ! (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]) ! (match_operand:SI 1 "s_register_operand" "0,?r")])) ! (clobber (reg 24))] ! "" ! "* ! { ! char *instr = arithmetic_instr (operands[5], TRUE); ! char pattern[100]; ! ! if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx) ! { ! sprintf (pattern, \"%s\\t%%0, %%1, %%2, lsr #31\", instr); ! return arm_output_asm_insn (pattern, operands); ! } ! arm_output_asm_insn (\"cmp\\t%2, %3\", operands); ! if (GET_CODE (operands[5]) == AND) ! arm_output_asm_insn (\"mov%D4\\t%0, #0\", operands); ! else if (which_alternative != 0) ! arm_output_asm_insn (\"mov%D4\\t%0, %1\", operands); ! sprintf (pattern, \"%s%%d4\\t%%0, %%1, #1\", instr); ! return arm_output_asm_insn (pattern, operands); ! } ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "3")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r") ! (match_operator:SI 4 "comparison_operator" ! [(match_operand:SI 2 "s_register_operand" "r,r") ! (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]))) ! (clobber (reg 24))] ! "" ! "* ! arm_output_asm_insn (\"cmp\\t%2, %3\", operands); ! if (which_alternative != 0) ! arm_output_asm_insn (\"mov%D4\\t%0, %1\", operands); ! return arm_output_asm_insn (\"sub%d4\\t%0, %1, #1\", operands); ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "2,3")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=&r") ! (and:SI (match_operator 1 "comparison_operator" ! [(match_operand:SI 2 "s_register_operand" "r") ! (match_operand:SI 3 "arm_rhs_operand" "rI")]) ! (match_operator 4 "comparison_operator" ! [(match_operand:SI 5 "s_register_operand" "r") ! (match_operand:SI 6 "arm_rhs_operand" "rI")]))) ! (clobber (reg 24))] ! "" ! "* ! { ! int dominant = ! comparison_dominates_p (reverse_condition (GET_CODE (operands[1])), ! reverse_condition (GET_CODE (operands[4]))) ! ? 1 ! : comparison_dominates_p (reverse_condition (GET_CODE (operands[4])), ! reverse_condition (GET_CODE (operands[1]))) ! ? 2 : 0; ! arm_output_asm_insn (dominant == 2 ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\", ! operands); ! arm_output_asm_insn (\"mov\\t%0, #1\", operands); ! if (GET_CODE (operands[1]) == GET_CODE (operands[4]) || dominant) ! { ! arm_output_asm_insn (dominant == 2 ? \"cmp%d4\\t%2, %3\" ! : \"cmp%d1\\t%5, %6\", operands); ! } ! else ! { ! arm_output_asm_insn (\"mov%D1\\t%0, #0\", operands); ! arm_output_asm_insn (\"cmp\\t%5, %6\", operands); ! } ! return arm_output_asm_insn (dominant == 2 ? \"mov%D1\\t%0, #0\" ! : \"mov%D4\\t%0, #0\", operands); ! } ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "5")]) ! ! (define_split ! [(set (pc) ! (if_then_else (match_operator 1 "equality_operator" ! [(and:SI (match_operator 2 "comparison_operator" ! [(match_operand:SI 3 "s_register_operand" "r") ! (match_operand:SI 4 "arm_add_operand" "rL")]) ! (match_operator 0 "comparison_operator" ! [(match_operand:SI 5 "s_register_operand" "r") ! (match_operand:SI 6 "arm_add_operand" "rL")])) ! (const_int 0)]) ! (label_ref (match_operand 7 "" "")) ! (pc))) ! (clobber (reg 24))] ! "(GET_CODE (operands[2]) == GET_CODE (operands[0]) ! || comparison_dominates_p (reverse_condition (GET_CODE (operands[2])), ! reverse_condition (GET_CODE (operands[0]))) ! || comparison_dominates_p (reverse_condition (GET_CODE (operands[0])), ! reverse_condition (GET_CODE (operands[2]))))" ! [(set (reg:CC 24) ! (compare:CC (ior:CC (match_op_dup 2 ! [(match_dup 3) (match_dup 4)]) ! (match_op_dup 0 ! [(match_dup 5) (match_dup 6)])) ! (const_int 0))) ! (set (pc) ! (if_then_else (match_op_dup 1 [(reg:CC 24) (const_int 0)]) ! (label_ref (match_dup 7)) ! (pc)))] ! " ! { ! /* Use DeMorgans law to convert this into an IOR of the inverse conditions ! This is safe since we only do it for integer comparisons. */ ! enum rtx_code code = ! comparison_dominates_p (reverse_condition (GET_CODE (operands[2])), ! reverse_condition (GET_CODE (operands[0]))) ! ? GET_CODE (operands[0]) : GET_CODE (operands[2]); ! ! operands[2] = gen_rtx (reverse_condition (GET_CODE (operands[2])), ! GET_MODE (operands[2]), operands[3], operands[4]); ! operands[0] = gen_rtx (reverse_condition (GET_CODE (operands[0])), ! GET_MODE (operands[0]), operands[5], operands[6]); ! if (GET_CODE (operands[1]) == NE) ! operands[1] = gen_rtx (code, CCmode, ! XEXP (operands[1], 0), XEXP (operands[1], 1)); ! else ! operands[1] = gen_rtx (reverse_condition (code), CCmode, ! XEXP (operands[1], 0), XEXP (operands[1], 1)); ! } ! ") ! ! ;; Don't match these patterns if we can use a conditional compare, since they ! ;; tell the final prescan branch elimator code that full branch inlining ! ;; can't be done. ! ! (define_insn "" ! [(set (pc) ! (if_then_else (eq ! (and:SI (match_operator 1 "comparison_operator" ! [(match_operand:SI 2 "s_register_operand" "r") ! (match_operand:SI 3 "arm_add_operand" "rL")]) ! (match_operator 4 "comparison_operator" ! [(match_operand:SI 5 "s_register_operand" "r") ! (match_operand:SI 6 "arm_rhs_operand" "rL")])) ! (const_int 0)) ! (label_ref (match_operand 0 "" "")) ! (pc))) ! (clobber (reg 24))] ! "!(GET_CODE (operands[1]) == GET_CODE (operands[4]) ! || comparison_dominates_p (reverse_condition (GET_CODE (operands[1])), ! reverse_condition (GET_CODE (operands[4]))) ! || comparison_dominates_p (reverse_condition (GET_CODE (operands[4])), ! reverse_condition (GET_CODE (operands[1]))))" ! "* ! { ! extern int arm_ccfsm_state; ! ! if (GET_CODE (operands[3]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[3]))) ! arm_output_asm_insn (\"cmn\\t%2, #%n3\", operands); ! else ! arm_output_asm_insn (\"cmp\\t%2, %3\", operands); ! arm_output_asm_insn (\"b%D1\\t%l0\", operands); ! if (GET_CODE (operands[6]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[6]))) ! arm_output_asm_insn (\"cmn\\t%5, #%n6\", operands); ! else ! arm_output_asm_insn (\"cmp\\t%5, %6\", operands); ! if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) ! { ! arm_ccfsm_state += 2; ! return \"\"; ! } ! return arm_output_asm_insn (\"b%D4\\t%l0\", operands); ! }" ! [(set_attr "conds" "jump_clob") ! (set_attr "length" "4")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (neg:SI (match_operator 3 "comparison_operator" ! [(match_operand:SI 1 "s_register_operand" "r") ! (match_operand:SI 2 "arm_rhs_operand" "rI")]))) ! (clobber (reg 24))] ! "" ! "* ! if (GET_CODE (operands[3]) == LT) ! { ! if (operands[3] == const0_rtx) ! return arm_output_asm_insn (\"mov\\t%0, %1, asr #31\", operands); ! arm_output_asm_insn (\"sub\\t%0, %1, %2\", operands); ! return arm_output_asm_insn (\"mov\\t%0, %0, asr #31\", operands); ! } ! if (GET_CODE (operands[3]) == NE) ! { ! arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands); ! return arm_output_asm_insn (\"mvnne\\t%0, #0\", operands); ! } ! if (GET_CODE (operands[3]) == GT) ! { ! arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands); ! return arm_output_asm_insn (\"mvnne\\t%0, %0, asr #31\", operands); ! } ! arm_output_asm_insn (\"cmp\\t%1, %2\", operands); ! arm_output_asm_insn (\"mov%D3\\t%0, #0\", operands); ! return arm_output_asm_insn (\"mvn%d3\\t%0, #0\", operands); ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "3")]) ! ! (define_insn "movcond" ! [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") ! (if_then_else:SI (match_operator 5 "comparison_operator" ! [(match_operand:SI 3 "s_register_operand" "r,r,r") ! (match_operand:SI 4 "arm_add_operand" "rL,rL,rL")]) ! (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI") ! (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) ! (clobber (reg 24))] ! "" ! "* ! if (GET_CODE (operands[5]) == LT ! && (operands[4] == const0_rtx)) ! { ! if (which_alternative != 1 && GET_CODE (operands[4]) == REG) ! { ! arm_output_asm_insn (\"ands\\t%0, %1, %3, asr #32\", operands); ! if (operands[2] == const0_rtx) ! return \"\"; ! return arm_output_asm_insn (\"movcc\\t%0, %2\", operands); ! } ! else if (which_alternative != 0 && GET_CODE (operands[2]) == REG) ! { ! arm_output_asm_insn (\"bics\\t%0, %2, %3, asr #32\", operands); ! if (operands[1] == const0_rtx) ! return \"\"; ! return arm_output_asm_insn (\"movcs\\t%0, %1\", operands); ! } ! /* The only case that falls through to here is when both ops 1 & 2 ! are constants */ ! } ! if (GET_CODE (operands[5]) == GE ! && (operands[4] == const0_rtx)) ! { ! if (which_alternative != 1 && GET_CODE (operands[1]) == REG) ! { ! arm_output_asm_insn (\"bics\\t%0, %1, %3, asr #32\", operands); ! if (operands[2] == const0_rtx) ! return \"\"; ! return arm_output_asm_insn (\"movcs\\t%0, %2\", operands); ! } ! else if (which_alternative != 0 && GET_CODE (operands[2]) == REG) ! { ! arm_output_asm_insn (\"ands\\t%0, %2, %3, asr #32\", operands); ! if (operands[1] == const0_rtx) ! return \"\"; ! return arm_output_asm_insn (\"movcc\\t%0, %1\", operands); ! } ! /* The only case that falls through to here is when both ops 1 & 2 ! are constants */ ! } ! if (GET_CODE (operands[4]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[4]))) ! arm_output_asm_insn (\"cmn\\t%3, #%n4\", operands); ! else ! arm_output_asm_insn (\"cmp\\t%3, %4\", operands); ! if (which_alternative != 0) ! arm_output_asm_insn (\"mov%d5\\t%0, %1\", operands); ! if (which_alternative != 1) ! arm_output_asm_insn (\"mov%D5\\t%0, %2\", operands); ! return \"\"; ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "2,2,3")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (if_then_else:SI (match_operator 9 "comparison_operator" ! [(match_operand:SI 5 "s_register_operand" "r") ! (match_operand:SI 6 "arm_add_operand" "rL")]) ! (match_operator:SI 8 "shiftable_operator" ! [(match_operand:SI 1 "s_register_operand" "r") ! (match_operand:SI 2 "arm_rhs_operand" "rI")]) ! (match_operator:SI 7 "shiftable_operator" ! [(match_operand:SI 3 "s_register_operand" "r") ! (match_operand:SI 4 "arm_rhs_operand" "rI")]))) ! (clobber (reg 24))] ! "" ! "* ! { ! char pattern[100]; ! ! if (GET_CODE (operands[6]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[6]))) ! arm_output_asm_insn (\"cmn\\t%5, #%n6\", operands); ! else ! arm_output_asm_insn (\"cmp\\t%5, %6\", operands); ! sprintf (pattern, \"%s%%d9\\t%%0, %%1, %%2\", arithmetic_instr (operands[8], ! FALSE)); ! arm_output_asm_insn (pattern, operands); ! sprintf (pattern, \"%s%%D9\\t%%0, %%3, %%4\", arithmetic_instr (operands[7], ! FALSE)); ! return arm_output_asm_insn (pattern, operands); ! } ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "3")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! (if_then_else:SI (match_operator 6 "comparison_operator" ! [(match_operand:SI 2 "s_register_operand" "r,r") ! (match_operand:SI 3 "arm_add_operand" "rL,rL")]) ! (match_operator:SI 7 "shiftable_operator" ! [(match_operand:SI 4 "s_register_operand" "r,r") ! (match_operand:SI 5 "arm_rhs_operand" "rI,rI")]) ! (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm"))) ! (clobber (reg 24))] ! "" ! "* ! { ! char pattern[100]; ! ! /* If we have an operation where (op x 0) is the identity operation and ! the condtional operator is LT or GE and we are comparing against zero and ! everything is in registers then we can do this in two instructions */ ! if (operands[3] == const0_rtx ! && GET_CODE (operands[7]) != AND ! && GET_CODE (operands[5]) == REG ! && GET_CODE (operands[1]) == REG ! && REGNO (operands[1]) == REGNO (operands[4]) ! && REGNO (operands[4]) != REGNO (operands[0])) ! { ! if (GET_CODE (operands[6]) == LT) ! { ! arm_output_asm_insn (\"and\\t%0, %5, %2, asr #31\", operands); ! sprintf (pattern, \"%s\\t%%0, %%4, %%0\", ! arithmetic_instr (operands[7], FALSE)); ! return arm_output_asm_insn (pattern, operands); ! } ! else if (GET_CODE (operands[6]) == GE) ! { ! arm_output_asm_insn (\"bic\\t%0, %5, %2, asr #31\", operands); ! sprintf (pattern, \"%s\\t%%0, %%4, %%0\", ! arithmetic_instr (operands[7], FALSE)); ! return arm_output_asm_insn (pattern, operands); ! } ! } ! if (GET_CODE (operands[3]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[3]))) ! arm_output_asm_insn (\"cmn\\t%2, #%n3\", operands); ! else ! arm_output_asm_insn (\"cmp\\t%2, %3\", operands); ! sprintf (pattern, \"%s%%d6\\t%%0, %%4, %%5\", arithmetic_instr (operands[7], ! FALSE)); ! arm_output_asm_insn (pattern, operands); ! if (which_alternative != 0) ! { ! if (GET_CODE (operands[1]) == MEM) ! arm_output_asm_insn (\"ldr%D6\\t%0, %1\", operands); ! else ! arm_output_asm_insn (\"mov%D6\\t%0, %1\", operands); ! } ! return \"\"; ! } ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "2,3")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! (if_then_else:SI (match_operator 6 "comparison_operator" ! [(match_operand:SI 4 "s_register_operand" "r,r") ! (match_operand:SI 5 "arm_add_operand" "rL,rL")]) ! (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm") ! (match_operator:SI 7 "shiftable_operator" ! [(match_operand:SI 2 "s_register_operand" "r,r") ! (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]))) ! (clobber (reg 24))] ! "" ! "* ! { ! char pattern[100]; ! ! /* If we have an operation where (op x 0) is the identity operation and ! the condtional operator is LT or GE and we are comparing against zero and ! everything is in registers then we can do this in two instructions */ ! if (operands[5] == const0_rtx ! && GET_CODE (operands[7]) != AND ! && GET_CODE (operands[3]) == REG ! && GET_CODE (operands[1]) == REG ! && REGNO (operands[1]) == REGNO (operands[2]) ! && REGNO (operands[2]) != REGNO (operands[0])) ! { ! if (GET_CODE (operands[6]) == GE) ! { ! arm_output_asm_insn (\"and\\t%0, %3, %4, asr #31\", operands); ! sprintf (pattern, \"%s\\t%%0, %%2, %%0\", ! arithmetic_instr (operands[7], FALSE)); ! return arm_output_asm_insn (pattern, operands); ! } ! else if (GET_CODE (operands[6]) == LT) ! { ! arm_output_asm_insn (\"bic\\t%0, %3, %4, asr #31\", operands); ! sprintf (pattern, \"%s\\t%%0, %%2, %%0\", ! arithmetic_instr (operands[7], FALSE)); ! return arm_output_asm_insn (pattern, operands); ! } ! } ! if (GET_CODE (operands[5]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[5]))) ! arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands); ! else ! arm_output_asm_insn (\"cmp\\t%4, %5\", operands); ! if (which_alternative != 0) ! { ! if (GET_CODE (operands[1]) == MEM) ! arm_output_asm_insn (\"ldr%d6\\t%0, %1\", operands); ! else ! arm_output_asm_insn (\"mov%d6\\t%0, %1\", operands); ! } ! sprintf (pattern, \"%s%%D6\\t%%0, %%2, %%3\", arithmetic_instr (operands[7], ! FALSE)); ! return arm_output_asm_insn (pattern, operands); ! } ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "2,3")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! (if_then_else:SI (match_operator 6 "comparison_operator" ! [(match_operand:SI 4 "s_register_operand" "r,r") ! (match_operand:SI 5 "arm_add_operand" "rL,rL")]) ! (plus:SI ! (match_operand:SI 2 "s_register_operand" "r,r") ! (match_operand:SI 3 "arm_add_operand" "rL,rL")) ! (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm"))) ! (clobber (reg 24))] ! "" ! "* ! { ! if (GET_CODE (operands[5]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[5]))) ! arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands); ! else ! arm_output_asm_insn (\"cmp\\t%4, %5\", operands); ! if (GET_CODE (operands[3]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[3]))) ! arm_output_asm_insn (\"sub%d6\\t%0, %2, #%n3\", operands); ! else ! arm_output_asm_insn (\"add%d6\\t%0, %2, %3\", operands); ! if (which_alternative != 0) ! { ! if (GET_CODE (operands[1]) == MEM) ! arm_output_asm_insn (\"ldr%D6\\t%0, %1\", operands); ! else ! arm_output_asm_insn (\"mov%D6\\t%0, %1\", operands); ! } ! return \"\"; ! } ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "2,3")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! (if_then_else:SI (match_operator 6 "comparison_operator" ! [(match_operand:SI 4 "s_register_operand" "r,r") ! (match_operand:SI 5 "arm_add_operand" "rL,rL")]) ! (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm") ! (plus:SI ! (match_operand:SI 2 "s_register_operand" "r,r") ! (match_operand:SI 3 "arm_add_operand" "rL,rL")))) ! (clobber (reg 24))] ! "" ! "* ! { ! if (GET_CODE (operands[5]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[5]))) ! arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands); ! else ! arm_output_asm_insn (\"cmp\\t%4, %5\", operands); ! if (GET_CODE (operands[3]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[3]))) ! arm_output_asm_insn (\"sub%D6\\t%0, %2, #%n3\", operands); ! else ! arm_output_asm_insn (\"add%D6\\t%0, %2, %3\", operands); ! if (which_alternative != 0) ! { ! if (GET_CODE (operands[6]) == MEM) ! arm_output_asm_insn (\"ldr%d6\\t%0, %1\", operands); ! else ! arm_output_asm_insn (\"mov%d6\\t%0, %1\", operands); ! } ! return \"\"; ! } ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "2,3")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! (if_then_else:SI (match_operator 5 "comparison_operator" ! [(match_operand:SI 3 "s_register_operand" "r,r") ! (match_operand:SI 4 "arm_add_operand" "rL,rL")]) ! (match_operand:SI 1 "arm_rhs_operand" "0,?rI") ! (not:SI ! (match_operand:SI 2 "s_register_operand" "r,r")))) ! (clobber (reg 24))] ! "" ! "#" ! [(set_attr "conds" "clob") ! (set_attr "length" "2,3")]) ! ! ;; if (GET_CODE (operands[3]) == CONST_INT ! ;; && !const_ok_for_arm (INTVAL (operands[3]))) ! ;; arm_output_asm_insn (\"cmn\\t%2, #%n3\", operands); ! ;; else ! ;; arm_output_asm_insn (\"cmp\\t%2, %3\", operands); ! ;; if (which_alternative != 0) ! ;; arm_output_asm_insn (\"mov%d1\\t%0, %4\", operands); ! ;; return arm_output_asm_insn (\"mvn%D1\\t%0, %5\", operands); ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! (if_then_else:SI (match_operator 5 "comparison_operator" ! [(match_operand:SI 3 "s_register_operand" "r,r") ! (match_operand:SI 4 "arm_add_operand" "rL,rL")]) ! (not:SI ! (match_operand:SI 2 "s_register_operand" "r,r")) ! (match_operand:SI 1 "arm_rhs_operand" "0,?rI"))) ! (clobber (reg 24))] ! "" ! "* ! { ! char pattern[100]; ! ! if (GET_CODE (operands[30]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[4]))) ! arm_output_asm_insn (\"cmn\\t%3, #%n4\", operands); ! else ! arm_output_asm_insn (\"cmp\\t%3, %4\", operands); ! if (which_alternative != 0) ! arm_output_asm_insn (\"mov%D5\\t%0, %1\", operands); ! return arm_output_asm_insn (\"mvn%d5\\t%0, %2\", operands); ! ! } ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "2,3")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! (if_then_else:SI (match_operator 6 "comparison_operator" ! [(match_operand:SI 4 "s_register_operand" "r,r") ! (match_operand:SI 5 "arm_add_operand" "rL,rL")]) ! (match_operator:SI 7 "shift_operator" ! [(match_operand:SI 2 "s_register_operand" "r,r") ! (match_operand:SI 3 "arm_rhs_operand" "rn,rn")]) ! (match_operand:SI 1 "arm_rhs_operand" "0,?rI"))) ! (clobber (reg 24))] ! "" ! "* ! { ! char pattern[100]; ! ! if (GET_CODE (operands[5]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[5]))) ! arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands); ! else ! arm_output_asm_insn (\"cmp\\t%4, %5\", operands); ! if (which_alternative != 0) ! arm_output_asm_insn (\"mov%D6\\t%0, %1\", operands); ! sprintf (pattern, \"mov%%d6\\t%%0, %%2, %s %%3\", ! shift_instr (GET_CODE (operands[7]), &operands[3])); ! return arm_output_asm_insn (pattern, operands); ! } ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "2,3")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! (if_then_else:SI (match_operator 6 "comparison_operator" ! [(match_operand:SI 4 "s_register_operand" "r,r") ! (match_operand:SI 5 "arm_add_operand" "rL,rL")]) ! (match_operand:SI 1 "arm_rhs_operand" "0,?rI") ! (match_operator:SI 7 "shift_operator" ! [(match_operand:SI 2 "s_register_operand" "r,r") ! (match_operand:SI 3 "arm_rhs_operand" "rn,rn")]))) ! (clobber (reg 24))] ! "" ! "* ! { ! char pattern[100]; ! ! if (GET_CODE (operands[5]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[5]))) ! arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands); ! else ! arm_output_asm_insn (\"cmp\\t%4, %5\", operands); ! if (which_alternative != 0) ! arm_output_asm_insn (\"mov%d6\\t%0, %1\", operands); ! sprintf (pattern, \"mov%%D6\\t%%0, %%2, %s %%3\", ! shift_instr (GET_CODE (operands[7]), &operands[3])); ! return arm_output_asm_insn (pattern, operands); ! } ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "2,3")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (if_then_else:SI (match_operator 7 "comparison_operator" ! [(match_operand:SI 5 "s_register_operand" "r") ! (match_operand:SI 6 "arm_add_operand" "rL")]) ! (match_operator:SI 8 "shift_operator" ! [(match_operand:SI 1 "s_register_operand" "r") ! (match_operand:SI 2 "arm_rhs_operand" "rn")]) ! (match_operator:SI 9 "shift_operator" ! [(match_operand:SI 3 "s_register_operand" "r") ! (match_operand:SI 4 "arm_rhs_operand" "rI")]))) ! (clobber (reg 24))] ! "" ! "* ! { ! char pattern[100]; ! ! if (GET_CODE (operands[6]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[6]))) ! arm_output_asm_insn (\"cmn\\t%5, #%n6\", operands); ! else ! arm_output_asm_insn (\"cmp\\t%5, %6\", operands); ! sprintf (pattern, \"mov%%d7\\t%%0, %%1, %s %%2\", ! shift_instr (GET_CODE (operands[8]), &operands[2])); ! arm_output_asm_insn (pattern, operands); ! sprintf (pattern, \"mov%%D7\\t%%0, %%3, %s %%4\", ! shift_instr (GET_CODE (operands[9]), &operands[4])); ! return arm_output_asm_insn (pattern, operands); ! } ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "3")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (if_then_else:SI (match_operator 6 "comparison_operator" ! [(match_operand:SI 4 "s_register_operand" "r") ! (match_operand:SI 5 "arm_add_operand" "rL")]) ! (not:SI (match_operand:SI 1 "s_register_operand" "r")) ! (match_operator:SI 7 "shiftable_operator" ! [(match_operand:SI 2 "s_register_operand" "r") ! (match_operand:SI 3 "arm_rhs_operand" "rI")]))) ! (clobber (reg 24))] ! "" ! "* ! { ! char pattern[100]; ! ! if (GET_CODE (operands[5]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[5]))) ! arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands); ! else ! arm_output_asm_insn (\"cmp\\t%4, %5\", operands); ! arm_output_asm_insn (\"mvn%d6\\t%0, %1\", operands); ! sprintf (pattern, \"%s%%D6\\t%%0, %%2, %%3\", arithmetic_instr (operands[7], ! FALSE)); ! return arm_output_asm_insn (pattern, operands); ! } ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "3")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (if_then_else:SI (match_operator 6 "comparison_operator" ! [(match_operand:SI 4 "s_register_operand" "r") ! (match_operand:SI 5 "arm_add_operand" "rL")]) ! (match_operator:SI 7 "shiftable_operator" ! [(match_operand:SI 2 "s_register_operand" "r") ! (match_operand:SI 3 "arm_rhs_operand" "rI")]) ! (not:SI (match_operand:SI 1 "s_register_operand" "r")))) ! (clobber (reg 24))] ! "" ! "* ! { ! char pattern[100]; ! ! if (GET_CODE (operands[5]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[5]))) ! arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands); ! else ! arm_output_asm_insn (\"cmp\\t%4, %5\", operands); ! arm_output_asm_insn (\"mvn%D6\\t%0, %1\", operands); ! sprintf (pattern, \"%s%%d6\\t%%0, %%2, %%3\", arithmetic_instr (operands[7], ! FALSE)); ! return arm_output_asm_insn (pattern, operands); ! } ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "3")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! (if_then_else:SI (match_operator 5 "comparison_operator" ! [(match_operand:SI 3 "s_register_operand" "r,r") ! (match_operand:SI 4 "arm_add_operand" "rL,rL")]) ! (neg:SI ! (match_operand:SI 2 "s_register_operand" "r,r")) ! (match_operand:SI 1 "arm_rhs_operand" "0,?rI"))) ! (clobber (reg:CC 24))] ! "" ! "* ! if (GET_CODE (operands[4]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[4]))) ! arm_output_asm_insn (\"cmn\\t%3, #%n4\", operands); ! else ! arm_output_asm_insn (\"cmp\\t%3, %4\", operands); ! if (which_alternative != 0) ! arm_output_asm_insn (\"mov%D5\\t%0, %1\", operands); ! return arm_output_asm_insn (\"rsb%d5\\t%0, %2, #0\", operands); ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "2,3")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! (if_then_else:SI (match_operator 5 "comparison_operator" ! [(match_operand:SI 3 "s_register_operand" "r,r") ! (match_operand:SI 4 "arm_add_operand" "rL,rL")]) ! (match_operand:SI 1 "arm_rhs_operand" "0,?rI") ! (neg:SI ! (match_operand:SI 2 "s_register_operand" "r,r")))) ! (clobber (reg:CC 24))] ! "" ! "* ! if (GET_CODE (operands[4]) == CONST_INT ! && !const_ok_for_arm (INTVAL (operands[4]))) ! arm_output_asm_insn (\"cmn\\t%3, #%n4\", operands); ! else ! arm_output_asm_insn (\"cmp\\t%3, %4\", operands); ! if (which_alternative != 0) ! arm_output_asm_insn (\"mov%d5\\t%0, %1\", operands); ! return arm_output_asm_insn (\"rsb%D5\\t%0, %2, #0\", operands); ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "2,3")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (match_operator:SI 1 "shiftable_operator" ! [(match_operand:SI 2 "memory_operand" "m") ! (match_operand:SI 3 "memory_operand" "m")])) ! (clobber (match_scratch:SI 4 "=r"))] ! "adjacent_mem_locations (operands[2], operands[3])" ! "* ! { ! rtx ldm[3]; ! rtx arith[3]; ! char pattern[100]; ! int val1 = 0, val2 = 0; ! ! sprintf (pattern, \"%s\\t%%0, %%1, %%2\", ! arithmetic_instr (operands[1], FALSE)); ! if (REGNO (operands[0]) > REGNO (operands[4])) ! { ! ldm[1] = operands[4]; ! ldm[2] = operands[0]; ! } ! else ! { ! ldm[1] = operands[0]; ! ldm[2] = operands[4]; ! } ! if (GET_CODE (XEXP (operands[2], 0)) != REG) ! val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1)); ! if (GET_CODE (XEXP (operands[3], 0)) != REG) ! val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1)); ! arith[0] = operands[0]; ! if (val1 < val2) ! { ! arith[1] = ldm[1]; ! arith[2] = ldm[2]; ! } ! else ! { ! arith[1] = ldm[2]; ! arith[2] = ldm[1]; ! } ! if (val1 && val2) ! { ! rtx ops[3]; ! ldm[0] = ops[0] = operands[4]; ! ops[1] = XEXP (XEXP (operands[2], 0), 0); ! ops[2] = XEXP (XEXP (operands[2], 0), 1); ! output_add_immediate (ops); ! if (val1 < val2) ! arm_output_asm_insn (\"ldmia\\t%0, {%1, %2}\", ldm); ! else ! arm_output_asm_insn (\"ldmda\\t%0, {%1, %2}\", ldm); ! } ! else if (val1) ! { ! ldm[0] = XEXP (operands[3], 0); ! if (val1 < val2) ! arm_output_asm_insn (\"ldmda\\t%0, {%1, %2}\", ldm); ! else ! arm_output_asm_insn (\"ldmia\\t%0, {%1, %2}\", ldm); ! } ! else ! { ! ldm[0] = XEXP (operands[2], 0); ! if (val1 < val2) ! arm_output_asm_insn (\"ldmia\\t%0, {%1, %2}\", ldm); ! else ! arm_output_asm_insn (\"ldmda\\t%0, {%1, %2}\", ldm); ! } ! return arm_output_asm_insn (pattern, arith); ! } ! " ! [(set_attr "length" "3") ! (set_attr "type" "load")]) ! ! ;; the arm can support extended pre-inc instructions ! ! ;; In all these cases, we use operands 0 and 1 for the register being ! ;; incremented because those are the operands that local-alloc will ! ;; tie and these are the pair most likely to be tieable (and the ones ! ;; that will benefit the most). ! ! ;; We reject the frame pointer if it occurs anywhere in these patterns since ! ;; elimination will cause too many headaches. ! ! (define_insn "" ! [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0") ! (match_operand:SI 2 "index_operand" "rJ"))) ! (match_operand:QI 3 "s_register_operand" "r")) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (plus:SI (match_dup 1) (match_dup 2)))] ! "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! && (GET_CODE (operands[2]) != REG ! || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" ! "* ! return arm_output_asm_insn (\"strb\\t%3, [%0, %2]!\", operands); ! " ! [(set_attr "type" "store1")]) ! ! (define_insn "" ! [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0") ! (match_operand:SI 2 "s_register_operand" "r"))) ! (match_operand:QI 3 "s_register_operand" "r")) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (minus:SI (match_dup 1) (match_dup 2)))] ! "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! && (GET_CODE (operands[2]) != REG ! || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" ! "* ! return arm_output_asm_insn (\"strb\\t%3, [%0, -%2]!\", operands); ! " ! [(set_attr "type" "store1")]) ! ! (define_insn "" ! [(set (match_operand:QI 3 "s_register_operand" "=r") ! (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0") ! (match_operand:SI 2 "index_operand" "rJ")))) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (plus:SI (match_dup 1) (match_dup 2)))] ! "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! && (GET_CODE (operands[2]) != REG ! || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" ! "* ! return arm_output_asm_insn (\"ldrb\\t%3, [%0, %2]!\", operands); ! " ! [(set_attr "type" "load")]) ! ! (define_insn "" ! [(set (match_operand:QI 3 "s_register_operand" "=r") ! (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0") ! (match_operand:SI 2 "s_register_operand" "r")))) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (minus:SI (match_dup 1) (match_dup 2)))] ! "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! && (GET_CODE (operands[2]) != REG ! || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" ! "* ! return arm_output_asm_insn (\"ldrb\\t%3, [%0, -%2]!\", operands); ! " ! [(set_attr "type" "load")]) ! ! (define_insn "" ! [(set (match_operand:SI 3 "s_register_operand" "=r") ! (zero_extend:SI ! (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0") ! (match_operand:SI 2 "index_operand" "rJ"))))) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (plus:SI (match_dup 1) (match_dup 2)))] ! "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! && (GET_CODE (operands[2]) != REG ! || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" ! "* ! return arm_output_asm_insn (\"ldrb\\t%3, [%0, %2]!\\t@ z_extendqisi\", ! operands); ! " ! [(set_attr "type" "load")]) ! ! (define_insn "" ! [(set (match_operand:SI 3 "s_register_operand" "=r") ! (zero_extend:SI ! (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0") ! (match_operand:SI 2 "s_register_operand" "r"))))) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (minus:SI (match_dup 1) (match_dup 2)))] ! "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! && (GET_CODE (operands[2]) != REG ! || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" ! "* ! return arm_output_asm_insn (\"ldrb\\t%3, [%0, -%2]!\\t@ z_extendqisi\", ! operands); ! " ! [(set_attr "type" "load")]) ! ! (define_insn "" ! [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0") ! (match_operand:SI 2 "index_operand" "rJ"))) ! (match_operand:SI 3 "s_register_operand" "r")) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (plus:SI (match_dup 1) (match_dup 2)))] ! "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! && (GET_CODE (operands[2]) != REG ! || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" ! "* ! return arm_output_asm_insn (\"str\\t%3, [%0, %2]!\", operands); ! " ! [(set_attr "type" "store1")]) ! ! (define_insn "" ! [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0") ! (match_operand:SI 2 "s_register_operand" "r"))) ! (match_operand:SI 3 "s_register_operand" "r")) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (minus:SI (match_dup 1) (match_dup 2)))] ! "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! && (GET_CODE (operands[2]) != REG ! || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" ! "* ! return arm_output_asm_insn (\"str\\t%3, [%0, -%2]!\", operands); ! " ! [(set_attr "type" "store1")]) ! ! (define_insn "" ! [(set (match_operand:SI 3 "s_register_operand" "=r") ! (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0") ! (match_operand:SI 2 "index_operand" "rJ")))) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (plus:SI (match_dup 1) (match_dup 2)))] ! "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! && (GET_CODE (operands[2]) != REG ! || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" ! "* ! return arm_output_asm_insn (\"ldr\\t%3, [%0, %2]!\", operands); ! " ! [(set_attr "type" "load")]) ! ! (define_insn "" ! [(set (match_operand:SI 3 "s_register_operand" "=r") ! (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0") ! (match_operand:SI 2 "s_register_operand" "r")))) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (minus:SI (match_dup 1) (match_dup 2)))] ! "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! && (GET_CODE (operands[2]) != REG ! || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" ! "* ! return arm_output_asm_insn (\"ldr\\t%3, [%0, -%2]!\", operands); ! " ! [(set_attr "type" "load")]) ! ! (define_insn "" ! [(set (match_operand:HI 3 "s_register_operand" "=r") ! (mem:HI (plus:SI (match_operand:SI 1 "s_register_operand" "%0") ! (match_operand:SI 2 "index_operand" "rJ")))) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (plus:SI (match_dup 1) (match_dup 2)))] ! "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! && (GET_CODE (operands[2]) != REG ! || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" ! "* ! return arm_output_asm_insn (\"ldr\\t%3, [%0, %2]!\\t@ loadhi\", operands); ! " ! [(set_attr "type" "load")]) ! ! (define_insn "" ! [(set (match_operand:HI 3 "s_register_operand" "=r") ! (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0") ! (match_operand:SI 2 "s_register_operand" "r")))) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (minus:SI (match_dup 1) (match_dup 2)))] ! "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! && (GET_CODE (operands[2]) != REG ! || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" ! "* ! return arm_output_asm_insn (\"ldr\\t%3, [%0, -%2]!\\t@ loadhi\", operands); ! " ! [(set_attr "type" "load")]) ! ! (define_insn "" ! [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator" ! [(match_operand:SI 3 "s_register_operand" "r") ! (match_operand:SI 4 "const_shift_operand" "n")]) ! (match_operand:SI 1 "s_register_operand" "0"))) ! (match_operand:QI 5 "s_register_operand" "r")) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)]) ! (match_dup 1)))] ! "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! && REGNO (operands[3]) != FRAME_POINTER_REGNUM" ! "* ! { ! char instr[100]; ! ! sprintf (instr, \"strb\\t%%5, [%%0, %%3, %s %%4]!\", ! shift_instr (GET_CODE (operands[2]), &operands[4])); ! return arm_output_asm_insn (instr, operands); ! } ! " ! [(set_attr "type" "store1")]) ! ! (define_insn "" ! [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0") ! (match_operator:SI 2 "shift_operator" ! [(match_operand:SI 3 "s_register_operand" "r") ! (match_operand:SI 4 "const_shift_operand" "n")]))) ! (match_operand:QI 5 "s_register_operand" "r")) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3) ! (match_dup 4)])))] ! "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! && REGNO (operands[3]) != FRAME_POINTER_REGNUM" ! "* ! { ! char instr[100]; ! ! sprintf (instr, \"strb\\t%%5, [%%0, -%%3, %s %%4]!\", ! shift_instr (GET_CODE (operands[2]), &operands[4])); ! return arm_output_asm_insn (instr, operands); ! } ! " ! [(set_attr "type" "store1")]) ! ! (define_insn "" ! [(set (match_operand:QI 5 "s_register_operand" "=r") ! (mem:QI (plus:SI (match_operator:SI 2 "shift_operator" ! [(match_operand:SI 3 "s_register_operand" "r") ! (match_operand:SI 4 "const_shift_operand" "n")]) ! (match_operand:SI 1 "s_register_operand" "0")))) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)]) ! (match_dup 1)))] ! "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! && REGNO (operands[3]) != FRAME_POINTER_REGNUM" ! "* ! { ! char instr[100]; ! ! sprintf (instr, \"ldrb\\t%%5, [%%0, %%3, %s %%4]!\", ! shift_instr (GET_CODE (operands[2]), &operands[4])); ! return arm_output_asm_insn (instr, operands); ! } ! " ! [(set_attr "type" "load")]) ! ! (define_insn "" ! [(set (match_operand:QI 5 "s_register_operand" "=r") ! (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0") ! (match_operator:SI 2 "shift_operator" ! [(match_operand:SI 3 "s_register_operand" "r") ! (match_operand:SI 4 "const_shift_operand" "n")])))) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3) ! (match_dup 4)])))] ! "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! && REGNO (operands[3]) != FRAME_POINTER_REGNUM" ! "* ! { ! char instr[100]; ! ! sprintf (instr, \"ldrb\\t%%5, [%%0, -%%3, %s %%4]!\", ! shift_instr (GET_CODE (operands[2]), &operands[4])); ! return arm_output_asm_insn (instr, operands); ! } ! " ! [(set_attr "type" "load")]) ! ! (define_insn "" ! [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator" ! [(match_operand:SI 3 "s_register_operand" "r") ! (match_operand:SI 4 "const_shift_operand" "n")]) ! (match_operand:SI 1 "s_register_operand" "0"))) ! (match_operand:SI 5 "s_register_operand" "r")) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)]) ! (match_dup 1)))] ! "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! && REGNO (operands[3]) != FRAME_POINTER_REGNUM" ! "* ! { ! char instr[100]; ! ! sprintf (instr, \"str\\t%%5, [%%0, %%3, %s %%4]!\", ! shift_instr (GET_CODE (operands[2]), &operands[4])); ! return arm_output_asm_insn (instr, operands); ! } ! " ! [(set_attr "type" "store1")]) ! ! (define_insn "" ! [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0") ! (match_operator:SI 2 "shift_operator" ! [(match_operand:SI 3 "s_register_operand" "r") ! (match_operand:SI 4 "const_shift_operand" "n")]))) ! (match_operand:SI 5 "s_register_operand" "r")) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3) ! (match_dup 4)])))] ! "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! && REGNO (operands[3]) != FRAME_POINTER_REGNUM" ! "* ! { ! char instr[100]; ! ! sprintf (instr, \"str\\t%%5, [%%0, -%%3, %s %%4]!\", ! shift_instr (GET_CODE (operands[2]), &operands[4])); ! return arm_output_asm_insn (instr, operands); ! } ! " ! [(set_attr "type" "store1")]) ! ! (define_insn "" ! [(set (match_operand:SI 5 "s_register_operand" "=r") ! (mem:SI (plus:SI (match_operator:SI 2 "shift_operator" ! [(match_operand:SI 3 "s_register_operand" "r") ! (match_operand:SI 4 "const_shift_operand" "n")]) ! (match_operand:SI 1 "s_register_operand" "0")))) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)]) ! (match_dup 1)))] ! "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! && REGNO (operands[3]) != FRAME_POINTER_REGNUM" ! "* ! { ! char instr[100]; ! ! sprintf (instr, \"ldr\\t%%5, [%%0, %%3, %s %%4]!\", ! shift_instr (GET_CODE (operands[2]), &operands[4])); ! return arm_output_asm_insn (instr, operands); ! } ! " ! [(set_attr "type" "load")]) ! ! (define_insn "" ! [(set (match_operand:SI 5 "s_register_operand" "=r") ! (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0") ! (match_operator:SI 2 "shift_operator" ! [(match_operand:SI 3 "s_register_operand" "r") ! (match_operand:SI 4 "const_shift_operand" "n")])))) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3) ! (match_dup 4)])))] ! "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! && REGNO (operands[3]) != FRAME_POINTER_REGNUM" ! "* ! { ! char instr[100]; ! ! sprintf (instr, \"ldr\\t%%5, [%%0, -%%3, %s %%4]!\", ! shift_instr (GET_CODE (operands[2]), &operands[4])); ! return arm_output_asm_insn (instr, operands); ! } ! " ! [(set_attr "type" "load")]) ! ! (define_insn "" ! [(set (match_operand:HI 5 "s_register_operand" "=r") ! (mem:HI (plus:SI (match_operator:SI 2 "shift_operator" ! [(match_operand:SI 3 "s_register_operand" "r") ! (match_operand:SI 4 "const_shift_operand" "n")]) ! (match_operand:SI 1 "s_register_operand" "0")))) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)]) ! (match_dup 1)))] ! "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! && REGNO (operands[3]) != FRAME_POINTER_REGNUM" ! "* ! { ! char instr[100]; ! ! sprintf (instr, \"ldr\\t%%5, [%%0, %%3, %s %%4]!\\t@ loadhi\", ! shift_instr (GET_CODE (operands[2]), &operands[4])); ! return arm_output_asm_insn (instr, operands); ! } ! " ! [(set_attr "type" "load")]) ! ! (define_insn "" ! [(set (match_operand:HI 5 "s_register_operand" "=r") ! (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0") ! (match_operator:SI 2 "shift_operator" ! [(match_operand:SI 3 "s_register_operand" "r") ! (match_operand:SI 4 "const_shift_operand" "n")])))) ! (set (match_operand:SI 0 "s_register_operand" "=r") ! (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3) ! (match_dup 4)])))] ! "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! && REGNO (operands[3]) != FRAME_POINTER_REGNUM" ! "* ! { ! char instr[100]; ! ! sprintf (instr, \"ldr\\t%%5, [%%0, -%%3, %s %%4]!\\t@ loadhi\", ! shift_instr (GET_CODE (operands[2]), &operands[4])); ! return arm_output_asm_insn (instr, operands); ! } ! " ! [(set_attr "type" "load")]) ! ! ; It can also support extended post-inc expressions, but combine doesn't ! ; try these.... ! ; It doesn't seem worth adding peepholes for anything but the most common ! ; cases since, unlike combine, the increment must immediately follow the load ! ; for this pattern to match. ! ; When loading we must watch to see that the base register isn't trampled by ! ; the load. In such cases this isn't a post-inc expression. ! ! (define_peephole ! [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r")) ! (match_operand:QI 2 "s_register_operand" "r")) ! (set (match_dup 0) ! (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))] ! "" ! "* ! return arm_output_asm_insn (\"strb\\t%2, [%0], %1\", operands); ! ") ! ! (define_peephole ! [(set (match_operand:QI 0 "s_register_operand" "=r") ! (mem:QI (match_operand:SI 1 "s_register_operand" "+r"))) ! (set (match_dup 1) ! (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))] ! "REGNO(operands[0]) != REGNO(operands[1]) ! && (GET_CODE (operands[2]) != REG ! || REGNO(operands[0]) != REGNO (operands[2]))" ! "* ! return arm_output_asm_insn (\"ldrb\\t%0, [%1], %2\", operands); ! ") ! ! (define_peephole ! [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r")) ! (match_operand:SI 2 "s_register_operand" "r")) ! (set (match_dup 0) ! (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))] ! "" ! "* ! return arm_output_asm_insn (\"str\\t%2, [%0], %1\", operands); ! ") ! ! (define_peephole ! [(set (match_operand:HI 0 "s_register_operand" "=r") ! (mem:HI (match_operand:SI 1 "s_register_operand" "+r"))) ! (set (match_dup 1) ! (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))] ! "REGNO(operands[0]) != REGNO(operands[1]) ! && (GET_CODE (operands[2]) != REG ! || REGNO(operands[0]) != REGNO (operands[2]))" ! "* ! return arm_output_asm_insn (\"ldr\\t%0, [%1], %2\\t@ loadhi\", operands); ! ") ! ! (define_peephole ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (mem:SI (match_operand:SI 1 "s_register_operand" "+r"))) ! (set (match_dup 1) ! (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))] ! "REGNO(operands[0]) != REGNO(operands[1]) ! && (GET_CODE (operands[2]) != REG ! || REGNO(operands[0]) != REGNO (operands[2]))" ! "* ! return arm_output_asm_insn (\"ldr\\t%0, [%1], %2\", operands); ! ") ! ! ; This pattern is never tried by combine, so do it as a peephole ! ! (define_peephole ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (match_operand:SI 1 "s_register_operand" "r")) ! (set (match_operand 2 "cc_register" "") ! (compare (match_dup 1) (const_int 0)))] ! "" ! "* ! return arm_output_asm_insn (\"subs\\t%0, %1, #0\", operands); ! " ! [(set_attr "conds" "set")]) ! ! ; Peepholes to spot possible load- and store-multiples, if the ordering is ! ; reversed, check that the memory references aren't volatile. ! ! (define_peephole ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r") ! (const_int 12)))) ! (set (match_operand:SI 2 "s_register_operand" "=r") ! (mem:SI (plus:SI (match_dup 1) (const_int 8)))) ! (set (match_operand:SI 3 "s_register_operand" "=r") ! (mem:SI (plus:SI (match_dup 1) (const_int 4)))) ! (set (match_operand:SI 4 "s_register_operand" "=r") ! (mem:SI (match_dup 1)))] ! "REGNO (operands[0]) > REGNO (operands[2]) ! && REGNO (operands[2]) > REGNO (operands[3]) ! && REGNO (operands[3]) > REGNO (operands[4]) ! && !(REGNO (operands[1]) == REGNO (operands[0]) ! || REGNO (operands[1]) == REGNO (operands[2]) ! || REGNO (operands[1]) == REGNO (operands[3]) ! || REGNO (operands[1]) == REGNO (operands[4])) ! && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn))) ! && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn)))) ! && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn ! (prev_nonnote_insn (insn))))) ! && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn ! (prev_nonnote_insn ! (prev_nonnote_insn (insn))))))" ! "* ! return arm_output_asm_insn (\"ldmia\\t%1, {%4, %3, %2, %0}\\t@ phole ldm\", ! operands); ! ") ! ! (define_peephole ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r") ! (const_int 8)))) ! (set (match_operand:SI 2 "s_register_operand" "=r") ! (mem:SI (plus:SI (match_dup 1) (const_int 4)))) ! (set (match_operand:SI 3 "s_register_operand" "=r") ! (mem:SI (match_dup 1)))] ! "REGNO (operands[0]) > REGNO (operands[2]) ! && REGNO (operands[2]) > REGNO (operands[3]) ! && !(REGNO (operands[1]) == REGNO (operands[0]) ! || REGNO (operands[1]) == REGNO (operands[2]) ! || REGNO (operands[1]) == REGNO (operands[3])) ! && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn))) ! && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn)))) ! && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn ! (prev_nonnote_insn (insn)))))" ! "* ! return arm_output_asm_insn (\"ldmia\\t%1, {%3, %2, %0}\\t@ phole ldm\", ! operands); ! ") ! ! (define_peephole ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r") ! (const_int 4)))) ! (set (match_operand:SI 2 "s_register_operand" "=r") ! (mem:SI (match_dup 1)))] ! "REGNO (operands[0]) > REGNO (operands[2]) ! && !(REGNO (operands[1]) == REGNO (operands[0]) ! || REGNO (operands[1]) == REGNO (operands[2])) ! && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn))) ! && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))" ! "* ! return arm_output_asm_insn (\"ldmia\\t%1, {%2, %0}\\t@ phole ldm\", ! operands); ! ") ! ! (define_peephole ! [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r") ! (const_int 12))) ! (match_operand:SI 0 "s_register_operand" "r")) ! (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) ! (match_operand:SI 2 "s_register_operand" "r")) ! (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) ! (match_operand:SI 3 "s_register_operand" "r")) ! (set (mem:SI (match_dup 1)) ! (match_operand:SI 4 "s_register_operand" "r"))] ! "REGNO (operands[0]) > REGNO (operands[2]) ! && REGNO (operands[2]) > REGNO (operands[3]) ! && REGNO (operands[3]) > REGNO (operands[4]) ! && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn))) ! && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn)))) ! && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn ! (prev_nonnote_insn (insn))))) ! && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn ! (prev_nonnote_insn ! (prev_nonnote_insn (insn))))))" ! "* ! return arm_output_asm_insn (\"stmia\\t%1, {%4, %3, %2, %0}\\t@ phole stm\", ! operands); ! ") ! ! (define_peephole ! [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r") ! (const_int 8))) ! (match_operand:SI 0 "s_register_operand" "r")) ! (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) ! (match_operand:SI 2 "s_register_operand" "r")) ! (set (mem:SI (match_dup 1)) ! (match_operand:SI 3 "s_register_operand" "r"))] ! "REGNO (operands[0]) > REGNO (operands[2]) ! && REGNO (operands[2]) > REGNO (operands[3]) ! && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn))) ! && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn)))) ! && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn ! (prev_nonnote_insn (insn)))))" ! "* ! return arm_output_asm_insn (\"stmia\\t%1, {%3, %2, %0}\\t@ phole stm\", ! operands); ! ") ! ! (define_peephole ! [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r") ! (const_int 4))) ! (match_operand:SI 0 "s_register_operand" "r")) ! (set (mem:SI (match_dup 1)) ! (match_operand:SI 2 "s_register_operand" "r"))] ! "REGNO (operands[0]) > REGNO (operands[2]) ! && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn))) ! && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))" ! "* ! return arm_output_asm_insn (\"stmia\\t%1, {%2, %0}\\t@ phole stm\", ! operands); ! ") ! ! ;; A call followed by return can be replaced by restoring the regs and ! ;; jumping to the subroutine, provided we aren't passing the address of ! ;; any of our local variables. If we call alloca then this is unsafe ! ;; since restoring the frame frees the memory, which is not what we want. ! ;; Sometimes the return might have been targeted by the final prescan: ! ;; if so then emit a propper return insn as well. ! ;; Unfortunately, if the frame pointer is required, we don't know if the ! ;; current function has any implicit stack pointer adjustments that will ! ;; be restored by the return: we can't therefore do a tail call. ! ;; Another unfortunate that we can't handle is if current_function_args_size ! ;; is non-zero: in this case elimination of the argument pointer assumed ! ;; that lr was pushed onto the stack, so eliminating upsets the offset ! ;; calculations. ! ! (define_peephole ! [(parallel [(call (mem:SI (match_operand:SI 0 "" "i")) ! (match_operand:SI 1 "general_operand" "g")) ! (clobber (reg:SI 14))]) ! (return)] ! "(GET_CODE (operands[0]) == SYMBOL_REF && USE_RETURN_INSN ! && !get_frame_size () && !current_function_calls_alloca ! && !frame_pointer_needed && !current_function_args_size)" ! "* ! { ! extern rtx arm_target_insn; ! extern int arm_ccfsm_state, arm_current_cc; ! ! if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn)) ! { ! arm_current_cc ^= 1; ! output_return_instruction (NULL, TRUE); ! arm_ccfsm_state = 0; ! arm_target_insn = NULL; ! } ! ! output_return_instruction (NULL, FALSE); ! return (arm_output_asm_insn (\"b\\t%a0\", operands)); ! }" ! [(set (attr "conds") ! (if_then_else (eq_attr "cpu" "arm6") ! (const_string "clob") ! (const_string "nocond"))) ! (set_attr "length" "2")]) ! ! (define_peephole ! [(parallel [(set (match_operand 0 "s_register_operand" "=rf") ! (call (mem:SI (match_operand:SI 1 "" "i")) ! (match_operand:SI 2 "general_operand" "g"))) ! (clobber (reg:SI 14))]) ! (return)] ! "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN ! && !get_frame_size () && !current_function_calls_alloca ! && !frame_pointer_needed && !current_function_args_size)" ! "* ! { ! extern rtx arm_target_insn; ! extern int arm_ccfsm_state, arm_current_cc; ! ! if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn)) ! { ! arm_current_cc ^= 1; ! output_return_instruction (NULL, TRUE); ! arm_ccfsm_state = 0; ! arm_target_insn = NULL; ! } ! ! output_return_instruction (NULL, FALSE); ! return (arm_output_asm_insn (\"b\\t%a1\", operands)); ! }" ! [(set (attr "conds") ! (if_then_else (eq_attr "cpu" "arm6") ! (const_string "clob") ! (const_string "nocond"))) ! (set_attr "length" "2")]) ! ! ;; As above but when this function is not void, we must be returning the ! ;; result of the called subroutine. ! ! (define_peephole ! [(parallel [(set (match_operand 0 "s_register_operand" "=rf") ! (call (mem:SI (match_operand:SI 1 "" "i")) ! (match_operand:SI 2 "general_operand" "g"))) ! (clobber (reg:SI 14))]) ! (use (match_dup 0)) ! (return)] ! "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN ! && !get_frame_size () && !current_function_calls_alloca ! && !frame_pointer_needed && !current_function_args_size)" ! "* ! { ! extern rtx arm_target_insn; ! extern int arm_ccfsm_state, arm_current_cc; ! ! if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn)) ! { ! arm_current_cc ^= 1; ! output_return_instruction (NULL, TRUE); ! arm_ccfsm_state = 0; ! arm_target_insn = NULL; ! } ! ! output_return_instruction (NULL, FALSE); ! return (arm_output_asm_insn (\"b\\t%a1\", operands)); ! }" ! [(set (attr "conds") ! (if_then_else (eq_attr "cpu" "arm6") ! (const_string "clob") ! (const_string "nocond"))) ! (set_attr "length" "2")]) ! ! ;; If calling a subroutine and then jumping back to somewhere else, but not ! ;; too far away, then we can set the link register with the branch address ! ;; and jump direct to the subroutine. On return from the subroutine ! ;; execution continues at the branch; this avoids a prefetch stall. ! ;; We use the length attribute (via short_branch ()) to establish whether or ! ;; not this is possible, this is the same asthe sparc does. ! ! (define_peephole ! [(parallel[(call (mem:SI (match_operand:SI 0 "" "i")) ! (match_operand:SI 1 "general_operand" "g")) ! (clobber (reg:SI 14))]) ! (set (pc) ! (label_ref (match_operand 2 "" "")))] ! "GET_CODE (operands[0]) == SYMBOL_REF ! && short_branch (INSN_UID (insn), INSN_UID (operands[2])) ! && arm_insn_not_targeted (insn)" ! "* ! { ! int backward = arm_backwards_branch (INSN_UID (insn), ! INSN_UID (operands[2])); ! ! #if 0 ! /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or ! * above, leaving it out means that the code will still run on an arm 2 or 3 ! */ ! if (TARGET_6) ! { ! if (backward) ! arm_output_asm_insn (\"sub\\tlr, pc, #(8 + . -%l2)\", operands); ! else ! arm_output_asm_insn (\"add\\tlr, pc, #(%l2 - . -8)\", operands); ! } ! else ! #endif ! { ! arm_output_asm_insn (\"mov\\tlr, pc\\t@ protect cc\"); ! if (backward) ! arm_output_asm_insn (\"sub\\tlr, lr, #(4 + . -%l2)\", operands); ! else ! arm_output_asm_insn (\"add\\tlr, lr, #(%l2 - . -4)\", operands); ! } ! return arm_output_asm_insn (\"b\\t%a0\", operands); ! }" ! [(set (attr "conds") ! (if_then_else (eq_attr "cpu" "arm6") ! (const_string "clob") ! (const_string "nocond"))) ! (set (attr "length") ! (if_then_else (eq_attr "cpu" "arm6") ! (const_int 2) ! (const_int 3)))]) ! ! (define_peephole ! [(parallel[(set (match_operand:SI 0 "s_register_operand" "=r") ! (call (mem:SI (match_operand:SI 1 "" "i")) ! (match_operand:SI 2 "general_operand" "g"))) ! (clobber (reg:SI 14))]) ! (set (pc) ! (label_ref (match_operand 3 "" "")))] ! "GET_CODE (operands[0]) == SYMBOL_REF ! && short_branch (INSN_UID (insn), INSN_UID (operands[3])) ! && arm_insn_not_targeted (insn)" ! "* ! { ! int backward = arm_backwards_branch (INSN_UID (insn), ! INSN_UID (operands[3])); ! ! #if 0 ! /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or ! * above, leaving it out means that the code will still run on an arm 2 or 3 ! */ ! if (TARGET_6) ! { ! if (backward) ! arm_output_asm_insn (\"sub\\tlr, pc, #(8 + . -%l3)\", operands); ! else ! arm_output_asm_insn (\"add\\tlr, pc, #(%l3 - . -8)\", operands); ! } ! else ! #endif ! { ! arm_output_asm_insn (\"mov\\tlr, pc\\t@ protect cc\"); ! if (backward) ! arm_output_asm_insn (\"sub\\tlr, lr, #(4 + . -%l3)\", operands); ! else ! arm_output_asm_insn (\"add\\tlr, lr, #(%l3 - . -4)\", operands); ! } ! return arm_output_asm_insn (\"b\\t%a1\", operands); ! }" ! [(set (attr "conds") ! (if_then_else (eq_attr "cpu" "arm6") ! (const_string "clob") ! (const_string "nocond"))) ! (set (attr "length") ! (if_then_else (eq_attr "cpu" "arm6") ! (const_int 2) ! (const_int 3)))]) ! ! (define_split ! [(set (pc) ! (if_then_else (match_operator 0 "comparison_operator" ! [(match_operator:SI 1 "shift_operator" ! [(match_operand:SI 2 "s_register_operand" "r") ! (match_operand:SI 3 "nonmemory_operand" "rn")]) ! (match_operand:SI 4 "s_register_operand" "r")]) ! (label_ref (match_operand 5 "" "")) ! (pc))) ! (clobber (reg 24))] ! "" ! [(set (reg:CC 24) ! (compare:CC (match_dup 4) ! (match_op_dup 1 [(match_dup 2) (match_dup 3)]))) ! (set (pc) ! (if_then_else (match_op_dup 0 [(reg 24) (const_int 0)]) ! (label_ref (match_dup 5)) ! (pc)))] ! " ! operands[0] = gen_rtx (swap_condition (GET_CODE (operands[0])), VOIDmode, ! operands[1], operands[2]); ! ") ! ! (define_split ! [(set (match_operand:SI 0 "s_register_operand" "") ! (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "") ! (const_int 0)) ! (neg:SI (match_operator:SI 2 "comparison_operator" ! [(match_operand:SI 3 "s_register_operand" "") ! (match_operand:SI 4 "arm_rhs_operand" "")])))) ! (clobber (match_operand:SI 5 "s_register_operand" ""))] ! "" ! [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31)))) ! (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)]) ! (match_dup 5)))] ! "") ! ! ;; This pattern can be used because cc_noov mode implies that the following ! ;; branch will be an equality (EQ or NE), so the sign extension is not ! ;; needed. Combine doesn't eliminate these because by the time it sees the ! ;; branch it no-longer knows that the data came from memory. ! ! (define_insn "" ! [(set (reg:CC_NOOV 24) ! (compare:CC_NOOV ! (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "m") 0) ! (const_int 24)) ! (match_operand 1 "immediate_operand" "I"))) ! (clobber (match_scratch:SI 2 "=r"))] ! "((unsigned long) INTVAL (operands[1])) ! == (((unsigned long) INTVAL (operands[1])) >> 24) << 24" ! "* ! operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24); ! arm_output_asm_insn (\"ldrb\\t%2, %0\", operands); ! return arm_output_asm_insn (\"cmp\\t%2, %1\", operands); ! " ! [(set_attr "conds" "set") ! (set_attr "length" "2") ! (set_attr "type" "load")]) ! ! (define_expand "save_stack_nonlocal" ! [(match_operand:DI 0 "memory_operand" "") ! (match_operand:SI 1 "s_register_operand" "")] ! "" ! " ! { ! /* We also need to save the frame pointer for non-local gotos */ ! emit_move_insn (operand_subword (operands[0], 0, 0, DImode), ! hard_frame_pointer_rtx); ! emit_move_insn (operand_subword (operands[0], 1, 0, DImode), operands[1]); ! DONE; ! }") ! ! (define_expand "restore_stack_nonlocal" ! [(match_operand:SI 0 "s_register_operand" "") ! (match_operand:DI 1 "memory_operand" "")] ! "" ! " ! { ! /* Restore the frame pointer first, the stack pointer second. */ ! emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, DImode)); ! emit_move_insn (hard_frame_pointer_rtx, operand_subword (operands[1], 0, 0, ! DImode)); ! DONE; ! }") ! ! ;; This split is only used during output to reduce the number of patterns ! ;; that need assembler instructions adding to them. We allowed the setting ! ;; of the conditions to be implicit during rtl generation so that ! ;; the conditional compare patterns would work. However this conflicts to ! ;; some extend with the conditional data operations, so we have to split them ! ;; up again here. ! ! (define_split ! [(set (match_operand:SI 0 "s_register_operand" "") ! (if_then_else:SI (match_operator 1 "comparison_operator" ! [(match_operand 2 "" "") (match_operand 3 "" "")]) ! (match_operand 4 "" "") ! (match_operand 5 "" ""))) ! (clobber (reg 24))] ! "reload_completed" ! [(set (match_dup 6) (match_dup 7)) ! (set (match_dup 0) ! (if_then_else:SI (match_op_dup 1 [(match_dup 6) (const_int 0)]) ! (match_dup 4) ! (match_dup 5)))] ! " ! { ! enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), operands[2], ! operands[3]); ! ! operands[6] = gen_rtx (REG, mode, 24); ! operands[7] = gen_rtx (COMPARE, mode, operands[2], operands[3]); ! } ! ") ! ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! (if_then_else:SI (match_operator 4 "comparison_operator" ! [(match_operand 3 "cc_register" "") (const_int 0)]) ! (match_operand:SI 1 "arm_rhs_operand" "0,?rI") ! (not:SI ! (match_operand:SI 2 "s_register_operand" "r,r"))))] ! "" ! "* ! if (which_alternative != 0) ! arm_output_asm_insn (\"mov%d4\\t%0, %1\", operands); ! return arm_output_asm_insn (\"mvn%D4\\t%0, %2\", operands); ! " ! [(set_attr "conds" "use") ! (set_attr "length" "1,2")]) ! ! ;; The next two patterns occur when an AND operation is followed by a ! ;; scc insn sequence ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") ! (const_int 1) ! (match_operand:SI 2 "immediate_operand" "n")))] ! "" ! "* ! operands[2] = GEN_INT (1 << INTVAL (operands[2])); ! arm_output_asm_insn (\"ands\\t%0, %1, %2\", operands); ! return arm_output_asm_insn (\"mvnne\\t%0, #0\", operands); ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "2")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "s_register_operand" "=r") ! (not:SI ! (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") ! (const_int 1) ! (match_operand:SI 2 "immediate_operand" "n"))))] ! "" ! "* ! operands[2] = GEN_INT (1 << INTVAL (operands[2])); ! arm_output_asm_insn (\"tst\\t%1, %2\", operands); ! arm_output_asm_insn (\"mvneq\\t%0, #0\", operands); ! return arm_output_asm_insn (\"movne\\t%0, #0\", operands); ! " ! [(set_attr "conds" "clob") ! (set_attr "length" "3")]) diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/arm/riscix.h gcc-2.5.0/config/arm/riscix.h *** gcc-2.4.5/config/arm/riscix.h --- gcc-2.5.0/config/arm/riscix.h Sun Oct 3 12:29:37 1993 *************** *** 0 **** --- 1,116 ---- + /* Definitions of target machine for GNU compiler. ARM RISCiX version. + Copyright (C) 1993 Free Software Foundation, Inc. + Contributed by Richard Earnshaw (rwe11@cl.cam.ac.uk), based on original + work by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) + and Martin Simmons (@harleqn.co.uk). + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + /* Translation to find startup files. On RISCiX boxes, gcrt0.o is in + /usr/lib. */ + #define STARTFILE_SPEC \ + "%{pg:/usr/lib/gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}" + + #ifndef CPP_PREDEFINES + #define CPP_PREDEFINES \ + "-Darm -Driscix -Dunix -Asystem(unix) -Acpu(arm) -Amachine(arm)" + #endif + #if 0 + #define CPP_PREDEFINES "-Darm -Driscos -Acpu(arm) -Amachine(arm)" + #endif + + #ifndef CPP_SPEC + #define CPP_SPEC "%{m6:-D__arm6__} \ + %{mbsd:%{pedantic:%e-mbsd and -pedantic incompatible} -D_BSD_C} \ + %{mxopen:%{mbsd:%e-mbsd and -mxopen incompatible} \ + %{pedantic:%e-mxopen and -pedantic incompatible} -D_XOPEN_C} \ + %{!mbsd:%{!mxopen:%{!ansi: -D_BSD_C}}}" + #endif + + /* RISCiX has some wierd symbol name munging, that is done to the object module + after assembly, which enables multiple libraries to be supported within + one (possibly shared) library. It basically changes the symbol name of + certain symbols (for example _bcopy is converted to _$bcopy if using BSD) + Symrename's parameters are determined as follows: + -mno-symrename Don't run symrename + -mbsd symrename -BSD + -mxopen symrename -XOPEN + -ansi symrename - + symrename -BSD + */ + + #ifndef ASM_FINAL_SPEC + #if !defined (CROSS_COMPILER) + #define ASM_FINAL_SPEC "\ + %{!mno-symrename: \ + \n /usr/bin/symrename \ + -%{mbsd:%{ansi:%e-mbsd and -ansi incompatible}BSD}\ + %{mxopen:%{mbsd:%e-mbsd and -mxopen incompatible}\ + %{ansi:%e-mxopen and -ansi incompatible}XOPEN}\ + %{!mbsd:%{!mxopen:%{!ansi:BSD}}} %{c:%{o*:%*}%{!o*:%b.o}}%{!c:%U.o}}" + #endif + #endif + + /* None of these is actually used in cc1, so they modify bit 31 */ + #define ARM_EXTRA_TARGET_SWITCHES \ + {"bsd", 0x80000000}, {"xopen", 0x80000000}, {"no-symrename", 0x80000000}, + + + + /* Run-time Target Specification. */ + #define TARGET_VERSION \ + fputs (" (ARM/RISCiX)", stderr); + + /* This is used in ASM_FILE_START */ + #define ARM_OS_NAME "RISCiX" + + #ifdef riscos + #define TARGET_WHEN_DEBUGGING 3 + #else + #define TARGET_WHEN_DEBUGGING 1 + #endif + + /* 'char' is signed by default on RISCiX, unsigned on RISCOS. */ + #ifdef riscos + #define DEFAULT_SIGNED_CHAR 0 + #else + #define DEFAULT_SIGNED_CHAR 1 + #endif + + /* Define this if the target system supports the function atexit form the + ANSI C standard. If this is not defined, and INIT_SECTION_ASM_OP is not + defined, a default exit function will be provided to support C++. + The man page only describes on_exit, but atexit is also there. */ + #define HAVE_ATEXIT 1 + /* Some systems use __main in a way incompatible with its use in gcc, in these + cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to + give the same symbol without quotes for an alternative entry point. You + must define both, or niether. */ + #ifndef NAME__MAIN + #define NAME__MAIN "__gccmain" + #define SYMBOL__MAIN __gccmain + #endif + + #include "arm/arm.h" + + /* The native RISCiX assembler does not support stabs of any kind; because + the native assembler is not used by the compiler, Acorn didn't feel it was + necessary to put them in! */ + + #ifdef DBX_DEBUGGING_INFO + #undef DBX_DEBUGGING_INFO + #endif diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/arm/riscix1-1.h gcc-2.5.0/config/arm/riscix1-1.h *** gcc-2.4.5/config/arm/riscix1-1.h --- gcc-2.5.0/config/arm/riscix1-1.h Sun Oct 3 12:29:37 1993 *************** *** 0 **** --- 1,92 ---- + /* Definitions of target machine for GNU compiler. ARM RISCiX 1.1x version. + Copyright (C) 1993 Free Software Foundation, Inc. + Contributed by Richard Earnshaw (rwe11@cl.cam.ac.uk), based on original + work by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) + and Martin Simmons (@harleqn.co.uk). + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + /* RISCix 1.1x is basically the same as 1.2x except that it doesn't have + symrename or atexit. */ + + /* Translation to find startup files. On RISCiX boxes, gcrt0.o is in + /usr/lib. */ + #define STARTFILE_SPEC \ + "%{pg:/usr/lib/gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}" + + #ifndef CPP_PREDEFINES + #define CPP_PREDEFINES "-Darm -Driscix -Dunix -Asystem(unix) -Acpu(arm) -Amachine(arm)" + #endif + + #ifndef CPP_SPEC + #define CPP_SPEC "%{m6:-D__arm6__} %{!ansi: -D_BSD_C}" + #endif + + /* Riscix 1.1 doesn't have X/OPEN support, so only accept -mbsd (but ignore + it). + By not having -mxopen and -mno-symrename, we get warning messages, + but everything still compiles. */ + /* None of these is actually used in cc1, so they modify bit 31 */ + #define ARM_EXTRA_TARGET_SWITCHES \ + {"bsd", 0x80000000}, + + + + /* Run-time Target Specification. */ + #define TARGET_VERSION \ + fputs (" (ARM/RISCiX)", stderr); + + /* This is used in ASM_FILE_START */ + #define ARM_OS_NAME "RISCiX" + + #ifdef riscos + #define TARGET_WHEN_DEBUGGING 3 + #else + #define TARGET_WHEN_DEBUGGING 1 + #endif + + /* 'char' is signed by default on RISCiX, unsigned on RISCOS. */ + #ifdef riscos + #define DEFAULT_SIGNED_CHAR 0 + #else + #define DEFAULT_SIGNED_CHAR 1 + #endif + + /* Define this if the target system supports the function atexit form the + ANSI C standard. If this is not defined, and INIT_SECTION_ASM_OP is not + defined, a default exit function will be provided to support C++. + The man page only describes on_exit, but atexit is also there. + This seems to be missing in early versions. */ + /*#define HAVE_ATEXIT 1 */ + /* Some systems use __main in a way incompatible with its use in gcc, in these + cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to + give the same symbol without quotes for an alternative entry point. You + must define both, or niether. */ + #ifndef NAME__MAIN + #define NAME__MAIN "__gccmain" + #define SYMBOL__MAIN __gccmain + #endif + + #include "arm/arm.h" + + /* The native RISCiX assembler does not support stabs of any kind; because + the native assembler is not used by the compiler, Acorn didn't feel it was + necessary to put them in! */ + + #ifdef DBX_DEBUGGING_INFO + #undef DBX_DEBUGGING_INFO + #endif diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/arm/rix-gas.h gcc-2.5.0/config/arm/rix-gas.h *** gcc-2.4.5/config/arm/rix-gas.h --- gcc-2.5.0/config/arm/rix-gas.h Sun Oct 3 12:29:38 1993 *************** *** 0 **** --- 1,38 ---- + /* Definitions of target machine for GNU compiler. ARM RISCiX(stabs) version. + Copyright (C) 1993 Free Software Foundation, Inc. + Contributed by Richard Earnshaw (rwe11@cl.cam.ac.uk), based on original + work by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) + and Martin Simmons (@harleqn.co.uk). + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + #include "arm/riscix.h" + + /* The native RISCiX assembler does not support stabs of any kind; because + the native assembler is not used by the compiler, Acorn didn't feel it was + necessary to put them in! + However, this file assumes that we have an assembler that does have stabs, + so we put them back in. */ + + #define DBX_DEBUGGING_INFO + + /* Unfortunately dbx doesn't understand these */ + #define DEFAULT_GDB_EXTENSIONS 0 + /* RISCiX dbx doesn't accept xrefs */ + #define DBX_NO_XREFS 1 + /* dbx wants lbracs before variables */ + /* #define DBX_LBRAC_FIRST 1*/ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/arm/xm-arm.h gcc-2.5.0/config/arm/xm-arm.h *** gcc-2.4.5/config/arm/xm-arm.h Sat Dec 26 17:19:55 1992 --- gcc-2.5.0/config/arm/xm-arm.h Tue Oct 19 17:34:54 1993 *************** *** 1,6 **** /* Configuration for GNU C-compiler for Acorn RISC Machine. ! Copyright (C) 1991 Free Software Foundation, Inc. Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) and Martin Simmons (@harleqn.co.uk). This file is part of GNU CC. --- 1,7 ---- /* Configuration for GNU C-compiler for Acorn RISC Machine. ! Copyright (C) 1991, 1993 Free Software Foundation, Inc. Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) and Martin Simmons (@harleqn.co.uk). + More major hacks by Richard Earnshaw (rwe11@cl.cam.ac.uk) This file is part of GNU CC. *************** *** 30,38 **** #define HOST_BITS_PER_LONG 32 ! /* If compiled with GNU C, use the built-in alloca. */ ! #ifdef __GNUC__ ! #define alloca __builtin_alloca #endif /* target machine dependencies. tm.h is a symbolic link to the actual target specific file. */ --- 31,58 ---- #define HOST_BITS_PER_LONG 32 ! /* A code distinguishing the floating point format of the host ! machine. There are three defined values: IEEE_FLOAT_FORMAT, ! VAX_FLOAT_FORMAT, and UNKNOWN_FLOAT_FORMAT. */ ! ! #define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT ! ! #define HOST_FLOAT_WORDS_BIG_ENDIAN 1 ! ! /* If not compiled with GNU C, use C alloca. */ ! #ifndef __GNUC__ ! #define USE_C_ALLOCA #endif + /* Define this if the library function putenv is available on your machine */ + #define HAVE_PUTENV 1 + + /* Define this if the library function vprintf is available on your machine */ + #define HAVE_VPRINTF 1 + + /* Define this to be 1 if you know the host compiler supports prototypes, even + if it doesn't define __STDC__, or define it to be 0 if you do not want any + prototypes when compiling GNU CC. */ + #define USE_PROTOTYPES 1 + /* target machine dependencies. tm.h is a symbolic link to the actual target specific file. */ *************** *** 44,45 **** --- 64,67 ---- /* EOF xm-arm.h */ + + diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/clipper/clipper.c gcc-2.5.0/config/clipper/clipper.c *** gcc-2.4.5/config/clipper/clipper.c Thu Apr 15 15:58:21 1993 --- gcc-2.5.0/config/clipper/clipper.c Fri Jul 9 18:17:16 1993 *************** *** 367,374 **** /* Do what is necessary for `va_start'. The argument is ignored; ! We look at the current function to determine if stdargs or varargs ! is used and fill in an initial va_list. A pointer to this constructor ! is returned. */ struct rtx_def * clipper_builtin_saveregs (arglist) --- 367,374 ---- /* Do what is necessary for `va_start'. The argument is ignored; ! We fill in an initial va_list. A pointer to this constructor ! is returned. */ + struct rtx_def * clipper_builtin_saveregs (arglist) *************** *** 376,382 **** { extern int current_function_varargs; ! rtx block, addr, argsize; ! /* Allocate the va_list constructor */ ! block = assign_stack_local (BLKmode, 8 * UNITS_PER_WORD, 2 * BITS_PER_WORD); RTX_UNCHANGING_P (block) = 1; RTX_UNCHANGING_P (XEXP (block, 0)) = 1; --- 376,386 ---- { extern int current_function_varargs; ! rtx block, addr, argsize, scratch, r0_addr,r1_addr,f0_addr,f1_addr; ! ! /* Allocate the va_list constructor + save area for r0,r1,f0,f1 */ ! ! block = assign_stack_local (BLKmode, ! (6 + 6) * UNITS_PER_WORD, 2 * BITS_PER_WORD); ! RTX_UNCHANGING_P (block) = 1; RTX_UNCHANGING_P (XEXP (block, 0)) = 1; *************** *** 384,417 **** addr = copy_to_reg (XEXP (block, 0)); ! /* Store float regs */ - emit_move_insn (gen_rtx (MEM, DFmode, addr), - gen_rtx (REG, DFmode, 16)); ! emit_move_insn (gen_rtx (MEM, DFmode, ! gen_rtx (PLUS, Pmode, addr, ! gen_rtx (CONST_INT, Pmode, 8))), ! gen_rtx (REG, DFmode, 17)); /* Store int regs */ ! emit_move_insn (gen_rtx (MEM, SImode, ! gen_rtx (PLUS, Pmode, addr, ! gen_rtx (CONST_INT, Pmode, 16))), ! gen_rtx (REG, SImode, 0)); ! emit_move_insn (gen_rtx (MEM, SImode, ! gen_rtx (PLUS, Pmode, addr, ! gen_rtx (CONST_INT, Pmode, 20))), ! gen_rtx (REG, SImode, 1)); ! /* Store the arg pointer in the __va_stk member. */ emit_move_insn (gen_rtx (MEM, SImode, gen_rtx (PLUS, Pmode, addr, ! gen_rtx (CONST_INT, Pmode, 24))), ! copy_to_reg (virtual_incoming_args_rtx)); ! /* Return the address of the va_list constructor, but don't put it in a --- 388,440 ---- addr = copy_to_reg (XEXP (block, 0)); ! f0_addr = gen_rtx (PLUS, Pmode, addr, gen_rtx (CONST_INT, Pmode, 24)); ! f1_addr = gen_rtx (PLUS, Pmode, addr, gen_rtx (CONST_INT, Pmode, 32)); ! r0_addr = gen_rtx (PLUS, Pmode, addr, gen_rtx (CONST_INT, Pmode, 40)); ! r1_addr = gen_rtx (PLUS, Pmode, addr, gen_rtx (CONST_INT, Pmode, 44)); ! /* Store float regs */ + emit_move_insn (gen_rtx (MEM, DFmode, f0_addr), gen_rtx (REG, DFmode, 16)); + emit_move_insn (gen_rtx (MEM, DFmode, f1_addr), gen_rtx (REG, DFmode, 17)); + /* Store int regs */ ! emit_move_insn (gen_rtx (MEM, SImode, r0_addr), gen_rtx (REG, SImode, 0)); ! emit_move_insn (gen_rtx (MEM, SImode, r1_addr), gen_rtx (REG, SImode, 1)); ! /* Store the arg pointer in the __va_stk member. */ + emit_move_insn (gen_rtx (MEM, SImode, addr), + copy_to_reg (virtual_incoming_args_rtx)); + ! /* now move addresses of the saved regs into the pointer array */ + scratch = gen_reg_rtx (Pmode); + + emit_move_insn (scratch, r0_addr); emit_move_insn (gen_rtx (MEM, SImode, gen_rtx (PLUS, Pmode, addr, ! gen_rtx (CONST_INT, Pmode, 4))), ! scratch); ! ! emit_move_insn (scratch, f0_addr); ! emit_move_insn (gen_rtx (MEM, SImode, ! gen_rtx (PLUS, Pmode, addr, ! gen_rtx (CONST_INT, Pmode, 8))), ! scratch); ! ! emit_move_insn (scratch, r1_addr); ! emit_move_insn (gen_rtx (MEM, SImode, ! gen_rtx (PLUS, Pmode, addr, ! gen_rtx (CONST_INT, Pmode, 12))), ! scratch); ! ! emit_move_insn (scratch, f1_addr); ! emit_move_insn (gen_rtx (MEM, SImode, ! gen_rtx (PLUS, Pmode, addr, ! gen_rtx (CONST_INT, Pmode, 16))), ! scratch); /* Return the address of the va_list constructor, but don't put it in a *************** *** 418,421 **** --- 441,445 ---- register. This fails when not optimizing and produces worse code when optimizing. */ + return XEXP (block, 0); } diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/clipper/clipper.h gcc-2.5.0/config/clipper/clipper.h *** gcc-2.4.5/config/clipper/clipper.h Thu Apr 15 15:58:25 1993 --- gcc-2.5.0/config/clipper/clipper.h Sat Sep 25 08:17:34 1993 *************** *** 1,4 **** /* Definitions of target machine for GNU compiler. Clipper version. ! Copyright (C) 1987, 1988, 1991 Free Software Foundation, Inc. Contributed by Holger Teutsch (holger@hotbso.rhein-main.de) --- 1,4 ---- /* Definitions of target machine for GNU compiler. Clipper version. ! Copyright (C) 1987, 1988, 1991, 1993 Free Software Foundation, Inc. Contributed by Holger Teutsch (holger@hotbso.rhein-main.de) *************** *** 39,49 **** An empty string NAME is used to identify the default VALUE. */ ! #define TARGET_SWITCHES \ ! { { "", TARGET_DEFAULT} } /* Default target_flags if no switches specified. */ #ifndef TARGET_DEFAULT ! #define TARGET_DEFAULT 0 #endif --- 39,54 ---- An empty string NAME is used to identify the default VALUE. */ ! #define TARGET_SWITCHES \ ! { { "c400", 1 }, \ ! { "c300", -1 }, \ ! { "", TARGET_DEFAULT} } + #define TARGET_C400 1 + #define TARGET_C300 0 + /* Default target_flags if no switches specified. */ #ifndef TARGET_DEFAULT ! #define TARGET_DEFAULT TARGET_C300 #endif *************** *** 176,180 **** #define FIXED_REGISTERS \ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,\ ! 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1} /* FIXME: C300 only */ /* 1 for registers not available across function calls. --- 181,185 ---- #define FIXED_REGISTERS \ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,\ ! 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1} /* Default: C300 */ /* 1 for registers not available across function calls. *************** *** 186,190 **** #define CALL_USED_REGISTERS \ {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,\ ! 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1} /* FIXME: C300 only */ /* Return number of consecutive hard regs needed starting at reg REGNO --- 191,204 ---- #define CALL_USED_REGISTERS \ {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,\ ! 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1} /* default: C300 */ ! ! /* Zero or more C statements that may conditionally modify two ! variables `fixed_regs' and `call_used_regs' (both of type `char ! []') after they have been initialized from the two preceding ! macros. A C400 has additional floating registers f8 -> f15 */ ! #define CONDITIONAL_REGISTER_USAGE \ ! if (target_flags & TARGET_C400) \ ! { int i; \ ! for (i = 24; i < 32; i++) fixed_regs[i] = call_used_regs[i] = 0; } /* Return number of consecutive hard regs needed starting at reg REGNO *************** *** 455,459 **** #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME) \ ! ((CUM).num = ((FNTYPE) != 0 && aggregate_value_p (FNTYPE)), \ (CUM).size = 0) --- 469,473 ---- #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME) \ ! ((CUM).num = ((FNTYPE) != 0 && aggregate_value_p (TREE_TYPE (FNTYPE))), \ (CUM).size = 0) *************** *** 760,767 **** /* #define CASE_DROPS_THROUGH */ ! /* Define this macro if an instruction to load a value narrower than a ! word from memory into a register also sign-extends the value to ! the whole register. */ ! #define BYTE_LOADS_SIGN_EXTEND /* Specify the tree operation to be used to convert reals to integers. */ --- 774,786 ---- /* #define CASE_DROPS_THROUGH */ ! /* Define if operations between registers always perform the operation ! on the full register even if a narrower mode is specified. */ ! #define WORD_REGISTER_OPERATIONS ! ! /* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD ! will either zero-extend or sign-extend. The value of this macro should ! be the code that says which one of the two operations is implicitly ! done, NIL if none. */ ! #define LOAD_EXTEND_OP(MODE) SIGN_EXTEND /* Specify the tree operation to be used to convert reals to integers. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/clipper/clipper.md gcc-2.5.0/config/clipper/clipper.md *** gcc-2.4.5/config/clipper/clipper.md Sun Apr 18 00:42:25 1993 --- gcc-2.5.0/config/clipper/clipper.md Tue Oct 19 20:05:12 1993 *************** *** 204,223 **** (define_insn "" [(set (match_operand:DF 0 "memory_operand" "=o,m") ! (match_operand:DF 1 "register_operand" "r,f"))] "" "* { ! if (which_alternative == 0) /* r -> o */ ! { ! rtx xops[4]; ! xops[0] = operands[0]; ! xops[1] = adj_offsettable_operand (operands[0], 4); ! xops[2] = operands[1]; ! xops[3] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); ! output_asm_insn (\"storw %2,%0\;storw %3,%1\", xops); ! return \"\"; ! } ! return \"stord %1,%0\"; /* f-> m */ }" [(set_attr "type" "store,store") --- 204,222 ---- (define_insn "" [(set (match_operand:DF 0 "memory_operand" "=o,m") ! (match_operand:DF 1 "register_operand" "rf,f"))] "" "* { ! rtx xops[4]; ! ! if (REGNO (operands[1]) >= 16) /* f -> m */ ! return \"stord %1,%0\"; ! xops[0] = operands[0]; /* r -> o */ ! xops[1] = adj_offsettable_operand (operands[0], 4); ! xops[2] = operands[1]; ! xops[3] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); ! output_asm_insn (\"storw %2,%0\;storw %3,%1\", xops); ! return \"\"; }" [(set_attr "type" "store,store") *************** *** 308,313 **** }") (define_insn "" ! [(set (match_operand:DI 0 "register_operand" "=r,r,r") (match_operand:DI 1 "general_operand" "r,n,o"))] "" --- 307,315 ---- }") + ;; If an operand is a MEM but not offsetable, we can't load it into + ;; a register, so we must force the third alternative to be the one + ;; reloaded. Hence we show the first as more expensive. (define_insn "" ! [(set (match_operand:DI 0 "register_operand" "=?r,r,r") (match_operand:DI 1 "general_operand" "r,n,o"))] "" diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/clipper/clix.h gcc-2.5.0/config/clipper/clix.h *** gcc-2.4.5/config/clipper/clix.h Thu May 6 22:54:22 1993 --- gcc-2.5.0/config/clipper/clix.h Sat Oct 2 04:17:37 1993 *************** *** 24,28 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dclipper -Dunix" #undef STARTFILE_SPEC --- 24,28 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dclipper -Dunix -Asystem(unix) -Asystem(svr3) -Acpu(clipper) -Amachine(clipper)" #undef STARTFILE_SPEC diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/clipper/xm-clix.h gcc-2.5.0/config/clipper/xm-clix.h *** gcc-2.4.5/config/clipper/xm-clix.h Tue Feb 9 18:47:23 1993 --- gcc-2.5.0/config/clipper/xm-clix.h Sat Jun 26 11:41:31 1993 *************** *** 25,33 **** #define FATAL_EXIT_CODE 33 - /* If compiled with GNU C, use the built-in alloca */ - #ifdef __GNUC__ - #define alloca __builtin_alloca - #endif - /* isinf isn't there, but finite is. */ #define isinf(x) (!finite(x)) --- 25,28 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/convex/convex.h gcc-2.5.0/config/convex/convex.h *** gcc-2.4.5/config/convex/convex.h Tue Jun 1 12:47:42 1993 --- gcc-2.5.0/config/convex/convex.h Wed Oct 20 16:55:53 1993 *************** *** 95,99 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dconvex -Dunix" /* Print subsidiary information on the compiler version in use. */ --- 95,99 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dconvex -Dunix -Asystem(unix) -Acpu(convex) -Amachine(convex)" /* Print subsidiary information on the compiler version in use. */ *************** *** 498,501 **** --- 498,503 ---- #define DOUBLE_TYPE_SIZE 64 #define LONG_DOUBLE_TYPE_SIZE 64 + /* This prevents cexp.c from depending on LONG_TYPE_SIZE. */ + #define MAX_LONG_TYPE_SIZE 64 /* Declare the standard types used by builtins to match convex stddef.h -- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/convex/xm-convex.h gcc-2.5.0/config/convex/xm-convex.h *** gcc-2.4.5/config/convex/xm-convex.h Fri May 7 07:53:25 1993 --- gcc-2.5.0/config/convex/xm-convex.h Sat Jun 26 11:41:06 1993 *************** *** 37,45 **** #define FATAL_EXIT_CODE 33 - /* If compiled with GNU C, use the built-in alloca */ - #ifdef __GNUC__ - #define alloca __builtin_alloca - #endif - /* Convex ships /tmp as a separate file system - thus it usually has more free space than /usr/tmp */ --- 37,40 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/elxsi/elxsi.h gcc-2.5.0/config/elxsi/elxsi.h *** gcc-2.4.5/config/elxsi/elxsi.h Mon May 3 20:13:10 1993 --- gcc-2.5.0/config/elxsi/elxsi.h Sat Oct 2 04:17:48 1993 *************** *** 24,28 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Delxsi -Dunix" /* Print subsidiary information on the compiler version in use. */ --- 24,28 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Delxsi -Dunix -Asystem(unix) -Acpu(elxsi) -Amachine(elxsi)" /* Print subsidiary information on the compiler version in use. */ *************** *** 728,732 **** /* Output the name of the file we are compiling. */ #define ASM_OUTPUT_SOURCE_FILENAME(STREAM, NAME) \ ! fprintf(STREAM, "\t.file\t\"%s\"\n", NAME); /* Output at beginning of assembler file. */ --- 728,735 ---- /* Output the name of the file we are compiling. */ #define ASM_OUTPUT_SOURCE_FILENAME(STREAM, NAME) \ ! do { fprintf (STREAM, "\t.file\t"); \ ! output_quoted_string (STREAM, NAME); \ ! fprintf (STREAM, "\n"); \ ! } while (0) /* Output at beginning of assembler file. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/elxsi/xm-elxsi.h gcc-2.5.0/config/elxsi/xm-elxsi.h *** gcc-2.4.5/config/elxsi/xm-elxsi.h Thu Nov 26 21:29:21 1992 --- gcc-2.5.0/config/elxsi/xm-elxsi.h Sat Jun 26 11:40:45 1993 *************** *** 1,4 **** /* Configuration for GNU C-compiler for Elxsi. ! Copyright (C) 1987 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,4 ---- /* Configuration for GNU C-compiler for Elxsi. ! Copyright (C) 1987, 1993 Free Software Foundation, Inc. This file is part of GNU CC. *************** *** 35,42 **** #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 --- 35,37 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/fx80/fx80.h gcc-2.5.0/config/fx80/fx80.h *** gcc-2.4.5/config/fx80/fx80.h Wed Mar 31 15:00:15 1993 --- gcc-2.5.0/config/fx80/fx80.h Mon Oct 11 07:35:57 1993 *************** *** 27,31 **** /* 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. */ --- 27,31 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dmc68000 -Dalliant -Dunix -Asystem(unix) -Acpu(m68k) -Amachine(m68k)" /* Print subsidiary information on the compiler version in use. */ *************** *** 842,849 **** #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 --- 842,848 ---- #define SLOW_BYTE_ACCESS 0 ! /* Define this to be nonzero if shift instructions ignore all but the low-order ! few bits. */ ! #define SHIFT_COUNT_TRUNCATED 1 /* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/fx80/xm-fx80.h gcc-2.5.0/config/fx80/xm-fx80.h *** gcc-2.4.5/config/fx80/xm-fx80.h Sat Dec 26 17:20:07 1992 --- gcc-2.5.0/config/fx80/xm-fx80.h Sat Jun 26 11:40:14 1993 *************** *** 1,4 **** /* Configuration for GNU C-compiler for Alliant FX computers. ! Copyright (C) 1989 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,4 ---- /* Configuration for GNU C-compiler for Alliant FX computers. ! Copyright (C) 1989, 1993 Free Software Foundation, Inc. This file is part of GNU CC. *************** *** 37,44 **** #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 - --- 37,38 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/gmicro/gmicro.h gcc-2.5.0/config/gmicro/gmicro.h *** gcc-2.4.5/config/gmicro/gmicro.h Wed Mar 31 15:00:25 1993 --- gcc-2.5.0/config/gmicro/gmicro.h Sat Oct 2 04:18:01 1993 *************** *** 32,36 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dgmicro" /* #define CPP_SPEC ** currently not defined **/ --- 32,36 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dgmicro -Acpu(tron) -Amachine(tron)" /* #define CPP_SPEC ** currently not defined **/ *************** *** 169,173 **** /* Set this non-zero if move instructions will actually fail to work ! when given unaligned data. */ Unaligned data is allowed on Gmicro, though the access is slow. */ --- 169,173 ---- /* Set this non-zero if move instructions will actually fail to work ! when given unaligned data. Unaligned data is allowed on Gmicro, though the access is slow. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/h8300/h8300.h gcc-2.5.0/config/h8300/h8300.h *** gcc-2.4.5/config/h8300/h8300.h Wed Mar 31 15:16:01 1993 --- gcc-2.5.0/config/h8300/h8300.h Sat Oct 2 04:18:06 1993 *************** *** 22,26 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-D__H8300__ -D_DOUBLE_IS_32BITS" #define LIB_SPEC "%{mrelax:-relax} %{g:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} " --- 22,26 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-D__H8300__ -D_DOUBLE_IS_32BITS -Acpu(h8300) -Amachine(h8300)" #define LIB_SPEC "%{mrelax:-relax} %{g:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} " diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/h8300/t-h8300 gcc-2.5.0/config/h8300/t-h8300 *** gcc-2.4.5/config/h8300/t-h8300 Thu Mar 4 13:03:48 1993 --- gcc-2.5.0/config/h8300/t-h8300 Thu Sep 9 16:02:44 1993 *************** *** 1,3 **** --- 1,4 ---- LIBGCC1 = libgcc1.null + CROSS_LIBGCC1 = libgcc1.null T_CFLAGS = -DDONT_HAVE_STDIO -DDONT_HAVE_SETJMP # we do not have DF or DI types, so fake out the libgcc2 compilation diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i370/i370.md gcc-2.5.0/config/i370/i370.md *** gcc-2.4.5/config/i370/i370.md --- gcc-2.5.0/config/i370/i370.md Sun Oct 3 15:41:26 1993 *************** *** 0 **** --- 1,4286 ---- + ;;- Machine description for GNU compiler -- System/370 version. + ;; Copyright (C) 1989, 1993 Free Software Foundation, Inc. + ;; Contributed by Jan Stein (jan@cd.chalmers.se). + ;; Modifed for MVS C/370 by Dave Pitts (pitts@mcdata.com) + + ;; This file is part of GNU CC. + + ;; GNU CC is free software; you can redistribute it and/or modify + ;; it under the terms of the GNU General Public License as published by + ;; the Free Software Foundation; either version 2, or (at your option) + ;; any later version. + + ;; GNU CC is distributed in the hope that it will be useful, + ;; but WITHOUT ANY WARRANTY; without even the implied warranty of + ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ;; GNU General Public License for more details. + + ;; You should have received a copy of the GNU General Public License + ;; along with GNU CC; see the file COPYING. If not, write to + ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code + ;;- updates for most instructions. + + ;; + ;; Special constraints for 370 machine description: + ;; + ;; a -- Any address register from 1 to 15. + ;; d -- Any register from 0 to 15. + ;; I -- An 8-bit constant (0..255). + ;; J -- A 12-bit constant (0..4095). + ;; K -- A 16-bit constant (-32768..32767). + ;; + ;; Special formats used for outputting 370 instructions. + ;; + ;; %B -- Print a constant byte integer. + ;; %H -- Print a signed 16-bit constant. + ;; %L -- Print least significant word of a CONST_DOUBLE. + ;; %M -- Print most significant word of a CONST_DOUBLE. + ;; %N -- Print next register (second word of a DImode reg). + ;; %O -- Print the offset of a memory reference (PLUS (REG) (CONST_INT)). + ;; %R -- Print the register of a memory reference (PLUS (REG) (CONST_INT)). + ;; %X -- Print a constant byte integer in hex. + ;; + ;; We have a special contraint for pattern matching. + ;; + ;; s_operand -- Matches a valid S operand in a RS, SI or SS type instruction. + ;; + ;; r_or_s_operand -- Matches a register or a valid S operand in a RS, SI + ;; or SS type instruction or a register + ;; + ;; For MVS C/370 we use the following stack locations for: + ;; + ;; 136 - internal function result buffer + ;; 140 - numeric conversion buffer + ;; 144 - pointer to internal function result buffer + ;; 148 - start of automatic variables and function arguments + ;; + ;; To support programs larger than a page, 4096 bytes, PAGE_REGISTER points + ;; to a page origin table, all internal labels are generated to reload the + ;; BASE_REGISTER knowing what page it is on and all branch instructions go + ;; directly to the target if it is known that the target is on the current + ;; page (essentially backward references). All forward references and off + ;; page references are handled by loading the address of target into a + ;; register and branching indirectly. + ;; + ;; Some *di patterns have been commented out per advice from RMS, as gcc + ;; will generate the right things to do. + ;; + + ;; + ;;- Test instructions. + ;; + + ; + ; tstdi instruction pattern(s). + ; + + (define_insn "tstdi" + [(set (cc0) + (match_operand:DI 0 "register_operand" "d"))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 4, 0); + return \"SRDA %0,0\"; + }") + + ; + ; tstsi instruction pattern(s). + ; + + (define_insn "tstsi" + [(set (cc0) + (match_operand:SI 0 "register_operand" "d"))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 2, 0); + return \"LTR %0,%0\"; + }") + + ; + ; tsthi instruction pattern(s). + ; + + (define_insn "tsthi" + [(set (cc0) + (match_operand:HI 0 "register_operand" "d"))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 4, 2); + return \"CH %0,=H'0'\"; + }") + + ; + ; tstqi instruction pattern(s). + ; + + (define_insn "" + [(set (cc0) + (match_operand:QI 0 "r_or_s_operand" "dm"))] + "unsigned_jump_follows_p (insn)" + "* + { + check_label_emit (); + if (REG_P (operands[0])) + { + mvs_check_page (0, 4, 4); + return \"N %0,=X'000000FF'\"; + } + mvs_check_page (0, 4, 0); + return \"CLI %0,0\"; + }") + + (define_insn "tstqi" + [(set (cc0) + (match_operand:QI 0 "register_operand" "d"))] + "" + "* + { + check_label_emit (); + if (unsigned_jump_follows_p (insn)) + { + mvs_check_page (0, 4, 4); + return \"N %0,=X'000000FF'\"; + } + mvs_check_page (0, 8, 0); + return \"SLL %0,24\;SRA %0,24\"; + }") + + ; + ; tstdf instruction pattern(s). + ; + + (define_insn "tstdf" + [(set (cc0) + (match_operand:DF 0 "general_operand" "f"))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 2, 0); + return \"LTDR %0,%0\"; + }") + + ; + ; tstsf instruction pattern(s). + ; + + (define_insn "tstsf" + [(set (cc0) + (match_operand:SF 0 "general_operand" "f"))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 2, 0); + return \"LTER %0,%0\"; + }") + + ;; + ;;- Compare instructions. + ;; + + ; + ; cmpdi instruction pattern(s). + ; + + ;(define_insn "cmpdi" + ; [(set (cc0) + ; (compare (match_operand:DI 0 "register_operand" "d") + ; (match_operand:DI 1 "general_operand" "")))] + ; "" + ; "* + ;{ + ; check_label_emit (); + ; if (REG_P (operands[1])) + ; { + ; mvs_check_page (0, 8, 0); + ; if (unsigned_jump_follows_p (insn)) + ; return \"CLR %0,%1\;BNE *+6\;CLR %N0,%N1\"; + ; return \"CR %0,%1\;BNE *+6\;CLR %N0,%N1\"; + ; } + ; mvs_check_page (0, 12, 0); + ; if (unsigned_jump_follows_p (insn)) + ; return \"CL %0,%M1\;BNE *+8\;CL %N0,%L1\"; + ; return \"C %0,%M1\;BNE *+8\;CL %N0,%L1\"; + ;}") + + ; + ; cmpsi instruction pattern(s). + ; + + (define_insn "cmpsi" + [(set (cc0) + (compare (match_operand:SI 0 "register_operand" "d") + (match_operand:SI 1 "general_operand" "")))] + "" + "* + { + check_label_emit (); + if (REG_P (operands[1])) + { + mvs_check_page (0, 2, 0); + if (unsigned_jump_follows_p (insn)) + return \"CLR %0,%1\"; + return \"CR %0,%1\"; + } + if (GET_CODE (operands[1]) == CONST_INT) + { + mvs_check_page (0, 4, 4); + if (unsigned_jump_follows_p (insn)) + return \"CL %0,=F'%c1'\"; + return \"C %0,=F'%c1'\"; + } + mvs_check_page (0, 4, 0); + if (unsigned_jump_follows_p (insn)) + return \"CL %0,%1\"; + return \"C %0,%1\"; + }") + + ; + ; cmphi instruction pattern(s). + ; + + (define_insn "cmphi" + [(set (cc0) + (compare (match_operand:HI 0 "register_operand" "d") + (match_operand:HI 1 "general_operand" "")))] + "" + "* + { + check_label_emit (); + if (REG_P (operands[1])) + { + mvs_check_page (0, 8, 0); + if (unsigned_jump_follows_p (insn)) + return \"STH %1,140(,13)\;CLM %0,3,140(13)\"; + return \"STH %1,140(,13)\;CH %0,140(,13)\"; + } + if (GET_CODE (operands[1]) == CONST_INT) + { + mvs_check_page (0, 4, 2); + return \"CH %0,=H'%h1'\"; + } + mvs_check_page (0, 4, 0); + return \"CH %0,%1\"; + }") + + ; + ; cmpqi instruction pattern(s). + ; + + (define_insn "" + [(set (cc0) + (compare (match_operand:QI 0 "r_or_s_operand" "g") + (match_operand:QI 1 "r_or_s_operand" "g")))] + "unsigned_jump_follows_p (insn)" + "* + { + check_label_emit (); + if (REG_P (operands[0])) + { + if (REG_P (operands[1])) + { + mvs_check_page (0, 8, 0); + return \"STC %1,140(,13)\;CLM %0,1,140(13)\"; + } + if (GET_CODE (operands[1]) == CONST_INT) + { + mvs_check_page (0, 4, 1); + return \"CLM %0,1,=X'%X1'\"; + } + mvs_check_page (0, 4, 0); + return \"CLM %0,1,%1\"; + } + else if (GET_CODE (operands[0]) == CONST_INT) + { + cc_status.flags |= CC_REVERSED; + if (REG_P (operands[1])) + { + mvs_check_page (0, 4, 1); + return \"CLM %1,1,=X'%X0'\"; + } + mvs_check_page (0, 4, 0); + return \"CLI %1,%B0\"; + } + if (GET_CODE (operands[1]) == CONST_INT) + { + mvs_check_page (0, 4, 0); + return \"CLI %0,%B1\"; + } + if (GET_CODE (operands[1]) == MEM) + { + mvs_check_page (0, 6, 0); + return \"CLC %O0(1,%R0),%1\"; + } + cc_status.flags |= CC_REVERSED; + mvs_check_page (0, 4, 0); + return \"CLM %1,1,%0\"; + }") + + (define_insn "cmpqi" + [(set (cc0) + (compare (match_operand:QI 0 "register_operand" "d") + (match_operand:QI 1 "general_operand" "di")))] + "" + "* + { + check_label_emit (); + if (unsigned_jump_follows_p (insn)) + { + if (REG_P (operands[1])) + { + mvs_check_page (0, 4, 0); + return \"CLM %0,1,%1\"; + } + if (GET_CODE (operands[1]) == CONST_INT) + { + mvs_check_page (0, 4, 1); + return \"CLM %0,1,=X'%X1'\"; + } + mvs_check_page (0, 8, 0); + return \"STC %1,140(,13)\;CLM %0,1,140(13)\"; + } + if (REG_P (operands[1])) + { + mvs_check_page (0, 18, 0); + return \"SLL %0,24\;SRA %0,24\;SLL %1,24\;SRA %1,24\;CR %0,%1\"; + } + mvs_check_page (0, 12, 0); + return \"SLL %0,24\;SRA %0,24\;C %0,%1\"; + }") + + ; + ; cmpdf instruction pattern(s). + ; + + (define_insn "cmpdf" + [(set (cc0) + (compare (match_operand:DF 0 "general_operand" "f,mF") + (match_operand:DF 1 "general_operand" "fmF,f")))] + "" + "* + { + check_label_emit (); + if (FP_REG_P (operands[0])) + { + if (FP_REG_P (operands[1])) + { + mvs_check_page (0, 2, 0); + return \"CDR %0,%1\"; + } + mvs_check_page (0, 4, 0); + return \"CD %0,%1\"; + } + cc_status.flags |= CC_REVERSED; + mvs_check_page (0, 4, 0); + return \"CD %1,%0\"; + }") + + ; + ; cmpsf instruction pattern(s). + ; + + (define_insn "cmpsf" + [(set (cc0) + (compare (match_operand:SF 0 "general_operand" "f,mF") + (match_operand:SF 1 "general_operand" "fmF,f")))] + "" + "* + { + check_label_emit (); + if (FP_REG_P (operands[0])) + { + if (FP_REG_P (operands[1])) + { + mvs_check_page (0, 2, 0); + return \"CER %0,%1\"; + } + mvs_check_page (0, 4, 0); + return \"CE %0,%1\"; + } + cc_status.flags |= CC_REVERSED; + mvs_check_page (0, 4, 0); + return \"CE %1,%0\"; + }") + + ; + ; cmpstrsi instruction pattern(s). + ; + + (define_expand "cmpstrsi" + [(set (match_operand:SI 0 "general_operand" "") + (compare (match_operand:BLK 1 "general_operand" "") + (match_operand:BLK 2 "general_operand" ""))) + (use (match_operand:SI 3 "general_operand" "")) + (use (match_operand:SI 4 "" ""))] + "" + " + { + rtx op1, op2; + + op1 = XEXP (operands[1], 0); + if (GET_CODE (op1) == REG + || (GET_CODE (op1) == PLUS && GET_CODE (XEXP (op1, 0)) == REG + && GET_CODE (XEXP (op1, 1)) == CONST_INT + && (unsigned) INTVAL (XEXP (op1, 1)) < 4096)) + { + op1 = operands[1]; + } + else + { + op1 = gen_rtx (MEM, BLKmode, copy_to_mode_reg (SImode, op1)); + } + + op2 = XEXP (operands[2], 0); + if (GET_CODE (op2) == REG + || (GET_CODE (op2) == PLUS && GET_CODE (XEXP (op2, 0)) == REG + && GET_CODE (XEXP (op2, 1)) == CONST_INT + && (unsigned) INTVAL (XEXP (op2, 1)) < 4096)) + { + op2 = operands[2]; + } + else + { + op2 = gen_rtx (MEM, BLKmode, copy_to_mode_reg (SImode, op2)); + } + + if (GET_CODE (operands[3]) == CONST_INT && INTVAL (operands[3]) < 256) + { + emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, + gen_rtx (SET, VOIDmode, operands[0], + gen_rtx (COMPARE, VOIDmode, op1, op2)), + gen_rtx (USE, VOIDmode, operands[3])))); + } + else + { + rtx reg1 = gen_reg_rtx (DImode); + rtx reg2 = gen_reg_rtx (DImode); + rtx subreg = gen_rtx (SUBREG, SImode, reg1, 1); + + emit_insn (gen_rtx (SET, VOIDmode, subreg, operands[3])); + emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (SUBREG, SImode, reg2, 1), + subreg)); + emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (5, + gen_rtx (SET, VOIDmode, operands[0], + gen_rtx (COMPARE, VOIDmode, op1, op2)), + gen_rtx (USE, VOIDmode, reg1), + gen_rtx (USE, VOIDmode, reg2), + gen_rtx (CLOBBER, VOIDmode, reg1), + gen_rtx (CLOBBER, VOIDmode, reg2)))); + } + DONE; + }") + + ; Compare a block that is less than 256 bytes in length. + + (define_insn "" + [(set (match_operand:SI 0 "register_operand" "d") + (compare (match_operand:BLK 1 "s_operand" "m") + (match_operand:BLK 2 "s_operand" "m"))) + (use (match_operand:QI 3 "immediate_operand" "I"))] + "((unsigned) INTVAL (operands[3]) < 256)" + "* + { + check_label_emit (); + mvs_check_page (0, 22, 0); + return \"LA %0,1\;CLC %O1(%c3,%R1),%2\;BH *+12\;BL *+6\;SLR %0,%0\;LNR %0,%0\"; + }") + + ; Compare a block that is larger than 255 bytes in length. + + (define_insn "" + [(set (match_operand:SI 0 "register_operand" "d") + (compare (match_operand:BLK 1 "general_operand" "m") + (match_operand:BLK 2 "general_operand" "m"))) + (use (match_operand:DI 3 "register_operand" "d")) + (use (match_operand:DI 4 "register_operand" "d")) + (clobber (match_dup 3)) + (clobber (match_dup 4))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 26, 0); + return \"LA %3,%1\;LA %4,%2\;LA %0,1\;CLCL %3,%4\;BH *+12\;BL *+6\;SLR %0,%0\;LNR %0,%0\"; + }") + + ;; + ;;- Move instructions. + ;; + + ; + ; movdi instruction pattern(s). + ; + + (define_insn "" + [(set (match_operand:DI 0 "r_or_s_operand" "=dm") + (match_operand:DI 1 "r_or_s_operand" "dim*fF"))] + "TARGET_CHAR_INSTRUCTIONS" + "* + { + check_label_emit (); + if (REG_P (operands[0])) + { + if (FP_REG_P (operands[1])) + { + mvs_check_page (0, 8, 0); + return \"STD %1,140(,13)\;LM %0,%N0,140(13)\"; + } + if (REG_P (operands[1])) + { + mvs_check_page (0, 4, 0); + return \"LR %0,%1\;LR %N0,%N1\"; + } + if (operands[1] == const0_rtx) + { + CC_STATUS_INIT; + mvs_check_page (0, 4, 0); + return \"SLR %0,%0\;SLR %N0,%N0\"; + } + if (GET_CODE (operands[1]) == CONST_INT + && (unsigned) INTVAL (operands[1]) < 4096) + { + CC_STATUS_INIT; + mvs_check_page (0, 6, 0); + return \"SLR %0,%0\;LA %N0,%c1\"; + } + if (GET_CODE (operands[1]) == CONST_INT) + { + CC_STATUS_SET (operands[0], operands[1]); + mvs_check_page (0, 8, 0); + return \"L %0,%1\;SRDA %0,32\"; + } + mvs_check_page (0, 4, 0); + return \"LM %0,%N0,%1\"; + } + else if (FP_REG_P (operands[1])) + { + mvs_check_page (0, 4, 0); + return \"STD %1,%0\"; + } + else if (REG_P (operands[1])) + { + mvs_check_page (0, 4, 0); + return \"STM %1,%N1,%0\"; + } + mvs_check_page (0, 6, 0); + return \"MVC %O0(8,%R0),%1\"; + }") + + (define_insn "movdi" + [(set (match_operand:DI 0 "general_operand" "=dm") + (match_operand:DI 1 "general_operand" "dim*fF"))] + "" + "* + { + check_label_emit (); + if (REG_P (operands[0])) + { + if (FP_REG_P (operands[1])) + { + mvs_check_page (0, 8, 0); + return \"STD %1,140(,13)\;LM %0,%N0,140(13)\"; + } + if (REG_P (operands[1])) + { + mvs_check_page (0, 4, 0); + return \"LR %0,%1\;LR %N0,%N1\"; + } + if (operands[1] == const0_rtx) + { + CC_STATUS_INIT; + mvs_check_page (0, 4, 0); + return \"SLR %0,%0\;SLR %N0,%N0\"; + } + if (GET_CODE (operands[1]) == CONST_INT + && (unsigned) INTVAL (operands[1]) < 4096) + { + CC_STATUS_INIT; + mvs_check_page (0, 6, 0); + return \"SLR %0,%0\;LA %N0,%c1\"; + } + if (GET_CODE (operands[1]) == CONST_INT) + { + CC_STATUS_SET (operands[0], operands[1]); + mvs_check_page (0, 8, 0); + return \"L %0,%1\;SRDA %0,32\"; + } + mvs_check_page (0, 4, 0); + return \"LM %0,%N0,%1\"; + } + else if (FP_REG_P (operands[1])) + { + mvs_check_page (0, 4, 0); + return \"STD %1,%0\"; + } + mvs_check_page (0, 4, 0); + return \"STM %1,%N1,%0\"; + }") + + ; + ; movsi instruction pattern(s). + ; + + (define_insn "" + [(set (match_operand:SI 0 "r_or_s_operand" "=dm,dm") + (match_operand:SI 1 "r_or_s_operand" "dim,*fF"))] + "TARGET_CHAR_INSTRUCTIONS" + "* + { + check_label_emit (); + if (REG_P (operands[0])) + { + if (FP_REG_P (operands[1])) + { + mvs_check_page (0, 8, 0); + return \"STE %1,140(,13)\;L %0,140(,13)\"; + } + if (REG_P (operands[1])) + { + mvs_check_page (0, 2, 0); + return \"LR %0,%1\"; + } + if (operands[1] == const0_rtx) + { + CC_STATUS_INIT; + mvs_check_page (0, 2, 0); + return \"SLR %0,%0\"; + } + if (GET_CODE (operands[1]) == CONST_INT + && (unsigned) INTVAL (operands[1]) < 4096) + { + mvs_check_page (0, 4, 0); + return \"LA %0,%c1\"; + } + mvs_check_page (0, 4, 0); + return \"L %0,%1\"; + } + else if (FP_REG_P (operands[1])) + { + mvs_check_page (0, 4, 0); + return \"STE %1,%0\"; + } + else if (REG_P (operands[1])) + { + mvs_check_page (0, 4, 0); + return \"ST %1,%0\"; + } + mvs_check_page (0, 6, 0); + return \"MVC %O0(4,%R0),%1\"; + }") + + (define_insn "movsi" + [(set (match_operand:SI 0 "general_operand" "=d,dm") + (match_operand:SI 1 "general_operand" "dimF,*fd"))] + "" + "* + { + check_label_emit (); + if (REG_P (operands[0])) + { + if (FP_REG_P (operands[1])) + { + mvs_check_page (0, 8, 0); + return \"STE %1,140(,13)\;L %0,140(,13)\"; + } + if (REG_P (operands[1])) + { + mvs_check_page (0, 2, 0); + return \"LR %0,%1\"; + } + if (operands[1] == const0_rtx) + { + CC_STATUS_INIT; + mvs_check_page (0, 2, 0); + return \"SLR %0,%0\"; + } + if (GET_CODE (operands[1]) == CONST_INT + && (unsigned) INTVAL (operands[1]) < 4096) + { + mvs_check_page (0, 4, 0); + return \"LA %0,%c1\"; + } + mvs_check_page (0, 4, 0); + return \"L %0,%1\"; + } + else if (FP_REG_P (operands[1])) + { + mvs_check_page (0, 4, 0); + return \"STE %1,%0\"; + } + mvs_check_page (0, 4, 0); + return \"ST %1,%0\"; + }") + + ;(define_expand "movsi" + ; [(set (match_operand:SI 0 "general_operand" "=d,dm") + ; (match_operand:SI 1 "general_operand" "dimF,*fd"))] + ; "" + ; " + ;{ + ; rtx op0, op1; + ; + ; op0 = operands[0]; + ; if (GET_CODE (op0) == CONST + ; && GET_CODE (XEXP (XEXP (op0, 0), 0)) == SYMBOL_REF + ; && SYMBOL_REF_FLAG (XEXP (XEXP (op0, 0), 0))) + ; { + ; op0 = gen_rtx (MEM, SImode, copy_to_mode_reg (SImode, XEXP (op0, 0))); + ; } + ; + ; op1 = operands[1]; + ; if (GET_CODE (op1) == CONST + ; && GET_CODE (XEXP (XEXP (op1, 0), 0)) == SYMBOL_REF + ; && SYMBOL_REF_FLAG (XEXP (XEXP (op1, 0), 0))) + ; { + ; op1 = gen_rtx (MEM, SImode, copy_to_mode_reg (SImode, XEXP (op1, 0))); + ; } + ; + ; emit_insn (gen_rtx (SET, VOIDmode, op0, op1)); + ; DONE; + ;}") + + ; + ; movhi instruction pattern(s). + ; + + (define_insn "" + [(set (match_operand:HI 0 "r_or_s_operand" "=g") + (match_operand:HI 1 "r_or_s_operand" "g"))] + "TARGET_CHAR_INSTRUCTIONS" + "* + { + check_label_emit (); + if (REG_P (operands[0])) + { + if (REG_P (operands[1])) + { + mvs_check_page (0, 2, 0); + return \"LR %0,%1\"; + } + if (operands[1] == const0_rtx) + { + CC_STATUS_INIT; + mvs_check_page (0, 2, 0); + return \"SLR %0,%0\"; + } + if (GET_CODE (operands[1]) == CONST_INT + && (unsigned) INTVAL (operands[1]) < 4096) + { + mvs_check_page (0, 4, 0); + return \"LA %0,%c1\"; + } + if (GET_CODE (operands[1]) == CONST_INT) + { + mvs_check_page (0, 4, 2); + return \"LH %0,=H'%h1'\"; + } + mvs_check_page (0, 4, 0); + return \"LH %0,%1\"; + } + else if (REG_P (operands[1])) + { + mvs_check_page (0, 4, 0); + return \"STH %1,%0\"; + } + if (GET_CODE (operands[1]) == CONST_INT) + { + mvs_check_page (0, 6, 0); + return \"MVC %O0(2,%R0),=H'%h1'\"; + } + mvs_check_page (0, 6, 0); + return \"MVC %O0(2,%R0),%1\"; + }") + + (define_insn "movhi" + [(set (match_operand:HI 0 "general_operand" "=d,m") + (match_operand:HI 1 "general_operand" "g,d"))] + "" + "* + { + check_label_emit (); + if (REG_P (operands[0])) + { + if (REG_P (operands[1])) + { + mvs_check_page (0, 2, 0); + return \"LR %0,%1\"; + } + if (operands[1] == const0_rtx) + { + CC_STATUS_INIT; + mvs_check_page (0, 2, 0); + return \"SLR %0,%0\"; + } + if (GET_CODE (operands[1]) == CONST_INT + && (unsigned) INTVAL (operands[1]) < 4096) + { + mvs_check_page (0, 4, 0); + return \"LA %0,%c1\"; + } + if (GET_CODE (operands[1]) == CONST_INT) + { + mvs_check_page (0, 4, 2); + return \"LH %0,=H'%h1'\"; + } + mvs_check_page (0, 4, 0); + return \"LH %0,%1\"; + } + mvs_check_page (0, 4, 0); + return \"STH %1,%0\"; + }") + + ; + ; movqi instruction pattern(s). + ; + + (define_insn "" + [(set (match_operand:QI 0 "r_or_s_operand" "=g") + (match_operand:QI 1 "r_or_s_operand" "g"))] + "TARGET_CHAR_INSTRUCTIONS" + "* + { + check_label_emit (); + if (REG_P (operands[0])) + { + if (REG_P (operands[1])) + { + mvs_check_page (0, 2, 0); + return \"LR %0,%1\"; + } + if (operands[1] == const0_rtx) + { + CC_STATUS_INIT; + mvs_check_page (0, 2, 0); + return \"SLR %0,%0\"; + } + if (GET_CODE (operands[1]) == CONST_INT) + { + if (INTVAL (operands[1]) >= 0) + { + mvs_check_page (0, 4, 0); + return \"LA %0,%c1\"; + } + mvs_check_page (0, 4, 0); + return \"L %0,=F'%c1'\"; + } + mvs_check_page (0, 4, 0); + return \"IC %0,%1\"; + } + else if (REG_P (operands[1])) + { + mvs_check_page (0, 4, 0); + return \"STC %1,%0\"; + } + else if (GET_CODE (operands[1]) == CONST_INT) + { + mvs_check_page (0, 4, 0); + return \"MVI %0,%B1\"; + } + mvs_check_page (0, 6, 0); + return \"MVC %O0(1,%R0),%1\"; + }") + + (define_insn "movqi" + [(set (match_operand:QI 0 "general_operand" "=d,m") + (match_operand:QI 1 "general_operand" "g,d"))] + "" + "* + { + check_label_emit (); + if (REG_P (operands[0])) + { + if (REG_P (operands[1])) + { + mvs_check_page (0, 2, 0); + return \"LR %0,%1\"; + } + if (operands[1] == const0_rtx) + { + CC_STATUS_INIT; + mvs_check_page (0, 2, 0); + return \"SLR %0,%0\"; + } + if (GET_CODE (operands[1]) == CONST_INT) + { + if (INTVAL (operands[1]) >= 0) + { + mvs_check_page (0, 4, 0); + return \"LA %0,%c1\"; + } + mvs_check_page (0, 4, 0); + return \"L %0,=F'%c1'\"; + } + mvs_check_page (0, 4, 0); + return \"IC %0,%1\"; + } + mvs_check_page (0, 4, 0); + return \"STC %1,%0\"; + }") + + ; + ; movestrictqi instruction pattern(s). + ; + + (define_insn "movestrictqi" + [(set (strict_low_part (match_operand:QI 0 "general_operand" "=d")) + (match_operand:QI 1 "general_operand" "g"))] + "" + "* + { + check_label_emit (); + if (REG_P (operands[1])) + { + mvs_check_page (0, 8, 0); + return \"STC %1,140(,13)\;IC %0,140(,13)\"; + } + mvs_check_page (0, 4, 0); + return \"IC %0,%1\"; + }") + + ; + ; movstricthi instruction pattern(s). + ; + + (define_insn "" + [(set (strict_low_part (match_operand:HI 0 "register_operand" "=d")) + (match_operand:HI 1 "r_or_s_operand" "g"))] + "" + "* + { + check_label_emit (); + if (REG_P (operands[1])) + { + mvs_check_page (0, 8, 0); + return \"STH %1,140(,13)\;ICM %0,3,140(13)\"; + } + else if (GET_CODE (operands[1]) == CONST_INT) + { + mvs_check_page (0, 4, 2); + return \"ICM %0,3,=H'%h1'\"; + } + mvs_check_page (0, 4, 0); + return \"ICM %0,3,%1\"; + }") + + (define_insn "movestricthi" + [(set (strict_low_part (match_operand:HI 0 "general_operand" "=dm")) + (match_operand:HI 1 "general_operand" "d"))] + "" + "* + { + check_label_emit (); + if (REG_P (operands[0])) + { + mvs_check_page (0, 8, 0); + return \"STH %1,140(,13)\;ICM %0,3,140(13)\"; + } + mvs_check_page (0, 4, 0); + return \"STH %1,%0\"; + }") + + ; + ; movdf instruction pattern(s). + ; + + (define_insn "" + [(set (match_operand:DF 0 "r_or_s_operand" "=fm,fm,*dm") + (match_operand:DF 1 "r_or_s_operand" "fmF,*dm,fmF"))] + "TARGET_CHAR_INSTRUCTIONS" + "* + { + check_label_emit (); + if (FP_REG_P (operands[0])) + { + if (FP_REG_P (operands[1])) + { + mvs_check_page (0, 2, 0); + return \"LDR %0,%1\"; + } + if (REG_P (operands[1])) + { + mvs_check_page (0, 8, 0); + return \"STM %1,%N1,140(13)\;LD %0,140(,13)\"; + } + if (operands[1] == const0_rtx) + { + CC_STATUS_SET (operands[0], operands[1]); + mvs_check_page (0, 2, 0); + return \"SDR %0,%0\"; + } + mvs_check_page (0, 4, 0); + return \"LD %0,%1\"; + } + if (REG_P (operands[0])) + { + if (FP_REG_P (operands[1])) + { + mvs_check_page (0, 12, 0); + return \"STD %1,140(,13)\;LM %0,%N0,140(13)\"; + } + mvs_check_page (0, 4, 0); + return \"LM %0,%N0,%1\"; + } + else if (FP_REG_P (operands[1])) + { + mvs_check_page (0, 4, 0); + return \"STD %1,%0\"; + } + else if (REG_P (operands[1])) + { + mvs_check_page (0, 4, 0); + return \"STM %1,%N1,%0\"; + } + mvs_check_page (0, 6, 0); + return \"MVC %O0(8,%R0),%1\"; + }") + + (define_insn "movdf" + [(set (match_operand:DF 0 "general_operand" "=f,fm,m,*d") + (match_operand:DF 1 "general_operand" "fmF,*d,f,fmF"))] + "" + "* + { + check_label_emit (); + if (FP_REG_P (operands[0])) + { + if (FP_REG_P (operands[1])) + { + mvs_check_page (0, 2, 0); + return \"LDR %0,%1\"; + } + if (REG_P (operands[1])) + { + mvs_check_page (0, 8, 0); + return \"STM %1,%N1,140(13)\;LD %0,140(,13)\"; + } + if (operands[1] == const0_rtx) + { + CC_STATUS_SET (operands[0], operands[1]); + mvs_check_page (0, 2, 0); + return \"SDR %0,%0\"; + } + mvs_check_page (0, 4, 0); + return \"LD %0,%1\"; + } + else if (REG_P (operands[0])) + { + if (FP_REG_P (operands[1])) + { + mvs_check_page (0, 12, 0); + return \"STD %1,140(,13)\;LM %0,%N0,140(13)\"; + } + mvs_check_page (0, 4, 0); + return \"LM %0,%N0,%1\"; + } + else if (FP_REG_P (operands[1])) + { + mvs_check_page (0, 4, 0); + return \"STD %1,%0\"; + } + mvs_check_page (0, 4, 0); + return \"STM %1,%N1,%0\"; + }") + + ; + ; movsf instruction pattern(s). + ; + + (define_insn "" + [(set (match_operand:SF 0 "r_or_s_operand" "=fm,fm,*dm") + (match_operand:SF 1 "r_or_s_operand" "fmF,*dm,fmF"))] + "TARGET_CHAR_INSTRUCTIONS" + "* + { + check_label_emit (); + if (FP_REG_P (operands[0])) + { + if (FP_REG_P (operands[1])) + { + mvs_check_page (0, 2, 0); + return \"LER %0,%1\"; + } + if (REG_P (operands[1])) + { + mvs_check_page (0, 8, 0); + return \"ST %1,140(,13)\;LE %0,140(,13)\"; + } + if (operands[1] == const0_rtx) + { + CC_STATUS_SET (operands[0], operands[1]); + mvs_check_page (0, 2, 0); + return \"SER %0,%0\"; + } + mvs_check_page (0, 4, 0); + return \"LE %0,%1\"; + } + else if (REG_P (operands[0])) + { + if (FP_REG_P (operands[1])) + { + mvs_check_page (0, 8, 0); + return \"STE %1,140(,13)\;L %0,140(,13)\"; + } + mvs_check_page (0, 4, 0); + return \"L %0,%1\"; + } + else if (FP_REG_P (operands[1])) + { + mvs_check_page (0, 4, 0); + return \"STE %1,%0\"; + } + else if (REG_P (operands[1])) + { + mvs_check_page (0, 4, 0); + return \"ST %1,%0\"; + } + mvs_check_page (0, 6, 0); + return \"MVC %O0(4,%R0),%1\"; + }") + + (define_insn "movsf" + [(set (match_operand:SF 0 "general_operand" "=f,fm,m,*d") + (match_operand:SF 1 "general_operand" "fmF,*d,f,fmF"))] + "" + "* + { + check_label_emit (); + if (FP_REG_P (operands[0])) + { + if (FP_REG_P (operands[1])) + { + mvs_check_page (0, 2, 0); + return \"LER %0,%1\"; + } + if (REG_P (operands[1])) + { + mvs_check_page (0, 8, 0); + return \"ST %1,140(,13)\;LE %0,140(,13)\"; + } + if (operands[1] == const0_rtx) + { + CC_STATUS_SET (operands[0], operands[1]); + mvs_check_page (0, 2, 0); + return \"SER %0,%0\"; + } + mvs_check_page (0, 4, 0); + return \"LE %0,%1\"; + } + else if (REG_P (operands[0])) + { + if (FP_REG_P (operands[1])) + { + mvs_check_page (0, 8, 0); + return \"STE %1,140(,13)\;L %0,140(,13)\"; + } + mvs_check_page (0, 4, 0); + return \"L %0,%1\"; + } + else if (FP_REG_P (operands[1])) + { + mvs_check_page (0, 4, 0); + return \"STE %1,%0\"; + } + mvs_check_page (0, 4, 0); + return \"ST %1,%0\"; + }") + + ; + ; movstrsi instruction pattern(s). + ; + + (define_expand "movstrsi" + [(set (match_operand:BLK 0 "general_operand" "") + (match_operand:BLK 1 "general_operand" "")) + (use (match_operand:SI 2 "general_operand" "")) + (match_operand 3 "" "")] + "" + " + { + rtx op0, op1; + + op0 = XEXP (operands[0], 0); + if (GET_CODE (op0) == REG + || (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 0)) == REG + && GET_CODE (XEXP (op0, 1)) == CONST_INT + && (unsigned) INTVAL (XEXP (op0, 1)) < 4096)) + { + op0 = operands[0]; + } + else + { + op0 = gen_rtx (MEM, BLKmode, copy_to_mode_reg (SImode, op0)); + } + + op1 = XEXP (operands[1], 0); + if (GET_CODE (op1) == REG + || (GET_CODE (op1) == PLUS && GET_CODE (XEXP (op1, 0)) == REG + && GET_CODE (XEXP (op1, 1)) == CONST_INT + && (unsigned) INTVAL (XEXP (op1, 1)) < 4096)) + { + op1 = operands[1]; + } + else + { + op1 = gen_rtx (MEM, BLKmode, copy_to_mode_reg (SImode, op1)); + } + + if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 256) + { + emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, + gen_rtx (SET, VOIDmode, op0, op1), + gen_rtx (USE, VOIDmode, operands[2])))); + } + else + { + rtx reg1 = gen_reg_rtx (DImode); + rtx reg2 = gen_reg_rtx (DImode); + rtx subreg = gen_rtx (SUBREG, SImode, reg1, 1); + + emit_insn (gen_rtx (SET, VOIDmode, subreg, operands[2])); + emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (SUBREG, SImode, reg2, 1), + subreg)); + emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (5, + gen_rtx (SET, VOIDmode, op0, op1), + gen_rtx (USE, VOIDmode, reg1), + gen_rtx (USE, VOIDmode, reg2), + gen_rtx (CLOBBER, VOIDmode, reg1), + gen_rtx (CLOBBER, VOIDmode, reg2)))); + } + DONE; + }") + + ; Move a block that is less than 256 bytes in length. + + (define_insn "" + [(set (match_operand:BLK 0 "s_operand" "=m") + (match_operand:BLK 1 "s_operand" "m")) + (use (match_operand 2 "immediate_operand" "I"))] + "((unsigned) INTVAL (operands[2]) < 256)" + "* + { + check_label_emit (); + mvs_check_page (0, 6, 0); + return \"MVC %O0(%c2,%R0),%1\"; + }") + + ; Move a block that is larger than 255 bytes in length. + + (define_insn "" + [(set (match_operand:BLK 0 "general_operand" "=m") + (match_operand:BLK 1 "general_operand" "m")) + (use (match_operand:DI 2 "register_operand" "d")) + (use (match_operand:DI 3 "register_operand" "d")) + (clobber (match_dup 2)) + (clobber (match_dup 3))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 10, 0); + return \"LA %2,%0\;LA %3,%1\;MVCL %2,%3\"; + }") + + ;; + ;;- Conversion instructions. + ;; + + ; + ; extendsidi2 instruction pattern(s). + ; + + (define_expand "extendsidi2" + [(set (match_operand:DI 0 "general_operand" "") + (sign_extend:DI (match_operand:SI 1 "general_operand" "")))] + "" + " + { + if (GET_CODE (operands[1]) != CONST_INT) + { + emit_insn (gen_rtx (SET, VOIDmode, + operand_subword (operands[0], 0, 1, DImode), operands[1])); + emit_insn (gen_rtx (SET, VOIDmode, operands[0], + gen_rtx (ASHIFTRT, DImode, operands[0], + gen_rtx (CONST_INT, SImode, 32)))); + } + else + { + if (INTVAL (operands[1]) < 0) + { + emit_insn (gen_rtx (SET, VOIDmode, + operand_subword (operands[0], 0, 1, DImode), + gen_rtx (CONST_INT, SImode, -1))); + } + else + { + emit_insn (gen_rtx (SET, VOIDmode, + operand_subword (operands[0], 0, 1, DImode), + gen_rtx (CONST_INT, SImode, 0))); + } + emit_insn (gen_rtx (SET, VOIDmode, gen_lowpart (SImode, operands[0]), + operands[1])); + } + DONE; + }") + + ; + ; extendhisi2 instruction pattern(s). + ; + + (define_insn "extendhisi2" + [(set (match_operand:SI 0 "general_operand" "=d,m") + (sign_extend:SI (match_operand:HI 1 "general_operand" "g,d")))] + "" + "* + { + check_label_emit (); + if (REG_P (operands[0])) + { + if (REG_P (operands[1])) + if (REGNO (operands[0]) != REGNO (operands[1])) + { + mvs_check_page (0, 2, 0); + return \"LR %0,%1\;SLL %0,16\;SRA %0,16\"; + } + else + return \"\"; /* Should be empty. 16-bits regs are always 32-bits. */ + if (operands[1] == const0_rtx) + { + CC_STATUS_INIT; + mvs_check_page (0, 2, 0); + return \"SLR %0,%0\"; + } + if (GET_CODE (operands[1]) == CONST_INT + && (unsigned) INTVAL (operands[1]) < 4096) + { + mvs_check_page (0, 4, 0); + return \"LA %0,%c1\"; + } + if (GET_CODE (operands[1]) == CONST_INT) + { + mvs_check_page (0, 4, 2); + return \"LH %0,=H'%h1'\"; + } + mvs_check_page (0, 4, 0); + return \"LH %0,%1\"; + } + mvs_check_page (0, 4, 0); + return \"SLL %0,16\;SRA %0,16\;ST %1,%0\"; + }") + + ; + ; extendqisi2 instruction pattern(s). + ; + + (define_insn "extendqisi2" + [(set (match_operand:SI 0 "general_operand" "=d") + (sign_extend:SI (match_operand:QI 1 "general_operand" "0mi")))] + "" + "* + { + check_label_emit (); + CC_STATUS_SET (operands[0], operands[1]); + if (REG_P (operands[1])) + { + mvs_check_page (0, 8, 0); + return \"SLL %0,24\;SRA %0,24\"; + } + if (s_operand (operands[1])) + { + mvs_check_page (0, 8, 0); + return \"ICM %0,8,%1\;SRA %0,24\"; + } + mvs_check_page (0, 12, 0); + return \"IC %0,%1\;SLL %0,24\;SRA %0,24\"; + }") + + ; + ; extendqihi2 instruction pattern(s). + ; + + (define_insn "extendqihi2" + [(set (match_operand:HI 0 "general_operand" "=d") + (sign_extend:HI (match_operand:QI 1 "general_operand" "0m")))] + "" + "* + { + check_label_emit (); + CC_STATUS_SET (operands[0], operands[1]); + if (REG_P (operands[1])) + { + mvs_check_page (0, 8, 0); + return \"SLL %0,24\;SRA %0,24\"; + } + if (s_operand (operands[1])) + { + mvs_check_page (0, 8, 0); + return \"ICM %0,8,%1\;SRA %0,24\"; + } + mvs_check_page (0, 12, 0); + return \"IC %0,%1\;SLL %0,24\;SRA %0,24\"; + }") + + ; + ; zero_extendsidi2 instruction pattern(s). + ; + + (define_expand "zero_extendsidi2" + [(set (match_operand:DI 0 "general_operand" "") + (zero_extend:DI (match_operand:SI 1 "general_operand" "")))] + "" + " + { + emit_insn (gen_rtx (SET, VOIDmode, + operand_subword (operands[0], 0, 1, DImode), operands[1])); + emit_insn (gen_rtx (SET, VOIDmode, operands[0], + gen_rtx (LSHIFTRT, DImode, operands[0], + gen_rtx (CONST_INT, SImode, 32)))); + DONE; + }") + + ; + ; zero_extendhisi2 instruction pattern(s). + ; + + (define_insn "zero_extendhisi2" + [(set (match_operand:SI 0 "general_operand" "=d") + (zero_extend:SI (match_operand:HI 1 "general_operand" "0")))] + "" + "* + { + check_label_emit (); + CC_STATUS_SET (operands[0], operands[1]); + mvs_check_page (0, 4, 4); + return \"N %1,=X'0000FFFF'\"; + }") + + ; + ; zero_extendqisi2 instruction pattern(s). + ; + + (define_insn "zero_extendqisi2" + [(set (match_operand:SI 0 "general_operand" "=d,&d") + (zero_extend:SI (match_operand:QI 1 "general_operand" "0i,m")))] + "" + "* + { + check_label_emit (); + if (REG_P (operands[1])) + { + CC_STATUS_SET (operands[0], operands[1]); + mvs_check_page (0, 4, 4); + return \"N %0,=X'000000FF'\"; + } + if (GET_CODE (operands[1]) == CONST_INT) + { + mvs_check_page (0, 4, 0); + return \"LA %0,%c1\"; + } + CC_STATUS_INIT; + mvs_check_page (0, 8, 0); + return \"SLR %0,%0\;IC %0,%1\"; + }") + + ; + ; zero_extendqihi2 instruction pattern(s). + ; + + (define_insn "zero_extendqihi2" + [(set (match_operand:HI 0 "general_operand" "=d,&d") + (zero_extend:HI (match_operand:QI 1 "general_operand" "0i,m")))] + "" + "* + { + check_label_emit (); + if (REG_P (operands[1])) + { + CC_STATUS_SET (operands[0], operands[1]); + mvs_check_page (0, 4, 4); + return \"N %0,=X'000000FF'\"; + } + if (GET_CODE (operands[1]) == CONST_INT) + { + mvs_check_page (0, 4, 0); + return \"LA %0,%c1\"; + } + CC_STATUS_INIT; + mvs_check_page (0, 8, 0); + return \"SLR %0,%0\;IC %0,%1\"; + }") + + ; + ; truncsihi2 instruction pattern(s). + ; + + (define_insn "truncsihi2" + [(set (match_operand:HI 0 "general_operand" "=d,m") + (truncate:HI (match_operand:SI 1 "general_operand" "0,d")))] + "" + "* + { + check_label_emit (); + if (REG_P (operands[0])) + { + CC_STATUS_SET (operands[0], operands[1]); + mvs_check_page (0, 8, 0); + return \"SLL %0,16\;SRA %0,16\"; + } + mvs_check_page (0, 4, 0); + return \"STH %1,%0\"; + }") + + ; + ; fix_truncdfsi2 instruction pattern(s). + ; + + (define_insn "fix_truncdfsi2" + [(set (match_operand:SI 0 "general_operand" "=d") + (fix:SI (truncate:DF (match_operand:DF 1 "general_operand" "f")))) + (clobber (reg:DF 16))] + "" + "* + { + check_label_emit (); + CC_STATUS_INIT; + if (REGNO (operands[1]) == 16) + { + mvs_check_page (0, 12, 8); + return \"AD 0,=XL8'4F08000000000000'\;STD 0,140(,13)\;L %0,144(,13)\"; + } + mvs_check_page (0, 14, 8); + return \"LDR 0,%1\;AD 0,=XL8'4F08000000000000'\;STD 0,140(,13)\;L %0,144(,13)\"; + }") + + ; + ; floatsidf2 instruction pattern(s). + ; + ; Uses the float field of the TCA. + ; + + (define_insn "floatsidf2" + [(set (match_operand:DF 0 "general_operand" "=f") + (float:DF (match_operand:SI 1 "general_operand" "d")))] + "" + "* + { + check_label_emit (); + CC_STATUS_INIT; + mvs_check_page (0, 16, 8); + return \"ST %1,508(,12)\;XI 508(12),128\;LD %0,504(,12)\;SD %0,=XL8'4E00000080000000'\"; + }") + + ; + ; truncdfsf2 instruction pattern(s). + ; + + (define_insn "truncdfsf2" + [(set (match_operand:SF 0 "general_operand" "=f") + (float_truncate:SF (match_operand:DF 1 "general_operand" "f")))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 2, 0); + return \"LRER %0,%1\"; + }") + + ; + ; extendsfdf2 instruction pattern(s). + ; + + (define_insn "extendsfdf2" + [(set (match_operand:DF 0 "general_operand" "=f") + (float_extend:DF (match_operand:SF 1 "general_operand" "fmF")))] + "" + "* + { + check_label_emit (); + CC_STATUS_SET (0, const0_rtx); + if (FP_REG_P (operands[1])) + { + if (REGNO (operands[0]) == REGNO (operands[1])) + { + mvs_check_page (0, 10, 0); + return \"STE %1,140(,13)\;SDR %0,%0\;LE %0,140(,13)\"; + } + mvs_check_page (0, 4, 0); + return \"SDR %0,%0\;LER %0,%1\"; + } + mvs_check_page (0, 6, 0); + return \"SDR %0,%0\;LE %0,%1\"; + }") + + ;; + ;;- Add instructions. + ;; + + ; + ; adddi3 instruction pattern(s). + ; + + (define_expand "adddi3" + [(set (match_operand:DI 0 "general_operand" "") + (plus:DI (match_operand:DI 1 "general_operand" "") + (match_operand:DI 2 "general_operand" "")))] + "" + " + { + rtx label = gen_label_rtx (); + rtx op0_high = operand_subword (operands[0], 0, 1, DImode); + rtx op0_low = gen_lowpart (SImode, operands[0]); + + emit_insn (gen_rtx (SET, VOIDmode, op0_high, + gen_rtx (PLUS, SImode, + operand_subword (operands[1], 0, 1, DImode), + operand_subword (operands[2], 0, 1, DImode)))); + emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, + gen_rtx (SET, VOIDmode, op0_low, + gen_rtx (PLUS, SImode, gen_lowpart (SImode, operands[1]), + gen_lowpart (SImode, operands[2]))), + gen_rtx (USE, VOIDmode, gen_rtx (LABEL_REF, VOIDmode, label))))); + emit_insn (gen_rtx (SET, VOIDmode, op0_high, + gen_rtx (PLUS, SImode, op0_high, + gen_rtx (CONST_INT, SImode, 1)))); + emit_label (label); + DONE; + }") + + (define_insn "" + [(set (match_operand:SI 0 "general_operand" "=d") + (plus:SI (match_operand:SI 1 "general_operand" "%0") + (match_operand:SI 2 "general_operand" "g"))) + (use (label_ref (match_operand 3 "" "")))] + "" + "* + { + int onpage; + + check_label_emit (); + onpage = mvs_check_label (CODE_LABEL_NUMBER (operands[3])); + if (REG_P (operands[2])) + { + if (!onpage) + { + mvs_check_page (0, 8, 4); + return \"ALR %0,%2\;L 14,=A(%l3)\;BCR 12,14\"; + } + if (mvs_check_page (0, 6, 0)) + { + mvs_check_page (0, 2, 4); + return \"ALR %0,%2\;L 14,=A(%l3)\;BCR 12,14\"; + } + return \"ALR %0,%2\;BC 12,%l3\"; + } + if (!onpage) + { + mvs_check_page (0, 10, 4); + return \"AL %0,%2\;L 14,=A(%l3)\;BCR 12,14\"; + } + if (mvs_check_page (0, 8 ,0)) + { + mvs_check_page (0, 2, 4); + return \"AL %0,%2\;L 14,=A(%l3)\;BCR 12,14\"; + } + return \"AL %0,%2\;BC 12,%l3\"; + }") + + ; + ; addsi3 instruction pattern(s). + ; + ; The following insn is used when it is known that operand one is an address, + ; frame, stack or argument pointer, and operand two is a constant that is + ; small enough to fit in the displacement field. + ; Notice that we can't allow the frame pointer to used as a normal register + ; because of this insn. + ; + + (define_insn "" + [(set (match_operand:SI 0 "register_operand" "=d") + (plus:SI (match_operand:SI 1 "general_operand" "%a") + (match_operand:SI 2 "immediate_operand" "J")))] + "((REGNO (operands[1]) == FRAME_POINTER_REGNUM || REGNO (operands[1]) == ARG_POINTER_REGNUM || REGNO (operands[1]) == STACK_POINTER_REGNUM) && (unsigned) INTVAL (operands[2]) < 4096)" + "* + { + check_label_emit (); + CC_STATUS_INIT; + mvs_check_page (0, 4, 0); + return \"LA %0,%c2(,%1)\"; + }") + + ; This insn handles additions that are relative to the frame pointer. + + (define_insn "" + [(set (match_operand:SI 0 "register_operand" "=d") + (plus:SI (match_operand:SI 1 "register_operand" "%a") + (match_operand:SI 2 "immediate_operand" "i")))] + "REGNO (operands[1]) == FRAME_POINTER_REGNUM" + "* + { + check_label_emit (); + if ((unsigned) INTVAL (operands[2]) < 4096) + { + mvs_check_page (0, 4, 0); + return \"LA %0,%c2(,%1)\"; + } + if (REGNO (operands[1]) == REGNO (operands[0])) + { + mvs_check_page (0, 4, 0); + return \"A %0,%2\"; + } + mvs_check_page (0, 6, 0); + return \"L %0,%2\;AR %0,%1\"; + }") + + (define_insn "addsi3" + [(set (match_operand:SI 0 "general_operand" "=d") + (plus:SI (match_operand:SI 1 "general_operand" "%0") + (match_operand:SI 2 "general_operand" "g")))] + "" + "* + { + check_label_emit (); + if (REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"AR %0,%2\"; + } + if (GET_CODE (operands[2]) == CONST_INT) + { + if (INTVAL (operands[2]) == -1) + { + CC_STATUS_INIT; + mvs_check_page (0, 2, 0); + return \"BCTR %0,0\"; + } + } + mvs_check_page (0, 4, 0); + return \"A %0,%2\"; + }") + + ; + ; addhi3 instruction pattern(s). + ; + + (define_insn "addhi3" + [(set (match_operand:HI 0 "general_operand" "=d") + (plus:HI (match_operand:HI 1 "general_operand" "%0") + (match_operand:HI 2 "general_operand" "dmi")))] + "" + "* + { + check_label_emit (); + if (REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"STH %2,140(,13)\;AH %0,140(,13)\"; + } + if (GET_CODE (operands[2]) == CONST_INT) + { + if (INTVAL (operands[2]) == -1) + { + CC_STATUS_INIT; + mvs_check_page (0, 2, 0); + return \"BCTR %0,0\"; + } + mvs_check_page (0, 4, 2); + return \"AH %0,=H'%h2'\"; + } + mvs_check_page (0, 4, 0); + return \"AH %0,%2\"; + }") + + ; + ; addqi3 instruction pattern(s). + ; + + (define_insn "addqi3" + [(set (match_operand:QI 0 "general_operand" "=d") + (plus:QI (match_operand:QI 1 "general_operand" "%a") + (match_operand:QI 2 "general_operand" "ai")))] + "" + "* + { + check_label_emit (); + CC_STATUS_INIT; + mvs_check_page (0, 4, 0); + if (REG_P (operands[2])) + return \"LA %0,0(%1,%2)\"; + return \"LA %0,%B2(,%1)\"; + }") + + ; + ; adddf3 instruction pattern(s). + ; + + (define_insn "adddf3" + [(set (match_operand:DF 0 "general_operand" "=f") + (plus:DF (match_operand:DF 1 "general_operand" "%0") + (match_operand:DF 2 "general_operand" "fmF")))] + "" + "* + { + check_label_emit (); + if (FP_REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"ADR %0,%2\"; + } + mvs_check_page (0, 4, 0); + return \"AD %0,%2\"; + }") + + ; + ; addsf3 instruction pattern(s). + ; + + (define_insn "addsf3" + [(set (match_operand:SF 0 "general_operand" "=f") + (plus:SF (match_operand:SF 1 "general_operand" "%0") + (match_operand:SF 2 "general_operand" "fmF")))] + "" + "* + { + check_label_emit (); + if (FP_REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"AER %0,%2\"; + } + mvs_check_page (0, 4, 0); + return \"AE %0,%2\"; + }") + + ;; + ;;- Subtract instructions. + ;; + + ; + ; subdi3 instruction pattern(s). + ; + + (define_expand "subdi3" + [(set (match_operand:DI 0 "general_operand" "") + (minus:DI (match_operand:DI 1 "general_operand" "") + (match_operand:DI 2 "general_operand" "")))] + "" + " + { + rtx label = gen_label_rtx (); + rtx op0_high = operand_subword (operands[0], 0, 1, DImode); + rtx op0_low = gen_lowpart (SImode, operands[0]); + + emit_insn (gen_rtx (SET, VOIDmode, op0_high, + gen_rtx (MINUS, SImode, + operand_subword (operands[1], 0, 1, DImode), + operand_subword (operands[2], 0, 1, DImode)))); + emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, + gen_rtx (SET, VOIDmode, op0_low, + gen_rtx (MINUS, SImode, + gen_lowpart (SImode, operands[1]), + gen_lowpart (SImode, operands[2]))), + gen_rtx (USE, VOIDmode, + gen_rtx (LABEL_REF, VOIDmode, label))))); + emit_insn (gen_rtx (SET, VOIDmode, op0_high, + gen_rtx (MINUS, SImode, op0_high, + gen_rtx (CONST_INT, SImode, 1)))); + emit_label (label); + DONE; + }") + + (define_insn "" + [(set (match_operand:SI 0 "general_operand" "=d") + (minus:SI (match_operand:SI 1 "general_operand" "0") + (match_operand:SI 2 "general_operand" "g"))) + (use (label_ref (match_operand 3 "" "")))] + "" + "* + { + int onpage; + + check_label_emit (); + CC_STATUS_INIT; + onpage = mvs_check_label (CODE_LABEL_NUMBER (operands[3])); + if (REG_P (operands[2])) + { + if (!onpage) + { + mvs_check_page (0, 8, 4); + return \"SLR %0,%2\;L 14,=A(%l3)\;BCR 12,14\"; + } + if (mvs_check_page (0, 6, 0)) + { + mvs_check_page (0, 2, 4); + return \"SLR %0,%2\;L 14,=A(%l3)\;BCR 12,14\"; + } + return \"SLR %0,%2\;BC 12,%l3\"; + } + if (!onpage) + { + mvs_check_page (0, 10, 4); + return \"SL %0,%2\;L 14,=A(%l3)\;BCR 12,14\"; + } + if (mvs_check_page (0, 8, 0)) + { + mvs_check_page (0, 2, 4); + return \"SL %0,%2\;L 14,=A(%l3)\;BCR 12,14\"; + } + return \"SL %0,%2\;BC 12,%l3\"; + }") + + ; + ; subsi3 instruction pattern(s). + ; + + (define_insn "subsi3" + [(set (match_operand:SI 0 "general_operand" "=d") + (minus:SI (match_operand:SI 1 "general_operand" "0") + (match_operand:SI 2 "general_operand" "g")))] + "" + "* + { + check_label_emit (); + if (REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"SR %0,%2\"; + } + if (operands[2] == const1_rtx) + { + CC_STATUS_INIT; + mvs_check_page (0, 2, 0); + return \"BCTR %0,0\"; + } + mvs_check_page (0, 4, 0); + return \"S %0,%2\"; + }") + + ; + ; subhi3 instruction pattern(s). + ; + + (define_insn "subhi3" + [(set (match_operand:HI 0 "general_operand" "=d") + (minus:HI (match_operand:HI 1 "general_operand" "0") + (match_operand:HI 2 "general_operand" "g")))] + "" + "* + { + check_label_emit (); + if (REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"STH %2,140(,13)\;SH %0,140(,13)\"; + } + if (operands[2] == const1_rtx) + { + CC_STATUS_INIT; + mvs_check_page (0, 2, 0); + return \"BCTR %0,0\"; + } + if (GET_CODE (operands[2]) == CONST_INT) + { + mvs_check_page (0, 4, 2); + return \"SH %0,=H'%h2'\"; + } + mvs_check_page (0, 4, 0); + return \"SH %0,%2\"; + }") + + ; + ; subqi3 instruction pattern(s). + ; + + (define_expand "subqi3" + [(set (match_operand:QI 0 "general_operand" "=d") + (minus:QI (match_operand:QI 1 "general_operand" "%0") + (match_operand:QI 2 "general_operand" "di")))] + "" + " + { + if (REG_P (operands[2])) + { + emit_insn (gen_rtx (SET, VOIDmode, operands[0], + gen_rtx (MINUS, QImode, operands[1], operands[2]))); + } + else + { + emit_insn (gen_rtx (SET, VOIDmode, operands[0], + gen_rtx (PLUS, QImode, operands[1], + negate_rtx (QImode, operands[2])))); + } + DONE; + }") + + (define_insn "" + [(set (match_operand:QI 0 "register_operand" "=d") + (minus:QI (match_operand:QI 1 "register_operand" "%0") + (match_operand:QI 2 "register_operand" "d")))] + "" + "* + { + check_label_emit (); + CC_STATUS_INIT; + mvs_check_page (0, 2, 0); + return \"SR %0,%2\"; + }") + + ; + ; subdf3 instruction pattern(s). + ; + + (define_insn "subdf3" + [(set (match_operand:DF 0 "general_operand" "=f") + (minus:DF (match_operand:DF 1 "general_operand" "0") + (match_operand:DF 2 "general_operand" "fmF")))] + "" + "* + { + check_label_emit (); + if (FP_REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"SDR %0,%2\"; + } + mvs_check_page (0, 4, 0); + return \"SD %0,%2\"; + }") + + ; + ; subsf3 instruction pattern(s). + ; + + (define_insn "subsf3" + [(set (match_operand:SF 0 "general_operand" "=f") + (minus:SF (match_operand:SF 1 "general_operand" "0") + (match_operand:SF 2 "general_operand" "fmF")))] + "" + "* + { + check_label_emit (); + if (FP_REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"SER %0,%2\"; + } + mvs_check_page (0, 4, 0); + return \"SE %0,%2\"; + }") + + ;; + ;;- Multiply instructions. + ;; + + ; + ; mulsi3 instruction pattern(s). + ; + + (define_expand "mulsi3" + [(set (match_operand:SI 0 "general_operand" "") + (mult:SI (match_operand:SI 1 "general_operand" "") + (match_operand:SI 2 "general_operand" "")))] + "" + " + { + if (GET_CODE (operands[1]) == CONST_INT + && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')) + { + emit_insn (gen_rtx (SET, VOIDmode, operands[0], + gen_rtx (MULT, SImode, operands[2], operands[1]))); + } + else if (GET_CODE (operands[2]) == CONST_INT + && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')) + { + emit_insn (gen_rtx (SET, VOIDmode, operands[0], + gen_rtx (MULT, SImode, operands[1], operands[2]))); + } + else + { + rtx r = gen_reg_rtx (DImode); + + emit_insn (gen_rtx (SET, VOIDmode, + gen_rtx (SUBREG, SImode, r, 1), operands[1])); + emit_insn (gen_rtx (SET, VOIDmode, r, + gen_rtx (MULT, SImode, r, operands[2]))); + emit_insn (gen_rtx (SET, VOIDmode, operands[0], + gen_rtx (SUBREG, SImode, r, 1))); + } + DONE; + }") + + (define_insn "" + [(set (match_operand:SI 0 "register_operand" "=d") + (mult:SI (match_operand:SI 1 "general_operand" "%0") + (match_operand:SI 2 "immediate_operand" "K")))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 4, 0); + return \"MH %0,%2\"; + }") + + (define_insn "" + [(set (match_operand:DI 0 "register_operand" "=d") + (mult:SI (match_operand:DI 1 "general_operand" "%0") + (match_operand:SI 2 "general_operand" "g")))] + "" + "* + { + check_label_emit (); + if (REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"MR %0,%2\"; + } + mvs_check_page (0, 4, 0); + return \"M %0,%2\"; + }") + + ; + ; muldf3 instruction pattern(s). + ; + + (define_insn "muldf3" + [(set (match_operand:DF 0 "general_operand" "=f") + (mult:DF (match_operand:DF 1 "general_operand" "%0") + (match_operand:DF 2 "general_operand" "fmF")))] + "" + "* + { + check_label_emit (); + if (FP_REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"MDR %0,%2\"; + } + mvs_check_page (0, 4, 0); + return \"MD %0,%2\"; + }") + + ; + ; mulsf3 instruction pattern(s). + ; + + (define_insn "mulsf3" + [(set (match_operand:SF 0 "general_operand" "=f") + (mult:SF (match_operand:SF 1 "general_operand" "%0") + (match_operand:SF 2 "general_operand" "fmF")))] + "" + "* + { + check_label_emit (); + if (FP_REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"MER %0,%2\"; + } + mvs_check_page (0, 4, 0); + return \"ME %0,%2\"; + }") + + ;; + ;;- Divide instructions. + ;; + + ; + ; divsi3 instruction pattern(s). + ; + + (define_expand "divsi3" + [(set (match_operand:SI 0 "general_operand" "") + (div:SI (match_operand:SI 1 "general_operand" "") + (match_operand:SI 2 "general_operand" "")))] + "" + " + { + rtx r = gen_reg_rtx (DImode); + + emit_insn (gen_extendsidi2 (r, operands[1])); + emit_insn (gen_rtx (SET, VOIDmode, r, + gen_rtx (DIV, SImode, r, operands[2]))); + emit_insn (gen_rtx (SET, VOIDmode, operands[0], + gen_rtx (SUBREG, SImode, r, 1))); + DONE; + }") + + + ; + ; udivsi3 instruction pattern(s). + ; + + (define_expand "udivsi3" + [(set (match_operand:SI 0 "general_operand" "") + (udiv:SI (match_operand:SI 1 "general_operand" "") + (match_operand:SI 2 "general_operand" "")))] + "" + " + { + rtx dr = gen_reg_rtx (DImode); + rtx dr_0 = gen_rtx (SUBREG, SImode, dr, 0); + rtx dr_1 = gen_rtx (SUBREG, SImode, dr, 1); + + + if (GET_CODE (operands[2]) == CONST_INT) + { + if (INTVAL (operands[2]) > 0) + { + emit_insn (gen_zero_extendsidi2 (dr, operands[1])); + emit_insn (gen_rtx (SET, VOIDmode, dr, + gen_rtx (DIV, SImode, dr, operands[2]))); + } + else + { + rtx label1 = gen_label_rtx (); + + emit_insn (gen_rtx (SET, VOIDmode, dr_0, operands[1])); + emit_insn (gen_rtx (SET, VOIDmode, dr_1, const0_rtx)); + emit_insn (gen_cmpsi (dr_0, operands[2])); + emit_jump_insn (gen_bltu (label1)); + emit_insn (gen_rtx (SET, VOIDmode, dr_1, const1_rtx)); + emit_label (label1); + } + } + else + { + rtx label1 = gen_label_rtx (); + rtx label2 = gen_label_rtx (); + rtx label3 = gen_label_rtx (); + rtx sr = gen_reg_rtx (SImode); + + emit_insn (gen_rtx (SET, VOIDmode, dr_0, operands[1])); + emit_insn (gen_rtx (SET, VOIDmode, sr, operands[2])); + emit_insn (gen_rtx (SET, VOIDmode, dr_1, const0_rtx)); + emit_insn (gen_cmpsi (sr, dr_0)); + emit_jump_insn (gen_bgtu (label3)); + emit_insn (gen_cmpsi (sr, const1_rtx)); + emit_jump_insn (gen_blt (label2)); + emit_jump_insn (gen_beq (label1)); + emit_insn (gen_rtx (SET, VOIDmode, dr, + gen_rtx (LSHIFTRT, DImode, dr, + gen_rtx (CONST_INT, SImode, 32)))); + emit_insn (gen_rtx (SET, VOIDmode, dr, + gen_rtx (DIV, SImode, dr, sr))); + emit_jump_insn (gen_jump (label3)); + emit_label (label1); + emit_insn (gen_rtx (SET, VOIDmode, dr_1, dr_0)); + emit_jump_insn (gen_jump (label3)); + emit_label (label2); + emit_insn (gen_rtx (SET, VOIDmode, dr_1, const1_rtx)); + emit_label (label3); + } + emit_insn (gen_rtx (SET, VOIDmode, operands[0], dr_1)); + + DONE; + }") + + ; This is used by divsi3 & udivsi3. + + (define_insn "" + [(set (match_operand:DI 0 "register_operand" "=d") + (div:SI (match_operand:DI 1 "register_operand" "0") + (match_operand:SI 2 "general_operand" "")))] + "" + "* + { + check_label_emit (); + if (REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"DR %0,%2\"; + } + mvs_check_page (0, 4, 0); + return \"D %0,%2\"; + }") + + ; + ; divdf3 instruction pattern(s). + ; + + (define_insn "divdf3" + [(set (match_operand:DF 0 "general_operand" "=f") + (div:DF (match_operand:DF 1 "general_operand" "0") + (match_operand:DF 2 "general_operand" "fmF")))] + "" + "* + { + check_label_emit (); + if (FP_REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"DDR %0,%2\"; + } + mvs_check_page (0, 4, 0); + return \"DD %0,%2\"; + }") + + ; + ; divsf3 instruction pattern(s). + ; + + (define_insn "divsf3" + [(set (match_operand:SF 0 "general_operand" "=f") + (div:SF (match_operand:SF 1 "general_operand" "0") + (match_operand:SF 2 "general_operand" "fmF")))] + "" + "* + { + check_label_emit (); + if (FP_REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"DER %0,%2\"; + } + mvs_check_page (0, 4, 0); + return \"DE %0,%2\"; + }") + + ;; + ;;- Modulo instructions. + ;; + + ; + ; modsi3 instruction pattern(s). + ; + + (define_expand "modsi3" + [(set (match_operand:SI 0 "general_operand" "") + (mod:SI (match_operand:SI 1 "general_operand" "") + (match_operand:SI 2 "general_operand" "")))] + "" + " + { + rtx r = gen_reg_rtx (DImode); + + emit_insn (gen_extendsidi2 (r, operands[1])); + emit_insn (gen_rtx (SET, VOIDmode, r, + gen_rtx (MOD, SImode, r, operands[2]))); + emit_insn (gen_rtx (SET, VOIDmode, operands[0], + gen_rtx (SUBREG, SImode, r, 0))); + DONE; + }") + + ; + ; umodsi3 instruction pattern(s). + ; + + (define_expand "umodsi3" + [(set (match_operand:SI 0 "general_operand" "") + (umod:SI (match_operand:SI 1 "general_operand" "") + (match_operand:SI 2 "general_operand" "")))] + "" + " + { + rtx dr = gen_reg_rtx (DImode); + rtx dr_0 = gen_rtx (SUBREG, SImode, dr, 0); + rtx dr_1 = gen_rtx (SUBREG, SImode, dr, 1); + + emit_insn (gen_rtx (SET, VOIDmode, dr_0, operands[1])); + + if (GET_CODE (operands[2]) == CONST_INT) + { + if (INTVAL (operands[2]) > 0) + { + emit_insn (gen_rtx (SET, VOIDmode, dr, + gen_rtx (LSHIFTRT, DImode, dr, + gen_rtx (CONST_INT, SImode, 32)))); + emit_insn (gen_rtx (SET, VOIDmode, dr, + gen_rtx (MOD, SImode, dr, operands[2]))); + } + else + { + rtx label1 = gen_label_rtx (); + rtx sr = gen_reg_rtx (SImode); + + emit_insn (gen_rtx (SET, VOIDmode, sr, operands[2])); + emit_insn (gen_cmpsi (dr_0, sr)); + emit_jump_insn (gen_bltu (label1)); + emit_insn (gen_rtx (SET, VOIDmode, sr, gen_rtx (ABS, SImode, sr))); + emit_insn (gen_rtx (SET, VOIDmode, dr_0, + gen_rtx (PLUS, SImode, dr_0, sr))); + emit_label (label1); + } + } + else + { + rtx label1 = gen_label_rtx (); + rtx label2 = gen_label_rtx (); + rtx label3 = gen_label_rtx (); + rtx sr = gen_reg_rtx (SImode); + + emit_insn (gen_rtx (SET, VOIDmode, dr_0, operands[1])); + emit_insn (gen_rtx (SET, VOIDmode, sr, operands[2])); + emit_insn (gen_cmpsi (sr, dr_0)); + emit_jump_insn (gen_bgtu (label3)); + emit_insn (gen_cmpsi (sr, const1_rtx)); + emit_jump_insn (gen_blt (label2)); + emit_jump_insn (gen_beq (label1)); + emit_insn (gen_rtx (SET, VOIDmode, dr, + gen_rtx (LSHIFTRT, DImode, dr, + gen_rtx (CONST_INT, SImode, 32)))); + emit_insn (gen_rtx (SET, VOIDmode, dr, gen_rtx (MOD, SImode, dr, sr))); + emit_jump_insn (gen_jump (label3)); + emit_label (label1); + emit_insn (gen_rtx (SET, VOIDmode, dr_0, const0_rtx)); + emit_jump_insn (gen_jump (label3)); + emit_label (label2); + emit_insn (gen_rtx (SET, VOIDmode, dr_0, + gen_rtx (MINUS, SImode, dr_0, sr))); + emit_label (label3); + + } + emit_insn (gen_rtx (SET, VOIDmode, operands[0], dr_0)); + + DONE; + }") + + ; This is used by modsi3 & umodsi3. + + (define_insn "" + [(set (match_operand:DI 0 "register_operand" "=d") + (mod:SI (match_operand:DI 1 "register_operand" "0") + (match_operand:SI 2 "general_operand" "")))] + "" + "* + { + check_label_emit (); + if (REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"DR %0,%2\"; + } + mvs_check_page (0, 4, 0); + return \"D %0,%2\"; + }") + + ;; + ;;- And instructions. + ;; + + ; + ; anddi3 instruction pattern(s). + ; + + ;(define_expand "anddi3" + ; [(set (match_operand:DI 0 "general_operand" "") + ; (and:DI (match_operand:DI 1 "general_operand" "") + ; (match_operand:DI 2 "general_operand" "")))] + ; "" + ; " + ;{ + ; rtx gen_andsi3(); + ; + ; emit_insn (gen_andsi3 (operand_subword (operands[0], 0, 1, DImode), + ; operand_subword (operands[1], 0, 1, DImode), + ; operand_subword (operands[2], 0, 1, DImode))); + ; emit_insn (gen_andsi3 (gen_lowpart (SImode, operands[0]), + ; gen_lowpart (SImode, operands[1]), + ; gen_lowpart (SImode, operands[2]))); + ; DONE; + ;}") + + ; + ; andsi3 instruction pattern(s). + ; + + (define_insn "" + [(set (match_operand:SI 0 "r_or_s_operand" "=d,m") + (and:SI (match_operand:SI 1 "r_or_s_operand" "%0,0") + (match_operand:SI 2 "r_or_s_operand" "g,mi")))] + "TARGET_CHAR_INSTRUCTIONS" + "* + { + check_label_emit (); + if (REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"NR %0,%2\"; + } + if (REG_P (operands[0])) + { + mvs_check_page (0, 4, 0); + return \"N %0,%2\"; + } + CC_STATUS_INIT; + mvs_check_page (0, 6, 0); + return \"NC %O0(4,%R0),%2\"; + }") + + (define_insn "andsi3" + [(set (match_operand:SI 0 "general_operand" "=d") + (and:SI (match_operand:SI 1 "general_operand" "%0") + (match_operand:SI 2 "general_operand" "g")))] + "" + "* + { + check_label_emit (); + if (REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"NR %0,%2\"; + } + mvs_check_page (0, 4, 0); + return \"N %0,%2\"; + }") + + ; + ; andhi3 instruction pattern(s). + ; + + (define_insn "" + [(set (match_operand:HI 0 "r_or_s_operand" "=d,m") + (and:HI (match_operand:HI 1 "r_or_s_operand" "%0,0") + (match_operand:HI 2 "r_or_s_operand" "di,mi")))] + "TARGET_CHAR_INSTRUCTIONS" + "* + { + check_label_emit (); + if (REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"NR %0,%2\"; + } + if (REG_P (operands[0])) + { + mvs_check_page (0, 4, 0); + return \"N %0,%H2\"; + } + CC_STATUS_INIT; + if (GET_CODE (operands[2]) == CONST_INT) + { + mvs_check_page (0, 6, 2); + return \"NC %O0(2,%R0),=H'%h2'\"; + } + mvs_check_page (0, 6, 0); + return \"NC %O0(2,%R0),%2\"; + }") + + (define_insn "andhi3" + [(set (match_operand:HI 0 "general_operand" "=d") + (and:HI (match_operand:HI 1 "general_operand" "%0") + (match_operand:HI 2 "general_operand" "di")))] + "" + "* + { + check_label_emit (); + if (GET_CODE (operands[2]) == CONST_INT) + { + mvs_check_page (0, 4, 0); + return \"N %0,%H2\"; + } + mvs_check_page (0, 2, 0); + return \"NR %0,%2\"; + }") + + ; + ; andqi3 instruction pattern(s). + ; + + (define_insn "" + [(set (match_operand:QI 0 "r_or_s_operand" "=d,m") + (and:QI (match_operand:QI 1 "r_or_s_operand" "%0,0") + (match_operand:QI 2 "r_or_s_operand" "di,mi")))] + "TARGET_CHAR_INSTRUCTIONS" + "* + { + check_label_emit (); + CC_STATUS_INIT; + if (REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"NR %0,%2\"; + } + if (REG_P (operands[0])) + { + mvs_check_page (0, 4, 0); + return \"N %0,%2\"; + } + if (GET_CODE (operands[2]) == CONST_INT) + { + mvs_check_page (0, 4, 0); + return \"NI %0,%B2\"; + } + mvs_check_page (0, 6, 0); + return \"NC %O0(1,%R0),%2\"; + }") + + (define_insn "andqi3" + [(set (match_operand:QI 0 "general_operand" "=d") + (and:QI (match_operand:QI 1 "general_operand" "%0") + (match_operand:QI 2 "general_operand" "di")))] + "" + "* + { + check_label_emit (); + CC_STATUS_INIT; + if (GET_CODE (operands[2]) == CONST_INT) + { + mvs_check_page (0, 4, 0); + return \"N %0,%2\"; + } + mvs_check_page (0, 2, 0); + return \"NR %0,%2\"; + }") + + ;; + ;;- Bit set (inclusive or) instructions. + ;; + + ; + ; iordi3 instruction pattern(s). + ; + + ;(define_expand "iordi3" + ; [(set (match_operand:DI 0 "general_operand" "") + ; (ior:DI (match_operand:DI 1 "general_operand" "") + ; (match_operand:DI 2 "general_operand" "")))] + ; "" + ; " + ;{ + ; rtx gen_iorsi3(); + ; + ; emit_insn (gen_iorsi3 (operand_subword (operands[0], 0, 1, DImode), + ; operand_subword (operands[1], 0, 1, DImode), + ; operand_subword (operands[2], 0, 1, DImode))); + ; emit_insn (gen_iorsi3 (gen_lowpart (SImode, operands[0]), + ; gen_lowpart (SImode, operands[1]), + ; gen_lowpart (SImode, operands[2]))); + ; DONE; + ;}") + + ; + ; iorsi3 instruction pattern(s). + ; + + (define_insn "" + [(set (match_operand:SI 0 "r_or_s_operand" "=d,m") + (ior:SI (match_operand:SI 1 "r_or_s_operand" "%0,0") + (match_operand:SI 2 "r_or_s_operand" "g,mi")))] + "TARGET_CHAR_INSTRUCTIONS" + "* + { + check_label_emit (); + if (REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"OR %0,%2\"; + } + if (REG_P (operands[0])) + { + mvs_check_page (0, 4, 0); + return \"O %0,%2\"; + } + CC_STATUS_INIT; + mvs_check_page (0, 6, 0); + return \"OC %O0(4,%R0),%2\"; + }") + + (define_insn "iorsi3" + [(set (match_operand:SI 0 "general_operand" "=d") + (ior:SI (match_operand:SI 1 "general_operand" "%0") + (match_operand:SI 2 "general_operand" "g")))] + "" + "* + { + check_label_emit (); + if (REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"OR %0,%2\"; + } + mvs_check_page (0, 4, 0); + return \"O %0,%2\"; + }") + + ; + ; iorhi3 instruction pattern(s). + ; + + (define_insn "" + [(set (match_operand:HI 0 "r_or_s_operand" "=d,m") + (ior:HI (match_operand:HI 1 "r_or_s_operand" "%0,0") + (match_operand:HI 2 "r_or_s_operand" "di,mi")))] + "TARGET_CHAR_INSTRUCTIONS" + "* + { + check_label_emit (); + if (REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"OR %0,%2\"; + } + if (REG_P (operands[0])) + { + mvs_check_page (0, 4, 0); + return \"O %0,%H2\"; + } + CC_STATUS_INIT; + if (GET_CODE (operands[2]) == CONST_INT) + { + mvs_check_page (0, 6, 2); + return \"OC %O0(2,%R0),=H'%h2'\"; + } + mvs_check_page (0, 6, 0); + return \"OC %O0(2,%R0),%2\"; + }") + + (define_insn "iorhi3" + [(set (match_operand:HI 0 "general_operand" "=d") + (ior:HI (match_operand:HI 1 "general_operand" "%0") + (match_operand:HI 2 "general_operand" "di")))] + "" + "* + { + check_label_emit (); + if (GET_CODE (operands[2]) == CONST_INT) + { + mvs_check_page (0, 4, 0); + return \"O %0,%H2\"; + } + mvs_check_page (0, 2, 0); + return \"OR %0,%2\"; + }") + + ; + ; iorqi3 instruction pattern(s). + ; + + (define_insn "" + [(set (match_operand:QI 0 "r_or_s_operand" "=d,m") + (ior:QI (match_operand:QI 1 "r_or_s_operand" "%0,0") + (match_operand:QI 2 "r_or_s_operand" "di,mi")))] + "TARGET_CHAR_INSTRUCTIONS" + "* + { + check_label_emit (); + CC_STATUS_INIT; + if (REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"OR %0,%2\"; + } + if (REG_P (operands[0])) + { + mvs_check_page (0, 4, 0); + return \"O %0,%2\"; + } + CC_STATUS_INIT; + if (GET_CODE (operands[2]) == CONST_INT) + { + mvs_check_page (0, 4, 0); + return \"OI %0,%B2\"; + } + mvs_check_page (0, 6, 0); + return \"OC %O0(1,%R0),%2\"; + }") + + (define_insn "iorqi3" + [(set (match_operand:QI 0 "general_operand" "=d") + (ior:QI (match_operand:QI 1 "general_operand" "%0") + (match_operand:QI 2 "general_operand" "di")))] + "" + "* + { + check_label_emit (); + CC_STATUS_INIT; + if (GET_CODE (operands[2]) == CONST_INT) + { + mvs_check_page (0, 4, 0); + return \"O %0,%2\"; + } + mvs_check_page (0, 2, 0); + return \"OR %0,%2\"; + }") + + ;; + ;;- Xor instructions. + ;; + + ; + ; xordi3 instruction pattern(s). + ; + + ;(define_expand "xordi3" + ; [(set (match_operand:DI 0 "general_operand" "") + ; (xor:DI (match_operand:DI 1 "general_operand" "") + ; (match_operand:DI 2 "general_operand" "")))] + ; "" + ; " + ;{ + ; rtx gen_xorsi3(); + ; + ; emit_insn (gen_xorsi3 (operand_subword (operands[0], 0, 1, DImode), + ; operand_subword (operands[1], 0, 1, DImode), + ; operand_subword (operands[2], 0, 1, DImode))); + ; emit_insn (gen_xorsi3 (gen_lowpart (SImode, operands[0]), + ; gen_lowpart (SImode, operands[1]), + ; gen_lowpart (SImode, operands[2]))); + ; DONE; + ;}") + + ; + ; xorsi3 instruction pattern(s). + ; + + (define_insn "" + [(set (match_operand:SI 0 "r_or_s_operand" "=d,m") + (xor:SI (match_operand:SI 1 "r_or_s_operand" "%0,0") + (match_operand:SI 2 "r_or_s_operand" "g,mi")))] + "TARGET_CHAR_INSTRUCTIONS" + "* + { + check_label_emit (); + if (REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"XR %0,%2\"; + } + if (REG_P (operands[0])) + { + mvs_check_page (0, 4, 0); + return \"X %0,%2\"; + } + CC_STATUS_INIT; + mvs_check_page (0, 6, 0); + return \"XC %O0(4,%R0),%2\"; + }") + + (define_insn "xorsi3" + [(set (match_operand:SI 0 "general_operand" "=d") + (xor:SI (match_operand:SI 1 "general_operand" "%0") + (match_operand:SI 2 "general_operand" "g")))] + "" + "* + { + check_label_emit (); + if (REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"XR %0,%2\"; + } + mvs_check_page (0, 4, 0); + return \"X %0,%2\"; + }") + + ; + ; xorhi3 instruction pattern(s). + ; + + (define_insn "" + [(set (match_operand:HI 0 "r_or_s_operand" "=d,m") + (xor:HI (match_operand:HI 1 "r_or_s_operand" "%0,0") + (match_operand:HI 2 "r_or_s_operand" "di,mi")))] + "TARGET_CHAR_INSTRUCTIONS" + "* + { + check_label_emit (); + if (REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"XR %0,%2\"; + } + if (REG_P (operands[0])) + { + mvs_check_page (0, 4, 0); + return \"X %0,%H2\"; + } + CC_STATUS_INIT; + if (GET_CODE (operands[2]) == CONST_INT) + { + mvs_check_page (0, 6, 2); + return \"XC %O0(2,%R0),=H'%h2'\"; + } + mvs_check_page (0, 6, 0); + return \"XC %O0(2,%R0),%2\"; + }") + + (define_insn "xorhi3" + [(set (match_operand:HI 0 "general_operand" "=d") + (xor:HI (match_operand:HI 1 "general_operand" "%0") + (match_operand:HI 2 "general_operand" "di")))] + "" + "* + { + check_label_emit (); + if (GET_CODE (operands[2]) == CONST_INT) + { + mvs_check_page (0, 4, 0); + return \"X %0,%2\"; + } + mvs_check_page (0, 2, 0); + return \"XR %0,%2\"; + }") + + ; + ; xorqi3 instruction pattern(s). + ; + + (define_insn "" + [(set (match_operand:QI 0 "r_or_s_operand" "=d,m") + (xor:QI (match_operand:QI 1 "r_or_s_operand" "%0,0") + (match_operand:QI 2 "r_or_s_operand" "di,mi")))] + "TARGET_CHAR_INSTRUCTIONS" + "* + { + check_label_emit (); + CC_STATUS_INIT; + if (REG_P (operands[2])) + { + mvs_check_page (0, 2, 0); + return \"XR %0,%2\"; + } + if (REG_P (operands[0])) + { + mvs_check_page (0, 4, 0); + return \"X %0,%2\"; + } + if (GET_CODE (operands[2]) == CONST_INT) + { + mvs_check_page (0, 4, 0); + return \"XI %0,%B2\"; + } + mvs_check_page (0, 6, 0); + return \"XC %O0(1,%R0),%2\"; + }") + + (define_insn "xorqi3" + [(set (match_operand:QI 0 "general_operand" "=d") + (xor:QI (match_operand:QI 1 "general_operand" "%0") + (match_operand:QI 2 "general_operand" "di")))] + "" + "* + { + check_label_emit (); + CC_STATUS_INIT; + if (GET_CODE (operands[2]) == CONST_INT) + { + mvs_check_page (0, 4, 0); + return \"X %0,%2\"; + } + mvs_check_page (0, 2, 0); + return \"XR %0,%2\"; + }") + + ;; + ;;- Negate instructions. + ;; + + ; + ; negsi2 instruction pattern(s). + ; + + (define_insn "negsi2" + [(set (match_operand:SI 0 "general_operand" "=d") + (neg:SI (match_operand:SI 1 "general_operand" "d")))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 2, 0); + return \"LCR %0,%1\"; + }") + + ; + ; neghi2 instruction pattern(s). + ; + + (define_insn "neghi2" + [(set (match_operand:HI 0 "general_operand" "=d") + (neg:HI (match_operand:HI 1 "general_operand" "d")))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 10, 0); + return \"SLL %1,16\;SRA %1,16\;LCR %0,%1\"; + }") + + ; + ; negdf2 instruction pattern(s). + ; + + (define_insn "negdf2" + [(set (match_operand:DF 0 "general_operand" "=f") + (neg:DF (match_operand:DF 1 "general_operand" "f")))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 2, 0); + return \"LCDR %0,%1\"; + }") + + ; + ; negsf2 instruction pattern(s). + ; + + (define_insn "negsf2" + [(set (match_operand:SF 0 "general_operand" "=f") + (neg:SF (match_operand:SF 1 "general_operand" "f")))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 2, 0); + return \"LCER %0,%1\"; + }") + + ;; + ;;- Absolute value instructions. + ;; + + ; + ; abssi2 instruction pattern(s). + ; + + (define_insn "abssi2" + [(set (match_operand:SI 0 "general_operand" "=d") + (abs:SI (match_operand:SI 1 "general_operand" "d")))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 2, 0); + return \"LPR %0,%1\"; + }") + + ; + ; abshi2 instruction pattern(s). + ; + + (define_insn "abshi2" + [(set (match_operand:HI 0 "general_operand" "=d") + (abs:HI (match_operand:HI 1 "general_operand" "d")))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 10, 0); + return \"SLL %1,16\;SRA %1,16\;LPR %0,%1\"; + }") + + ; + ; absdf2 instruction pattern(s). + ; + + (define_insn "absdf2" + [(set (match_operand:DF 0 "general_operand" "=f") + (abs:DF (match_operand:DF 1 "general_operand" "f")))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 2, 0); + return \"LPDR %0,%1\"; + }") + + ; + ; abssf2 instruction pattern(s). + ; + + (define_insn "abssf2" + [(set (match_operand:SF 0 "general_operand" "=f") + (abs:SF (match_operand:SF 1 "general_operand" "f")))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 2, 0); + return \"LPER %0,%1\"; + }") + + ;; + ;;- One complement instructions. + ;; + + ; + ; one_cmpldi2 instruction pattern(s). + ; + + ;(define_expand "one_cmpldi2" + ; [(set (match_operand:DI 0 "general_operand" "") + ; (not:DI (match_operand:DI 1 "general_operand" "")))] + ; "" + ; " + ;{ + ; rtx gen_one_cmplsi2(); + ; + ; emit_insn (gen_one_cmplsi2 (operand_subword (operands[0], 0, 1, DImode), + ; operand_subword (operands[1], 0, 1, DImode))); + ; emit_insn (gen_one_cmplsi2 (gen_lowpart (SImode, operands[0]), + ; gen_lowpart (SImode, operands[1]))); + ; DONE; + ;}") + + ; + ; one_cmplsi2 instruction pattern(s). + ; + + (define_insn "" + [(set (match_operand:SI 0 "r_or_s_operand" "=dm") + (not:SI (match_operand:SI 1 "r_or_s_operand" "0")))] + "TARGET_CHAR_INSTRUCTIONS" + "* + { + check_label_emit (); + if (REG_P (operands[0])) + { + mvs_check_page (0, 4, 4); + return \"X %0,=F'-1'\"; + } + CC_STATUS_INIT; + mvs_check_page (0, 6, 4); + return \"XC %O0(4,%R0),=F'-1'\"; + }") + + (define_insn "one_cmplsi2" + [(set (match_operand:SI 0 "general_operand" "=d") + (not:SI (match_operand:SI 1 "general_operand" "0")))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 4, 4); + return \"X %0,=F'-1'\"; + }") + + ; + ; one_cmplhi2 instruction pattern(s). + ; + + (define_insn "" + [(set (match_operand:HI 0 "r_or_s_operand" "=dm") + (not:HI (match_operand:HI 1 "r_or_s_operand" "0")))] + "TARGET_CHAR_INSTRUCTIONS" + "* + { + check_label_emit (); + if (REG_P (operands[0])) + { + mvs_check_page (0, 4, 4); + return \"X %0,=F'-1'\"; + } + CC_STATUS_INIT; + mvs_check_page (0, 6, 4); + return \"XC %O0(2,%R0),=X'FFFF'\"; + }") + + (define_insn "one_cmplhi2" + [(set (match_operand:HI 0 "general_operand" "=d") + (not:HI (match_operand:HI 1 "general_operand" "0")))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 4, 4); + return \"X %0,=F'-1'\"; + }") + + ; + ; one_cmplqi2 instruction pattern(s). + ; + + (define_insn "" + [(set (match_operand:QI 0 "r_or_s_operand" "=dm") + (not:QI (match_operand:QI 1 "r_or_s_operand" "0")))] + "TARGET_CHAR_INSTRUCTIONS" + "* + { + check_label_emit (); + CC_STATUS_INIT; + if (REG_P (operands[0])) + { + mvs_check_page (0, 4, 4); + return \"X %0,=F'-1'\"; + } + mvs_check_page (0, 4, 0); + return \"XI %0,255\"; + }") + + (define_insn "one_cmplqi2" + [(set (match_operand:QI 0 "general_operand" "=d") + (not:QI (match_operand:QI 1 "general_operand" "0")))] + "" + "* + { + check_label_emit (); + CC_STATUS_INIT; + mvs_check_page (0, 4, 4); + return \"X %0,=F'-1'\"; + }") + + ;; + ;;- Arithmetic shift instructions. + ;; + + ; + ; ashldi3 instruction pattern(s). + ; + + (define_insn "ashldi3" + [(set (match_operand:DI 0 "general_operand" "=d") + (ashift:DI (match_operand:DI 1 "general_operand" "0") + (match_operand:SI 2 "general_operand" "Ja")))] + "" + "* + { + check_label_emit (); + CC_STATUS_INIT; + mvs_check_page (0, 4, 0); + if (REG_P (operands[2])) + return \"SLDA %0,0(%2)\"; + return \"SLDA %0,%c2\"; + }") + + ; + ; ashrdi3 instruction pattern(s). + ; + + (define_insn "ashrdi3" + [(set (match_operand:DI 0 "register_operand" "=d") + (ashiftrt:DI (match_operand:DI 1 "general_operand" "0") + (match_operand:SI 2 "general_operand" "Ja")))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 4, 0); + if (REG_P (operands[2])) + return \"SRDA %0,0(%2)\"; + return \"SRDA %0,%c2\"; + }") + + ; + ; ashlsi3 instruction pattern(s). + ; + + (define_insn "ashlsi3" + [(set (match_operand:SI 0 "general_operand" "=d") + (ashift:SI (match_operand:SI 1 "general_operand" "0") + (match_operand:SI 2 "general_operand" "Ja")))] + "" + "* + { + check_label_emit (); + CC_STATUS_INIT; + mvs_check_page (0, 4, 0); + if (REG_P (operands[2])) + return \"SLL %0,0(%2)\"; + return \"SLL %0,%c2\"; + }") + + ; + ; ashrsi3 instruction pattern(s). + ; + + (define_insn "ashrsi3" + [(set (match_operand:SI 0 "general_operand" "=d") + (ashiftrt:SI (match_operand:SI 1 "general_operand" "0") + (match_operand:SI 2 "general_operand" "Ja")))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 4, 0); + if (REG_P (operands[2])) + return \"SRA %0,0(%2)\"; + return \"SRA %0,%c2\"; + }") + + ; + ; ashlhi3 instruction pattern(s). + ; + + (define_insn "ashlhi3" + [(set (match_operand:HI 0 "general_operand" "=d") + (ashift:HI (match_operand:HI 1 "general_operand" "0") + (match_operand:SI 2 "general_operand" "Ja")))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 8, 0); + if (REG_P (operands[2])) + return \"SLL %0,16(%2)\;SRA %0,16\"; + return \"SLL %0,16+%c2\;SRA %0,16\"; + }") + + ; + ; ashrhi3 instruction pattern(s). + ; + + (define_insn "ashrhi3" + [(set (match_operand:HI 0 "general_operand" "=d") + (ashiftrt:HI (match_operand:HI 1 "general_operand" "0") + (match_operand:SI 2 "general_operand" "Ja")))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 4, 0); + if (REG_P (operands[2])) + return \"SLL %0,16\;SRA %0,16(%2)\"; + return \"SLL %0,16\;SRA %0,16+%c2\"; + }") + + ; + ; ashlqi3 instruction pattern(s). + ; + + (define_insn "ashlqi3" + [(set (match_operand:QI 0 "general_operand" "=d") + (ashift:QI (match_operand:QI 1 "general_operand" "0") + (match_operand:SI 2 "general_operand" "Ja")))] + "" + "* + { + check_label_emit (); + CC_STATUS_INIT; + mvs_check_page (0, 4, 0); + if (REG_P (operands[2])) + return \"SLL %0,0(%2)\"; + return \"SLL %0,%c2\"; + }") + + ; + ; ashrqi3 instruction pattern(s). + ; + + (define_insn "ashrqi3" + [(set (match_operand:QI 0 "general_operand" "=d") + (ashiftrt:QI (match_operand:QI 1 "general_operand" "0") + (match_operand:SI 2 "general_operand" "Ja")))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 8, 0); + if (REG_P (operands[2])) + return \"SLL %0,24\;SRA %0,24(%2)\"; + return \"SLL %0,24\;SRA %0,24+%c2\"; + }") + + ;; + ;;- Logical shift instructions. + ;; + + ; + ; lshldi3 instruction pattern(s). + ; + + (define_insn "lshldi3" + [(set (match_operand:DI 0 "general_operand" "=d") + (lshift:DI (match_operand:DI 1 "general_operand" "0") + (match_operand:SI 2 "general_operand" "Ja")))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 4, 0); + if (REG_P (operands[2])) + return \"SLDL %0,0(%2)\"; + return \"SLDL %0,%c2\"; + }") + + ; + ; lshrdi3 instruction pattern(s). + ; + + (define_insn "lshrdi3" + [(set (match_operand:DI 0 "general_operand" "=d") + (lshiftrt:DI (match_operand:DI 1 "general_operand" "0") + (match_operand:SI 2 "general_operand" "Ja")))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 4, 0); + if (REG_P (operands[2])) + return \"SRDL %0,0(%2)\"; + return \"SRDL %0,%c2\"; + }") + + ; + ; lshlsi3 instruction pattern(s). + ; + + (define_insn "lshlsi3" + [(set (match_operand:SI 0 "general_operand" "=d") + (lshift:SI (match_operand:SI 1 "general_operand" "0") + (match_operand:SI 2 "general_operand" "Ja")))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 4, 0); + if (REG_P (operands[2])) + return \"SLL %0,0(%2)\"; + return \"SLL %0,%c2\"; + }") + + ; + ; lshrsi3 instruction pattern(s). + ; + + (define_insn "lshrsi3" + [(set (match_operand:SI 0 "general_operand" "=d") + (lshiftrt:SI (match_operand:SI 1 "general_operand" "0") + (match_operand:SI 2 "general_operand" "Ja")))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 4, 0); + if (REG_P (operands[2])) + return \"SRL %0,0(%2)\"; + return \"SRL %0,%c2\"; + }") + + ; + ; lshlhi3 instruction pattern(s). + ; + + (define_insn "lshlhi3" + [(set (match_operand:HI 0 "general_operand" "=d") + (lshift:HI (match_operand:HI 1 "general_operand" "0") + (match_operand:SI 2 "general_operand" "Ja")))] + "" + "* + { + check_label_emit (); + CC_STATUS_INIT; + mvs_check_page (0, 4, 0); + if (REG_P (operands[2])) + return \"SLL %0,0(%2)\"; + return \"SLL %0,%c2\"; + }") + + ; + ; lshrhi3 instruction pattern(s). + ; + + (define_insn "lshrhi3" + [(set (match_operand:HI 0 "general_operand" "=d") + (lshiftrt:HI (match_operand:HI 1 "general_operand" "0") + (match_operand:SI 2 "general_operand" "Ja")))] + "" + "* + { + check_label_emit (); + CC_STATUS_INIT; + if (REG_P (operands[2])) + { + mvs_check_page (0, 8, 4); + return \"N %0,=X'0000FFFF'\;SRL %0,0(%2)\"; + } + mvs_check_page (0, 8, 4); + return \"N %0,=X'0000FFFF'\;SRL %0,%c2\"; + }") + + ; + ; lshlqi3 instruction pattern(s). + ; + + (define_insn "lshlqi3" + [(set (match_operand:QI 0 "general_operand" "=d") + (lshift:QI (match_operand:QI 1 "general_operand" "0") + (match_operand:SI 2 "general_operand" "Ja")))] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 4, 0); + if (REG_P (operands[2])) + return \"SLL %0,0(%2)\"; + return \"SLL %0,%c2\"; + }") + + ; + ; lshrqi3 instruction pattern(s). + ; + + (define_insn "lshrqi3" + [(set (match_operand:QI 0 "general_operand" "=d") + (lshiftrt:QI (match_operand:QI 1 "general_operand" "0") + (match_operand:SI 2 "general_operand" "Ja")))] + "" + "* + { + check_label_emit (); + CC_STATUS_INIT; + mvs_check_page (0, 8, 4); + if (REG_P (operands[2])) + return \"N %0,=X'000000FF'\;SRL %0,0(%2)\"; + return \"N %0,=X'000000FF'\;SRL %0,%c2\"; + }") + + ;; + ;;- Conditional jump instructions. + ;; + + ; + ; beq instruction pattern(s). + ; + + (define_insn "beq" + [(set (pc) + (if_then_else (eq (cc0) + (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "* + { + check_label_emit (); + if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) + { + mvs_check_page (0, 6, 4); + return \"L 14,=A(%l0)\;BER 14\"; + } + if (mvs_check_page (0, 4, 0)) + { + mvs_check_page (0, 2, 4); + return \"L 14,=A(%l0)\;BER 14\"; + } + return \"BE %l0\"; + }") + + ; + ; bne instruction pattern(s). + ; + + (define_insn "bne" + [(set (pc) + (if_then_else (ne (cc0) + (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "* + { + check_label_emit (); + if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) + { + mvs_check_page (0, 6, 4); + return \"L 14,=A(%l0)\;BNER 14\"; + } + if (mvs_check_page (0, 4, 0)) + { + mvs_check_page (0, 2, 4); + return \"L 14,=A(%l0)\;BNER 14\"; + } + return \"BNE %l0\"; + }") + + ; + ; bgt instruction pattern(s). + ; + + (define_insn "bgt" + [(set (pc) + (if_then_else (gt (cc0) + (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "* + { + check_label_emit (); + if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) + { + mvs_check_page (0, 6, 4); + return \"L 14,=A(%l0)\;BHR 14\"; + } + if (mvs_check_page (0, 4, 0)) + { + mvs_check_page (0, 2, 4); + return \"L 14,=A(%l0)\;BHR 14\"; + } + return \"BH %l0\"; + }") + + ; + ; bgtu instruction pattern(s). + ; + + (define_insn "bgtu" + [(set (pc) + (if_then_else (gtu (cc0) + (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "* + { + check_label_emit (); + if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) + { + mvs_check_page (0, 6, 4); + return \"L 14,=A(%l0)\;BHR 14\"; + } + if (mvs_check_page (0, 4, 0)) + { + mvs_check_page (0, 2, 4); + return \"L 14,=A(%l0)\;BHR 14\"; + } + return \"BH %l0\"; + }") + + ; + ; blt instruction pattern(s). + ; + + (define_insn "blt" + [(set (pc) + (if_then_else (lt (cc0) + (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "* + { + check_label_emit (); + if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) + { + mvs_check_page (0, 6, 4); + return \"L 14,=A(%l0)\;BLR 14\"; + } + if (mvs_check_page (0, 4, 0)) + { + mvs_check_page (0, 2, 4); + return \"L 14,=A(%l0)\;BLR 14\"; + } + return \"BL %l0\"; + }") + + ; + ; bltu instruction pattern(s). + ; + + (define_insn "bltu" + [(set (pc) + (if_then_else (ltu (cc0) + (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "* + { + check_label_emit (); + if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) + { + mvs_check_page (0, 6, 4); + return \"L 14,=A(%l0)\;BLR 14\"; + } + if (mvs_check_page (0, 4, 0)) + { + mvs_check_page (0, 2, 4); + return \"L 14,=A(%l0)\;BLR 14\"; + } + return \"BL %l0\"; + }") + + ; + ; bge instruction pattern(s). + ; + + (define_insn "bge" + [(set (pc) + (if_then_else (ge (cc0) + (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "* + { + check_label_emit (); + if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) + { + mvs_check_page (0, 6, 4); + return \"L 14,=A(%l0)\;BNLR 14\"; + } + if (mvs_check_page (0, 4, 0)) + { + mvs_check_page (0, 2, 4); + return \"L 14,=A(%l0)\;BNLR 14\"; + } + return \"BNL %l0\"; + }") + + ; + ; bgeu instruction pattern(s). + ; + + (define_insn "bgeu" + [(set (pc) + (if_then_else (geu (cc0) + (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "* + { + check_label_emit (); + if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) + { + mvs_check_page (0, 6, 4); + return \"L 14,=A(%l0)\;BNLR 14\"; + } + if (mvs_check_page (0, 4, 0)) + { + mvs_check_page (0, 2, 4); + return \"L 14,=A(%l0)\;BNLR 14\"; + } + return \"BNL %l0\"; + }") + + ; + ; ble instruction pattern(s). + ; + + (define_insn "ble" + [(set (pc) + (if_then_else (le (cc0) + (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "* + { + check_label_emit (); + if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) + { + mvs_check_page (0, 6, 4); + return \"L 14,=A(%l0)\;BNHR 14\"; + } + if (mvs_check_page (0, 4, 0)) + { + mvs_check_page (0, 2, 4); + return \"L 14,=A(%l0)\;BNHR 14\"; + } + return \"BNH %l0\"; + }") + + ; + ; bleu instruction pattern(s). + ; + + (define_insn "bleu" + [(set (pc) + (if_then_else (leu (cc0) + (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "* + { + check_label_emit (); + if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) + { + mvs_check_page (0, 6, 4); + return \"L 14,=A(%l0)\;BNHR 14\"; + } + if (mvs_check_page (0, 4, 0)) + { + mvs_check_page (0, 2, 4); + return \"L 14,=A(%l0)\;BNHR 14\"; + } + return \"BNH %l0\"; + }") + + ;; + ;;- Negated conditional jump instructions. + ;; + + (define_insn "" + [(set (pc) + (if_then_else (eq (cc0) + (const_int 0)) + (pc) + (label_ref (match_operand 0 "" ""))))] + "" + "* + { + check_label_emit (); + if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) + { + mvs_check_page (0, 6, 4); + return \"L 14,=A(%l0)\;BNER 14\"; + } + if (mvs_check_page (0, 4, 0)) + { + mvs_check_page (0, 2, 4); + return \"L 14,=A(%l0)\;BNER 14\"; + } + return \"BNE %l0\"; + }") + + (define_insn "" + [(set (pc) + (if_then_else (ne (cc0) + (const_int 0)) + (pc) + (label_ref (match_operand 0 "" ""))))] + "" + "* + { + check_label_emit (); + if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) + { + mvs_check_page (0, 6, 4); + return \"L 14,=A(%l0)\;BER 14\"; + } + if (mvs_check_page (0, 4, 0)) + { + mvs_check_page (0, 2, 4); + return \"L 14,=A(%l0)\;BER 14\"; + } + return \"BE %l0\"; + }") + + (define_insn "" + [(set (pc) + (if_then_else (gt (cc0) + (const_int 0)) + (pc) + (label_ref (match_operand 0 "" ""))))] + "" + "* + { + check_label_emit (); + if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) + { + mvs_check_page (0, 6, 4); + return \"L 14,=A(%l0)\;BNHR 14\"; + } + if (mvs_check_page (0, 4, 0)) + { + mvs_check_page (0, 2, 4); + return \"L 14,=A(%l0)\;BNHR 14\"; + } + return \"BNH %l0\"; + }") + + (define_insn "" + [(set (pc) + (if_then_else (gtu (cc0) + (const_int 0)) + (pc) + (label_ref (match_operand 0 "" ""))))] + "" + "* + { + check_label_emit (); + if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) + { + mvs_check_page (0, 6, 4); + return \"L 14,=A(%l0)\;BNHR 14\"; + } + if (mvs_check_page (0, 4, 0)) + { + mvs_check_page (0, 2, 4); + return \"L 14,=A(%l0)\;BNHR 14\"; + } + return \"BNH %l0\"; + }") + + (define_insn "" + [(set (pc) + (if_then_else (lt (cc0) + (const_int 0)) + (pc) + (label_ref (match_operand 0 "" ""))))] + "" + "* + { + check_label_emit (); + if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) + { + mvs_check_page (0, 6, 4); + return \"L 14,=A(%l0)\;BNLR 14\"; + } + if (mvs_check_page (0, 4, 0)) + { + mvs_check_page (0, 2, 4); + return \"L 14,=A(%l0)\;BNLR 14\"; + } + return \"BNL %l0\"; + }") + + (define_insn "" + [(set (pc) + (if_then_else (ltu (cc0) + (const_int 0)) + (pc) + (label_ref (match_operand 0 "" ""))))] + "" + "* + { + check_label_emit (); + if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) + { + mvs_check_page (0, 6, 4); + return \"L 14,=A(%l0)\;BNLR 14\"; + } + if (mvs_check_page (0, 4, 0)) + { + mvs_check_page (0, 2, 4); + return \"L 14,=A(%l0)\;BNLR 14\"; + } + return \"BNL %l0\"; + }") + + (define_insn "" + [(set (pc) + (if_then_else (ge (cc0) + (const_int 0)) + (pc) + (label_ref (match_operand 0 "" ""))))] + "" + "* + { + check_label_emit (); + if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) + { + mvs_check_page (0, 6, 4); + return \"L 14,=A(%l0)\;BLR 14\"; + } + if (mvs_check_page (0, 4, 0)) + { + mvs_check_page (0, 2, 4); + return \"L 14,=A(%l0)\;BLR 14\"; + } + return \"BL %l0\"; + }") + + (define_insn "" + [(set (pc) + (if_then_else (geu (cc0) + (const_int 0)) + (pc) + (label_ref (match_operand 0 "" ""))))] + "" + "* + { + check_label_emit (); + if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) + { + mvs_check_page (0, 6, 4); + return \"L 14,=A(%l0)\;BLR 14\"; + } + if (mvs_check_page (0, 4, 0)) + { + mvs_check_page (0, 2, 4); + return \"L 14,=A(%l0)\;BLR 14\"; + } + return \"BL %l0\"; + }") + + (define_insn "" + [(set (pc) + (if_then_else (le (cc0) + (const_int 0)) + (pc) + (label_ref (match_operand 0 "" ""))))] + "" + "* + { + check_label_emit (); + if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) + { + mvs_check_page (0, 6, 4); + return \"L 14,=A(%l0)\;BHR 14\"; + } + if (mvs_check_page (0, 4, 0)) + { + mvs_check_page (0, 2, 4); + return \"L 14,=A(%l0)\;BHR 14\"; + } + return \"BH %l0\"; + }") + + (define_insn "" + [(set (pc) + (if_then_else (leu (cc0) + (const_int 0)) + (pc) + (label_ref (match_operand 0 "" ""))))] + "" + "* + { + check_label_emit (); + if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) + { + mvs_check_page (0, 6, 4); + return \"L 14,=A(%l0)\;BHR 14\"; + } + if (mvs_check_page (0, 4, 0)) + { + mvs_check_page (0, 2, 4); + return \"L 14,=A(%l0)\;BHR 14\"; + } + return \"BH %l0\"; + }") + + ;; + ;;- Subtract one and jump if not zero. + ;; + + (define_insn "" + [(set (pc) + (if_then_else + (ne (plus:SI (match_operand:SI 0 "register_operand" "+d") + (const_int -1)) + (const_int 0)) + (label_ref (match_operand 1 "" "")) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int -1)))] + "" + "* + { + check_label_emit (); + if (!mvs_check_label (CODE_LABEL_NUMBER (operands[1]))) + { + mvs_check_page (0, 6, 4); + return \"L 14,=A(%l1)\;BCTR %0,14\"; + } + if (mvs_check_page (0, 4, 0)) + { + mvs_check_page (0, 2, 4); + return \"L 14,=A(%l1)\;BCTR %0,14\"; + } + return \"BCT %0,%l1\"; + }") + + (define_insn "" + [(set (pc) + (if_then_else + (eq (plus:SI (match_operand:SI 0 "register_operand" "+d") + (const_int -1)) + (const_int 0)) + (pc) + (label_ref (match_operand 1 "" "")))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int -1)))] + "" + "* + { + check_label_emit (); + if (!mvs_check_label (CODE_LABEL_NUMBER (operands[1]))) + { + mvs_check_page (0, 6, 4); + return \"L 14,=A(%l1)\;BCTR %0,14\"; + } + if (mvs_check_page (0, 4, 0)) + { + mvs_check_page (0, 2, 4); + return \"L 14,=A(%l1)\;BCTR %0,14\"; + } + return \"BCT %0,%l1\"; + }") + + ;; + ;;- Unconditional jump instructions. + ;; + + ; + ; jump instruction pattern(s). + ; + + (define_insn "jump" + [(set (pc) + (label_ref (match_operand 0 "" "")))] + "" + "* + { + check_label_emit (); + if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0]))) + { + mvs_check_page (0, 6, 4); + return \"L 14,=A(%l0)\;BR 14\"; + } + if (mvs_check_page (0, 4, 0)) + { + mvs_check_page (0, 2, 4); + return \"L 14,=A(%l0)\;BR 14\"; + } + return \"B %l0\"; + }") + + ; + ; indirect-jump instruction pattern(s). + ; + + (define_insn "indirect_jump" + [(set (pc) (match_operand:SI 0 "general_operand" "r"))] + "(GET_CODE (operands[0]) != MEM )" + "* + { + check_label_emit (); + mvs_check_page (0, 2, 0); + return \"BR %0\"; + }") + + ; + ; tablejump instruction pattern(s). + ; + + (define_insn "tablejump" + [(set (pc) + (match_operand:SI 0 "general_operand" "am")) + (use (label_ref (match_operand 1 "" "")))] + "" + "* + { + check_label_emit (); + if (REG_P (operands[0])) + { + mvs_check_page (0, 6, 0); + return \"BR %0\;DS 0F\"; + } + mvs_check_page (0, 10, 0); + return \"L 14,%0\;BR 14\;DS 0F\"; + }") + + ;; + ;;- Jump to subroutine. + ;; + ;; For the C/370 environment the internal functions, ie. sqrt, are called with + ;; a non-standard form. So, we must fix it here. There's no BM like IBM. + ;; + + ; + ; call instruction pattern(s). + ; + + (define_insn "call" + [(call (match_operand:QI 0 "memory_operand" "m") + (match_operand:SI 1 "immediate_operand" "i"))] + "" + "* + { + static char temp[128]; + int i = STACK_POINTER_OFFSET; + + check_label_emit (); + if (mvs_function_check (XSTR (operands[0], 0))) + { + mvs_check_page (0, 22, 4); + sprintf ( temp, \"LA 1,136(,13)\;ST 1,%d(,13)\;LA 1,%d(,13)\;L 15,%%0\;BALR 14,15\;LD 0,136(,13)\", + i - 4, i - 4 ); + } + else + { + mvs_check_page (0, 10, 4); + sprintf ( temp, \"LA 1,%d(,13)\;L 15,%%0\;BALR 14,15\", i ); + } + return temp; + }") + + ; + ; call_value instruction pattern(s). + ; + + (define_insn "call_value" + [(set (match_operand 0 "" "rf") + (call (match_operand:QI 1 "memory_operand" "m") + (match_operand:SI 2 "general_operand" "i")))] + "" + "* + { + static char temp[128]; + int i = STACK_POINTER_OFFSET; + + check_label_emit (); + if (mvs_function_check (XSTR (operands[1], 0))) + { + mvs_check_page (0, 22, 4); + sprintf ( temp, \"LA 1,136(,13)\;ST 1,%d(,13)\;LA 1,%d(,13)\;L 15,%%1\;BALR 14,15\;LD 0,136(,13)\", + i - 4, i - 4 ); + } + else + { + mvs_check_page (0, 10, 4); + sprintf ( temp, \"LA 1,%d(,13)\;L 15,%%1\;BALR 14,15\", i ); + } + return temp; + }") + + (define_insn "" + [(call (mem:QI (match_operand:SI 0 "" "i")) + (match_operand:SI 1 "general_operand" "g"))] + "GET_CODE (operands[0]) == SYMBOL_REF" + "* + { + static char temp[128]; + int i = STACK_POINTER_OFFSET; + + check_label_emit (); + if (mvs_function_check (XSTR (operands[0], 0))) + { + mvs_check_page (0, 22, 4); + sprintf ( temp, \"LA 1,136(,13)\;ST 1,%d(,13)\;LA 1,%d(,13)\;L 15,%%0\;BALR 14,15\;LD 0,136(,13)\", + i - 4, i - 4 ); + } + else + { + mvs_check_page (0, 10, 4); + sprintf ( temp, \"LA 1,%d(,13)\;L 15,%%0\;BALR 14,15\", i ); + } + return temp; + }") + + (define_insn "" + [(set (match_operand 0 "" "rf") + (call (mem:QI (match_operand:SI 1 "" "i")) + (match_operand:SI 2 "general_operand" "g")))] + "GET_CODE (operands[1]) == SYMBOL_REF" + "* + { + static char temp[128]; + int i = STACK_POINTER_OFFSET; + + check_label_emit (); + if (mvs_function_check (XSTR (operands[1], 0))) + { + mvs_check_page (0, 22, 4); + sprintf ( temp, \"LA 1,136(,13)\;ST 1,%d(,13)\;LA 1,%d(,13)\;L 15,%%1\;BALR 14,15\;LD 0,136(,13)\", + i - 4, i - 4 ); + } + else + { + mvs_check_page (0, 10, 4); + sprintf ( temp, \"LA 1,%d(,13)\;L 15,%%1\;BALR 14,15\", i ); + } + return temp; + }") + + + ;; + ;;- Miscellaneous instructions. + ;; + + ; + ; nop instruction pattern(s). + ; + + (define_insn "nop" + [(const_int 0)] + "" + "* + { + check_label_emit (); + mvs_check_page (0, 2, 0); + return \"LR 0,0\"; + }") + diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i370/mvs.h gcc-2.5.0/config/i370/mvs.h *** gcc-2.4.5/config/i370/mvs.h --- gcc-2.5.0/config/i370/mvs.h Sun Oct 3 15:42:13 1993 *************** *** 0 **** --- 1,1498 ---- + /* Definitions of target machine for GNU compiler. System/370 version. + Copyright (C) 1989, 1993 Free Software Foundation, Inc. + Contributed by Jan Stein (jan@cd.chalmers.se). + Modified for C/370 MVS by Dave Pitts (pitts@mcdata.com) + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + #ifdef sun + #include + #include + #endif + #include + + #define TARGET_VERSION printf (" (370/MVS)"); + + /* Names to predefine in the preprocessor for this target machine. */ + + #define CPP_PREDEFINES "-DGCC -Dgcc -DMVS -Dmvs -Asystem(mvs) -Acpu(i370) -Amachine(i370)" + + /* Run-time compilation parameters selecting different hardware subsets. */ + + extern int target_flags; + + /* The sizes of the code and literals on the current page. */ + + extern int mvs_page_code, mvs_page_lit; + + /* The current page number and the base page number for the function. */ + + extern int mvs_page_num, function_base_page; + + /* True if a label has been emitted. */ + + extern int mvs_label_emited; + + /* The name of the current function. */ + + extern char *mvs_function_name; + + /* The length of the function name malloc'd area. */ + + extern int mvs_function_name_length; + + /* The amount of space used for outgoing arguments. */ + + extern int current_function_outgoing_args_size; + + /* Compile using char instructins (mvc, nc, oc, xc). On 4341 use this since + these are more than twice as fast as load-op-store. + On 3090 don't use this since load-op-store is much faster. */ + + #define TARGET_CHAR_INSTRUCTIONS (target_flags & 1) + + /* Default target switches */ + + #define TARGET_DEFAULT 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 \ + { { "char-instructions", 1}, \ + { "no-char-instructions", -1}, \ + { "", TARGET_DEFAULT} } + + /* Target machine storage layout */ + + /* Define this if most significant bit is lowest numbered in instructions + that operate on numbered bit-fields. */ + + #define BITS_BIG_ENDIAN 1 + + /* Define this if most significant byte of a word is the lowest numbered. */ + + #define BYTES_BIG_ENDIAN 1 + + /* Define this if MS word of a multiword is the lowest numbered. */ + + #define WORDS_BIG_ENDIAN 1 + + /* 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. */ + + #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 + + /* There is no point aligning anything to a rounder boundary than this. */ + + #define BIGGEST_ALIGNMENT 64 + + /* Alignment of field after `int : 0' in a structure. */ + + #define EMPTY_FIELD_BOUNDARY 32 + + /* Define this if move instructions will actually fail to work when given + unaligned data. */ + + #define STRICT_ALIGNMENT 0 + + /* Define target floating point format. */ + + #define TARGET_FLOAT_FORMAT IBM_FLOAT_FORMAT + + /* Define character mapping for cross-compiling. */ + + #define TARGET_EBCDIC 1 + + #ifdef HOST_EBCDIC + #define MAP_CHARACTER(c) ((char)(c)) + #else + #define MAP_CHARACTER(c) ((char)mvs_map_char (c)) + #endif + + /* Define maximum length of page minus page escape overhead. */ + + #define MAX_MVS_PAGE_LENGTH 4080 + + /* Define if special allocation order desired. */ + + #define REG_ALLOC_ORDER \ + { 0, 1, 2, 3, 14, 15, 12, 10, 9, 8, 7, 6, 5, 4, 16, 17, 18, 19, 11, 13 } + + /* 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. + For the 370, we give the data registers numbers 0-15, + and the floating point registers numbers 16-19. */ + + #define FIRST_PSEUDO_REGISTER 20 + + /* Define base and page registers. */ + + #define BASE_REGISTER 3 + #define PAGE_REGISTER 4 + + /* 1 for registers that have pervasive standard uses and are not available + for the register allocator. On the 370 under C/370, R13 is stack (DSA) + pointer, R12 is the TCA pointer, R3 is the base register, R4 is the page + origin table pointer and R11 is the arg pointer. */ + + #define FIXED_REGISTERS \ + { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0 } + /*0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19*/ + + /* 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. + NOTE: all floating registers are undefined across calls. */ + + #define CALL_USED_REGISTERS \ + { 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 } + /*0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19*/ + + /* 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. */ + + #define HARD_REGNO_NREGS(REGNO, MODE) \ + ((REGNO) > 15 ? 1 : (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 370, the cpu registers can hold QI, HI, SI, SF and DF. The + even registers can hold DI. The floating point registers can hold + either SF or DF. */ + + #define HARD_REGNO_MODE_OK(REGNO, MODE) \ + ((REGNO) < 16 ? ((REGNO) & 1) == 0 || (MODE) != DImode \ + : (MODE) == SFmode || (MODE) == DFmode) + + /* 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) \ + (((MODE1) == SFmode || (MODE1) == DFmode) \ + == ((MODE2) == SFmode || (MODE2) == DFmode)) + + /* Mark external references. */ + + #define ENCODE_SECTION_INFO(decl) \ + if (DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)) \ + SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1; + + /* Specify the registers used for certain standard purposes. + The values of these macros are register numbers. */ + + /* 370 PC isn't overloaded on a register. */ + + /* #define PC_REGNUM */ + + /* Register to use for pushing function arguments. */ + + #define STACK_POINTER_REGNUM 13 + + /* Base register for access to local variables of the function. */ + + #define FRAME_POINTER_REGNUM 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. */ + + #define FRAME_POINTER_REQUIRED 1 + + /* Base register for access to arguments of the function. */ + + #define ARG_POINTER_REGNUM 11 + + /* Register in which static-chain is passed to a function. */ + + #define STATIC_CHAIN_REGNUM 10 + + /* Register in which address to store a structure value is passed to + a function. */ + + #define STRUCT_VALUE_REGNUM 1 + + /* 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. */ + + enum reg_class + { + NO_REGS, ADDR_REGS, DATA_REGS, + FP_REGS, ALL_REGS, LIM_REG_CLASSES + }; + + #define GENERAL_REGS DATA_REGS + #define N_REG_CLASSES (int) LIM_REG_CLASSES + + /* Give names of register classes as strings for dump file. */ + + #define REG_CLASS_NAMES \ + { "NO_REGS", "ADDR_REGS", "DATA_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, 0x0fffe, 0x0ffff, 0xf0000, 0xfffff} + + /* 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) >= 16 ? FP_REGS : (REGNO) != 0 ? ADDR_REGS : DATA_REGS) + + /* The class value for index registers, and the one for base regs. */ + + #define INDEX_REG_CLASS ADDR_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) \ + ((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 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. */ + + #define CONST_OK_FOR_LETTER_P(VALUE, C) \ + ((C) == 'I' ? (unsigned) (VALUE) < 256 : \ + (C) == 'J' ? (unsigned) (VALUE) < 4096 : \ + (C) == 'K' ? (VALUE) >= -32768 && (VALUE) < 32768 : 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) 1 + + /* 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) \ + (GET_CODE(X) == CONST_DOUBLE ? FP_REGS : \ + GET_CODE(X) == CONST_INT ? DATA_REGS : \ + GET_CODE(X) == LABEL_REF || \ + GET_CODE(X) == SYMBOL_REF || \ + GET_CODE(X) == CONST ? ADDR_REGS : (CLASS)) + + /* Return the maximum number of consecutive registers needed to represent + mode MODE in a register of class CLASS. */ + + #define CLASS_MAX_NREGS(CLASS, MODE) \ + ((CLASS) == FP_REGS ? 1 : \ + (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) + + /* 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 \ + (STACK_POINTER_OFFSET + current_function_outgoing_args_size) + + #define INITIAL_FRAME_POINTER_OFFSET(DEPTH) (DEPTH) = STARTING_FRAME_OFFSET + + /* If we generate an insn to push BYTES bytes, this says how many the stack + pointer really advances by. On the 370, we have no push instruction. */ + + /* #define PUSH_ROUNDING(BYTES) */ + + /* Accumulate the outgoing argument count so we can request the right + DSA size and determine stack offset. */ + + #define ACCUMULATE_OUTGOING_ARGS + + /* Define offset from stack pointer, to location where a parm can be + pushed. */ + + #define STACK_POINTER_OFFSET 148 + + /* Offset of first parameter from the argument pointer register value. */ + + #define FIRST_PARM_OFFSET(FNDECL) 0 + + /* 1 if N is a possible register number for function argument passing. + On the 370, no registers are used in this way. */ + + #define FUNCTION_ARG_REGNO_P(N) 0 + + /* 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. */ + + #define CUMULATIVE_ARGS int + + /* 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, LIBNAME) ((CUM) = 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) += ((MODE) == DFmode || (MODE) == SFmode \ + ? 256 \ + : (MODE) != BLKmode \ + ? (GET_MODE_SIZE (MODE) + 3) / 4 \ + : (int_size_in_bytes (TYPE) + 3) / 4)) + + /* Define where to put the arguments to a function. Value is zero to push + the argument on the stack, or a hard register in which to store the + argument. */ + + #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) 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 + + /* Define if returning from a function call automatically pops the + arguments described by the number-of-args field in the call. */ + + #define RETURN_POPS_ARGS(FUNTYPE, STACKSIZE) 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 15. */ + + #define RET_REG(MODE) ((MODE) == DFmode || (MODE) == SFmode ? 16 : 15) + + /* On the 370 the return value is in R15 or R16. */ + + #define FUNCTION_VALUE(VALTYPE, FUNC) \ + gen_rtx(REG, TYPE_MODE (VALTYPE), RET_REG(TYPE_MODE(VALTYPE))) + + /* 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, RET_REG(MODE)) + + /* 1 if N is a possible register number for a function value. + On the 370 under C/370, R15 and R16 are thus used. */ + + #define FUNCTION_VALUE_REGNO_P(N) ((N) == 15 || (N) == 16) + + /* This macro definition sets up a default value for `main' to return. */ + + #define DEFAULT_MAIN_RETURN c_expand_return (integer_zero_node) + + /* This macro generates the assembly code for function entry. + All of the C/370 environment is preserved. */ + + #define FUNCTION_PROLOGUE(FILE, LSIZE) \ + { \ + static int function_label_index = 1; \ + static int function_first = 0; \ + static int function_year, function_month, function_day; \ + static int function_hour, function_minute, function_second; \ + int i; \ + if (!function_first) \ + { \ + struct tm *function_time; \ + time_t lcltime; \ + time (&lcltime); \ + function_time = localtime (&lcltime); \ + function_year = function_time->tm_year + 1900; \ + function_month = function_time->tm_mon + 1; \ + function_day = function_time->tm_mday; \ + function_hour = function_time->tm_hour; \ + function_minute = function_time->tm_min; \ + function_second = function_time->tm_sec; \ + } \ + fprintf (FILE, "\tUSING\t*,15\n"); \ + fprintf (FILE, "\tB\tFPL%03d\n", function_label_index); \ + fprintf (FILE, "\tDC\tAL1(FPL%03d+4-*)\n", function_label_index + 1); \ + fprintf (FILE, "\tDC\tX'CE',X'A0',X'10'\n"); \ + fprintf (FILE, "\tDC\tA($PPA2)\n"); \ + fprintf (FILE, "\tDC\tF'%d'\n", 0); \ + fprintf (FILE, "\tDC\tF'%d'\n", STACK_POINTER_OFFSET + LSIZE \ + + current_function_outgoing_args_size); \ + fprintf (FILE, "FPL%03d\tEQU\t*\n", function_label_index + 1); \ + fprintf (FILE, "\tDC\tAL2(%d),C'%s'\n", strlen (mvs_function_name), \ + mvs_function_name); \ + fprintf (FILE, "\tDS\t0F\n"); \ + if (!function_first) \ + { \ + fprintf (FILE, "$PPA2\tEQU\t*\n"); \ + fprintf (FILE, "\tDC\tX'03',X'00',X'33',X'00'\n"); \ + fprintf (FILE, "\tDC\tV(CEESTART),A(0)\n"); \ + fprintf (FILE, "\tDC\tA($TIMES)\n"); \ + fprintf (FILE, "\tDS\t0F\n"); \ + fprintf (FILE, "$TIMES\tEQU\t*\n"); \ + fprintf (FILE, "\tDC\tCL4'%d',CL4'%02d%02d',CL6'%02d%02d00'\n", \ + function_year, function_month, function_day, \ + function_hour, function_minute, function_second); \ + fprintf (FILE, "\tDC\tCL2'01',CL4'0100'\n"); \ + } \ + fprintf (FILE, "\tDS\t0H\n"); \ + fprintf (FILE, "FPL%03d\tEQU\t*\n", function_label_index); \ + fprintf (FILE, "\tSTM\t14,12,12(13)\n"); \ + fprintf (FILE, "\tL\t2,76(,13)\n"); \ + fprintf (FILE, "\tL\t0,16(,15)\n"); \ + fprintf (FILE, "\tALR\t0,2\n"); \ + fprintf (FILE, "\tCL\t0,12(,12)\n"); \ + fprintf (FILE, "\tBNH\t*+10\n"); \ + fprintf (FILE, "\tL\t15,116(,12)\n"); \ + fprintf (FILE, "\tBALR\t14,15\n"); \ + fprintf (FILE, "\tL\t15,72(,13)\n"); \ + fprintf (FILE, "\tSTM\t15,0,72(2)\n"); \ + fprintf (FILE, "\tMVI\t0(2),X'10'\n"); \ + fprintf (FILE, "\tST\t13,4(,2)\n "); \ + fprintf (FILE, "\tLR\t13,2\n"); \ + fprintf (FILE, "\tLR\t11,1\n"); \ + fprintf (FILE, "\tDROP\t15\n"); \ + fprintf (FILE, "\tBALR\t%d,0\n", BASE_REGISTER); \ + fprintf (FILE, "PG%d\tEQU\t*\n", mvs_page_num ); \ + fprintf (FILE, "\tUSING\t*,%d\n", BASE_REGISTER); \ + fprintf (FILE, "\tL\t%d,=A(PGT%d)\n", PAGE_REGISTER, mvs_page_num); \ + mvs_page_code = 4; \ + mvs_page_lit = 4; \ + mvs_check_page (FILE, 0, 0); \ + function_base_page = mvs_page_num; \ + function_first = 1; \ + function_label_index += 2; \ + } + + #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ + { \ + if (strlen (NAME) * 2 > mvs_function_name_length) \ + { \ + if (mvs_function_name) \ + free (mvs_function_name); \ + mvs_function_name = 0; \ + } \ + if (!mvs_function_name) \ + { \ + mvs_function_name_length = strlen (NAME) * 2; \ + mvs_function_name = (char *) malloc (mvs_function_name_length); \ + if (mvs_function_name == 0) \ + { \ + fatal ("virtual memory exceeded"); \ + abort (); \ + } \ + } \ + if (!strcmp (NAME, "main")) \ + strcpy (mvs_function_name, "gccmain"); \ + else \ + strcpy (mvs_function_name, NAME); \ + fprintf (FILE, "\tDS\t0H\n"); \ + assemble_name (FILE, mvs_function_name); \ + fputs ("\tCSECT\n", FILE); \ + } + + /* 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, LSIZE) \ + { \ + int i; \ + check_label_emit(); \ + mvs_check_page (FILE,14,0); \ + fprintf (FILE, "\tL\t13,4(,13)\n"); \ + fprintf (FILE, "\tL\t14,12(,13)\n"); \ + fprintf (FILE, "\tLM\t2,12,28(13)\n"); \ + fprintf (FILE, "\tBALR\t1,14\n"); \ + fprintf (FILE, "\tDC\tA("); \ + mvs_page_num++; \ + assemble_name (FILE, mvs_function_name); \ + fprintf (FILE, ")\n" ); \ + fprintf (FILE, "\tDS\t0F\n" ); \ + fprintf (FILE, "\tLTORG\n"); \ + fprintf (FILE, "\tDS\t0F\n"); \ + fprintf (FILE, "PGT%d\tEQU\t*\n", function_base_page); \ + mvs_free_label(); \ + for ( i = function_base_page; i < mvs_page_num; i++ ) \ + fprintf (FILE, "\tDC\tA(PG%d)\n", i); \ + } + + /* Output assembler code for a block containing the constant parts of a + trampoline, leaving space for the variable parts. + + On the 370, the trampoline contains these instructions: + + BALR 14,0 + USING *,14 + L STATIC_CHAIN_REGISTER,X + L 15,Y + BR 15 + X DS 0F + Y DS 0F */ + + #define TRAMPOLINE_TEMPLATE(FILE) \ + { \ + ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x05E0)); \ + ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x5800 | \ + STATIC_CHAIN_REGNUM << 4)); \ + ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0xE00A)); \ + ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x58F0)); \ + ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0xE00E)); \ + ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x07FF)); \ + ASM_OUTPUT_SHORT (FILE, const0_rtx); \ + ASM_OUTPUT_SHORT (FILE, const0_rtx); \ + ASM_OUTPUT_SHORT (FILE, const0_rtx); \ + ASM_OUTPUT_SHORT (FILE, const0_rtx); \ + } + + /* Length in units of the trampoline for entering a nested function. */ + + #define TRAMPOLINE_SIZE 20 + + /* Emit RTL insns to initialize the variable parts of a trampoline. */ + + #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ + { \ + emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 12)), CXT); \ + emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 16)), FNADDR); \ + } + + /* Output assembler code to FILE to increment profiler label # LABELNO + for profiling a function entry. */ + + #define FUNCTION_PROFILER(FILE, LABELNO) \ + fprintf (FILE, "Error: No profiling availble.\n") + + /* Define EXIT_IGNORE_STACK if, when returning from a function, the stack + pointer does not matter (provided there is a frame pointer). */ + + #define EXIT_IGNORE_STACK 1 + + /* Addressing modes, and classification of registers for them. */ + + /* #define HAVE_POST_INCREMENT */ + /* #define HAVE_POST_DECREMENT */ + + /* #define HAVE_PRE_DECREMENT */ + /* #define HAVE_PRE_INCREMENT */ + + /* 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. + These definitions are NOT overridden anywhere. */ + + #define REGNO_OK_FOR_INDEX_P(REGNO) \ + (((REGNO) > 0 && (REGNO) < 16) \ + || (reg_renumber[REGNO] > 0 && reg_renumber[REGNO] < 16)) + + #define REGNO_OK_FOR_BASE_P(REGNO) REGNO_OK_FOR_INDEX_P(REGNO) + + #define REGNO_OK_FOR_DATA_P(REGNO) \ + ((REGNO) < 16 || (unsigned) reg_renumber[REGNO] < 16) + + #define REGNO_OK_FOR_FP_P(REGNO) \ + ((unsigned) ((REGNO) - 16) < 4 || (unsigned) (reg_renumber[REGNO] - 16) < 4) + + /* Now macros that check whether X is a register and also, + strictly, whether it is in a specified class. */ + + /* 1 if X is a data register. */ + + #define DATA_REG_P(X) (REG_P (X) && REGNO_OK_FOR_DATA_P (REGNO (X))) + + /* 1 if X is an fp register. */ + + #define FP_REG_P(X) (REG_P (X) && REGNO_OK_FOR_FP_P (REGNO (X))) + + /* 1 if X is an address register. */ + + #define ADDRESS_REG_P(X) (REG_P (X) && REGNO_OK_FOR_BASE_P (REGNO (X))) + + /* 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) \ + (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ + || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE \ + || (GET_CODE (X) == CONST \ + && GET_CODE (XEXP (XEXP (X, 0), 0)) == LABEL_REF) \ + || (GET_CODE (X) == CONST \ + && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF \ + && !SYMBOL_REF_FLAG (XEXP (XEXP (X, 0), 0)))) + + /* 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 all. 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. + Some source files that are used after register allocation + need to be strict. */ + + #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) \ + ((REGNO(X) > 0 && REGNO(X) < 16) || REGNO(X) >= 20) + + /* 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) REG_OK_FOR_INDEX_P(X) + + #else /* REG_OK_STRICT */ + + /* 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 /* REG_OK_STRICT */ + + /* 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. */ + + #define COUNT_REGS(X, REGS, FAIL) \ + if (REG_P (X) && REG_OK_FOR_BASE_P (X)) \ + REGS += 1; \ + else if (GET_CODE (X) != CONST_INT || (unsigned) INTVAL (X) >= 4096) \ + goto FAIL; + + #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ + { \ + if (REG_P (X) && REG_OK_FOR_BASE_P (X)) \ + goto ADDR; \ + if (GET_CODE (X) == PLUS) \ + { \ + int regs = 0; \ + rtx x0 = XEXP (X, 0); \ + rtx x1 = XEXP (X, 1); \ + if (GET_CODE (x0) == PLUS) \ + { \ + COUNT_REGS (XEXP (x0, 0), regs, FAIL); \ + COUNT_REGS (XEXP (x0, 1), regs, FAIL); \ + COUNT_REGS (x1, regs, FAIL); \ + if (regs == 2) \ + goto ADDR; \ + } \ + else if (GET_CODE (x1) == PLUS) \ + { \ + COUNT_REGS (x0, regs, FAIL); \ + COUNT_REGS (XEXP (x1, 0), regs, FAIL); \ + COUNT_REGS (XEXP (x1, 1), regs, FAIL); \ + if (regs == 2) \ + goto ADDR; \ + } \ + else \ + { \ + COUNT_REGS (x0, regs, FAIL); \ + COUNT_REGS (x1, regs, FAIL); \ + if (regs != 0) \ + goto ADDR; \ + } \ + } \ + FAIL: ; \ + } + + /* The 370 has no mode dependent addresses. */ + + #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) + + /* 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. */ + + #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \ + { \ + if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 1))) \ + (X) = gen_rtx (PLUS, SImode, XEXP (X, 0), \ + copy_to_mode_reg (SImode, XEXP (X, 1))); \ + if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 0))) \ + (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, 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 (memory_address_p (MODE, X)) \ + goto WIN; \ + } + + /* 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 + + /* Define this if fixuns_trunc is the same as fix_trunc. */ + + #define FIXUNS_TRUNC_LIKE_FIX_TRUNC + + /* We use "unsigned char" as default. */ + + #define DEFAULT_SIGNED_CHAR 0 + + /* This is the kind of divide that is easiest to do in the general case. */ + + #define EASY_DIV_EXPR TRUNC_DIV_EXPR + + /* Max number of bytes we can move from memory to memory in one reasonably + fast instruction. */ + + #define MOVE_MAX 256 + + /* Define this if zero-extension is slow (more than one real instruction). */ + + #define SLOW_ZERO_EXTEND + + /* Nonzero if access to memory by bytes is slow and undesirable. */ + + #define SLOW_BYTE_ACCESS 1 + + /* 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) (OUTPREC != 16) + + /* We assume that the store-condition-codes instructions store 0 for false + and some other value for true. This is the value stored for true. */ + + /* #define STORE_FLAG_VALUE -1 */ + + /* When a prototype says `char' or `short', really pass an `int'. */ + + #define PROMOTE_PROTOTYPES + + /* Don't perform CSE on function addresses. */ + + #define NO_FUNCTION_CSE + + /* 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, OUTERCODE) \ + case CONST_INT: \ + if ((unsigned) INTVAL (RTX) < 0xfff) return 1; \ + case CONST: \ + case LABEL_REF: \ + case SYMBOL_REF: \ + return 2; \ + case CONST_DOUBLE: \ + return 4; + + /* Tell final.c how to eliminate redundant test instructions. */ + + /* Here we define machine-dependent flags and fields in cc_status + (see `conditions.h'). */ + + /* 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 370, load insns do not alter the cc's. However, in some + cases these instructions can make it possibly invalid to use the + saved cc's. In those cases we clear out some or all of the saved + cc's so they won't be used. */ + + #define NOTICE_UPDATE_CC(EXP, INSN) \ + { \ + rtx exp = (EXP); \ + if (GET_CODE (exp) == PARALLEL) /* Check this */ \ + exp = XVECEXP (exp, 0, 0); \ + if (GET_CODE (exp) != SET) \ + CC_STATUS_INIT; \ + else \ + { \ + if (XEXP (exp, 0) == cc0_rtx) \ + { \ + cc_status.value1 = XEXP (exp, 0); \ + cc_status.value2 = XEXP (exp, 1); \ + cc_status.flags = 0; \ + } \ + else \ + { \ + if (cc_status.value1 \ + && reg_mentioned_p (XEXP (exp, 0), cc_status.value1)) \ + cc_status.value1 = 0; \ + if (cc_status.value2 \ + && reg_mentioned_p (XEXP (exp, 0), cc_status.value2)) \ + cc_status.value2 = 0; \ + switch (GET_CODE (XEXP (exp, 1))) \ + { \ + case PLUS: case MINUS: case MULT: /* case UMULT: */ \ + case DIV: case UDIV: case NEG: case ASHIFT: \ + case ASHIFTRT: case AND: case IOR: case XOR: \ + case ABS: case NOT: \ + CC_STATUS_SET (XEXP (exp, 0), XEXP (exp, 1)); \ + } \ + } \ + } \ + } + + + #define CC_STATUS_SET(V1, V2) \ + { \ + cc_status.flags = 0; \ + cc_status.value1 = (V1); \ + cc_status.value2 = (V2); \ + if (cc_status.value1 \ + && reg_mentioned_p (cc_status.value1, cc_status.value2)) \ + cc_status.value2 = 0; \ + } + + #define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV) \ + { if (cc_status.flags & CC_NO_OVERFLOW) return NO_OV; return NORMAL; } + + /* Control the assembler format that we output. */ + + #define TEXT_SECTION_ASM_OP "* Program text area" + #define DATA_SECTION_ASM_OP "* Program data area" + #define INIT_SECTION_ASM_OP "* Program initialization area" + #define CTOR_LIST_BEGIN /* NO OP */ + #define CTOR_LIST_END /* NO OP */ + + /* How to refer to registers in assembler output. This sequence is + indexed by compiler's hard-register-number (see above). */ + + #define REGISTER_NAMES \ + { "0", "1", "2", "3", "4", "5", "6", "7", \ + "8", "9", "10", "11", "12", "13", "14", "15", \ + "0", "2", "4", "6" \ + } + + /* How to renumber registers for dbx and gdb. */ + + #define DBX_REGISTER_NUMBER(REGNO) (REGNO) + + #define ASM_FILE_START(FILE) fputs ("\tCSECT\n", FILE); + #define ASM_FILE_END(FILE) fputs ("\tEND\n", FILE); + #define ASM_IDENTIFY_GCC(FILE) + #define ASM_COMMENT_START "*" + #define ASM_APP_OFF "" + #define ASM_APP_ON "" + + #define ASM_OUTPUT_LABEL(FILE, NAME) \ + { assemble_name (FILE, NAME); fputs ("\tEQU\t*\n", FILE); } + + #define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) /* NO OP */ + + #define ASM_GLOBALIZE_LABEL(FILE, NAME) \ + { fputs ("\tENTRY\t", FILE); assemble_name (FILE, NAME); fputs ("\n", FILE); } + + /* MVS externals are limited to 8 characters, upper case only. + The '_' is mapped to '@', except for MVS functions, then '#'. */ + + #define MAX_MVS_LABEL_SIZE 8 + + #define ASM_OUTPUT_LABELREF(FILE, NAME) \ + { \ + char *bp, ch, temp[MAX_MVS_LABEL_SIZE + 1]; \ + if (strlen (NAME) > MAX_MVS_LABEL_SIZE) \ + { \ + strncpy (temp, NAME, MAX_MVS_LABEL_SIZE); \ + temp[MAX_MVS_LABEL_SIZE] = '\0'; \ + } \ + else \ + strcpy (temp,NAME); \ + if (!strcmp (temp,"main")) \ + strcpy (temp,"gccmain"); \ + if (mvs_function_check (temp)) \ + ch = '#'; \ + else \ + ch = '@'; \ + for (bp = temp; *bp; bp++) \ + { \ + if (islower (*bp)) *bp = toupper (*bp); \ + if (*bp == '_') *bp = ch; \ + } \ + fprintf (FILE, "%s", temp); \ + } + + #define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \ + sprintf (LABEL, "*%s%d", PREFIX, NUM) + + /* Generate internal label. Since we can branch here from off page, we + must reload the base register. */ + + #define ASM_OUTPUT_INTERNAL_LABEL(FILE, PREFIX, NUM) \ + { \ + if (!strcmp (PREFIX,"L")) \ + { \ + mvs_add_label(NUM); \ + mvs_label_emited = 1; \ + } \ + fprintf (FILE, "%s%d\tEQU\t*\n", PREFIX, NUM); \ + } + + /* Generate case label. */ + + #define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, TABLE) \ + fprintf (FILE, "%s%d\tEQU\t*\n", PREFIX, NUM) + + /* This is how to output an element of a case-vector that is absolute. */ + + #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ + mvs_check_page (FILE, 4, 0); \ + fprintf (FILE, "\tDC\tA(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) \ + mvs_check_page (FILE, 4, 0); \ + fprintf (FILE, "\tDC\tA(L%d-L%d)\n", VALUE, REL) + + /* 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) \ + mvs_check_page (FILE, 8, 4); \ + fprintf (FILE, "\tS\t13,=F'4'\n\tST\t%s,%d(13)\n", \ + reg_names[REGNO], STACK_POINTER_OFFSET) + + /* 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) \ + mvs_check_page (FILE, 8, 0); \ + fprintf (FILE, "\tL\t%s,%d(13)\n\tLA\t13,4(13)\n", \ + reg_names[REGNO], STACK_POINTER_OFFSET) + + /* This is how to output an assembler line defining a `double' constant. */ + + #define ASM_OUTPUT_DOUBLE(FILE, VALUE) \ + fprintf (FILE, "\tDC\tD'%.18G'\n", (VALUE)) + + /* This is how to output an assembler line defining a `float' constant. */ + + #define ASM_OUTPUT_FLOAT(FILE, VALUE) \ + fprintf (FILE, "\tDC\tE'%.9G'\n", (VALUE)) + + /* This outputs an integer, if not a CONST_INT must be address constant. */ + + #define ASM_OUTPUT_INT(FILE, EXP) \ + { \ + if (GET_CODE (EXP) == CONST_INT) \ + { \ + fprintf (FILE, "\tDC\tF'"); \ + output_addr_const (FILE, EXP); \ + fprintf (FILE, "'\n"); \ + } \ + else \ + { \ + fprintf (FILE, "\tDC\tA("); \ + output_addr_const (FILE, EXP); \ + fprintf (FILE, ")\n"); \ + } \ + } + + /* This outputs a short integer. */ + + #define ASM_OUTPUT_SHORT(FILE, EXP) \ + { \ + fprintf (FILE, "\tDC\tH'"); \ + output_addr_const (FILE, EXP); \ + fprintf (FILE, "'\n"); \ + } + + /* This outputs a byte sized integer. */ + + #define ASM_OUTPUT_CHAR(FILE, EXP) \ + fprintf (FILE, "\tDC\tX'%02X'\n", INTVAL (EXP) ) + + #define ASM_OUTPUT_BYTE(FILE, VALUE) \ + fprintf (FILE, "\tDC\tX'%02X'\n", VALUE) + + /* This outputs a text string. The string are chopped up to fit into + an 80 byte record. Also, control and special characters, interpreted + by the IBM assembler, are output numerically. */ + + #define MVS_ASCII_TEXT_LENGTH 48 + + #define ASM_OUTPUT_ASCII(FILE, PTR, LEN) \ + { \ + int i, j; \ + int c; \ + for (j = 0, i = 0; i < LEN; j++, i++) \ + { \ + c = PTR[i]; \ + if (iscntrl (c) || c == '&') \ + { \ + if (j % MVS_ASCII_TEXT_LENGTH != 0 ) \ + fprintf (FILE, "'\n"); \ + j = -1; \ + if (c == '&') c = MAP_CHARACTER (c); \ + fprintf (FILE, "\tDC\tX'%X'\n", c ); \ + } \ + else \ + { \ + if (j % MVS_ASCII_TEXT_LENGTH == 0) \ + fprintf (FILE, "\tDC\tC'%c", c); \ + else \ + { \ + if ( c == '\'' ) \ + fprintf (FILE, "%c%c", c, c); \ + else \ + fprintf (FILE, "%c", c); \ + if (j % MVS_ASCII_TEXT_LENGTH \ + == MVS_ASCII_TEXT_LENGTH - 1) \ + fprintf (FILE, "'\n" ); \ + } \ + } \ + } \ + if (j % MVS_ASCII_TEXT_LENGTH != 0) \ + fprintf (FILE, "'\n"); \ + } + + /* 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) \ + { \ + if ((LOG) == 1) \ + fprintf (FILE, "\tDS\t0H\n" ); \ + else \ + fprintf (FILE, "\tDS\t0F\n" ); \ + } \ + + /* The maximum length of memory that the IBM assembler will allow in one + DS operation. */ + + #define MAX_CHUNK 32767 + + /* A C statement to output to the stdio stream FILE an assembler + instruction to advance the location counter by SIZE bytes. Those + bytes should be zero when loaded. */ + + #define ASM_OUTPUT_SKIP(FILE, SIZE) \ + { \ + int s, k; \ + for (s = (SIZE); s > 0; s -= MAX_CHUNK) \ + { \ + if (s > MAX_CHUNK) \ + k = MAX_CHUNK; \ + else \ + k = s; \ + fprintf (FILE, "\tDS\tXL%d\n", k); \ + } \ + } + + /* A C statement (sans semicolon) to output to the stdio stream + FILE the assembler definition of a common-label named NAME whose + size is SIZE bytes. The variable ROUNDED is the size rounded up + to whatever alignment the caller wants. */ + + #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ + { \ + fputs ("\tENTRY\t", FILE); \ + assemble_name (FILE, NAME); \ + fputs ("\n", FILE); \ + fprintf (FILE, "\tDS\t0F\n"); \ + ASM_OUTPUT_LABEL (FILE,NAME); \ + ASM_OUTPUT_SKIP (FILE,SIZE); \ + } + + /* A C statement (sans semicolon) to output to the stdio stream + FILE the assembler definition of a local-common-label named NAME + whose size is SIZE bytes. The variable ROUNDED is the size + rounded up to whatever alignment the caller wants. */ + + #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ + { \ + fprintf (FILE, "\tDS\t0F\n"); \ + ASM_OUTPUT_LABEL (FILE,NAME); \ + ASM_OUTPUT_SKIP (FILE,SIZE); \ + } + + /* 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 47 + #define TARGET_BS 22 + #define TARGET_TAB 5 + #define TARGET_NEWLINE 21 + #define TARGET_VT 11 + #define TARGET_FF 12 + #define TARGET_CR 13 + + /* 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. */ + + #define PRINT_OPERAND(FILE, X, CODE) \ + { \ + switch (GET_CODE (X)) \ + { \ + static char curreg[4]; \ + case REG: \ + if (CODE == 'N') \ + strcpy (curreg, reg_names[REGNO (X) + 1]); \ + else \ + strcpy (curreg, reg_names[REGNO (X)]); \ + fprintf (FILE, "%s", curreg); \ + break; \ + case MEM: \ + { \ + rtx addr = XEXP (X, 0); \ + if (CODE == 'O') \ + { \ + if (GET_CODE (addr) == PLUS) \ + fprintf (FILE, "%d", INTVAL (XEXP (addr, 1))); \ + else \ + fprintf (FILE, "0"); \ + } \ + else if (CODE == 'R') \ + { \ + if (GET_CODE (addr) == PLUS) \ + fprintf (FILE, "%s", reg_names[REGNO (XEXP (addr, 0))]);\ + else \ + fprintf (FILE, "%s", reg_names[REGNO (addr)]); \ + } \ + else \ + output_address (XEXP (X, 0)); \ + } \ + break; \ + case SYMBOL_REF: \ + case LABEL_REF: \ + mvs_page_lit += 4; \ + if (SYMBOL_REF_FLAG (X)) fprintf (FILE, "=V("); \ + else fprintf (FILE, "=A("); \ + output_addr_const (FILE, X); \ + fprintf (FILE, ")"); \ + break; \ + case CONST_INT: \ + if (CODE == 'B') \ + fprintf (FILE, "%d", INTVAL (X) & 0xff); \ + else if (CODE == 'X') \ + fprintf (FILE, "%02X", INTVAL (X) & 0xff); \ + else if (CODE == 'h') \ + fprintf (FILE, "%d", (INTVAL (X) << 16) >> 16); \ + else if (CODE == 'H') \ + { \ + mvs_page_lit += 4; \ + fprintf (FILE, "=F'%d'", (INTVAL (X) << 16) >> 16); \ + } \ + else \ + { \ + mvs_page_lit += 4; \ + fprintf (FILE, "=F'%d'", INTVAL (X)); \ + } \ + break; \ + case CONST_DOUBLE: \ + if (GET_MODE (X) == DImode) \ + { \ + if (CODE == 'M') \ + { \ + mvs_page_lit += 4; \ + fprintf (FILE, "=XL4'%08X'", CONST_DOUBLE_LOW (X)); \ + } \ + else if (CODE == 'L') \ + { \ + mvs_page_lit += 4; \ + fprintf (FILE, "=XL4'%08X'", CONST_DOUBLE_HIGH (X)); \ + } \ + else \ + { \ + mvs_page_lit += 8; \ + fprintf (FILE, "=XL8'%08X%08X'", CONST_DOUBLE_LOW (X), \ + CONST_DOUBLE_HIGH (X)); \ + } \ + } \ + else \ + { \ + union { double d; int i[2]; } u; \ + u.i[0] = CONST_DOUBLE_LOW (X); \ + u.i[1] = CONST_DOUBLE_HIGH (X); \ + if (GET_MODE (X) == SFmode) \ + { \ + mvs_page_lit += 4; \ + fprintf (FILE, "=E'%.9G'", u.d); \ + } \ + else \ + { \ + mvs_page_lit += 8; \ + fprintf (FILE, "=D'%.18G'", u.d); \ + } \ + } \ + break; \ + case CONST: \ + if (GET_CODE (XEXP (X, 0)) == PLUS \ + && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF) \ + { \ + mvs_page_lit += 4; \ + if (SYMBOL_REF_FLAG (XEXP (XEXP (X, 0), 0))) \ + { \ + fprintf (FILE, "=V("); \ + ASM_OUTPUT_LABELREF (FILE, \ + XSTR (XEXP (XEXP (X, 0), 0), 0)); \ + fprintf (FILE, ")\n\tA\t%s,=F'%d'", curreg, \ + INTVAL (XEXP (XEXP (X, 0), 1))); \ + } \ + else \ + { \ + fprintf (FILE, "=A("); \ + output_addr_const (FILE, X); \ + fprintf (FILE, ")"); \ + } \ + } \ + else \ + { \ + mvs_page_lit += 4; \ + fprintf (FILE, "=F'"); \ + output_addr_const (FILE, X); \ + fprintf (FILE, "'"); \ + } \ + break; \ + default: \ + abort(); \ + } \ + } + + #define PRINT_OPERAND_ADDRESS(FILE, ADDR) \ + { \ + rtx breg, xreg, offset, plus; \ + \ + switch (GET_CODE (ADDR)) \ + { \ + case REG: \ + fprintf (FILE, "0(%s)", reg_names[REGNO (ADDR)]); \ + break; \ + case PLUS: \ + breg = 0; \ + xreg = 0; \ + offset = 0; \ + if (GET_CODE (XEXP (ADDR, 0)) == PLUS) \ + { \ + if (GET_CODE (XEXP (ADDR, 1)) == REG) \ + breg = XEXP (ADDR, 1); \ + else \ + offset = XEXP (ADDR, 1); \ + plus = XEXP (ADDR, 0); \ + } \ + else \ + { \ + if (GET_CODE (XEXP (ADDR, 0)) == REG) \ + breg = XEXP (ADDR, 0); \ + else \ + offset = XEXP (ADDR, 0); \ + plus = XEXP (ADDR, 1); \ + } \ + if (GET_CODE (plus) == PLUS) \ + { \ + if (GET_CODE (XEXP (plus, 0)) == REG) \ + { \ + if (breg) \ + xreg = XEXP (plus, 0); \ + else \ + breg = XEXP (plus, 0); \ + } \ + else \ + { \ + offset = XEXP (plus, 0); \ + } \ + if (GET_CODE (XEXP (plus, 1)) == REG) \ + { \ + if (breg) \ + xreg = XEXP (plus, 1); \ + else \ + breg = XEXP (plus, 1); \ + } \ + else \ + { \ + offset = XEXP (plus, 1); \ + } \ + } \ + else if (GET_CODE (plus) == REG) \ + { \ + if (breg) \ + xreg = plus; \ + else \ + breg = plus; \ + } \ + else \ + { \ + offset = plus; \ + } \ + if (offset) \ + { \ + if (GET_CODE (offset) == LABEL_REF) \ + fprintf (FILE, "L%d", \ + CODE_LABEL_NUMBER (XEXP (offset, 0))); \ + else \ + output_addr_const (FILE, offset); \ + } \ + else \ + fprintf (FILE, "0"); \ + if (xreg) \ + fprintf (FILE, "(%s,%s)", \ + reg_names[REGNO (xreg)], reg_names[REGNO (breg)]); \ + else \ + fprintf (FILE, "(%s)", reg_names[REGNO (breg)]); \ + break; \ + default: \ + mvs_page_lit += 4; \ + if (SYMBOL_REF_FLAG (ADDR)) fprintf (FILE, "=V("); \ + else fprintf (FILE, "=A("); \ + output_addr_const (FILE, ADDR); \ + fprintf (FILE, ")"); \ + break; \ + } \ + } diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i370/mvs370.c gcc-2.5.0/config/i370/mvs370.c *** gcc-2.4.5/config/i370/mvs370.c --- gcc-2.5.0/config/i370/mvs370.c Sun Oct 3 15:42:29 1993 *************** *** 0 **** --- 1,481 ---- + /* Subroutines for insn-output.c for System/370. + Copyright (C) 1989, 1993 Free Software Foundation, Inc. + Contributed by Jan Stein (jan@cd.chalmers.se). + Modified for MVS C/370 by Dave Pitts (pitts@mcdata.com) + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + #include + #include + #include + #include "config.h" + #include "rtl.h" + #include "regs.h" + #include "hard-reg-set.h" + #include "real.h" + #include "insn-config.h" + #include "conditions.h" + #include "insn-flags.h" + #include "output.h" + #include "insn-attr.h" + #include "flags.h" + #include "recog.h" + + + /* Label node, this structure is used to keep track of labels on the + current page. */ + typedef struct label_node + { + struct label_node *label_next; + int label_id; + int label_page; + } + label_node_t; + + /* Is 1 when a label has been generated and the base register must be + reloaded. */ + int mvs_label_emited = 0; + + /* Current function starting base page. */ + int function_base_page; + + /* Length of the current page code. */ + int mvs_page_code; + + /* Length of the current page literals. */ + int mvs_page_lit; + + /* Current function name. */ + char *mvs_function_name = 0; + + /* Current function name length. */ + int mvs_function_name_length = 0; + + /* Page number for multi-page functions. */ + int mvs_page_num = 0; + + /* Label node list anchor. */ + static label_node_t *label_anchor = 0; + + /* Label node free list anchor. */ + static label_node_t *free_anchor = 0; + + /* Assembler source file decriptor. */ + static FILE *assembler_source = 0; + + /* Define the length of the internal MVS function table. */ + #define MVS_FUNCTION_TABLE_LENGTH 32 + + /* C/370 internal function table. These functions use non-standard linkage + and must handled in a special manner. */ + static char *mvs_function_table[MVS_FUNCTION_TABLE_LENGTH] = + { + "ceil", "edc_acos", "edc_asin", "edc_ata2", "edc_atan", "edc_cos", + "edc_cosh", "edc_erf", "edc_erfc", "edc_exp", "edc_gamm", "edc_lg10", + "edc_log", "edc_sin", "edc_sinh", "edc_sqrt", "edc_tan", "edc_tanh", + "fabs", "floor", "fmod", "frexp", "hypot", "j0", + "j1", "jn", "ldexp", "modf", "pow", "y0", + "y1", "yn" + }; + + /* ASCII to EBCDIC conversion table. */ + #if defined(TARGET_EBCDIC) && !defined(HOST_EBCDIC) + static unsigned char ascebc[256] = + { + /*00 NL SH SX EX ET NQ AK BL */ + 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F, + /*08 BS HT LF VT FF CR SO SI */ + 0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + /*10 DL D1 D2 D3 D4 NK SN EB */ + 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26, + /*18 CN EM SB EC FS GS RS US */ + 0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F, + /*20 SP ! " # $ % & ' */ + 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, + /*28 ( ) * + , - . / */ + 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61, + /*30 0 1 2 3 4 5 6 7 */ + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + /*38 8 9 : ; < = > ? */ + 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F, + /*40 @ A B C D E F G */ + 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + /*48 H I J K L M N O */ + 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, + /*50 P Q R S T U V W */ + 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, + /*58 X Y Z [ \ ] ^ _ */ + 0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D, + /*60 ` a b c d e f g */ + 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + /*68 h i j k l m n o */ + 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, + /*70 p q r s t u v w */ + 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + /*78 x y z { | } ~ DL */ + 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xFF + }; + #endif + + /* EBCDIC to ASCII conversion table. */ + #if defined(HOST_EBCDIC) && !defined(TARGET_EBCDIC) + unsigned char ebcasc[256] = + { + /*00 NU SH SX EX PF HT LC DL */ + 0x00, 0x01, 0x02, 0x03, 0x00, 0x09, 0x00, 0x7F, + /*08 SM VT FF CR SO SI */ + 0x00, 0x00, 0x00, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + /*10 DE D1 D2 TM RS NL BS IL */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x0A, 0x08, 0x00, + /*18 CN EM CC C1 FS GS RS US */ + 0x18, 0x19, 0x00, 0x00, 0x1C, 0x1D, 0x1E, 0x1F, + /*20 DS SS FS BP LF EB EC */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x17, 0x1B, + /*28 SM C2 EQ AK BL */ + 0x00, 0x00, 0x00, 0x00, 0x05, 0x06, 0x07, 0x00, + /*30 SY PN RS UC ET */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + /*38 C3 D4 NK SU */ + 0x00, 0x00, 0x00, 0x00, 0x14, 0x15, 0x00, 0x1A, + /*40 SP */ + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /*48 . < ( + | */ + 0x00, 0x00, 0x00, 0x2E, 0x3C, 0x28, 0x2B, 0x7C, + /*50 & */ + 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /*58 ! $ * ) ; ^ */ + 0x00, 0x00, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E, + /*60 - / */ + 0x2D, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /*68 , % _ > ? */ + 0x00, 0x00, 0x00, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, + /*70 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /*78 ` : # @ ' = " */ + 0x00, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, + /*80 a b c d e f g */ + 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + /*88 h i { */ + 0x68, 0x69, 0x00, 0x7B, 0x00, 0x00, 0x00, 0x00, + /*90 j k l m n o p */ + 0x00, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, + /*98 q r } */ + 0x71, 0x72, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x00, + /*A0 ~ s t u v w x */ + 0x00, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + /*A8 y z [ */ + 0x79, 0x7A, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, + /*B0 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /*B8 ] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x00, 0x00, + /*C0 { A B C D E F G */ + 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + /*C8 H I */ + 0x48, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /*D0 } J K L M N O P */ + 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, + /*D8 Q R */ + 0x51, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /*E0 \ S T U V W X */ + 0x5C, 0x00, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + /*E8 Y Z */ + 0x59, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /*F0 0 1 2 3 4 5 6 7 */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + /*F8 8 9 */ + 0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF + }; + #endif + + /* Map characters from one character set to another. + C is the character to be translated. */ + + char + mvs_map_char (c) + char c; + { + #if defined(TARGET_EBCDIC) && !defined(HOST_EBCDIC) + return ascebc[c]; + #else + #if defined(HOST_EBCDIC) && !defined(TARGET_EBCDIC) + return ebcasc[c]; + #else + return c; + #endif + #endif + } + + /* Emit reload of base register if indicated. This is to eliminate multiple + reloads when several labels are generated pointing to the same place + in the code. */ + + int + check_label_emit (void) + { + if (mvs_label_emited) + { + mvs_label_emited = 0; + mvs_page_code += 4; + fprintf (assembler_source, "\tL\t%d,%d(,%d)\n", + BASE_REGISTER, (mvs_page_num - function_base_page) * 4, + PAGE_REGISTER); + } + } + + /* Add the label to the current page label list. If a free element is available + it will be used for the new label. Otherwise, a label element will be + allocated from memory. + ID is the label number of the label being added to the list. */ + + int + mvs_add_label (id) + int id; + { + label_node_t *lp; + + if (free_anchor) + { + lp = free_anchor; + free_anchor = lp->label_next; + } + else + { + lp = (label_node_t *) malloc (sizeof (label_node_t)); + if (lp == 0) + { + fatal ("virtual memory exhausted\n"); + abort (); + } + } + lp->label_id = id; + lp->label_page = mvs_page_num; + lp->label_next = label_anchor; + label_anchor = lp; + } + + /* Check to see if the label is in the list. If 1 is returned then a load + and branch on register must be generated. + ID is the label number of the label being checked. */ + + int + mvs_check_label (id) + int id; + { + label_node_t *lp; + + for (lp = label_anchor; lp; lp = lp->label_next) + { + if (lp->label_id == id) + return 1; + } + return 0; + } + + /* The label list for the current page freed by linking the list onto the free + label element chain. */ + + int + mvs_free_label (void) + { + if (label_anchor) + { + if (free_anchor) + label_anchor->label_next = free_anchor; + free_anchor = label_anchor; + } + label_anchor = 0; + } + + /* If the page size limit is reached a new code page is started, and the base + register is set to it. This page break point is counted conservatively, + most literals that have the same value are collapsed by the assembler. + True is returned when a new page is started. + FILE is the assembler output file descriptor. + CODE is the length, in bytes, of the instruction to be emitted. + LIT is the length of the literal to be emitted. */ + + int + mvs_check_page (file, code, lit) + FILE *file; + int code, lit; + { + if (file) + assembler_source = file; + + if (mvs_page_code + code + mvs_page_lit + lit > MAX_MVS_PAGE_LENGTH) + { + fprintf (assembler_source, "\tB\tPGE%d\n", mvs_page_num); + fprintf (assembler_source, "\tDS\t0F\n"); + fprintf (assembler_source, "\tLTORG\n"); + fprintf (assembler_source, "\tDS\t0F\n"); + fprintf (assembler_source, "PGE%d\tEQU\t*\n", mvs_page_num); + fprintf (assembler_source, "\tDROP\t%d\n", BASE_REGISTER); + mvs_page_num++; + fprintf (assembler_source, "\tBALR\t%d,0\n", BASE_REGISTER); + fprintf (assembler_source, "PG%d\tEQU\t*\n", mvs_page_num); + fprintf (assembler_source, "\tUSING\t*,%d\n", BASE_REGISTER); + mvs_free_label (); + mvs_page_code = code; + mvs_page_lit = lit; + return 1; + } + mvs_page_code += code; + mvs_page_lit += lit; + return 0; + } + + /* Check for C/370 runtime function, they don't use standard calling + conventions. True is returned if the function is in the table. + NAME is the name of the current function. */ + + int + mvs_function_check (name) + char *name; + { + int lower, middle, upper; + int i; + + lower = 0; + upper = MVS_FUNCTION_TABLE_LENGTH - 1; + while (lower <= upper) + { + middle = (lower + upper) / 2; + i = strcmp (name, mvs_function_table[middle]); + if (i == 0) + return 1; + if (i < 0) + upper = middle - 1; + else + lower = middle + 1; + } + return 0; + } + + + /* Return 1 if OP is a valid S operand for an RS, SI or SS type instruction. + OP is the current operation. + MODE is the current operation mode. */ + + int + s_operand (op, mode) + register rtx op; + enum machine_mode mode; + { + extern int volatile_ok; + register enum rtx_code code = GET_CODE (op); + + if (CONSTANT_ADDRESS_P (op)) + return 1; + if (mode == VOIDmode || GET_MODE (op) != mode) + return 0; + if (code == MEM) + { + register rtx x = XEXP (op, 0); + + if (!volatile_ok && op->volatil) + return 0; + if (REG_P (x) && REG_OK_FOR_BASE_P (x)) + return 1; + if (GET_CODE (x) == PLUS + && REG_P (XEXP (x, 0)) && REG_OK_FOR_BASE_P (XEXP (x, 0)) + && GET_CODE (XEXP (x, 1)) == CONST_INT + && (unsigned) INTVAL (XEXP (x, 1)) < 4096) + return 1; + } + return 0; + } + + + /* Return 1 if OP is a valid R or S operand for an RS, SI or SS type + instruction. + OP is the current operation. + MODE is the current operation mode. */ + + int + r_or_s_operand (op, mode) + register rtx op; + enum machine_mode mode; + { + extern int volatile_ok; + register enum rtx_code code = GET_CODE (op); + + if (CONSTANT_ADDRESS_P (op)) + return 1; + if (mode == VOIDmode || GET_MODE (op) != mode) + return 0; + if (code == REG) + return 1; + else if (code == MEM) + { + register rtx x = XEXP (op, 0); + + if (!volatile_ok && op->volatil) + return 0; + if (REG_P (x) && REG_OK_FOR_BASE_P (x)) + return 1; + if (GET_CODE (x) == PLUS + && REG_P (XEXP (x, 0)) && REG_OK_FOR_BASE_P (XEXP (x, 0)) + && GET_CODE (XEXP (x, 1)) == CONST_INT + && (unsigned) INTVAL (XEXP (x, 1)) < 4096) + return 1; + } + return 0; + } + + + /* Return 1 if the next instruction is an unsigned jump instruction. + INSN is the current instruction. */ + + unsigned_jump_follows_p (insn) + register rtx insn; + { + insn = NEXT_INSN (insn); + if (GET_CODE (insn) != JUMP_INSN) + return 0; + + insn = XEXP (insn, 3); + if (GET_CODE (insn) != SET) + return 0; + + if (GET_CODE (XEXP (insn, 0)) != PC) + return 0; + + insn = XEXP (insn, 1); + if (GET_CODE (insn) != IF_THEN_ELSE) + return 0; + + insn = XEXP (insn, 0); + return GET_CODE (insn) != GE && GET_CODE (insn) != GT + && GET_CODE (insn) != LE && GET_CODE (insn) != LT; + } diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i370/xm-mvs.h gcc-2.5.0/config/i370/xm-mvs.h *** gcc-2.4.5/config/i370/xm-mvs.h --- gcc-2.5.0/config/i370/xm-mvs.h Sat Jun 26 11:38:45 1993 *************** *** 0 **** --- 1,56 ---- + /* Configuration for GNU C-compiler for System/370. + Copyright (C) 1989, 1993 Free Software Foundation, Inc. + Contributed by Jan Stein (jan@cd.chalmers.se). + Modifed for MVS C/370 by Dave Pitts (pitts@mcdata.com) + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 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 + #define HOST_FLOAT_FORMAT IBM_FLOAT_FORMAT + #define HOST_EBCDIC 1 + + #define USG + #ifndef MVS + #define MVS + #endif + + /* 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) + + /* Arguments to use with `exit'. */ + + #define SUCCESS_EXIT_CODE 0 + #define FATAL_EXIT_CODE 12 + + #define NO_DBX_FORMAT + diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/386bsd.h gcc-2.5.0/config/i386/386bsd.h *** gcc-2.4.5/config/i386/386bsd.h Tue Mar 23 14:19:58 1993 --- gcc-2.5.0/config/i386/386bsd.h Sat Oct 2 04:18:12 1993 *************** *** 10,14 **** #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dunix -Di386 -D____386BSD____ -D__386BSD__ -DBSD_NET2" /* Like the default, except no -lg. */ --- 10,14 ---- #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dunix -Di386 -D____386BSD____ -D__386BSD__ -DBSD_NET2 -Asystem(unix) -Asystem(bsd) -Acpu(i386) -Amachine(i386)" /* Like the default, except no -lg. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/aix386ng.h gcc-2.5.0/config/i386/aix386ng.h *** gcc-2.4.5/config/i386/aix386ng.h Thu Jun 17 16:19:00 1993 --- gcc-2.5.0/config/i386/aix386ng.h Sat Oct 2 04:18:14 1993 *************** *** 44,48 **** /* Specify predefined symbols in preprocessor. */ ! #define CPP_PREDEFINES "-Dps2 -Dunix -Di386" #define CPP_SPEC \ --- 44,48 ---- /* Specify predefined symbols in preprocessor. */ ! #define CPP_PREDEFINES "-Dps2 -Dunix -Di386 -Asystem(unix) -Asystem(aix) -Acpu(i386) -Amachine(i386)" #define CPP_SPEC \ *************** *** 58,62 **** #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); \ --- 58,64 ---- #undef ASM_FILE_START #define ASM_FILE_START(FILE) \ ! do { fprintf (FILE, "\t.file\t"); \ ! output_quoted_string (FILE, dump_base_name); \ ! fprintf (FILE, "\n"); \ if (optimize) \ ASM_FILE_START_1 (FILE); \ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/att.h gcc-2.5.0/config/i386/att.h *** gcc-2.4.5/config/i386/att.h Sun Dec 27 15:50:36 1992 --- gcc-2.5.0/config/i386/att.h Fri Sep 24 00:57:44 1993 *************** *** 38,41 **** --- 38,42 ---- #define ASM_OUTPUT_ASCII(FILE, p, size) \ + do \ { int i = 0; \ while (i < (size)) \ *************** *** 42,48 **** { if (i%10 == 0) { if (i!=0) fprintf ((FILE), "\n"); \ fprintf ((FILE), "%s ", ASM_BYTE_OP); } \ ! else fprintf ((FILE), ","); \ fprintf ((FILE), "0x%x", ((p)[i++] & 0377)) ;} \ ! fprintf ((FILE), "\n"); } /* Do use .optim by default on this machine. */ --- 43,50 ---- { if (i%10 == 0) { if (i!=0) fprintf ((FILE), "\n"); \ fprintf ((FILE), "%s ", ASM_BYTE_OP); } \ ! else fprintf ((FILE), ","); \ fprintf ((FILE), "0x%x", ((p)[i++] & 0377)) ;} \ ! fprintf ((FILE), "\n"); \ ! } while (0) /* Do use .optim by default on this machine. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/bsd.h gcc-2.5.0/config/i386/bsd.h *** gcc-2.4.5/config/i386/bsd.h Mon Jan 4 23:46:20 1993 --- gcc-2.5.0/config/i386/bsd.h Sun Oct 3 19:50:23 1993 *************** *** 49,53 **** #define ASM_FILE_START(FILE) \ ! fprintf (FILE, "\t.file\t\"%s\"\n", dump_base_name); /* This was suggested, but it shouldn't be right for DBX output. -- RMS --- 49,56 ---- #define ASM_FILE_START(FILE) \ ! do { fprintf (FILE, "\t.file\t"); \ ! output_quoted_string (FILE, dump_base_name); \ ! fprintf (FILE, "\n"); \ ! } while (0) /* This was suggested, but it shouldn't be right for DBX output. -- RMS *************** *** 125,132 **** /* Don't split DBX symbols into continuations. */ #define DBX_CONTIN_LENGTH 0 - - /* This is how to output an assembler line defining a `double' constant. */ - - #undef ASM_OUTPUT_DOUBLE - #define ASM_OUTPUT_DOUBLE(FILE,VALUE) \ - fprintf (FILE, "\t.double 0d%.20e\n", (VALUE)) --- 128,129 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/gas.h gcc-2.5.0/config/i386/gas.h *** gcc-2.4.5/config/i386/gas.h Wed Dec 30 00:24:59 1992 --- gcc-2.5.0/config/i386/gas.h Sat Oct 2 04:18:17 1993 *************** *** 1,4 **** /* Definitions for Intel 386 running system V with gnu tools ! Copyright (C) 1988 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,4 ---- /* Definitions for Intel 386 running system V with gnu tools ! Copyright (C) 1988, 1993 Free Software Foundation, Inc. This file is part of GNU CC. *************** *** 56,60 **** /* Specify predefined symbols in preprocessor. */ ! #define CPP_PREDEFINES "-Dunix -Di386" #define CPP_SPEC "%{posix:-D_POSIX_SOURCE}" --- 56,60 ---- /* Specify predefined symbols in preprocessor. */ ! #define CPP_PREDEFINES "-Dunix -Di386 -Asystem(unix) -Acpu(i386) -Amachine(i386)" #define CPP_SPEC "%{posix:-D_POSIX_SOURCE}" *************** *** 95,99 **** #undef ASM_FILE_START #define ASM_FILE_START(FILE) \ ! fprintf (FILE, "\t.file\t\"%s\"\n", dump_base_name); /* A C statement or statements which output an assembler instruction --- 95,102 ---- #undef ASM_FILE_START #define ASM_FILE_START(FILE) \ ! do { fprintf (FILE, "\t.file\t"); \ ! output_quoted_string (FILE, dump_base_name); \ ! fprintf (FILE, "\n"); \ ! } while (0) /* A C statement or statements which output an assembler instruction diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/go32.h gcc-2.5.0/config/i386/go32.h *** gcc-2.4.5/config/i386/go32.h Fri Apr 9 17:40:31 1993 --- gcc-2.5.0/config/i386/go32.h Sat Oct 2 04:18:20 1993 *************** *** 8,10 **** #undef CPP_PREDEFINES #endif ! #define CPP_PREDEFINES "-Dunix -Di386 -DGO32 -DMSDOS" --- 8,11 ---- #undef CPP_PREDEFINES #endif ! #define CPP_PREDEFINES "-Dunix -Di386 -DGO32 -DMSDOS \ ! -Asystem(unix) -Asystem(msdos) -Acpu(i386) -Amachine(i386)" diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/i386.c gcc-2.5.0/config/i386/i386.c *** gcc-2.4.5/config/i386/i386.c Sat Jun 19 18:33:39 1993 --- gcc-2.5.0/config/i386/i386.c Sun Oct 10 19:11:31 1993 *************** *** 32,35 **** --- 32,36 ---- #include "tree.h" #include "flags.h" + #include "function.h" #ifdef EXTRA_CONSTRAINT *************** *** 99,111 **** { rtx xops[4]; xops[0] = src; xops[1] = AT_SP (Pmode); ! xops[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (src))); xops[3] = stack_pointer_rtx; ! if (GET_MODE_SIZE (GET_MODE (src)) > UNITS_PER_WORD) { ! rtx high = gen_rtx (REG, SImode, REGNO (src) + 1); output_asm_insn (AS1 (push%L0,%0), &high); } --- 100,119 ---- { rtx xops[4]; + int size = GET_MODE_SIZE (GET_MODE (src)); xops[0] = src; xops[1] = AT_SP (Pmode); ! xops[2] = GEN_INT (size); xops[3] = stack_pointer_rtx; ! if (size > UNITS_PER_WORD) { ! rtx high; ! if (size > 2 * UNITS_PER_WORD) ! { ! high = gen_rtx (REG, SImode, REGNO (src) + 2); ! output_asm_insn (AS1 (push%L0,%0), &high); ! } ! high = gen_rtx (REG, SImode, REGNO (src) + 1); output_asm_insn (AS1 (push%L0,%0), &high); } *************** *** 128,135 **** { rtx xops[4]; xops[0] = AT_SP (Pmode); xops[1] = stack_pointer_rtx; ! xops[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (dest))); xops[3] = dest; --- 136,144 ---- { rtx xops[4]; + int size = GET_MODE_SIZE (GET_MODE (dest)); xops[0] = AT_SP (Pmode); xops[1] = stack_pointer_rtx; ! xops[2] = GEN_INT (size); xops[3] = dest; *************** *** 148,152 **** output_asm_insn (AS1 (fstp%z3,%y0), xops); else ! output_asm_insn (AS1 (fst%z3,%y0), xops); } else --- 157,169 ---- output_asm_insn (AS1 (fstp%z3,%y0), xops); else ! { ! if (GET_MODE (dest) == XFmode) ! { ! output_asm_insn (AS1 (fstp%z3,%y0), xops); ! output_asm_insn (AS1 (fld%z3,%y0), xops); ! } ! else ! output_asm_insn (AS1 (fst%z3,%y0), xops); ! } } else *************** *** 155,162 **** output_asm_insn (AS1 (pop%L0,%0), &dest); ! if (GET_MODE_SIZE (GET_MODE (dest)) > UNITS_PER_WORD) { dest = gen_rtx (REG, SImode, REGNO (dest) + 1); output_asm_insn (AS1 (pop%L0,%0), &dest); } } --- 172,184 ---- output_asm_insn (AS1 (pop%L0,%0), &dest); ! if (size > UNITS_PER_WORD) { dest = gen_rtx (REG, SImode, REGNO (dest) + 1); output_asm_insn (AS1 (pop%L0,%0), &dest); + if (size > 2 * UNITS_PER_WORD) + { + dest = gen_rtx (REG, SImode, REGNO (dest) + 1); + output_asm_insn (AS1 (pop%L0,%0), &dest); + } } } *************** *** 244,249 **** --- 266,277 ---- enum {REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1; rtx latehalf[2]; + rtx middlehalf[2]; + rtx xops[2]; rtx addreg0 = 0, addreg1 = 0; int dest_overlapped_low = 0; + int size = GET_MODE_SIZE (GET_MODE (operands[1])); + + middlehalf[0] = 0; + middlehalf[1] = 0; /* First classify both operands. */ *************** *** 290,303 **** if (optype0 == PUSHOP && optype1 == POPOP) { operands[0] = XEXP (XEXP (operands[0], 0), 0); ! asm_add (-8, operands[0]); ! operands[0] = gen_rtx (MEM, DImode, operands[0]); optype0 = OFFSOP; } if (optype0 == POPOP && optype1 == PUSHOP) { operands[1] = XEXP (XEXP (operands[1], 0), 0); ! asm_add (-8, operands[1]); ! operands[1] = gen_rtx (MEM, DImode, operands[1]); optype1 = OFFSOP; } --- 318,344 ---- if (optype0 == PUSHOP && optype1 == POPOP) { + /* ??? Can this ever happen on i386? */ operands[0] = XEXP (XEXP (operands[0], 0), 0); ! asm_add (-size, operands[0]); ! if (GET_MODE (operands[1]) == XFmode) ! operands[0] = gen_rtx (MEM, XFmode, operands[0]); ! else if (GET_MODE (operands[0]) == DFmode) ! operands[0] = gen_rtx (MEM, DFmode, operands[0]); ! else ! operands[0] = gen_rtx (MEM, DImode, operands[0]); optype0 = OFFSOP; } + if (optype0 == POPOP && optype1 == PUSHOP) { + /* ??? Can this ever happen on i386? */ operands[1] = XEXP (XEXP (operands[1], 0), 0); ! asm_add (-size, operands[1]); ! if (GET_MODE (operands[1]) == XFmode) ! operands[1] = gen_rtx (MEM, XFmode, operands[1]); ! else if (GET_MODE (operands[1]) == DFmode) ! operands[1] = gen_rtx (MEM, DFmode, operands[1]); ! else ! operands[1] = gen_rtx (MEM, DImode, operands[1]); optype1 = OFFSOP; } *************** *** 321,349 **** 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 (GET_CODE (operands[1]) == CONST_DOUBLE) ! split_double (operands[1], &operands[1], &latehalf[1]); ! else if (CONSTANT_P (operands[1])) { ! if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0) ! latehalf[1] = constm1_rtx; ! else ! latehalf[1] = const0_rtx; } } ! else ! latehalf[1] = operands[1]; /* If insn is effectively movd N (sp),-(sp) then we will do the --- 362,446 ---- operands in OPERANDS to be suitable for the low-numbered word. */ ! if (size == 12) ! { ! if (optype0 == REGOP) ! { ! middlehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); ! latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 2); ! } ! else if (optype0 == OFFSOP) ! { ! middlehalf[0] = adj_offsettable_operand (operands[0], 4); ! latehalf[0] = adj_offsettable_operand (operands[0], 8); ! } ! else ! { ! middlehalf[0] = operands[0]; ! latehalf[0] = operands[0]; ! } ! ! if (optype1 == REGOP) ! { ! middlehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); ! latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 2); ! } ! else if (optype1 == OFFSOP) ! { ! middlehalf[1] = adj_offsettable_operand (operands[1], 4); ! latehalf[1] = adj_offsettable_operand (operands[1], 8); ! } ! else if (optype1 == CNSTOP) ! { ! if (GET_CODE (operands[1]) == CONST_DOUBLE) ! { ! REAL_VALUE_TYPE r; long l[3]; ! REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); ! REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l); ! operands[1] = GEN_INT (l[0]); ! middlehalf[1] = GEN_INT (l[1]); ! latehalf[1] = GEN_INT (l[2]); ! } ! else if (CONSTANT_P (operands[1])) ! /* No non-CONST_DOUBLE constant should ever appear here. */ ! abort (); ! } ! else { ! middlehalf[1] = operands[1]; ! latehalf[1] = operands[1]; } } ! else /* size is not 12: */ ! { ! 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 (GET_CODE (operands[1]) == CONST_DOUBLE) ! split_double (operands[1], &operands[1], &latehalf[1]); ! else if (CONSTANT_P (operands[1])) ! { ! /* ??? jrv: Can this really happen? A DImode constant ! that isn't a CONST_DOUBLE? */ ! if (GET_CODE (operands[1]) == CONST_INT ! && INTVAL (operands[1]) < 0) ! latehalf[1] = constm1_rtx; ! else ! latehalf[1] = const0_rtx; ! } ! } ! else ! latehalf[1] = operands[1]; ! } /* If insn is effectively movd N (sp),-(sp) then we will do the *************** *** 368,377 **** /* If both halves of dest are used in the src memory address, compute the address into latehalf of dest. */ ! rtx xops[2]; xops[0] = latehalf[0]; xops[1] = XEXP (operands[1], 0); output_asm_insn (AS2 (lea%L0,%a1,%0), xops); ! operands[1] = gen_rtx (MEM, DImode, latehalf[0]); ! latehalf[1] = adj_offsettable_operand (operands[1], 4); } else if (reg_mentioned_p (operands[0], XEXP (operands[1], 0))) --- 465,502 ---- /* If both halves of dest are used in the src memory address, compute the address into latehalf of dest. */ ! compadr: xops[0] = latehalf[0]; xops[1] = XEXP (operands[1], 0); output_asm_insn (AS2 (lea%L0,%a1,%0), xops); ! if( GET_MODE (operands[1]) == XFmode ) ! { ! /* abort (); */ ! operands[1] = gen_rtx (MEM, XFmode, latehalf[0]); ! middlehalf[1] = adj_offsettable_operand (operands[1], size-8); ! latehalf[1] = adj_offsettable_operand (operands[1], size-4); ! } ! else ! { ! operands[1] = gen_rtx (MEM, DImode, latehalf[0]); ! latehalf[1] = adj_offsettable_operand (operands[1], size-4); ! } ! } ! else if (size == 12 ! && reg_mentioned_p (middlehalf[0], XEXP (operands[1], 0))) ! { ! /* Check for two regs used by both source and dest. */ ! if (reg_mentioned_p (operands[0], XEXP (operands[1], 0)) ! || reg_mentioned_p (latehalf[0], XEXP (operands[1], 0))) ! goto compadr; ! ! /* JRV says this can't happen: */ ! if (addreg0 || addreg1) ! abort(); ! ! /* Only the middle reg conflicts; simply put it last. */ ! output_asm_insn (singlemove_string (operands), operands); ! output_asm_insn (singlemove_string (latehalf), latehalf); ! output_asm_insn (singlemove_string (middlehalf), middlehalf); ! return ""; } else if (reg_mentioned_p (operands[0], XEXP (operands[1], 0))) *************** *** 389,392 **** --- 514,518 ---- sets it up, and that is an undefined circumstance. */ + /* if (optype0 == PUSHOP || optype1 == PUSHOP || (optype0 == REGOP && optype1 == REGOP *************** *** 393,402 **** && REGNO (operands[0]) == REGNO (latehalf[1])) || dest_overlapped_low) { /* Make any unoffsettable addresses point at high-numbered word. */ if (addreg0) ! asm_add (4, addreg0); if (addreg1) ! asm_add (4, addreg1); /* Do that word. */ --- 519,534 ---- && REGNO (operands[0]) == REGNO (latehalf[1])) || dest_overlapped_low) + */ + if (optype0 == PUSHOP || optype1 == PUSHOP + || (optype0 == REGOP && optype1 == REGOP + && ((middlehalf[1] && REGNO (operands[0]) == REGNO (middlehalf[1])) + || REGNO (operands[0]) == REGNO (latehalf[1]))) + || dest_overlapped_low) { /* Make any unoffsettable addresses point at high-numbered word. */ if (addreg0) ! asm_add (size-4, addreg0); if (addreg1) ! asm_add (size-4, addreg1); /* Do that word. */ *************** *** 409,412 **** --- 541,553 ---- asm_add (-4, addreg1); + if (size == 12) + { + output_asm_insn (singlemove_string (middlehalf), middlehalf); + if (addreg0) + asm_add (-4, addreg0); + if (addreg1) + asm_add (-4, addreg1); + } + /* Do low-numbered word. */ return singlemove_string (operands); *************** *** 417,420 **** --- 558,572 ---- output_asm_insn (singlemove_string (operands), operands); + /* Do the middle one of the three words for long double */ + if (size == 12) + { + if (addreg0) + asm_add (4, addreg0); + if (addreg1) + asm_add (4, addreg1); + + output_asm_insn (singlemove_string (middlehalf), middlehalf); + } + /* Make any unoffsettable addresses point at high-numbered word. */ if (addreg0) *************** *** 428,434 **** /* Undo the adds we just did. */ if (addreg0) ! asm_add (-4, addreg0); if (addreg1) ! asm_add (-4, addreg1); return ""; --- 580,586 ---- /* Undo the adds we just did. */ if (addreg0) ! asm_add (4-size, addreg0); if (addreg1) ! asm_add (4-size, addreg1); return ""; *************** *** 483,492 **** if (GET_CODE (operands[1]) == CONST_DOUBLE) { ! union { int i[2]; double d;} u1; ! union { int i; float f;} u2; ! u1.i[0] = CONST_DOUBLE_LOW (operands[1]); ! u1.i[1] = CONST_DOUBLE_HIGH (operands[1]); ! u2.f = u1.d; ! operands[1] = GEN_INT (u2.i); } return singlemove_string (operands); --- 635,646 ---- if (GET_CODE (operands[1]) == CONST_DOUBLE) { ! REAL_VALUE_TYPE r; long l; ! ! if (GET_MODE (operands[1]) == XFmode) ! abort (); ! ! REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); ! REAL_VALUE_TO_TARGET_SINGLE (r, l); ! operands[1] = GEN_INT (l); } return singlemove_string (operands); *************** *** 1046,1049 **** --- 1200,1207 ---- return; + case 'T': + PUT_OP_SIZE (code, 't', file); + return; + case 'z': /* 387 opcodes don't get size suffixes if the operands are *************** *** 1074,1077 **** --- 1232,1239 ---- return; + case 12: + PUT_OP_SIZE ('T', 't', file); + return; + case 8: if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT) *************** *** 1125,1142 **** 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; PRINT_IMMED_PREFIX (file); ! fprintf (file, "0x%x", u1.i); } ! else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode) { ! union { double d; int i[2]; } u; ! u.i[0] = CONST_DOUBLE_LOW (x); ! u.i[1] = CONST_DOUBLE_HIGH (x); ! fprintf (file, "%.22e", u.d); } else --- 1287,1310 ---- else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode) { ! REAL_VALUE_TYPE r; long l; ! REAL_VALUE_FROM_CONST_DOUBLE (r, x); ! REAL_VALUE_TO_TARGET_SINGLE (r, l); PRINT_IMMED_PREFIX (file); ! fprintf (file, "0x%x", l); } ! /* These float cases don't actually occur as immediate operands. */ ! else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode) { ! REAL_VALUE_TYPE r; char dstr[30]; ! REAL_VALUE_FROM_CONST_DOUBLE (r, x); ! REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr); ! fprintf (file, "%s", dstr); ! } ! else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == XFmode) ! { ! REAL_VALUE_TYPE r; char dstr[30]; ! REAL_VALUE_FROM_CONST_DOUBLE (r, x); ! REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr); ! fprintf (file, "%s", dstr); } else *************** *** 1501,1505 **** case FLOAT_EXTEND: ! return mode == DFmode && GET_MODE (XEXP (op, 0)) == SFmode; default: --- 1669,1675 ---- case FLOAT_EXTEND: ! return ((mode == DFmode && GET_MODE (XEXP (op, 0)) == SFmode) ! || (mode == XFmode && GET_MODE (XEXP (op, 0)) == DFmode) ! || (mode == XFmode && GET_MODE (XEXP (op, 0)) == SFmode)); default: *************** *** 1884,1890 **** static rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS]; /* Clear stack slot assignments remembered from previous functions. This is called from INIT_EXPANDERS once before RTL is emitted for each ! function. */ void --- 2054,2088 ---- static rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS]; + /* Define the structure for the machine field in struct function. */ + struct machine_function + { + rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS]; + }; + + /* Functions to save and restore i386_stack_locals. + These will be called, via pointer variables, + from push_function_context and pop_function_context. */ + + void + save_386_machine_status (p) + struct function *p; + { + p->machine = (struct machine_function *) xmalloc (sizeof i386_stack_locals); + bcopy (i386_stack_locals, p->machine->i386_stack_locals, + sizeof i386_stack_locals); + } + + void + restore_386_machine_status (p) + struct function *p; + { + bcopy (p->machine->i386_stack_locals, i386_stack_locals, + sizeof i386_stack_locals); + free (p->machine); + } + /* Clear stack slot assignments remembered from previous functions. This is called from INIT_EXPANDERS once before RTL is emitted for each ! function. */ void *************** *** 1898,1901 **** --- 2096,2103 ---- for (n = 0; n < MAX_386_STACK_LOCALS; n++) i386_stack_locals[(int) mode][n] = NULL_RTX; + + /* Arrange to save and restore i386_stack_locals around nested functions. */ + save_machine_status = save_386_machine_status; + restore_machine_status = restore_386_machine_status; } diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/i386.h gcc-2.5.0/config/i386/i386.h *** gcc-2.4.5/config/i386/i386.h Wed Mar 31 14:59:24 1993 --- gcc-2.5.0/config/i386/i386.h Wed Oct 13 02:02:45 1993 *************** *** 121,127 **** --- 121,143 ---- #define SUBTARGET_SWITCHES + #define OVERRIDE_OPTIONS \ + { \ + SUBTARGET_OVERRIDE_OPTIONS \ + } + + /* This is meant to be redefined in the host dependent files */ + #define SUBTARGET_OVERRIDE_OPTIONS /* target machine storage layout */ + /* Define for XFmode extended real floating point support. + This will automatically cause REAL_ARITHMETIC to be defined. */ + #define LONG_DOUBLE_TYPE_SIZE 96 + + /* Define if you don't want extended real, but do want to use the + software floating point emulator for REAL_ARITHMETIC and + decimal <-> binary conversion. */ + /* #define REAL_ARITHMETIC */ + /* Define this if most significant byte of a word is the lowest numbered. */ /* That is true on the 80386. */ *************** *** 282,286 **** ((REGNO) < 2 ? 1 \ : (REGNO) < 4 ? 1 \ ! : FP_REGNO_P ((REGNO)) \ ? (((int) GET_MODE_CLASS (MODE) == (int) MODE_FLOAT \ || (int) GET_MODE_CLASS (MODE) == (int) MODE_COMPLEX_FLOAT) \ --- 298,302 ---- ((REGNO) < 2 ? 1 \ : (REGNO) < 4 ? 1 \ ! : FP_REGNO_P (REGNO) \ ? (((int) GET_MODE_CLASS (MODE) == (int) MODE_FLOAT \ || (int) GET_MODE_CLASS (MODE) == (int) MODE_COMPLEX_FLOAT) \ *************** *** 606,610 **** || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (FUNTYPE))) \ == void_type_node))) ? (SIZE) \ ! : (aggregate_value_p (FUNTYPE)) ? GET_MODE_SIZE (Pmode) : 0) /* Define how to find the value returned by a function. --- 622,626 ---- || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (FUNTYPE))) \ == void_type_node))) ? (SIZE) \ ! : (aggregate_value_p (TREE_TYPE (FUNTYPE))) ? GET_MODE_SIZE (Pmode) : 0) /* Define how to find the value returned by a function. *************** *** 1102,1105 **** --- 1118,1138 ---- #define INIT_EXPANDERS clear_386_stack_locals () + + /* The `FINALIZE_PIC' macro serves as a hook to emit these special + codes once the function is being compiled into assembly code, but + not before. (It is not done before, because in the case of + compiling an inline function, it would lead to multiple PIC + prologues being included in functions which used inline functions + and were compiled to assembly language.) */ + + #define FINALIZE_PIC \ + do \ + { \ + extern int current_function_uses_pic_offset_table; \ + \ + current_function_uses_pic_offset_table |= profile_flag | profile_block_flag; \ + } \ + while (0) + /* Specify the machine mode that this machine uses *************** *** 1366,1382 **** /* This is how to output an assembler line defining a `double' constant. */ ! #define ASM_OUTPUT_DOUBLE(FILE,VALUE) \ ! fprintf (FILE, "%s %.22e\n", ASM_DOUBLE, (VALUE)) /* This is how to output an assembler line defining a `float' constant. */ ! #define ASM_OUTPUT_FLOAT(FILE,VALUE) \ ! do { union { float f; long l;} tem; \ ! tem.f = (VALUE); \ ! fprintf((FILE), "%s 0x%x\n", ASM_LONG, tem.l); \ } while (0) - /* Store in OUTPUT a string (made with alloca) containing an assembler-name for a local static variable named NAME. --- 1399,1434 ---- /* This is how to output an assembler line defining a `double' constant. */ ! #define ASM_OUTPUT_DOUBLE(FILE,VALUE) \ ! do { long l[2]; \ ! REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l); \ ! if (sizeof (int) == sizeof (long)) \ ! fprintf (FILE, "%s 0x%x,0x%x\n", ASM_LONG, l[0], l[1]); \ ! else \ ! fprintf (FILE, "%s 0x%lx,0x%lx\n", ASM_LONG, l[0], l[1]); \ ! } while (0) ! ! /* This is how to output a `long double' extended real constant. */ + #undef ASM_OUTPUT_LONG_DOUBLE + #define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE) \ + do { long l[3]; \ + REAL_VALUE_TO_TARGET_LONG_DOUBLE (VALUE, l); \ + if (sizeof (int) == sizeof (long)) \ + fprintf (FILE, "%s 0x%x,0x%x,0x%x\n", ASM_LONG, l[0], l[1], l[2]); \ + else \ + fprintf (FILE, "%s 0x%lx,0x%lx,0x%lx\n", ASM_LONG, l[0], l[1], l[2]); \ + } while (0) /* This is how to output an assembler line defining a `float' constant. */ ! #define ASM_OUTPUT_FLOAT(FILE,VALUE) \ ! do { long l; \ ! REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \ ! if (sizeof (int) == sizeof (long)) \ ! fprintf ((FILE), "%s 0x%x\n", ASM_LONG, l); \ ! else \ ! fprintf ((FILE), "%s 0x%lx\n", ASM_LONG, l); \ } while (0) /* Store in OUTPUT a string (made with alloca) containing an assembler-name for a local static variable named NAME. *************** *** 1472,1476 **** On the 80386, we use several such letters: f -- float insn (print a CONST_DOUBLE as a float rather than in hex). ! L,W,B,Q,S -- print the opcode suffix for specified size of operand. R -- print the prefix for register names. z -- print the opcode suffix for the size of the current operand. --- 1524,1528 ---- On the 80386, we use several such letters: f -- float insn (print a CONST_DOUBLE as a float rather than in hex). ! L,W,B,Q,S,T -- print the opcode suffix for specified size of operand. R -- print the prefix for register names. z -- print the opcode suffix for the size of the current operand. *************** *** 1513,1516 **** --- 1565,1569 ---- case 4: \ case 8: \ + case 12: \ if (! FP_REG_P (X)) fputs ("e", FILE); \ case 2: \ *************** *** 1547,1550 **** --- 1600,1604 ---- switch (GET_MODE_SIZE (GET_MODE (X))) \ { \ + case 12: \ case 8: \ case 4: \ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/i386.md gcc-2.5.0/config/i386/i386.md *** gcc-2.4.5/config/i386/i386.md Sat Jun 19 18:33:13 1993 --- gcc-2.5.0/config/i386/i386.md Tue Oct 5 01:43:48 1993 *************** *** 46,49 **** --- 46,50 ---- ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh. ;; 'y' Print "st(0)" instead of "st" as a register. + ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode. ;; UNSPEC usage: *************** *** 207,210 **** --- 208,244 ---- DONE; }") + + (define_insn "tstxf_cc" + [(set (cc0) + (match_operand:XF 0 "register_operand" "f")) + (clobber (match_scratch:HI 1 "=a"))] + "TARGET_80387 && ! TARGET_IEEE_FP" + "* + { + if (! STACK_TOP_P (operands[0])) + abort (); + + output_asm_insn (\"ftst\", operands); + + if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) + output_asm_insn (AS1 (fstp,%y0), operands); + + return (char *) output_fp_cc0_set (insn); + }") + + ;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode + ;; isn't IEEE compliant. + + (define_expand "tstxf" + [(parallel [(set (cc0) + (match_operand:XF 0 "register_operand" "")) + (clobber (match_scratch:HI 1 ""))])] + "TARGET_80387 && ! TARGET_IEEE_FP" + " + { + i386_compare_gen = gen_tstxf_cc; + i386_compare_op0 = operands[0]; + DONE; + }") ;;- compare instructions. See comments above tstM patterns about *************** *** 311,314 **** --- 345,406 ---- [(set (cc0) (match_operator 2 "VOIDmode_compare_op" + [(match_operand:XF 0 "nonimmediate_operand" "f") + (match_operand:XF 1 "nonimmediate_operand" "f")])) + (clobber (match_scratch:HI 3 "=a"))] + "TARGET_80387 + && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" + "* return (char *) output_float_compare (insn, operands);") + + (define_insn "" + [(set (cc0) + (match_operator 2 "VOIDmode_compare_op" + [(match_operand:XF 0 "register_operand" "f") + (float:XF + (match_operand:SI 1 "nonimmediate_operand" "rm"))])) + (clobber (match_scratch:HI 3 "=a"))] + "TARGET_80387" + "* return (char *) output_float_compare (insn, operands);") + + (define_insn "" + [(set (cc0) + (match_operator 2 "VOIDmode_compare_op" + [(float:XF + (match_operand:SI 0 "nonimmediate_operand" "rm")) + (match_operand:XF 1 "register_operand" "f")])) + (clobber (match_scratch:HI 3 "=a"))] + "TARGET_80387" + "* return (char *) output_float_compare (insn, operands);") + + (define_insn "" + [(set (cc0) + (match_operator 2 "VOIDmode_compare_op" + [(match_operand:XF 0 "register_operand" "f") + (float_extend:XF + (match_operand:DF 1 "nonimmediate_operand" "fm"))])) + (clobber (match_scratch:HI 3 "=a"))] + "TARGET_80387" + "* return (char *) output_float_compare (insn, operands);") + + (define_insn "" + [(set (cc0) + (match_operator 2 "VOIDmode_compare_op" + [(match_operand:XF 0 "register_operand" "f") + (float_extend:XF + (match_operand:SF 1 "nonimmediate_operand" "fm"))])) + (clobber (match_scratch:HI 3 "=a"))] + "TARGET_80387" + "* return (char *) output_float_compare (insn, operands);") + + (define_insn "" + [(set (cc0) + (compare:CCFPEQ (match_operand:XF 0 "register_operand" "f") + (match_operand:XF 1 "register_operand" "f"))) + (clobber (match_scratch:HI 2 "=a"))] + "TARGET_80387" + "* return (char *) output_float_compare (insn, operands);") + + (define_insn "" + [(set (cc0) + (match_operator 2 "VOIDmode_compare_op" [(match_operand:DF 0 "nonimmediate_operand" "f,fm") (match_operand:DF 1 "nonimmediate_operand" "fm,f")])) *************** *** 424,427 **** --- 516,533 ---- "* return (char *) output_float_compare (insn, operands);") + (define_expand "cmpxf" + [(set (cc0) + (compare (match_operand:XF 0 "register_operand" "") + (match_operand:XF 1 "nonimmediate_operand" "")))] + "TARGET_80387" + " + { + i386_compare_gen = gen_cmpxf_cc; + i386_compare_gen_eq = gen_cmpxf_ccfpeq; + i386_compare_op0 = operands[0]; + i386_compare_op1 = operands[1]; + DONE; + }") + (define_expand "cmpdf" [(set (cc0) *************** *** 452,455 **** --- 558,581 ---- }") + (define_expand "cmpxf_cc" + [(parallel [(set (cc0) + (compare (match_operand:XF 0 "register_operand" "") + (match_operand:XF 1 "register_operand" ""))) + (clobber (match_scratch:HI 2 ""))])] + "TARGET_80387" + "") + + (define_expand "cmpxf_ccfpeq" + [(parallel [(set (cc0) + (compare:CCFPEQ (match_operand:XF 0 "register_operand" "") + (match_operand:XF 1 "register_operand" ""))) + (clobber (match_scratch:HI 2 ""))])] + "TARGET_80387" + " + { + if (! register_operand (operands[1], XFmode)) + operands[1] = copy_to_mode_reg (XFmode, operands[1]); + }") + (define_expand "cmpdf_cc" [(parallel [(set (cc0) *************** *** 795,800 **** (define_insn "movstrictqi" ! [(set (strict_low_part (match_operand:QI 0 "general_operand" "+q,qm")) ! (match_operand:QI 1 "general_operand" "*g,qn"))] "" "* --- 921,926 ---- (define_insn "movstrictqi" ! [(set (strict_low_part (match_operand:QI 0 "general_operand" "+qm,q")) ! (match_operand:QI 1 "general_operand" "*qn,m"))] "" "* *************** *** 816,820 **** return AS1 (inc%B0,%0); ! /* If mov%B0 isn't allowed for one of these regs, use mov%W0. */ if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1])) { --- 942,946 ---- return AS1 (inc%B0,%0); ! /* If mov%B0 isn't allowed for one of these regs, use mov%L0. */ if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1])) { *************** *** 1015,1018 **** --- 1141,1241 ---- (define_insn "" + [(set (match_operand:XF 0 "push_operand" "=<,<") + (match_operand:XF 1 "general_operand" "gF,f"))] + "" + "* + { + if (STACK_REG_P (operands[1])) + { + rtx xops[3]; + + xops[0] = AT_SP (SFmode); + xops[1] = GEN_INT (12); + xops[2] = stack_pointer_rtx; + + output_asm_insn (AS2 (sub%L2,%1,%2), xops); + output_asm_insn (AS1 (fstp%T0,%0), xops); + if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) + output_asm_insn (AS1 (fld%T0,%0), xops); + + RET; + } + else + return (char *) output_move_double (operands); + }") + + (define_insn "swapxf" + [(set (match_operand:XF 0 "register_operand" "f") + (match_operand:XF 1 "register_operand" "f")) + (set (match_dup 1) + (match_dup 0))] + "" + "* + { + if (STACK_TOP_P (operands[0])) + return AS1 (fxch,%1); + else + return AS1 (fxch,%0); + }") + + (define_insn "movxf" + [(set (match_operand:XF 0 "general_operand" "=f,fm,!*rf,!*rm") + (match_operand:XF 1 "general_operand" "fmG,f,*rfm,*rfF"))] + ;; [(set (match_operand:XF 0 "general_operand" "=*rf,*rfm,f,!*rm") + ;; (match_operand:XF 1 "general_operand" "*rfm,*rf,fG,fF"))] + "" + "* + { + int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; + + /* First handle a `pop' insn or a `fld %st(0)' */ + + if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1])) + { + if (stack_top_dies) + return AS1 (fstp,%y0); + else + return AS1 (fld,%y0); + } + + /* Handle a transfer between the 387 and a 386 register */ + + if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1])) + { + output_op_from_reg (operands[1], AS1 (fld%z0,%y1)); + RET; + } + + if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0])) + { + output_to_reg (operands[0], stack_top_dies); + RET; + } + + /* Handle other kinds of writes from the 387 */ + + if (STACK_TOP_P (operands[1])) + { + output_asm_insn (AS1 (fstp%z0,%y0), operands); + if (! stack_top_dies) + return AS1 (fld%z0,%y0); + + RET; + } + + /* Handle other kinds of reads to the 387 */ + + if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE) + return (char *) output_move_const_single (operands); + + if (STACK_TOP_P (operands[0])) + return AS1 (fld%z1,%y1); + + /* Handle all XFmode moves not involving the 387 */ + + return (char *) output_move_double (operands); + }") + + (define_insn "" [(set (match_operand:DI 0 "push_operand" "=<") (match_operand:DI 1 "general_operand" "roiF"))] *************** *** 1242,1245 **** --- 1465,1538 ---- }") + (define_insn "extenddfxf2" + [(set (match_operand:XF 0 "general_operand" "=fm,f,f,!*r") + (float_extend:XF + (match_operand:DF 1 "general_operand" "f,fm,!*r,f")))] + "TARGET_80387" + "* + { + int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; + + if (NON_STACK_REG_P (operands[1])) + { + output_op_from_reg (operands[1], AS1 (fld%z0,%y1)); + RET; + } + + if (NON_STACK_REG_P (operands[0])) + { + output_to_reg (operands[0], stack_top_dies); + RET; + } + + if (STACK_TOP_P (operands[0])) + return AS1 (fld%z1,%y1); + + if (GET_CODE (operands[0]) == MEM) + { + output_asm_insn (AS1 (fstp%z0,%y0), operands); + if (! stack_top_dies) + return AS1 (fld%z0,%y0); + RET; + } + + abort (); + }") + + (define_insn "extendsfxf2" + [(set (match_operand:XF 0 "general_operand" "=fm,f,f,!*r") + (float_extend:XF + (match_operand:SF 1 "general_operand" "f,fm,!*r,f")))] + "TARGET_80387" + "* + { + int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; + + if (NON_STACK_REG_P (operands[1])) + { + output_op_from_reg (operands[1], AS1 (fld%z0,%y1)); + RET; + } + + if (NON_STACK_REG_P (operands[0])) + { + output_to_reg (operands[0], stack_top_dies); + RET; + } + + if (STACK_TOP_P (operands[0])) + return AS1 (fld%z1,%y1); + + if (GET_CODE (operands[0]) == MEM) + { + output_asm_insn (AS1 (fstp%z0,%y0), operands); + if (! stack_top_dies) + return AS1 (fld%z0,%y0); + RET; + } + + abort (); + }") + (define_expand "truncdfsf2" [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "") *************** *** 1283,1286 **** --- 1576,1646 ---- abort (); }") + + (define_insn "truncxfsf2" + [(set (match_operand:SF 0 "general_operand" "=m,!*r") + (float_truncate:SF + (match_operand:XF 1 "register_operand" "f,f")))] + "TARGET_80387" + "* + { + int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; + + if (NON_STACK_REG_P (operands[0])) + { + if (stack_top_dies == 0) + { + output_asm_insn (AS1 (fld,%y1), operands); + stack_top_dies = 1; + } + output_to_reg (operands[0], stack_top_dies); + RET; + } + else if (GET_CODE (operands[0]) == MEM) + { + if (stack_top_dies) + return AS1 (fstp%z0,%0); + else + { + output_asm_insn (AS1 (fld,%y1), operands); + return AS1 (fstp%z0,%0); + } + } + else + abort (); + }") + + (define_insn "truncxfdf2" + [(set (match_operand:DF 0 "general_operand" "=m,!*r") + (float_truncate:DF + (match_operand:XF 1 "register_operand" "f,f")))] + "TARGET_80387" + "* + { + int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; + + if (NON_STACK_REG_P (operands[0])) + { + if (stack_top_dies == 0) + { + output_asm_insn (AS1 (fld,%y1), operands); + stack_top_dies = 1; + } + output_to_reg (operands[0], stack_top_dies); + RET; + } + else if (GET_CODE (operands[0]) == MEM) + { + if (stack_top_dies) + return AS1 (fstp%z0,%0); + else + { + output_asm_insn (AS1 (fld,%y1), operands); + return AS1 (fstp%z0,%0); + } + } + else + abort (); + }") + ;; The 387 requires that the stack top dies after converting to DImode. *************** *** 1290,1293 **** --- 1650,1674 ---- ;; part. + (define_expand "fixuns_truncxfsi2" + [(set (match_dup 4) + (match_operand:XF 1 "register_operand" "")) + (parallel [(set (match_dup 2) + (fix:DI (fix:XF (match_dup 4)))) + (clobber (match_dup 4)) + (clobber (match_dup 5)) + (clobber (match_dup 6)) + (clobber (match_scratch:SI 7 ""))]) + (set (match_operand:SI 0 "general_operand" "") + (match_dup 3))] + "TARGET_80387" + " + { + operands[2] = gen_reg_rtx (DImode); + operands[3] = gen_lowpart (SImode, operands[2]); + operands[4] = gen_reg_rtx (XFmode); + operands[5] = (rtx) assign_386_stack_local (SImode, 0); + operands[6] = (rtx) assign_386_stack_local (SImode, 1); + }") + (define_expand "fixuns_truncdfsi2" [(set (match_dup 4) *************** *** 1334,1337 **** --- 1715,1736 ---- ;; Signed conversion to DImode. + (define_expand "fix_truncxfdi2" + [(set (match_dup 2) + (match_operand:XF 1 "register_operand" "")) + (parallel [(set (match_operand:DI 0 "general_operand" "") + (fix:DI (fix:XF (match_dup 2)))) + (clobber (match_dup 2)) + (clobber (match_dup 3)) + (clobber (match_dup 4)) + (clobber (match_scratch:SI 5 ""))])] + "TARGET_80387" + " + { + operands[1] = copy_to_mode_reg (XFmode, operands[1]); + operands[2] = gen_reg_rtx (XFmode); + operands[3] = (rtx) assign_386_stack_local (SImode, 0); + operands[4] = (rtx) assign_386_stack_local (SImode, 1); + }") + (define_expand "fix_truncdfdi2" [(set (match_dup 2) *************** *** 1374,1377 **** --- 1773,1786 ---- (define_insn "" [(set (match_operand:DI 0 "general_operand" "=rm") + (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f")))) + (clobber (match_dup 1)) + (clobber (match_operand:SI 2 "memory_operand" "m")) + (clobber (match_operand:SI 3 "memory_operand" "m")) + (clobber (match_scratch:SI 4 "=&q"))] + "TARGET_80387" + "* return (char *) output_fix_trunc (insn, operands);") + + (define_insn "" + [(set (match_operand:DI 0 "general_operand" "=rm") (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f")))) (clobber (match_dup 1)) *************** *** 1394,1397 **** --- 1803,1820 ---- ;; Signed MODE_FLOAT conversion to SImode. + (define_expand "fix_truncxfsi2" + [(parallel [(set (match_operand:SI 0 "general_operand" "") + (fix:SI + (fix:XF (match_operand:XF 1 "register_operand" "")))) + (clobber (match_dup 2)) + (clobber (match_dup 3)) + (clobber (match_scratch:SI 4 ""))])] + "TARGET_80387" + " + { + operands[2] = (rtx) assign_386_stack_local (SImode, 0); + operands[3] = (rtx) assign_386_stack_local (SImode, 1); + }") + (define_expand "fix_truncdfsi2" [(parallel [(set (match_operand:SI 0 "general_operand" "") *************** *** 1424,1427 **** --- 1847,1859 ---- (define_insn "" [(set (match_operand:SI 0 "general_operand" "=rm") + (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f")))) + (clobber (match_operand:SI 2 "memory_operand" "m")) + (clobber (match_operand:SI 3 "memory_operand" "m")) + (clobber (match_scratch:SI 4 "=&q"))] + "TARGET_80387" + "* return (char *) output_fix_trunc (insn, operands);") + + (define_insn "" + [(set (match_operand:SI 0 "general_operand" "=rm") (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f")))) (clobber (match_operand:SI 2 "memory_operand" "m")) *************** *** 1469,1475 **** --- 1901,1936 ---- "") + (define_expand "floatsixf2" + [(set (match_operand:XF 0 "register_operand" "") + (float:XF (match_operand:SI 1 "nonimmediate_operand" "")))] + "TARGET_80387" + "") + + (define_expand "floatdixf2" + [(set (match_operand:XF 0 "register_operand" "") + (float:XF (match_operand:DI 1 "nonimmediate_operand" "")))] + "TARGET_80387" + "") + ;; This will convert from SImode or DImode to MODE_FLOAT. (define_insn "" + [(set (match_operand:XF 0 "register_operand" "=f") + (float:XF (match_operand:DI 1 "general_operand" "rm")))] + "TARGET_80387" + "* + { + if (NON_STACK_REG_P (operands[1])) + { + output_op_from_reg (operands[1], AS1 (fild%z0,%1)); + RET; + } + else if (GET_CODE (operands[1]) == MEM) + return AS1 (fild%z1,%1); + else + abort (); + }") + + (define_insn "" [(set (match_operand:DF 0 "register_operand" "=f") (float:DF (match_operand:DI 1 "nonimmediate_operand" "rm")))] *************** *** 1523,1526 **** --- 1984,2004 ---- (define_insn "" + [(set (match_operand:XF 0 "register_operand" "=f,f") + (float:XF (match_operand:SI 1 "general_operand" "m,!*r")))] + "TARGET_80387" + "* + { + if (NON_STACK_REG_P (operands[1])) + { + output_op_from_reg (operands[1], AS1 (fild%z0,%1)); + RET; + } + else if (GET_CODE (operands[1]) == MEM) + return AS1 (fild%z1,%1); + else + abort (); + }") + + (define_insn "" [(set (match_operand:SF 0 "register_operand" "=f") (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm")))] *************** *** 1621,1624 **** --- 2099,2120 ---- "* { + /* ??? what about offsettable memory references? */ + if (QI_REG_P (operands[0]) + && GET_CODE (operands[2]) == CONST_INT + && (INTVAL (operands[2]) & 0xff) == 0) + { + CC_STATUS_INIT; + + operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff); + + if (operands[2] == const1_rtx) + return AS1 (inc%B0,%h0); + + if (operands[2] == constm1_rtx) + return AS1 (dec%B0,%h0); + + return AS2 (add%B0,%2,%h0); + } + if (operands[2] == const1_rtx) return AS1 (inc%W0,%0); *************** *** 1701,1704 **** --- 2197,2207 ---- ;; The patterns that match these are at the end of this file. + (define_expand "addxf3" + [(set (match_operand:XF 0 "register_operand" "") + (plus:XF (match_operand:XF 1 "nonimmediate_operand" "") + (match_operand:XF 2 "nonimmediate_operand" "")))] + "TARGET_80387" + "") + (define_expand "adddf3" [(set (match_operand:DF 0 "register_operand" "") *************** *** 1764,1767 **** --- 2267,2277 ---- ;; The patterns that match these are at the end of this file. + (define_expand "subxf3" + [(set (match_operand:XF 0 "register_operand" "") + (minus:XF (match_operand:XF 1 "nonimmediate_operand" "") + (match_operand:XF 2 "nonimmediate_operand" "")))] + "TARGET_80387" + "") + (define_expand "subdf3" [(set (match_operand:DF 0 "register_operand" "") *************** *** 1842,1845 **** --- 2352,2362 ---- ;; The patterns that match these are at the end of this file. + (define_expand "mulxf3" + [(set (match_operand:XF 0 "register_operand" "") + (mult:XF (match_operand:XF 1 "nonimmediate_operand" "") + (match_operand:XF 2 "nonimmediate_operand" "")))] + "TARGET_80387" + "") + (define_expand "muldf3" [(set (match_operand:DF 0 "register_operand" "") *************** *** 1874,1877 **** --- 2391,2401 ---- ;; The patterns that match these are at the end of this file. + (define_expand "divxf3" + [(set (match_operand:XF 0 "register_operand" "") + (div:XF (match_operand:XF 1 "nonimmediate_operand" "") + (match_operand:XF 2 "nonimmediate_operand" "")))] + "TARGET_80387" + "") + (define_expand "divdf3" [(set (match_operand:DF 0 "register_operand" "") *************** *** 2364,2367 **** --- 2888,2903 ---- "TARGET_80387" "fchs") + + (define_insn "negxf2" + [(set (match_operand:XF 0 "register_operand" "=f") + (neg:XF (match_operand:XF 1 "general_operand" "0")))] + "TARGET_80387" + "fchs") + + (define_insn "" + [(set (match_operand:XF 0 "register_operand" "=f") + (neg:XF (float_extend:XF (match_operand:DF 1 "general_operand" "0"))))] + "TARGET_80387" + "fchs") ;; Absolute value instructions *************** *** 2385,2388 **** --- 2921,2936 ---- "fabs") + (define_insn "absxf2" + [(set (match_operand:XF 0 "register_operand" "=f") + (abs:XF (match_operand:XF 1 "general_operand" "0")))] + "TARGET_80387" + "fabs") + + (define_insn "" + [(set (match_operand:XF 0 "register_operand" "=f") + (abs:XF (float_extend:XF (match_operand:DF 1 "general_operand" "0"))))] + "TARGET_80387" + "fabs") + (define_insn "sqrtsf2" [(set (match_operand:SF 0 "register_operand" "=f") *************** *** 2404,2407 **** --- 2952,2975 ---- "fsqrt") + (define_insn "sqrtxf2" + [(set (match_operand:XF 0 "register_operand" "=f") + (sqrt:XF (match_operand:XF 1 "general_operand" "0")))] + "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)" + "fsqrt") + + (define_insn "" + [(set (match_operand:XF 0 "register_operand" "=f") + (sqrt:XF (float_extend:XF + (match_operand:DF 1 "general_operand" "0"))))] + "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)" + "fsqrt") + + (define_insn "" + [(set (match_operand:XF 0 "register_operand" "=f") + (sqrt:XF (float_extend:XF + (match_operand:SF 1 "general_operand" "0"))))] + "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)" + "fsqrt") + (define_insn "sindf2" [(set (match_operand:DF 0 "register_operand" "=f") *************** *** 4461,4470 **** "* { ! rtx xops[2]; xops[0] = operands[0]; ! xops[1] = constm1_rtx; ! output_asm_insn (AS2 (mov%L0,%1,%0), xops); ! return AS2 (bsf%L0,%1,%0); }") --- 5029,5061 ---- "* { ! rtx xops[3]; ! static int ffssi_label_number; ! char buffer[30]; xops[0] = operands[0]; ! xops[1] = operands[1]; ! xops[2] = constm1_rtx; ! /* Can there be a way to avoid the jump here? */ ! output_asm_insn (AS2 (bsf%L0,%1,%0), xops); ! #ifdef LOCAL_LABEL_PREFIX ! sprintf (buffer, \"jnz %sLFFSSI%d\", ! LOCAL_LABEL_PREFIX, ffssi_label_number); ! #else ! sprintf (buffer, \"jnz %sLFFSSI%d\", ! \"\", ffssi_label_number); ! #endif ! output_asm_insn (buffer, xops); ! output_asm_insn (AS2 (mov%L0,%2,%0), xops); ! #ifdef LOCAL_LABEL_PREFIX ! sprintf (buffer, \"%sLFFSSI%d:\", ! LOCAL_LABEL_PREFIX, ffssi_label_number); ! #else ! sprintf (buffer, \"%sLFFSSI%d:\", ! \"\", ffssi_label_number); ! #endif ! output_asm_insn (buffer, xops); ! ! ffssi_label_number++; ! return \"\"; }") *************** *** 4485,4494 **** "* { ! rtx xops[2]; xops[0] = operands[0]; ! xops[1] = constm1_rtx; ! output_asm_insn (AS2 (mov%W0,%1,%0), xops); ! return AS2 (bsf%W0,%1,%0); }") --- 5076,5107 ---- "* { ! rtx xops[3]; ! static int ffshi_label_number; ! char buffer[30]; xops[0] = operands[0]; ! xops[1] = operands[1]; ! xops[2] = constm1_rtx; ! output_asm_insn (AS2 (bsf%W0,%1,%0), xops); ! #ifdef LOCAL_LABEL_PREFIX ! sprintf (buffer, \"jnz %sLFFSHI%d\", ! LOCAL_LABEL_PREFIX, ffshi_label_number); ! #else ! sprintf (buffer, \"jnz %sLFFSHI%d\", ! \"\", ffshi_label_number); ! #endif ! output_asm_insn (buffer, xops); ! output_asm_insn (AS2 (mov%W0,%2,%0), xops); ! #ifdef LOCAL_LABEL_PREFIX ! sprintf (buffer, \"%sLFFSHI%d:\", ! LOCAL_LABEL_PREFIX, ffshi_label_number); ! #else ! sprintf (buffer, \"%sLFFSHI%d:\", ! \"\", ffshi_label_number); ! #endif ! output_asm_insn (buffer, xops); ! ! ffshi_label_number++; ! return \"\"; }") *************** *** 4514,4517 **** --- 5127,5171 ---- [(float:DF (match_operand:SI 1 "general_operand" "rm")) (match_operand:DF 2 "general_operand" "0")]))] + "TARGET_80387" + "* return (char *) output_387_binary_op (insn, operands);") + + (define_insn "" + [(set (match_operand:XF 0 "register_operand" "=f,f") + (match_operator:XF 3 "binary_387_op" + [(match_operand:XF 1 "nonimmediate_operand" "0,f") + (match_operand:XF 2 "nonimmediate_operand" "f,0")]))] + "TARGET_80387" + "* return (char *) output_387_binary_op (insn, operands);") + + (define_insn "" + [(set (match_operand:XF 0 "register_operand" "=f") + (match_operator:XF 3 "binary_387_op" + [(float:XF (match_operand:SI 1 "general_operand" "rm")) + (match_operand:XF 2 "general_operand" "0")]))] + "TARGET_80387" + "* return (char *) output_387_binary_op (insn, operands);") + + (define_insn "" + [(set (match_operand:XF 0 "register_operand" "=f,f") + (match_operator:XF 3 "binary_387_op" + [(float_extend:XF (match_operand:SF 1 "general_operand" "fm,0")) + (match_operand:XF 2 "general_operand" "0,f")]))] + "TARGET_80387" + "* return (char *) output_387_binary_op (insn, operands);") + + (define_insn "" + [(set (match_operand:XF 0 "register_operand" "=f") + (match_operator:XF 3 "binary_387_op" + [(match_operand:XF 1 "general_operand" "0") + (float:XF (match_operand:SI 2 "general_operand" "rm"))]))] + "TARGET_80387" + "* return (char *) output_387_binary_op (insn, operands);") + + (define_insn "" + [(set (match_operand:XF 0 "register_operand" "=f,f") + (match_operator:XF 3 "binary_387_op" + [(match_operand:XF 1 "general_operand" "0,f") + (float_extend:XF + (match_operand:SF 2 "general_operand" "fm,0"))]))] "TARGET_80387" "* return (char *) output_387_binary_op (insn, operands);") diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/i386iscgas.h gcc-2.5.0/config/i386/i386iscgas.h *** gcc-2.4.5/config/i386/i386iscgas.h Sun Dec 27 20:04:54 1992 --- gcc-2.5.0/config/i386/i386iscgas.h Mon Sep 27 20:10:45 1993 *************** *** 32,40 **** use it here. --karl@cs.umb.edu */ #define DBX_OUTPUT_MAIN_SOURCE_DIRECTORY(asmfile, cwd) \ ! fprintf (asmfile, "%s \"%s/\",%d,0,0,%s\n", ASM_STABS_OP, \ ! cwd, N_SO, ltext_label_name) #define DBX_OUTPUT_MAIN_SOURCE_FILENAME(asmfile, input_file_name) \ ! fprintf (asmfile, "%s \"%s\",%d,0,0,%s\n", ASM_STABS_OP, input_file_name,\ ! N_SO, ltext_label_name); \ text_section (); \ ASM_OUTPUT_INTERNAL_LABEL (asmfile, "Ltext", 0) --- 32,43 ---- use it here. --karl@cs.umb.edu */ #define DBX_OUTPUT_MAIN_SOURCE_DIRECTORY(asmfile, cwd) \ ! do { fprintf (asmfile, "%s ", ASM_STABS_OP); \ ! output_quoted_string (asmfile, cwd); \ ! fprintf (asmfile, ",%d,0,0,%s\n", N_SO, ltext_label_name); \ ! } while (0) #define DBX_OUTPUT_MAIN_SOURCE_FILENAME(asmfile, input_file_name) \ ! fprintf (asmfile, "%s ", ASM_STABS_OP); \ ! output_quoted_string (input_file_name); \ ! fprintf (asmfile, ",%d,0,0,%s\n", N_SO, ltext_label_name); \ text_section (); \ ASM_OUTPUT_INTERNAL_LABEL (asmfile, "Ltext", 0) diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/isc.h gcc-2.5.0/config/i386/isc.h *** gcc-2.4.5/config/i386/isc.h Tue May 18 15:25:19 1993 --- gcc-2.5.0/config/i386/isc.h Wed Oct 20 01:09:26 1993 *************** *** 40,44 **** : 0) /* On other 386 systems, the last line looks like this: ! : (aggregate_value_p (FUNTYPE)) ? GET_MODE_SIZE (Pmode) : 0) */ #endif --- 40,44 ---- : 0) /* On other 386 systems, the last line looks like this: ! : (aggregate_value_p (TREE_TYPE (FUNTYPE))) ? GET_MODE_SIZE (Pmode) : 0) */ #endif *************** *** 56,57 **** --- 56,62 ---- #undef TARGET_DEFAULT #define TARGET_DEFAULT 0201 + + /* The ISC 2.0.2 software FPU emulator apparently can't handle + 80-bit XFmode insns, so don't generate them. */ + #undef LONG_DOUBLE_TYPE_SIZE + #define LONG_DOUBLE_TYPE_SIZE 64 diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/linux.h gcc-2.5.0/config/i386/linux.h *** gcc-2.4.5/config/i386/linux.h Thu May 6 01:41:58 1993 --- gcc-2.5.0/config/i386/linux.h Fri Oct 8 18:46:40 1993 *************** *** 21,25 **** --- 21,27 ---- #define YES_UNDERSCORES + #ifndef LINUX_ELF #include "i386/gstabs.h" + #endif /* Specify predefined symbols in preprocessor. */ *************** *** 26,30 **** #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dunix -Di386 -Dlinux" #undef CPP_SPEC --- 28,32 ---- #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dunix -Di386 -Dlinux -Asystem(unix) -Asystem(posix) -Acpu(i386) -Amachine(i386)" #undef CPP_SPEC *************** *** 59,63 **** #undef LIB_SPEC ! #define LIB_SPEC "%{g*:-lg} %{!g*:%{!p:%{!pg:-lc}}%{p:-lgmon -lc_p}%{pg:-lgmon -lc_p}}" --- 61,65 ---- #undef LIB_SPEC ! #define LIB_SPEC "%{p:-lgmon -lc_p} %{pg:-lgmon -lc_p} %{!p:%{!pg:%{!g*:-lc} %{g*:-lg}}}" *************** *** 72,76 **** #define STARTFILE_SPEC \ ! "%{g*:crt0.o%s -static} %{!g*:%{pg:gcrt0.o%s -static} %{!pg:%{p:gcrt0.o%s -static} %{!p:crt0.o%s %{!static:%{nojump:-nojump}} %{static:-static}}}}" /* --- 74,78 ---- #define STARTFILE_SPEC \ ! "%{pg:gcrt0.o%s -static} %{!pg:%{p:gcrt0.o%s -static} %{!p:crt0.o%s %{g*:-static} %{!static:%{nojump:-nojump}} %{static:-static}}} -L"TOOLDIR"/lib" /* *************** *** 82,86 **** #define STARTFILE_SPEC \ ! "%{g*:crt0.o%s -static} %{!g*:%{pg:gcrt0.o%s -static} %{!pg:%{p:gcrt0.o%s -static} %{!p:crt0.o%s %{!static:%{nojump:-nojump}} %{static:-static}}}}" /* --- 84,88 ---- #define STARTFILE_SPEC \ ! "%{pg:gcrt0.o%s -static} %{!pg:%{p:gcrt0.o%s -static} %{!p:crt0.o%s %{g*:-static}%{!static:%{nojump:-nojump}} %{static:-static}}}" /* diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/linuxelf.h gcc-2.5.0/config/i386/linuxelf.h *** gcc-2.4.5/config/i386/linuxelf.h --- gcc-2.5.0/config/i386/linuxelf.h Fri Oct 8 17:41:03 1993 *************** *** 0 **** --- 1,108 ---- + /* Definitions for Intel 386 running Linux with ELF format + Written by Eric Youngdale. */ + + /* A lie, I guess, but the general idea behind linux/ELF is that we are + supposed to be outputting something that will assemble under SVr4. + This gets us pretty close. */ + #include "i386/i386.h" /* Base i386 target machine definitions */ + #include "i386/att.h" /* Use the i386 AT&T assembler syntax */ + #include "svr4.h" + #undef MD_EXEC_PREFIX + #undef MD_STARTFILE_PREFIX + #undef TARGET_VERSION + #define TARGET_VERSION fprintf (stderr, " (i386 Linux/ELF)"); + /* Output at beginning of assembler file. */ + /* The .file command should always begin the output. */ + #undef ASM_FILE_START + #define ASM_FILE_START(FILE) \ + do { \ + output_file_directive (FILE, main_input_filename); \ + fprintf (FILE, "\t.version\t\"01.01\"\n"); \ + } while (0) + /* The svr4 ABI for the i386 says that records and unions are returned + in memory. */ + #undef RETURN_IN_MEMORY + #define RETURN_IN_MEMORY(TYPE) \ + (TYPE_MODE (TYPE) == BLKmode) + /* This is how to output an element of a case-vector that is relative. + This is only used for PIC code. See comments by the `casesi' insn in + i386.md for an explanation of the expression this outputs. */ + #undef ASM_OUTPUT_ADDR_DIFF_ELT + #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ + fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, VALUE) + /* Indicate that jump tables go in the text section. This is + necessary when compiling PIC code. */ + #define JUMP_TABLES_IN_TEXT_SECTION + /* Copy this from the svr4 specifications... */ + /* Define the register numbers to be used in Dwarf debugging information. + The SVR4 reference port C compiler uses the following register numbers + in its Dwarf output code: + 0 for %eax (gnu regno = 0) + 1 for %ecx (gnu regno = 2) + 2 for %edx (gnu regno = 1) + 3 for %ebx (gnu regno = 3) + 4 for %esp (gnu regno = 7) + 5 for %ebp (gnu regno = 6) + 6 for %esi (gnu regno = 4) + 7 for %edi (gnu regno = 5) + The following three DWARF register numbers are never generated by + the SVR4 C compiler or by the GNU compilers, but SDB on x86/svr4 + believes these numbers have these meanings. + 8 for %eip (no gnu equivalent) + 9 for %eflags (no gnu equivalent) + 10 for %trapno (no gnu equivalent) + It is not at all clear how we should number the FP stack registers + for the x86 architecture. If the version of SDB on x86/svr4 were + a bit less brain dead with respect to floating-point then we would + have a precedent to follow with respect to DWARF register numbers + for x86 FP registers, but the SDB on x86/svr4 is so completely + broken with respect to FP registers that it is hardly worth thinking + of it as something to strive for compatibility with. + The verison of x86/svr4 SDB I have at the moment does (partially) + seem to believe that DWARF register number 11 is associated with + the x86 register %st(0), but that's about all. Higher DWARF + register numbers don't seem to be associated with anything in + particular, and even for DWARF regno 11, SDB only seems to under- + stand that it should say that a variable lives in %st(0) (when + asked via an `=' command) if we said it was in DWARF regno 11, + but SDB still prints garbage when asked for the value of the + variable in question (via a `/' command). + (Also note that the labels SDB prints for various FP stack regs + when doing an `x' command are all wrong.) + Note that these problems generally don't affect the native SVR4 + C compiler because it doesn't allow the use of -O with -g and + because when it is *not* optimizing, it allocates a memory + location for each floating-point variable, and the memory + location is what gets described in the DWARF AT_location + attribute for the variable in question. + Regardless of the severe mental illness of the x86/svr4 SDB, we + do something sensible here and we use the following DWARF + register numbers. Note that these are all stack-top-relative + numbers. + 11 for %st(0) (gnu regno = 8) + 12 for %st(1) (gnu regno = 9) + 13 for %st(2) (gnu regno = 10) + 14 for %st(3) (gnu regno = 11) + 15 for %st(4) (gnu regno = 12) + 16 for %st(5) (gnu regno = 13) + 17 for %st(6) (gnu regno = 14) + 18 for %st(7) (gnu regno = 15) + */ + #undef DBX_REGISTER_NUMBER + #define DBX_REGISTER_NUMBER(n) \ + ((n) == 0 ? 0 \ + : (n) == 1 ? 2 \ + : (n) == 2 ? 1 \ + : (n) == 3 ? 3 \ + : (n) == 4 ? 6 \ + : (n) == 5 ? 7 \ + : (n) == 6 ? 5 \ + : (n) == 7 ? 4 \ + : ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG) ? (n)+3 \ + : (-1)) + #define LINUX_ELF + #include "i386/linux.h" + + #undef YES_UNDERSCORE + #undef DBX_DEBUGGING_INFO + #define DWARF_DEBUGGING_INFO diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/lynx.h gcc-2.5.0/config/i386/lynx.h *** gcc-2.4.5/config/i386/lynx.h --- gcc-2.5.0/config/i386/lynx.h Sat Oct 2 04:18:27 1993 *************** *** 0 **** --- 1,24 ---- + /* Definitions for Intel 386 running LynxOS. + Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + #include "i386/gstabs.h" + #include "lynx.h" + + #undef CPP_PREDEFINES + #define CPP_PREDEFINES "-Dunix -Di386 -DI386 -DLynx -DIBITS32 -Asystem(unix) -Asystem(lynx) -Acpu(i386) -Amachine(i386)" diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/mach.h gcc-2.5.0/config/i386/mach.h *** gcc-2.4.5/config/i386/mach.h Tue Mar 23 14:21:33 1993 --- gcc-2.5.0/config/i386/mach.h Sat Oct 2 04:18:30 1993 *************** *** 11,21 **** #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dunix -Di386 -DMACH" /* Specify extra dir to search for include files. */ #define SYSTEM_INCLUDE_DIR "/usr/mach/include" - - /* Make stddef.h agree with types.h. */ - #define SIZE_TYPE "long int" /* Don't default to pcc-struct-return, because gcc is the only compiler, and --- 11,18 ---- #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dunix -Di386 -DMACH -Asystem(unix) -Asystem(mach) -Acpu(i386) -Amachine(i386)" /* Specify extra dir to search for include files. */ #define SYSTEM_INCLUDE_DIR "/usr/mach/include" /* Don't default to pcc-struct-return, because gcc is the only compiler, and diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/next.h gcc-2.5.0/config/i386/next.h *** gcc-2.4.5/config/i386/next.h Sat May 8 20:44:50 1993 --- gcc-2.5.0/config/i386/next.h Sun Oct 3 19:50:28 1993 *************** *** 39,43 **** #undef VALUE_REGNO #define VALUE_REGNO(MODE) \ ! (((MODE)==SFmode || (MODE)==DFmode) ? FIRST_FLOAT_REG : 0) /* 1 if N is a possible register number for a function value. */ --- 39,44 ---- #undef VALUE_REGNO #define VALUE_REGNO(MODE) \ ! ((MODE) == SFmode || (MODE) == DFmode || (MODE) == XFmode \ ! ? FIRST_FLOAT_REG : 0) /* 1 if N is a possible register number for a function value. */ *************** *** 46,49 **** --- 47,65 ---- #define FUNCTION_VALUE_REGNO_P(N) ((N) == 0 || (N)== FIRST_FLOAT_REG) + #ifdef REAL_VALUE_TO_TARGET_LONG_DOUBLE + #undef ASM_OUTPUT_LONG_DOUBLE + #define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE) \ + do { \ + long hex[3]; \ + REAL_VALUE_TO_TARGET_LONG_DOUBLE (VALUE, hex); \ + if (sizeof (int) == sizeof (long)) \ + fprintf (FILE, "\t.long 0x%x\n\t.long 0x%x\n\t.long 0x%x\n", \ + hex[0], hex[1], hex[2]); \ + else \ + fprintf (FILE, "\t.long 0x%lx\n\t.long 0x%lx\n\t.long 0x%lx\n", \ + hex[0], hex[1], hex[2]); \ + } while (0) + #endif + #ifdef REAL_VALUE_TO_TARGET_DOUBLE #undef ASM_OUTPUT_DOUBLE *************** *** 52,56 **** long hex[2]; \ REAL_VALUE_TO_TARGET_DOUBLE (VALUE, hex); \ ! fprintf (FILE, "\t.long 0x%x\n\t.long 0x%x\n", hex[0], hex[1]); \ } while (0) #endif --- 68,75 ---- long hex[2]; \ REAL_VALUE_TO_TARGET_DOUBLE (VALUE, hex); \ ! if (sizeof (int) == sizeof (long)) \ ! fprintf (FILE, "\t.long 0x%x\n\t.long 0x%x\n", hex[0], hex[1]); \ ! else \ ! fprintf (FILE, "\t.long 0x%lx\n\t.long 0x%lx\n", hex[0], hex[1]); \ } while (0) #endif *************** *** 64,68 **** long hex; \ REAL_VALUE_TO_TARGET_SINGLE (VALUE, hex); \ ! fprintf (FILE, "\t.long 0x%x\n", hex); \ } while (0) #endif --- 83,90 ---- long hex; \ REAL_VALUE_TO_TARGET_SINGLE (VALUE, hex); \ ! if (sizeof (int) == sizeof (long)) \ ! fprintf (FILE, "\t.long 0x%x\n", hex); \ ! else \ ! fprintf (FILE, "\t.long 0x%lx\n", hex); \ } while (0) #endif *************** *** 111,115 **** #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Di386 -DNeXT -Dunix -D__MACH__ -D__LITTLE_ENDIAN__ -D__ARCHITECTURE__=\"i386\"" /* This accounts for the return pc and saved fp on the i386. */ --- 133,137 ---- #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Di386 -DNeXT -Dunix -D__MACH__ -D__LITTLE_ENDIAN__ -D__ARCHITECTURE__=\"i386\" -Asystem(unix) -Asystem(mach) -Acpu(i386) -Amachine(i386)" /* This accounts for the return pc and saved fp on the i386. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/osfelf.h gcc-2.5.0/config/i386/osfelf.h *** gcc-2.4.5/config/i386/osfelf.h Thu Jun 10 16:30:52 1993 --- gcc-2.5.0/config/i386/osfelf.h Wed Oct 20 22:43:00 1993 *************** *** 22,30 **** #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-DOSF -DOSF1 -Dunix -Di386 -Asystem(unix) -Acpu(i386) -Amachine(i386)" #undef CPP_SPEC #define CPP_SPEC "\ ! %{!mrose: %{!mno-elf: -D__ELF__}} %{mrose: -D__ROSE__} %{mno-elf: -D__ROSE__} \ %{.S: %{!ansi:%{!traditional:%{!traditional-cpp:%{!ftraditional: -traditional}}}}} \ %{.S: -D__LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ --- 22,33 ---- #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-DOSF -DOSF1 -Dunix -Di386 -Asystem(unix) -Asystem(xpg4) -Acpu(i386) -Amachine(i386)" #undef CPP_SPEC #define CPP_SPEC "\ ! %{mrose: -D__ROSE__ %{!pic-none: -D__SHARED__}} \ ! %{!mrose: -D__ELF__ %{fpic: -D__SHARED__}} \ ! %{mno-underscores: -D__NO_UNDERSCORES__} \ ! %{!mrose: %{!munderscores: -D__NO_UNDERSCORES__}} \ %{.S: %{!ansi:%{!traditional:%{!traditional-cpp:%{!ftraditional: -traditional}}}}} \ %{.S: -D__LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ *************** *** 38,51 **** #undef CC1_SPEC #define CC1_SPEC "\ ! %{!melf: %{!mrose: %{!mno-elf: -melf }}} \ %{gline:%{!g:%{!g0:%{!g1:%{!g2: -g1}}}}} \ ! %{pic-none: -mno-half-pic} \ ! %{fpic: -mno-half-pic} \ ! %{fPIC: -mno-half-pic} \ ! %{pic-lib: -mhalf-pic} \ ! %{pic-extern: -mhalf-pic} \ ! %{pic-calls: -mhalf-pic} \ ! %{pic-names*: -mhalf-pic} \ ! %{!pic-*: %{!fpic: %{!fPIC: -mhalf-pic}}}" #undef ASM_SPEC --- 41,50 ---- #undef CC1_SPEC #define CC1_SPEC "\ ! %{!melf: %{!mrose: -melf }} \ ! %{!mrose: %{!munderscores: %{!mno-underscores: -mno-underscores }}} \ %{gline:%{!g:%{!g0:%{!g1:%{!g2: -g1}}}}} \ ! %{mrose: %{pic-none: -mno-half-pic} \ ! %{pic-extern: } %{pic-lib: } %{pic-calls: } %{pic-names*: } \ ! %{!pic-none: -mhalf-pic }}" #undef ASM_SPEC *************** *** 53,57 **** #undef LINK_SPEC ! #define LINK_SPEC "%{noshrlib: } %{glue: }" #undef TARGET_VERSION_INTERNAL --- 52,67 ---- #undef LINK_SPEC ! #define LINK_SPEC "%{v*: -v} \ ! %{mrose: %{!noshrlib: %{pic-none: -noshrlib} %{!pic-none: -warn_nopic}} \ ! %{nostdlib} %{noshrlib} %{glue}} \ ! %{!mrose: %{dy} %{dn} %{glue: } \ ! %{h*} %{z*} \ ! %{static:-dn -Bstatic} \ ! %{shared:-G -dy} \ ! %{symbolic:-Bsymbolic -G -dy} \ ! %{G:-G} \ ! %{!dy: %{!dn: %{!static: %{!shared: %{!symbolic: \ ! %{noshrlib: -dn } %{pic-none: -dn } \ ! %{!noshrlib: %{!pic-none: -dy}}}}}}}}" #undef TARGET_VERSION_INTERNAL diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/osfrose.h gcc-2.5.0/config/i386/osfrose.h *** gcc-2.4.5/config/i386/osfrose.h Thu Jun 10 16:30:51 1993 --- gcc-2.5.0/config/i386/osfrose.h Wed Oct 20 22:42:59 1993 *************** *** 1,5 **** /* Definitions of target machine for GNU compiler. Intel 386 (OSF/1 with OSF/rose) version. ! Copyright (C) 1991 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,5 ---- /* Definitions of target machine for GNU compiler. Intel 386 (OSF/1 with OSF/rose) version. ! Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. This file is part of GNU CC. *************** *** 19,25 **** the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - /* Put leading underscores in front of names. */ - #define YES_UNDERSCORES - #include "halfpic.h" #include "i386/gstabs.h" --- 19,22 ---- *************** *** 34,37 **** --- 31,52 ---- (DEFAULT_WORD_SWITCH_TAKES_ARG (STR) || !strcmp (STR, "pic-names")) + /* This defines which switch letters take arguments. On svr4, most of + the normal cases (defined in gcc.c) apply, and we also have -h* and + -z* options (for the linker). */ + + #define SWITCH_TAKES_ARG(CHAR) \ + ( (CHAR) == 'D' \ + || (CHAR) == 'U' \ + || (CHAR) == 'o' \ + || (CHAR) == 'e' \ + || (CHAR) == 'T' \ + || (CHAR) == 'u' \ + || (CHAR) == 'I' \ + || (CHAR) == 'm' \ + || (CHAR) == 'L' \ + || (CHAR) == 'A' \ + || (CHAR) == 'h' \ + || (CHAR) == 'z') + #define MASK_HALF_PIC 0x40000000 /* Mask for half-pic code */ #define MASK_HALF_PIC_DEBUG 0x20000000 /* Debug flag */ *************** *** 38,48 **** #define MASK_ELF 0x10000000 /* ELF not rose */ #define MASK_NO_IDENT 0x08000000 /* suppress .ident */ ! ! #define TARGET_HALF_PIC (target_flags & MASK_HALF_PIC) ! #define TARGET_DEBUG (target_flags & MASK_HALF_PIC_DEBUG) ! #define HALF_PIC_DEBUG TARGET_DEBUG ! #define TARGET_ELF (target_flags & MASK_ELF) ! #define TARGET_ROSE ((target_flags & MASK_ELF) == 0) ! #define TARGET_IDENT ((target_flags & MASK_NO_IDENT) == 0) #undef SUBTARGET_SWITCHES --- 53,69 ---- #define MASK_ELF 0x10000000 /* ELF not rose */ #define MASK_NO_IDENT 0x08000000 /* suppress .ident */ ! #define MASK_NO_UNDERSCORES 0x04000000 /* suppress leading _ */ ! #define MASK_LARGE_ALIGN 0x02000000 /* align to >word boundaries */ ! #define MASK_NO_MCOUNT 0x01000000 /* profiling uses mcount_ptr */ ! ! #define TARGET_HALF_PIC (target_flags & MASK_HALF_PIC) ! #define TARGET_DEBUG (target_flags & MASK_HALF_PIC_DEBUG) ! #define HALF_PIC_DEBUG TARGET_DEBUG ! #define TARGET_ELF (target_flags & MASK_ELF) ! #define TARGET_ROSE ((target_flags & MASK_ELF) == 0) ! #define TARGET_IDENT ((target_flags & MASK_NO_IDENT) == 0) ! #define TARGET_UNDERSCORES ((target_flags & MASK_NO_UNDERSCORES) == 0) ! #define TARGET_LARGE_ALIGN (target_flags & MASK_LARGE_ALIGN) ! #define TARGET_MCOUNT ((target_flags & MASK_NO_MCOUNT) == 0) #undef SUBTARGET_SWITCHES *************** *** 50,59 **** { "half-pic", MASK_HALF_PIC}, \ { "no-half-pic", -MASK_HALF_PIC}, \ { "debugb", MASK_HALF_PIC_DEBUG}, \ { "elf", MASK_ELF}, \ - { "no-elf", -MASK_ELF}, \ { "rose", -MASK_ELF}, \ { "ident", -MASK_NO_IDENT}, \ ! { "no-ident", MASK_NO_IDENT}, /* OSF/rose uses stabs, not dwarf. */ --- 71,86 ---- { "half-pic", MASK_HALF_PIC}, \ { "no-half-pic", -MASK_HALF_PIC}, \ + { "debug-half-pic", MASK_HALF_PIC_DEBUG}, \ { "debugb", MASK_HALF_PIC_DEBUG}, \ { "elf", MASK_ELF}, \ { "rose", -MASK_ELF}, \ { "ident", -MASK_NO_IDENT}, \ ! { "no-ident", MASK_NO_IDENT}, \ ! { "underscores", -MASK_NO_UNDERSCORES}, \ ! { "no-underscores", MASK_NO_UNDERSCORES}, \ ! { "large-align", MASK_LARGE_ALIGN}, \ ! { "no-large-align",-MASK_LARGE_ALIGN}, \ ! { "mcount", -MASK_NO_MCOUNT}, \ ! { "no-mcount", MASK_NO_MCOUNT}, /* OSF/rose uses stabs, not dwarf. */ *************** *** 70,78 **** /* Change default predefines. */ #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-DOSF -DOSF1 -Dunix -Di386 -Asystem(unix) -Acpu(i386) -Amachine(i386)" #undef CPP_SPEC #define CPP_SPEC "\ ! %{!melf: -D__ROSE__} %{melf: -D__ELF__} \ %{.S: %{!ansi:%{!traditional:%{!traditional-cpp:%{!ftraditional: -traditional}}}}} \ %{.S: -D__LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ --- 97,108 ---- /* Change default predefines. */ #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-DOSF -DOSF1 -Dunix -Di386 -Asystem(unix) -Asystem(xpg4) -Acpu(i386) -Amachine(i386)" #undef CPP_SPEC #define CPP_SPEC "\ ! %{!melf: -D__ROSE__ %{!pic-none: -D__SHARED__}} \ ! %{melf: -D__ELF__ %{fpic: -D__SHARED__}} \ ! %{mno-underscores: -D__NO_UNDERSCORES__} \ ! %{melf: %{!munderscores: -D__NO_UNDERSCORES__}} \ %{.S: %{!ansi:%{!traditional:%{!traditional-cpp:%{!ftraditional: -traditional}}}}} \ %{.S: -D__LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ *************** *** 83,99 **** %{!.S: -D__LANGUAGE_C %{!ansi:-DLANGUAGE_C}}" ! /* Turn on -mpic-extern by default. */ #undef CC1_SPEC #define CC1_SPEC "\ ! %{!melf: %{!mrose: %{!mno-elf: -mrose }}} \ %{gline:%{!g:%{!g0:%{!g1:%{!g2: -g1}}}}} \ ! %{pic-none: -mno-half-pic} \ ! %{fpic: -mno-half-pic} \ ! %{fPIC: -mno-half-pic} \ ! %{pic-lib: -mhalf-pic} \ ! %{pic-extern: -mhalf-pic} \ ! %{pic-calls: -mhalf-pic} \ ! %{pic-names*: -mhalf-pic} \ ! %{!pic-*: %{!fpic: %{!fPIC: -mhalf-pic}}}" #undef ASM_SPEC --- 113,125 ---- %{!.S: -D__LANGUAGE_C %{!ansi:-DLANGUAGE_C}}" ! /* Turn on -pic-extern by default. */ #undef CC1_SPEC #define CC1_SPEC "\ ! %{!melf: %{!mrose: -mrose }} \ ! %{melf: %{!munderscores: %{!mno-underscores: -mno-underscores }}} \ %{gline:%{!g:%{!g0:%{!g1:%{!g2: -g1}}}}} \ ! %{!melf: %{pic-none: -mno-half-pic} \ ! %{pic-extern: } %{pic-lib: } %{pic-calls: } %{pic-names*: } \ ! %{!pic-none: -mhalf-pic }}" #undef ASM_SPEC *************** *** 101,107 **** #undef LINK_SPEC ! #define LINK_SPEC "%{v*: -v} \ ! %{!noshrlib: %{pic-none: -noshrlib} %{!pic-none: -warn_nopic}} \ ! %{nostdlib} %{noshrlib} %{glue}" #undef LIB_SPEC --- 127,142 ---- #undef LINK_SPEC ! #define LINK_SPEC "%{v*: -v} \ ! %{!melf: %{!noshrlib: %{pic-none: -noshrlib} %{!pic-none: -warn_nopic}} \ ! %{nostdlib} %{noshrlib} %{glue}} \ ! %{melf: %{dy} %{dn} %{glue: } \ ! %{h*} %{z*} \ ! %{static:-dn -Bstatic} \ ! %{shared:-G -dy} \ ! %{symbolic:-Bsymbolic -G -dy} \ ! %{G:-G} \ ! %{!dy: %{!dn: %{!static: %{!shared: %{!symbolic: \ ! %{noshrlib: -dn } %{pic-none: -dn } \ ! %{!noshrlib: %{!pic-none: -dy}}}}}}}}" #undef LIB_SPEC *************** *** 142,150 **** #undef LONG_DOUBLE_TYPE_SIZE ! /* Tell final.c we don't need a label passed to mcount. */ ! #define NO_PROFILE_DATA #undef FUNCTION_PROFILER ! #define FUNCTION_PROFILER(FILE, LABELNO) fprintf (FILE, "\tcall _mcount\n") /* A C expression that is 1 if the RTX X is a constant which is a --- 177,487 ---- #undef LONG_DOUBLE_TYPE_SIZE ! /* 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. ! ! We override it here to allow for the new profiling code to go before ! the prologue and the old mcount code to go after the prologue (and ! after %ebx has been set up for ELF shared library support). */ ! ! #define OSF_PROFILE_BEFORE_PROLOGUE \ ! (!TARGET_MCOUNT \ ! && !current_function_needs_context \ ! && (!flag_pic \ ! || !frame_pointer_needed \ ! || (!current_function_uses_pic_offset_table \ ! && !current_function_uses_const_pool))) ! ! #undef FUNCTION_PROLOGUE ! #define FUNCTION_PROLOGUE(FILE, SIZE) \ ! do \ ! { \ ! char *prefix = (TARGET_UNDERSCORES) ? "_" : ""; \ ! char *lprefix = LPREFIX; \ ! int labelno = profile_label_no; \ ! \ ! if (profile_flag && OSF_PROFILE_BEFORE_PROLOGUE) \ ! { \ ! if (!flag_pic && !HALF_PIC_P ()) \ ! { \ ! fprintf (FILE, "\tmovl $%sP%d,%%edx\n", lprefix, labelno); \ ! fprintf (FILE, "\tcall *%s_mcount_ptr\n", prefix); \ ! } \ ! \ ! else if (HALF_PIC_P ()) \ ! { \ ! rtx symref; \ ! \ ! HALF_PIC_EXTERNAL ("_mcount_ptr"); \ ! symref = HALF_PIC_PTR (gen_rtx (SYMBOL_REF, Pmode, \ ! "_mcount_ptr")); \ ! \ ! fprintf (FILE, "\tmovl $%sP%d,%%edx\n", lprefix, labelno); \ ! fprintf (FILE, "\tmovl %s%s,%%eax\n", prefix, \ ! XSTR (symref, 0)); \ ! fprintf (FILE, "\tcall *(%%eax)\n"); \ ! } \ ! \ ! else \ ! { \ ! static int call_no = 0; \ ! \ ! fprintf (FILE, "\tcall %sPc%d\n", lprefix, call_no); \ ! fprintf (FILE, "%sPc%d:\tpopl %%eax\n", lprefix, call_no); \ ! fprintf (FILE, "\taddl $_GLOBAL_OFFSET_TABLE_+[.-%sPc%d],%%eax\n", \ ! lprefix, call_no++); \ ! fprintf (FILE, "\tleal $%sP%d@GOTOFF(%%eax),%%edx\n", \ ! lprefix, labelno); \ ! fprintf (FILE, "\tmovl %s_mcount_ptr@GOT(%%eax),%%eax\n", \ ! prefix); \ ! fprintf (FILE, "\tcall *(%%eax)\n"); \ ! } \ ! } \ ! \ ! function_prologue (FILE, SIZE); \ ! } \ ! while (0) ! ! /* A C statement or compound statement to output to FILE some assembler code to ! call the profiling subroutine `mcount'. Before calling, the assembler code ! must load the address of a counter variable into a register where `mcount' ! expects to find the address. The name of this variable is `LP' followed by ! the number LABELNO, so you would generate the name using `LP%d' in a ! `fprintf'. ! ! The details of how the address should be passed to `mcount' are determined ! by your operating system environment, not by GNU CC. To figure them out, ! compile a small program for profiling using the system's installed C ! compiler and look at the assembler code that results. */ #undef FUNCTION_PROFILER ! #define FUNCTION_PROFILER(FILE, LABELNO) \ ! do \ ! { \ ! if (!OSF_PROFILE_BEFORE_PROLOGUE) \ ! { \ ! char *prefix = (TARGET_UNDERSCORES) ? "_" : ""; \ ! char *lprefix = LPREFIX; \ ! int labelno = LABELNO; \ ! \ ! /* Note that OSF/rose blew it in terms of calling mcount, \ ! since OSF/rose prepends a leading underscore, but mcount's \ ! doesn't. At present, we keep this kludge for ELF as well \ ! to allow old kernels to build profiling. */ \ ! \ ! if (flag_pic \ ! && !current_function_uses_pic_offset_table \ ! && !current_function_uses_const_pool) \ ! abort (); \ ! \ ! if (TARGET_MCOUNT && flag_pic) \ ! { \ ! fprintf (FILE, "\tleal %sP%d@GOTOFF(%%ebx),%%edx\n", \ ! lprefix, labelno); \ ! fprintf (FILE, "\tcall *%smcount@GOT(%%ebx)\n", prefix); \ ! } \ ! \ ! else if (TARGET_MCOUNT && HALF_PIC_P ()) \ ! { \ ! rtx symdef; \ ! \ ! HALF_PIC_EXTERNAL ("mcount"); \ ! symdef = HALF_PIC_PTR (gen_rtx (SYMBOL_REF, Pmode, "mcount")); \ ! fprintf (FILE, "\tmovl $%sP%d,%%edx\n", lprefix, labelno); \ ! fprintf (FILE, "\tcall *%s%s\n", prefix, XSTR (symdef, 0)); \ ! } \ ! \ ! else if (TARGET_MCOUNT) \ ! { \ ! fprintf (FILE, "\tmovl $%sP%d,%%edx\n", lprefix, labelno); \ ! fprintf (FILE, "\tcall %smcount\n", prefix); \ ! } \ ! \ ! else if (flag_pic && frame_pointer_needed) \ ! { \ ! fprintf (FILE, "\tmovl 4(%%ebp),%%ecx\n"); \ ! fprintf (FILE, "\tpushl %%ecx\n"); \ ! fprintf (FILE, "\tleal $%sP%d@GOTOFF(%%ebx),%%edx\n", \ ! lprefix, labelno); \ ! fprintf (FILE, "\tmovl _mcount_ptr@GOT(%%eax),%%eax\n"); \ ! fprintf (FILE, "\tcall *(%%eax)\n"); \ ! fprintf (FILE, "\tpopl %%eax\n"); \ ! } \ ! \ ! else if (frame_pointer_needed) \ ! { \ ! fprintf (FILE, "\tmovl 4(%%ebp),%%ecx\n"); \ ! fprintf (FILE, "\tpushl %%ecx\n"); \ ! fprintf (FILE, "\tmovl $%sP%d,%%edx\n", lprefix, labelno); \ ! fprintf (FILE, "\tcall *_mcount_ptr\n"); \ ! fprintf (FILE, "\tpopl %%eax\n"); \ ! } \ ! \ ! else \ ! abort (); \ ! } \ ! } \ ! while (0) ! ! /* A C statement or compound statement to output to FILE some ! assembler code to initialize basic-block profiling for the current ! object module. This code should call the subroutine ! `__bb_init_func' once per object module, passing it as its sole ! argument the address of a block allocated in the object module. ! ! The name of the block is a local symbol made with this statement: ! ! ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 0); ! ! Of course, since you are writing the definition of ! `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you ! can take a short cut in the definition of this macro and use the ! name that you know will result. ! ! The first word of this block is a flag which will be nonzero if the ! object module has already been initialized. So test this word ! first, and do not call `__bb_init_func' if the flag is nonzero. */ ! ! #undef FUNCTION_BLOCK_PROFILER ! #define FUNCTION_BLOCK_PROFILER(STREAM, LABELNO) \ ! do \ ! { \ ! if (!flag_pic) \ ! { \ ! fprintf (STREAM, "\tcmpl $0,%sPBX0\n", LPREFIX); \ ! fprintf (STREAM, "\tjne 0f\n"); \ ! fprintf (STREAM, "\tpushl $%sPBX0\n", LPREFIX); \ ! fprintf (STREAM, "\tcall %s__bb_init_func\n", \ ! (TARGET_UNDERSCORES) ? "_" : ""); \ ! fprintf (STREAM, "0:\n"); \ ! } \ ! else \ ! { \ ! fprintf (STREAM, "\tpushl %eax\n"); \ ! fprintf (STREAM, "\tmovl %sPBX0@GOT(%ebx),%eax\n"); \ ! fprintf (STREAM, "\tcmpl $0,(%eax)\n"); \ ! fprintf (STREAM, "\tjne 0f\n"); \ ! fprintf (STREAM, "\tpushl %eax\n"); \ ! fprintf (STREAM, "\tcall %s__bb_init_func@PLT\n", \ ! (TARGET_UNDERSCORES) ? "_" : ""); \ ! fprintf (STREAM, "0:\n"); \ ! fprintf (STREAM, "\tpopl %eax\n"); \ ! } \ ! } \ ! while (0) ! ! /* A C statement or compound statement to increment the count ! associated with the basic block number BLOCKNO. Basic blocks are ! numbered separately from zero within each compilation. The count ! associated with block number BLOCKNO is at index BLOCKNO in a ! vector of words; the name of this array is a local symbol made ! with this statement: ! ! ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 2); ! ! Of course, since you are writing the definition of ! `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you ! can take a short cut in the definition of this macro and use the ! name that you know will result. */ ! ! #undef BLOCK_PROFILER ! #define BLOCK_PROFILER(STREAM, BLOCKNO) \ ! do \ ! { \ ! if (!flag_pic) \ ! fprintf (STREAM, "\tincl %sPBX2+%d\n", LPREFIX, (BLOCKNO)*4); \ ! else \ ! { \ ! fprintf (STREAM, "\tpushl %eax\n"); \ ! fprintf (STREAM, "\tmovl %sPBX2@GOT(%ebx),%eax\n", LPREFIX); \ ! fprintf (STREAM, "\tincl %d(%eax)\n", (BLOCKNO)*4); \ ! fprintf (STREAM, "\tpopl %eax\n"); \ ! } \ ! } \ ! while (0) ! ! /* A C function or functions which are needed in the library to ! support block profiling. When support goes into libc, undo ! the #if 0. */ ! ! #if 0 ! #undef BLOCK_PROFILING_CODE ! #define BLOCK_PROFILING_CODE ! #endif ! ! /* Prefix for internally generated assembler labels. If we aren't using ! underscores, we are using prefix `.'s to identify labels that should ! be ignored, as in `i386/gas.h' --karl@cs.umb.edu */ ! #undef LPREFIX ! #define LPREFIX ((TARGET_UNDERSCORES) ? "L" : ".L") ! ! /* This is how to store into the string BUF ! 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'. */ ! ! #undef ASM_GENERATE_INTERNAL_LABEL ! #define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \ ! sprintf ((BUF), "*%s%s%d", (TARGET_UNDERSCORES) ? "" : ".", \ ! (PREFIX), (NUMBER)) ! ! /* This is how to output an internal numbered label where ! PREFIX is the class of label and NUM is the number within the class. */ ! ! #undef ASM_OUTPUT_INTERNAL_LABEL ! #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ ! fprintf (FILE, "%s%s%d:\n", (TARGET_UNDERSCORES) ? "" : ".", \ ! PREFIX, NUM) ! ! /* This is how to output a reference to a user-level label named NAME. */ ! ! #undef ASM_OUTPUT_LABELREF ! #define ASM_OUTPUT_LABELREF(FILE,NAME) \ ! fprintf (FILE, "%s%s", (TARGET_UNDERSCORES) ? "_" : "", NAME) ! ! /* This is how to output an element of a case-vector that is relative. ! This is only used for PIC code. See comments by the `casesi' insn in ! i386.md for an explanation of the expression this outputs. */ ! ! #undef ASM_OUTPUT_ADDR_DIFF_ELT ! #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ ! fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, VALUE) ! ! /* A C expression to output text to align the location counter in the ! way that is desirable at a point in the code that is reached only ! by jumping. ! ! This macro need not be defined if you don't want any special ! alignment to be done at such a time. Most machine descriptions do ! not currently define the macro. */ ! ! #undef ASM_OUTPUT_ALIGN_CODE ! #define ASM_OUTPUT_ALIGN_CODE(STREAM) \ ! fprintf (STREAM, "\t.align\t%d\n", \ ! (TARGET_486 && TARGET_LARGE_ALIGN) ? 4 : 2) ! ! /* A C expression to output text to align the location counter in the ! way that is desirable at the beginning of a loop. ! ! This macro need not be defined if you don't want any special ! alignment to be done at such a time. Most machine descriptions do ! not currently define the macro. */ ! ! #undef ASM_OUTPUT_LOOP_ALIGN ! #define ASM_OUTPUT_LOOP_ALIGN(STREAM) \ ! fprintf (STREAM, "\t.align\t2\n") ! ! /* A C statement to output to the stdio stream STREAM an assembler ! command to advance the location counter to a multiple of 2 to the ! POWER bytes. POWER will be a C expression of type `int'. */ ! ! #undef ASM_OUTPUT_ALIGN ! #define ASM_OUTPUT_ALIGN(STREAM, POWER) \ ! fprintf (STREAM, "\t.align\t%d\n", \ ! (!TARGET_LARGE_ALIGN && (POWER) > 2) ? 2 : (POWER)) /* A C expression that is 1 if the RTX X is a constant which is a *************** *** 237,241 **** been parsed. */ ! #define OVERRIDE_OPTIONS \ { \ /* \ --- 574,579 ---- been parsed. */ ! #undef SUBTARGET_OVERRIDE_OPTIONS ! #define SUBTARGET_OVERRIDE_OPTIONS \ { \ /* \ *************** *** 285,293 **** do \ { \ ! if (HALF_PIC_P ()) \ HALF_PIC_ENCODE (DECL); \ } \ while (0) /* Given a decl node or constant node, choose the section to output it in --- 623,675 ---- do \ { \ ! if (HALF_PIC_P ()) \ HALF_PIC_ENCODE (DECL); \ + \ + else if (flag_pic) \ + { \ + rtx rtl = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ + ? TREE_CST_RTL (DECL) : DECL_RTL (DECL)); \ + SYMBOL_REF_FLAG (XEXP (rtl, 0)) \ + = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ + || ! TREE_PUBLIC (DECL)); \ + } \ + } \ + while (0) + + + /* On most machines, read-only variables, constants, and jump tables + are placed in the text section. If this is not the case on your + machine, this macro should be defined to be the name of a function + (either `data_section' or a function defined in `EXTRA_SECTIONS') + that switches to the section to be used for read-only items. + + If these items should be placed in the text section, this macro + should not be defined. */ + + #if 0 + #undef READONLY_DATA_SECTION + #define READONLY_DATA_SECTION() \ + do \ + { \ + if (TARGET_ELF) \ + { \ + if (in_section != in_rodata) \ + { \ + fprintf (asm_out_file, "\t.section \"rodata\"\n"); \ + in_section = in_rodata; \ + } \ + } \ + else \ + text_section (); \ } \ while (0) + #endif + + /* A list of names for sections other than the standard two, which are + `in_text' and `in_data'. You need not define this macro on a + system with no other sections (that GCC needs to use). */ + #undef EXTRA_SECTIONS + #define EXTRA_SECTIONS in_rodata, in_data1 /* Given a decl node or constant node, choose the section to output it in *************** *** 339,342 **** --- 721,725 ---- #define SIZE_ASM_OP ".size" #define WEAK_ASM_OP ".weak" + #define SET_ASM_OP ".set" /* The following macro defines the format used to output the second *************** *** 359,384 **** #undef ASM_DECLARE_OBJECT_NAME ! #define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL) \ ! do \ ! { \ ! ASM_OUTPUT_LABEL(STREAM,NAME); \ ! HALF_PIC_DECLARE (NAME); \ ! if (TARGET_ELF) \ ! { \ ! fprintf (STREAM, "\t%s\t ", TYPE_ASM_OP); \ ! assemble_name (STREAM, NAME); \ ! putc (',', STREAM); \ ! fprintf (STREAM, TYPE_OPERAND_FMT, "object"); \ ! putc ('\n', STREAM); \ ! if (!flag_inhibit_size_directive) \ ! { \ ! fprintf (STREAM, "\t%s\t ", SIZE_ASM_OP); \ ! assemble_name (STREAM, NAME); \ ! fprintf (STREAM, ",%d\n", int_size_in_bytes (TREE_TYPE (decl))); \ ! } \ ! } \ ! } \ while (0) /* This is how to declare a function name. */ --- 742,790 ---- #undef ASM_DECLARE_OBJECT_NAME ! #define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL) \ ! do \ ! { \ ! ASM_OUTPUT_LABEL(STREAM,NAME); \ ! HALF_PIC_DECLARE (NAME); \ ! if (TARGET_ELF) \ ! { \ ! fprintf (STREAM, "\t%s\t ", TYPE_ASM_OP); \ ! assemble_name (STREAM, NAME); \ ! putc (',', STREAM); \ ! fprintf (STREAM, TYPE_OPERAND_FMT, "object"); \ ! putc ('\n', STREAM); \ ! size_directive_output = 0; \ ! if (!flag_inhibit_size_directive && DECL_SIZE (DECL)) \ ! { \ ! size_directive_output = 1; \ ! fprintf (STREAM, "\t%s\t ", SIZE_ASM_OP); \ ! assemble_name (STREAM, NAME); \ ! fprintf (STREAM, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \ ! } \ ! } \ ! } \ while (0) + /* Output the size directive for a decl in rest_of_decl_compilation + in the case where we did not do so before the initializer. + Once we find the error_mark_node, we know that the value of + size_directive_output was set + by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */ + + #define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \ + do { \ + char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \ + if (TARGET_ELF \ + && !flag_inhibit_size_directive && DECL_SIZE (DECL) \ + && ! AT_END && TOP_LEVEL \ + && DECL_INITIAL (DECL) == error_mark_node \ + && !size_directive_output) \ + { \ + fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ + assemble_name (FILE, name); \ + fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \ + } \ + } while (0) + /* This is how to declare a function name. */ *************** *** 421,425 **** ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno); \ ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno); \ ! fprintf (FILE, "/\t%s\t ", SIZE_ASM_OP); \ assemble_name (FILE, (FNAME)); \ fprintf (FILE, ","); \ --- 827,831 ---- ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno); \ ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno); \ ! fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ assemble_name (FILE, (FNAME)); \ fprintf (FILE, ","); \ *************** *** 452,458 **** if (TARGET_IDENT) \ { \ ! fprintf ((STREAM), "\t%s\t\"GCC: (GNU) %s -O%d", \ ! IDENT_ASM_OP, version_string, optimize); \ \ if (write_symbols == PREFERRED_DEBUGGING_TYPE) \ fprintf ((STREAM), " -g%d", (int)debug_info_level); \ --- 858,877 ---- if (TARGET_IDENT) \ { \ ! char *fstart = main_input_filename; \ ! char *fname; \ ! \ ! if (!fstart) \ ! fstart = ""; \ ! \ ! fname = fstart + strlen (fstart) - 1; \ ! while (fname > fstart && *fname != '/') \ ! fname--; \ \ + if (*fname == '/') \ + fname++; \ + \ + fprintf ((STREAM), "\t%s\t\"GCC: (GNU) %s %s -O%d", \ + IDENT_ASM_OP, version_string, fname, optimize); \ + \ if (write_symbols == PREFERRED_DEBUGGING_TYPE) \ fprintf ((STREAM), " -g%d", (int)debug_info_level); \ *************** *** 551,558 **** /* This is how to output an assembler line defining a `double' constant. */ - #undef ASM_OUTPUT_DOUBLE - - #ifndef CROSS_COMPILE #define ASM_OUTPUT_DOUBLE(STREAM, VALUE) \ do \ --- 970,974 ---- *************** *** 559,579 **** { \ long value_long[2]; \ REAL_VALUE_TO_TARGET_DOUBLE (VALUE, value_long); \ ! \ ! fprintf (STREAM, "\t.long\t0x%08lx\t\t# %.20g\n\t.long\t0x%08lx\n", \ ! value_long[0], VALUE, value_long[1]); \ } \ while (0) - #else - #define ASM_OUTPUT_DOUBLE(STREAM, VALUE) \ - fprintf (STREAM, "\t.double\t%.20g\n", VALUE) - #endif - /* This is how to output an assembler line defining a `float' constant. */ - #undef ASM_OUTPUT_FLOAT - - #ifndef CROSS_COMPILE #define ASM_OUTPUT_FLOAT(STREAM, VALUE) \ do \ --- 975,992 ---- { \ long value_long[2]; \ + char dstr[30]; \ REAL_VALUE_TO_TARGET_DOUBLE (VALUE, value_long); \ ! REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr); \ ! if (sizeof (int) == sizeof (long)) \ ! fprintf (STREAM, "\t.long\t0x%08x\t\t# %s\n\t.long\t0x%08x\n", \ ! value_long[0], dstr, value_long[1]); \ ! else \ ! fprintf (STREAM, "\t.long\t0x%08lx\t\t# %s\n\t.long\t0x%08lx\n", \ ! value_long[0], dstr, value_long[1]); \ } \ while (0) /* This is how to output an assembler line defining a `float' constant. */ #undef ASM_OUTPUT_FLOAT #define ASM_OUTPUT_FLOAT(STREAM, VALUE) \ do \ *************** *** 580,595 **** { \ long value_long; \ REAL_VALUE_TO_TARGET_SINGLE (VALUE, value_long); \ ! \ ! fprintf (STREAM, "\t.long\t0x%08lx\t\t# %.12g (float)\n", \ ! value_long, VALUE); \ } \ while (0) ! #else ! #define ASM_OUTPUT_FLOAT(STREAM, VALUE) \ ! fprintf (STREAM, "\t.float\t%.12g\n", VALUE) ! #endif ! /* Generate calls to memcpy, etc., not bcopy, etc. */ --- 993,1024 ---- { \ long value_long; \ + char dstr[30]; \ REAL_VALUE_TO_TARGET_SINGLE (VALUE, value_long); \ ! REAL_VALUE_TO_DECIMAL (VALUE, "%.12g", dstr); \ ! if (sizeof (int) == sizeof (long)) \ ! fprintf (STREAM, "\t.long\t0x%08x\t\t# %s (float)\n", \ ! value_long, dstr); \ ! else \ ! fprintf (STREAM, "\t.long\t0x%08lx\t\t# %s (float)\n", \ ! value_long, dstr); \ } \ while (0) ! /* This is how to output an assembler line for a `long double' constant. */ ! #undef ASM_OUTPUT_LONG_DOUBLE ! #define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE) \ ! do { long l[3]; \ ! char dstr[30]; \ ! REAL_VALUE_TO_TARGET_LONG_DOUBLE (VALUE, l); \ ! REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr); \ ! if (sizeof (int) == sizeof (long)) \ ! fprintf (FILE, \ ! "\t.long\t0x%08x\t\t# %s\n\t.long\t0x%08x\n\t.long\t0x%08x\n", \ ! l[0], dstr, l[1], l[2]); \ ! else \ ! fprintf (FILE, \ ! "\t.long\t0x%08lx\t\t# %s\n\t.long\t0x%08lx\n\t.long\t0x%08lx\n", \ ! l[0], dstr, l[1], l[2]); \ ! } while (0) /* Generate calls to memcpy, etc., not bcopy, etc. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/perform.h gcc-2.5.0/config/i386/perform.h *** gcc-2.4.5/config/i386/perform.h Fri Jan 8 03:40:57 1993 --- gcc-2.5.0/config/i386/perform.h Sun Jun 27 23:43:46 1993 *************** *** 1,4 **** /* Definitions for AT&T assembler syntax for the Intel 80386. ! Copyright (C) 1988 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,4 ---- /* Definitions for AT&T assembler syntax for the Intel 80386. ! Copyright (C) 1992 Free Software Foundation, Inc. This file is part of GNU CC. diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/sco.h gcc-2.5.0/config/i386/sco.h *** gcc-2.4.5/config/i386/sco.h Sat May 8 17:06:12 1993 --- gcc-2.5.0/config/i386/sco.h Wed Oct 20 01:10:06 1993 *************** *** 17,20 **** --- 17,25 ---- #define TARGET_DEFAULT 0201 + /* Let's guess that the SCO software FPU emulator can't handle + 80-bit XFmode insns, so don't generate them. */ + #undef LONG_DOUBLE_TYPE_SIZE + #define LONG_DOUBLE_TYPE_SIZE 64 + /* Use crt1.o as a startup file and crtn.o as a closing file. */ *************** *** 34,38 **** #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dunix -Di386 -DM_UNIX -DM_I386 -DM_COFF -DM_WORDSWAP" #undef CPP_SPEC --- 39,43 ---- #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dunix -Di386 -DM_UNIX -DM_I386 -DM_COFF -DM_WORDSWAP -Asystem(unix) -Asystem(svr3) -Acpu(i386) -Amachine(i386)" #undef CPP_SPEC *************** *** 63,67 **** #undef VALUE_REGNO #define VALUE_REGNO(MODE) \ ! ((TARGET_80387 && ((MODE) == SFmode || (MODE) == DFmode)) ? FIRST_FLOAT_REG : 0) --- 68,73 ---- #undef VALUE_REGNO #define VALUE_REGNO(MODE) \ ! ((TARGET_80387 ! && ((MODE) == SFmode || (MODE) == DFmode || (MODE) == XFmode) ? FIRST_FLOAT_REG : 0) *************** *** 89,91 **** : 0) /* On other 386 systems, the last line looks like this: ! : (aggregate_value_p (FUNTYPE)) ? GET_MODE_SIZE (Pmode) : 0) */ --- 95,97 ---- : 0) /* On other 386 systems, the last line looks like this: ! : (aggregate_value_p (TREE_TYPE (FUNTYPE))) ? GET_MODE_SIZE (Pmode) : 0) */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/sco4.h gcc-2.5.0/config/i386/sco4.h *** gcc-2.4.5/config/i386/sco4.h Mon May 24 01:40:12 1993 --- gcc-2.5.0/config/i386/sco4.h Sun Oct 3 19:50:39 1993 *************** *** 62,66 **** #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Di386 -Dunix" #undef CPP_SPEC --- 62,66 ---- #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Di386 -Dunix -Asystem(unix) -Asystem(svr3) -Acpu(i386) -Amachine(i386)" #undef CPP_SPEC *************** *** 80,98 **** %{scointl:-D_M_INTERNAT -DM_INTERNAT} \ %{traditional:-D_KR -D_SVID -D_NO_PROTOTYPE}}}}" - - /* Assembler bugs are suspected in floating constants. - So output them as hex. */ - - #undef ASM_OUTPUT_DOUBLE - #define ASM_OUTPUT_DOUBLE(FILE,VALUE) \ - do { long l[2]; \ - REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l); \ - fprintf (FILE, "%s 0x%x,0x%x\n", ASM_LONG, l[0], l[1]); \ - } while (0) - - #undef ASM_OUTPUT_FLOAT - #define ASM_OUTPUT_FLOAT(FILE,VALUE) \ - do { long l; \ - REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \ - fprintf ((FILE), "%s 0x%x\n", ASM_LONG, l); \ - } while (0) --- 80,81 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/sco4dbx.h gcc-2.5.0/config/i386/sco4dbx.h *** gcc-2.4.5/config/i386/sco4dbx.h Sat Mar 6 03:05:31 1993 --- gcc-2.5.0/config/i386/sco4dbx.h Sat Oct 2 04:18:50 1993 *************** *** 61,65 **** #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Di386 -Dunix" #undef CPP_SPEC --- 61,65 ---- #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Di386 -Dunix -Asystem(unix) -Asystem(svr3) -Acpu(i386) -Amachine(i386)" #undef CPP_SPEC diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/scodbx.h gcc-2.5.0/config/i386/scodbx.h *** gcc-2.4.5/config/i386/scodbx.h Sat Mar 6 03:14:18 1993 --- gcc-2.5.0/config/i386/scodbx.h Sat Oct 2 04:18:53 1993 *************** *** 50,54 **** #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dunix -Di386 -DM_UNIX -DM_I386 -DM_COFF -DM_WORDSWAP" #undef CPP_SPEC --- 50,54 ---- #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dunix -Di386 -DM_UNIX -DM_I386 -DM_COFF -DM_WORDSWAP -Asystem(unix) -Asystem(svr3) -Acpu(i386) -Amachine(i386)" #undef CPP_SPEC *************** *** 82,86 **** : 0) /* On other 386 systems, the last line looks like this: ! : (aggregate_value_p (FUNTYPE)) ? GET_MODE_SIZE (Pmode) : 0) */ /* Use periods rather than dollar signs in special g++ assembler names. */ --- 82,86 ---- : 0) /* On other 386 systems, the last line looks like this: ! : (aggregate_value_p (TREE_TYPE (FUNTYPE))) ? GET_MODE_SIZE (Pmode) : 0) */ /* Use periods rather than dollar signs in special g++ assembler names. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/seq-sysv3.h gcc-2.5.0/config/i386/seq-sysv3.h *** gcc-2.4.5/config/i386/seq-sysv3.h --- gcc-2.5.0/config/i386/seq-sysv3.h Mon Aug 2 23:13:17 1993 *************** *** 0 **** --- 1,14 ---- + #include "sysv3.h" + + /* Sequent Symmetry SVr3 doesn't have crtn.o; crt1.o doesn't work + but crt0.o does. */ + + #undef STARTFILE_SPEC + #define STARTFILE_SPEC \ + "%{pg:gcrt0.o%s}\ + %{!pg:%{posix:%{p:mcrtp0.o%s}%{!p:crtp0.o%s}}\ + %{!posix:%{p:mcrt0.o%s}%{!p:crt0.o%s}}} crtbegin.o%s\ + %{p:-L/usr/lib/libp}%{pg:-L/usr/lib/libp}" + + #undef LIB_SPEC + #define LIB_SPEC "%{posix:-lcposix} %{shlib:-lc_s} -lc crtend.o%s" diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/sequent.h gcc-2.5.0/config/i386/sequent.h *** gcc-2.4.5/config/i386/sequent.h Sat May 8 16:08:28 1993 --- gcc-2.5.0/config/i386/sequent.h Sat Oct 2 04:18:56 1993 *************** *** 34,38 **** /* Specify predefined symbols in preprocessor. */ ! #define CPP_PREDEFINES "-Dunix -Di386 -Dsequent" /* Pass -Z and -ZO options to the linker. */ --- 34,38 ---- /* Specify predefined symbols in preprocessor. */ ! #define CPP_PREDEFINES "-Dunix -Di386 -Dsequent -Asystem(unix) -Acpu(i386) -Amachine(i386)" /* Pass -Z and -ZO options to the linker. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/sol2.h gcc-2.5.0/config/i386/sol2.h *** gcc-2.4.5/config/i386/sol2.h Fri Feb 5 18:47:49 1993 --- gcc-2.5.0/config/i386/sol2.h Tue Sep 7 06:20:26 1993 *************** *** 32,33 **** --- 32,83 ---- #define FORCE_INIT_SECTION_ALIGN do { asm (ALIGN_ASM_OP ## " 16"); } while (0) + + #undef CPP_SPEC + #define CPP_SPEC "\ + %{compat-bsd:-iwithprefixbefore ucbinclude -I/usr/ucbinclude}" + + #undef LIB_SPEC + #define LIB_SPEC \ + "%{compat-bsd:-lucb -lsocket -lnsl -lelf -laio} \ + %{!shared:%{!symbolic:-lc}} \ + crtend.o%s \ + %{!shared:%{!symbolic:%{pg:crtn.o%s}%{!pg:crtn.o%s}}}" + + /* This should be the same as in svr4.h, except with -R added. */ + #undef LINK_SPEC + #define LINK_SPEC \ + "%{h*} %{V} %{v:%{!V:-V}} \ + %{b} %{Wl,*:%*} \ + %{static:-dn -Bstatic} \ + %{shared:-G -dy} \ + %{symbolic:-Bsymbolic -G -dy} \ + %{G:-G} \ + %{YP,*} \ + %{R*} \ + %{compat-bsd: \ + %{!YP,*:%{p:-Y P,/usr/ucblib:/usr/ccs/lib/libp:/usr/lib/libp:/usr/ccs/lib:/usr/lib} \ + %{!p:-Y P,/usr/ucblib:/usr/ccs/lib:/usr/lib}} \ + -R /usr/ucblib} \ + %{!compat-bsd: \ + %{!YP,*:%{p:-Y P,/usr/ccs/lib/libp:/usr/lib/libp:/usr/ccs/lib:/usr/lib} \ + %{!p:-Y P,/usr/ccs/lib:/usr/lib}}} \ + %{Qy:} %{!Qn:-Qy}" + + /* This defines which switch letters take arguments. + It is as in svr4.h but with -R added. */ + + #undef SWITCH_TAKES_ARG + #define SWITCH_TAKES_ARG(CHAR) \ + ( (CHAR) == 'D' \ + || (CHAR) == 'U' \ + || (CHAR) == 'o' \ + || (CHAR) == 'e' \ + || (CHAR) == 'u' \ + || (CHAR) == 'I' \ + || (CHAR) == 'm' \ + || (CHAR) == 'L' \ + || (CHAR) == 'R' \ + || (CHAR) == 'A' \ + || (CHAR) == 'h' \ + || (CHAR) == 'z') + diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/sun.h gcc-2.5.0/config/i386/sun.h *** gcc-2.4.5/config/i386/sun.h Sun Dec 27 18:11:33 1992 --- gcc-2.5.0/config/i386/sun.h Sat Oct 2 04:18:59 1993 *************** *** 44,52 **** /* Specify predefined symbols in preprocessor. */ ! #define CPP_PREDEFINES "-Dunix -Di386 -Dsun386 -Dsun" ! ! /* Define size_t for built-in functions. */ ! ! #define SIZE_TYPE "int" /* Allow #sccs in preprocessor. */ --- 44,48 ---- /* Specify predefined symbols in preprocessor. */ ! #define CPP_PREDEFINES "-Dunix -Di386 -Dsun386 -Dsun -Asystem(unix) -Asystem(bsd) -Acpu(i386) -Amachine(i386)" /* Allow #sccs in preprocessor. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/sun386.h gcc-2.5.0/config/i386/sun386.h *** gcc-2.4.5/config/i386/sun386.h Sun Dec 27 15:50:04 1992 --- gcc-2.5.0/config/i386/sun386.h Mon Sep 27 20:10:46 1993 *************** *** 41,51 **** #define ASM_OUTPUT_ASCII(FILE, p, size) \ { int i = 0; \ while (i < (size)) \ ! { if (i%10 == 0) { if (i!=0) fprintf ((FILE), "\n"); \ fprintf ((FILE), "%s ", ASM_BYTE_OP); } \ ! else fprintf ((FILE), ","); \ fprintf ((FILE), "0x%x", ((p)[i++] & 0377)) ;} \ ! fprintf ((FILE), "\n"); } /* Output at beginning of assembler file. */ --- 41,53 ---- #define ASM_OUTPUT_ASCII(FILE, p, size) \ + do \ { int i = 0; \ while (i < (size)) \ ! { if (i%10 == 0) { if (i!=0) fprintf ((FILE), "\n"); \ fprintf ((FILE), "%s ", ASM_BYTE_OP); } \ ! else fprintf ((FILE), ","); \ fprintf ((FILE), "0x%x", ((p)[i++] & 0377)) ;} \ ! fprintf ((FILE), "\n"); \ ! } while (0) /* Output at beginning of assembler file. */ *************** *** 69,73 **** strncpy (shorter, na, 14); \ shorter[14] = 0; \ ! fprintf (FILE, "\t.file\t\"%s\"\n", shorter); \ } \ fprintf (FILE, "\t.version\t\"%s %s\"\n", \ --- 71,77 ---- strncpy (shorter, na, 14); \ shorter[14] = 0; \ ! fprintf (FILE, "\t.file\t"); \ ! output_quoted_string (FILE, shorter); \ ! fprintf (FILE, "\n"); \ } \ fprintf (FILE, "\t.version\t\"%s %s\"\n", \ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/sysv3.h gcc-2.5.0/config/i386/sysv3.h *** gcc-2.4.5/config/i386/sysv3.h Sun Dec 27 17:36:22 1992 --- gcc-2.5.0/config/i386/sysv3.h Sat Oct 2 04:19:02 1993 *************** *** 42,46 **** /* Specify predefined symbols in preprocessor. */ ! #define CPP_PREDEFINES "-Dunix -Di386" #define CPP_SPEC "%{posix:-D_POSIX_SOURCE}" --- 42,46 ---- /* Specify predefined symbols in preprocessor. */ ! #define CPP_PREDEFINES "-Dunix -Di386 -Asystem(unix) -Asystem(svr3) -Acpu(i386) -Amachine(i386)" #define CPP_SPEC "%{posix:-D_POSIX_SOURCE}" diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/sysv4.h gcc-2.5.0/config/i386/sysv4.h *** gcc-2.4.5/config/i386/sysv4.h Mon May 17 13:44:14 1993 --- gcc-2.5.0/config/i386/sysv4.h Sun Oct 3 19:50:43 1993 *************** *** 38,46 **** is supposed to be defined optionally by user programs--not by default. */ #define CPP_PREDEFINES \ ! "-Di386 -Dunix -D__svr4__ -Asystem(unix) -Acpu(i386) -Amachine(i386)" - /* If the host and target formats match, output the floats as hex. */ - #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT - #if defined (HOST_WORDS_BIG_ENDIAN) == WORDS_BIG_ENDIAN /* This is how to output assembly code to define a `float' constant. We always have to use a .long pseudo-op to do this because the native --- 38,43 ---- is supposed to be defined optionally by user programs--not by default. */ #define CPP_PREDEFINES \ ! "-Di386 -Dunix -D__svr4__ -Asystem(unix) -Asystem(svr4) -Acpu(i386) -Amachine(i386)" /* This is how to output assembly code to define a `float' constant. We always have to use a .long pseudo-op to do this because the native *************** *** 52,56 **** do { long value; \ REAL_VALUE_TO_TARGET_SINGLE ((VALUE), value); \ ! fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value); \ } while (0) --- 49,56 ---- do { long value; \ REAL_VALUE_TO_TARGET_SINGLE ((VALUE), value); \ ! if (sizeof (int) == sizeof (long)) \ ! fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value); \ ! else \ ! fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value); \ } while (0) *************** *** 64,72 **** do { long value[2]; \ REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), value); \ ! fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[0]); \ ! fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[1]); \ } while (0) ! #endif /* word order matches */ ! #endif /* HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT */ /* Output at beginning of assembler file. */ --- 64,97 ---- do { long value[2]; \ REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), value); \ ! if (sizeof (int) == sizeof (long)) \ ! { \ ! fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[0]); \ ! fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[1]); \ ! } \ ! else \ ! { \ ! fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[0]); \ ! fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[1]); \ ! } \ } while (0) ! ! ! #undef ASM_OUTPUT_LONG_DOUBLE ! #define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE) \ ! do { long value[3]; \ ! REAL_VALUE_TO_TARGET_LONG_DOUBLE ((VALUE), value); \ ! if (sizeof (int) == sizeof (long)) \ ! { \ ! fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[0]); \ ! fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[1]); \ ! fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[2]); \ ! } \ ! else \ ! { \ ! fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[0]); \ ! fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[1]); \ ! fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[2]); \ ! } \ ! } while (0) /* Output at beginning of assembler file. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/t-aix gcc-2.5.0/config/i386/t-aix *** gcc-2.4.5/config/i386/t-aix Mon May 24 02:42:31 1993 --- gcc-2.5.0/config/i386/t-aix Fri Oct 8 08:00:29 1993 *************** *** 1,5 **** # target: IBM AIX PS/2 1.3.0 with gas-2.x and gnu ld 2.x - # The one that comes with the system is POSIX-compliant. - LIMITS_H = # For aix ps/2 we build crtbegin.o and crtend.o which serve to add begin and --- 1,3 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/t-isc gcc-2.5.0/config/i386/t-isc *** gcc-2.4.5/config/i386/t-isc Sun Dec 27 21:29:31 1992 --- gcc-2.5.0/config/i386/t-isc Fri Oct 8 08:00:32 1993 *************** *** 1,5 **** - # The one that comes with the system is POSIX-compliant. - LIMITS_H = - # For svr3 we build crtbegin.o and crtend.o which serve to add begin and # end labels to the .ctors and .dtors section when we link using gcc. --- 1,2 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/t-next gcc-2.5.0/config/i386/t-next *** gcc-2.4.5/config/i386/t-next Fri Apr 9 19:04:38 1993 --- gcc-2.5.0/config/i386/t-next Thu Sep 9 16:02:25 1993 *************** *** 1,4 **** # libgcc1.c is not needed, since the standard library has these functions. ! LIBGCC1= # Specify other dirs of system header files to be fixed. --- 1,5 ---- # libgcc1.c is not needed, since the standard library has these functions. ! LIBGCC1=libgcc1.null ! CROSS_LIBGCC1=libgcc1.null # Specify other dirs of system header files to be fixed. diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/t-osfrose gcc-2.5.0/config/i386/t-osfrose *** gcc-2.4.5/config/i386/t-osfrose Fri Apr 16 16:48:59 1993 --- gcc-2.5.0/config/i386/t-osfrose Fri Oct 8 08:00:34 1993 *************** *** 1,4 **** EXTRA_OBJS = halfpic.o - LIMITS_H = halfpic.o: halfpic.c $(CONFIG_H) $(CONFIG2_H) $(RTL_H) $(TREE_H) --- 1,3 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/t-sco gcc-2.5.0/config/i386/t-sco *** gcc-2.4.5/config/i386/t-sco Sun Dec 27 21:29:36 1992 --- gcc-2.5.0/config/i386/t-sco Fri Oct 8 08:00:37 1993 *************** *** 1,5 **** - # The one that comes with the system is POSIX-compliant. - LIMITS_H = - # For svr3 we build crtbegin.o and crtend.o which serve to add begin and # end labels to the .ctors and .dtors section when we link using gcc. --- 1,2 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/t-sol2 gcc-2.5.0/config/i386/t-sol2 *** gcc-2.4.5/config/i386/t-sol2 Fri Feb 5 18:50:46 1993 --- gcc-2.5.0/config/i386/t-sol2 Thu Sep 9 16:02:26 1993 *************** *** 8,11 **** --- 8,12 ---- LIBGCC1 = libgcc1.null + CROSS_LIBGCC1 = libgcc1.null # gmon build rule: diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/x-linux gcc-2.5.0/config/i386/x-linux *** gcc-2.4.5/config/i386/x-linux Mon Jan 18 13:37:51 1993 --- gcc-2.5.0/config/i386/x-linux Fri Sep 3 13:32:06 1993 *************** *** 1,3 **** ! X_CFLAGS=-DPOSIX ! # we are native. ! prefix=/usr --- 1,10 ---- ! X_CFLAGS = -DPOSIX ! ! # The following is needed when compiling stages 2 and 3 because gcc's ! # limits.h must be picked up before /usr/include/limits.h. This is because ! # each does an #include_next of the other if the other hasn't been included. ! # /usr/include/limits.h loses if it gets found first because /usr/include is ! # at the end of the search order. When a new version of gcc is released, ! # gcc's limits.h hasn't been installed yet and hence isn't found. ! ! BOOT_CFLAGS = -O $(CFLAGS) -Iinclude diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/x-ncr3000 gcc-2.5.0/config/i386/x-ncr3000 *** gcc-2.4.5/config/i386/x-ncr3000 Mon Sep 21 03:07:36 1992 --- gcc-2.5.0/config/i386/x-ncr3000 Thu Jul 29 14:17:28 1993 *************** *** 6,17 **** CCLIBFLAGS= ! # NCR3000 ships with a MetaWare compiler installed as CC, which chokes and ! # dies all over the place on GCC source. However, the AT&T compiler, ! # crusty as it is, can be used to bootstrap GCC. It can be found in ! # /usr/ccs/ATT/cc. It is also used to compile the things that should ! # not be compiled with GCC. ! ! CC = /usr/ccs/ATT/cc ! OLDCC = /usr/ccs/ATT/cc # The rest is just x-i386v4. --- 6,18 ---- CCLIBFLAGS= ! ## Supposedly not needed now that xm-sysv4.h includes alloc.h for Metaware. ! ### NCR3000 ships with a MetaWare compiler installed as CC, which chokes and ! ### dies all over the place on GCC source. However, the AT&T compiler, ! ### crusty as it is, can be used to bootstrap GCC. It can be found in ! ### /usr/ccs/ATT/cc. It is also used to compile the things that should ! ### not be compiled with GCC. ! ## ! ##CC = /usr/ccs/ATT/cc ! ##OLDCC = /usr/ccs/ATT/cc # The rest is just x-i386v4. diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/x-osfrose gcc-2.5.0/config/i386/x-osfrose *** gcc-2.4.5/config/i386/x-osfrose Sun Dec 27 21:29:47 1992 --- gcc-2.5.0/config/i386/x-osfrose Fri Oct 1 16:07:29 1993 *************** *** 15,19 **** DEBUG = DEBUG_COLLECT = # -DDEBUG ! GCC_CFLAGS = $(INTERNAL_CFLAGS) $(X_CFLAGS) $(T_CFLAGS) $(CFLAGS) -B./ -DPOSIX INSTALL = installbsd -c LDFLAGS = --- 15,20 ---- DEBUG = DEBUG_COLLECT = # -DDEBUG ! CCLIBFLAGS = -O -DNO_HALF_PIC ! GCC_CFLAGS = $(INTERNAL_CFLAGS) $(X_CFLAGS) $(T_CFLAGS) $(CFLAGS) -B./ -DPOSIX -DNO_HALF_PIC INSTALL = installbsd -c LDFLAGS = diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/xm-i386.h gcc-2.5.0/config/i386/xm-i386.h *** gcc-2.4.5/config/i386/xm-i386.h Sat Jan 9 16:49:39 1993 --- gcc-2.5.0/config/i386/xm-i386.h Sat Jun 26 11:38:04 1993 *************** *** 1,4 **** /* Configuration for GNU C-compiler for Intel 80386. ! Copyright (C) 1988 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,4 ---- /* Configuration for GNU C-compiler for Intel 80386. ! Copyright (C) 1988, 1993 Free Software Foundation, Inc. This file is part of GNU CC. *************** *** 36,45 **** #define SUCCESS_EXIT_CODE 0 #define FATAL_EXIT_CODE 33 - - /* If compiled with GNU C, use the built-in alloca */ - #ifdef __GNUC__ - #undef alloca - #define alloca __builtin_alloca - #endif /* target machine dependencies. --- 36,39 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i386/xm-sysv4.h gcc-2.5.0/config/i386/xm-sysv4.h *** gcc-2.4.5/config/i386/xm-sysv4.h Wed Jun 16 17:09:08 1993 --- gcc-2.5.0/config/i386/xm-sysv4.h Thu Jul 29 14:15:31 1993 *************** *** 8,11 **** --- 8,14 ---- #define USE_C_ALLOCA #endif + #ifdef __HIGHC__ + #include /* for MetaWare High-C on NCR System 3000 */ + #endif /* Univel, at least, has a small ARG_MAX. Defining this is harmless diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i860/fx2800.h gcc-2.5.0/config/i860/fx2800.h *** gcc-2.4.5/config/i860/fx2800.h Fri Jan 8 17:02:10 1993 --- gcc-2.5.0/config/i860/fx2800.h Sat Oct 2 04:19:09 1993 *************** *** 177,182 **** #define DBX_OUTPUT_MAIN_SOURCE_FILENAME(file,name) \ ! fprintf (file, ".stab \"%s\",.Ltext0,0x%x,0,0\n", \ ! name, N_SO); \ text_section (); \ ASM_OUTPUT_INTERNAL_LABEL (file, "Ltext", 0) --- 177,183 ---- #define DBX_OUTPUT_MAIN_SOURCE_FILENAME(file,name) \ ! fprintf (file, ".stab "); \ ! output_quoted_string (file, name); \ ! fprintf (file, ",.Ltext0,0x%x,0,0\n", N_SO); \ text_section (); \ ASM_OUTPUT_INTERNAL_LABEL (file, "Ltext", 0) *************** *** 183,188 **** #define DBX_OUTPUT_SOURCE_FILENAME(file,name) \ ! fprintf (file, ".stab \"%s\",.Ltext0,0x%x,0,0\n", \ ! name, N_SOL); #define DBX_OUTPUT_CONSTANT_SYMBOL(file,name,ival) \ --- 184,191 ---- #define DBX_OUTPUT_SOURCE_FILENAME(file,name) \ ! do { fprintf (file, ".stab "); \ ! output_quoted_string (file, name); \ ! fprintf (file, ",.Ltext0,0x%x,0,0\n", N_SOL); \ ! } while (0) #define DBX_OUTPUT_CONSTANT_SYMBOL(file,name,ival) \ *************** *** 267,271 **** #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Di860 -Dunix -DBSD4_3 -Dalliant -Asystem(unix) -Acpu(i860) -Amachine(i860)" #undef I860_REG_PREFIX --- 270,274 ---- #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Di860 -Dunix -DBSD4_3 -Dalliant -Asystem(unix) -Asystem(bsd) -Acpu(i860) -Amachine(i860)" #undef I860_REG_PREFIX diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i860/i860.c gcc-2.5.0/config/i860/i860.c *** gcc-2.4.5/config/i860/i860.c Sun May 9 12:44:24 1993 --- gcc-2.5.0/config/i860/i860.c Sun Jul 11 18:49:14 1993 *************** *** 573,576 **** --- 573,578 ---- rtx latehalf[2]; rtx addreg0 = 0, addreg1 = 0; + int highest_first = 0; + int no_addreg1_decrement = 0; /* First classify both operands. */ *************** *** 681,693 **** && 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); CC_STATUS_PARTIAL_INIT; --- 683,720 ---- && reg_overlap_mentioned_p (operands[0], operands[1])) { ! /* If both halves of dest are used in the src memory address, ! add the two regs and put them in the low reg (operands[0]). ! Then it works to load latehalf first. */ ! if (reg_mentioned_p (operands[0], XEXP (operands[1], 0)) ! && reg_mentioned_p (latehalf[0], XEXP (operands[1], 0))) ! { ! rtx xops[2]; ! xops[0] = latehalf[0]; ! xops[1] = operands[0]; ! output_asm_insn ("adds %1,%0,%1", xops); ! operands[1] = gen_rtx (MEM, DImode, operands[0]); ! latehalf[1] = adj_offsettable_operand (operands[1], 4); ! addreg1 = 0; ! highest_first = 1; ! } ! /* Only one register in the dest is used in the src memory address, ! and this is the first register of the dest, so we want to do ! the late half first here also. */ ! else if (! reg_mentioned_p (latehalf[0], XEXP (operands[1], 0))) ! highest_first = 1; ! /* Only one register in the dest is used in the src memory address, ! and this is the second register of the dest, so we want to do ! the late half last. If addreg1 is set, and addreg1 is the same ! register as latehalf, then we must suppress the trailing decrement, ! because it would clobber the value just loaded. */ ! else if (addreg1 && reg_mentioned_p (addreg1, latehalf[0])) ! no_addreg1_decrement = 1; } ! /* Normal case: do the two words, low-numbered first. ! Overlap case (highest_first set): do high-numbered word first. */ ! if (! highest_first) ! output_asm_insn (singlemove_string (operands), operands); CC_STATUS_PARTIAL_INIT; *************** *** 704,709 **** if (addreg0) output_asm_insn ("adds -0x4,%0,%0", &addreg0); ! if (addreg1) output_asm_insn ("adds -0x4,%0,%0", &addreg1); return ""; --- 731,739 ---- if (addreg0) output_asm_insn ("adds -0x4,%0,%0", &addreg0); ! if (addreg1 && !no_addreg1_decrement) output_asm_insn ("adds -0x4,%0,%0", &addreg1); + + if (highest_first) + output_asm_insn (singlemove_string (operands), operands); return ""; diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i860/i860.h gcc-2.5.0/config/i860/i860.h *** gcc-2.4.5/config/i860/i860.h Sat May 15 12:16:26 1993 --- gcc-2.5.0/config/i860/i860.h Sat Oct 2 04:19:15 1993 *************** *** 30,34 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Di860 -Dunix" /* Print subsidiary information on the compiler version in use. */ --- 30,34 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Di860 -Dunix -Asystem(unix) -Asystem(svr4) -Acpu(i860) -Amachine(i860)" /* Print subsidiary information on the compiler version in use. */ *************** *** 475,479 **** #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME) \ ! ((CUM).ints = ((FNTYPE) != 0 && aggregate_value_p ((FNTYPE)) \ ? 4 : 0), \ (CUM).floats = 0) --- 475,479 ---- #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME) \ ! ((CUM).ints = ((FNTYPE) != 0 && aggregate_value_p (TREE_TYPE ((FNTYPE))) \ ? 4 : 0), \ (CUM).floats = 0) *************** *** 1398,1408 **** compact and efficient, thus speeding up the compiler. The most important predicates to include in the list specified by this ! macro are thoses used in the most insn patterns. - Note that for the i860 we have one more predicate, i.e. - `single_insn_src_operand', however this is used only - infrequently, so we don't put in the PREDICATE_CODES list. - */ - #define PREDICATE_CODES \ {"reg_or_0_operand", {REG, SUBREG, CONST_INT}}, \ --- 1398,1403 ---- compact and efficient, thus speeding up the compiler. The most important predicates to include in the list specified by this ! macro are thoses used in the most insn patterns. */ #define PREDICATE_CODES \ {"reg_or_0_operand", {REG, SUBREG, CONST_INT}}, \ *************** *** 1415,1419 **** {"bte_operand", {REG, SUBREG, CONST_INT}}, \ {"indexed_operand", {MEM}}, \ ! {"load_operand", {MEM}}, /* Define the information needed to generate branch insns. This is stored --- 1410,1417 ---- {"bte_operand", {REG, SUBREG, CONST_INT}}, \ {"indexed_operand", {MEM}}, \ ! {"load_operand", {MEM}}, \ ! {"small_int", {CONST_INT}}, \ ! {"logic_int", {CONST_INT}}, \ ! {"call_insn_operand", {MEM}}, /* Define the information needed to generate branch insns. This is stored diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i860/i860.md gcc-2.5.0/config/i860/i860.md *** gcc-2.4.5/config/i860/i860.md Sun May 9 12:46:28 1993 --- gcc-2.5.0/config/i860/i860.md Mon Jun 28 13:45:18 1993 *************** *** 1053,1057 **** (define_insn "movdf" ! [(set (match_operand:DF 0 "general_operand" "=*rm,&*r,?f,?*rm") (match_operand:DF 1 "general_operand" "*r,m,*rfmG,f"))] "" --- 1053,1057 ---- (define_insn "movdf" ! [(set (match_operand:DF 0 "general_operand" "=*rm,*r,?f,?*rm") (match_operand:DF 1 "general_operand" "*r,m,*rfmG,f"))] "" *************** *** 1071,1075 **** (define_insn "movdi" ! [(set (match_operand:DI 0 "general_operand" "=rm,&r,?f,?rm") (match_operand:DI 1 "general_operand" "r,miF,rfmG,f"))] "" --- 1071,1075 ---- (define_insn "movdi" ! [(set (match_operand:DI 0 "general_operand" "=rm,r,?f,?rm") (match_operand:DI 1 "general_operand" "r,miF,rfmG,f"))] "" diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i860/mach.h gcc-2.5.0/config/i860/mach.h *** gcc-2.4.5/config/i860/mach.h Tue Mar 23 14:21:50 1993 --- gcc-2.5.0/config/i860/mach.h Sat Oct 2 04:19:18 1993 *************** *** 7,11 **** #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dunix -Di860 -DMACH" /* Specify extra dir to search for include files. */ --- 7,11 ---- #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dunix -Di860 -DMACH -Asystem(unix) -Asystem(mach) -Acpu(i860) -Amachine(i860)" /* Specify extra dir to search for include files. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i860/sysv3.h gcc-2.5.0/config/i860/sysv3.h *** gcc-2.4.5/config/i860/sysv3.h Sat Jan 9 10:23:55 1993 --- gcc-2.5.0/config/i860/sysv3.h Sat Oct 2 04:19:21 1993 *************** *** 28,32 **** /* Provide a set of pre-definitions and pre-assertions appropriate for the i860 running svr3. */ ! #define CPP_PREDEFINES "-Di860 -Dunix -D__svr3__" /* Use crt1.o as a startup file and crtn.o as a closing file. */ --- 28,32 ---- /* Provide a set of pre-definitions and pre-assertions appropriate for the i860 running svr3. */ ! #define CPP_PREDEFINES "-Di860 -Dunix -D__svr3__ -Asystem(unix) -Asystem(svr3) -Acpu(i860) -Amachine(i860)" /* Use crt1.o as a startup file and crtn.o as a closing file. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i860/sysv4.h gcc-2.5.0/config/i860/sysv4.h *** gcc-2.4.5/config/i860/sysv4.h Sat Feb 27 15:24:20 1993 --- gcc-2.5.0/config/i860/sysv4.h Sat Oct 2 04:19:25 1993 *************** *** 36,40 **** #define CPP_PREDEFINES \ ! "-Di860 -Dunix -DSVR4 -D__svr4__ -Asystem(unix) -Acpu(i860) -Amachine(i860)" /* The prefix to be used in assembler output for all names of registers. --- 36,40 ---- #define CPP_PREDEFINES \ ! "-Di860 -Dunix -DSVR4 -D__svr4__ -Asystem(unix) -Asystem(svr4) -Acpu(i860) -Amachine(i860)" /* The prefix to be used in assembler output for all names of registers. diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i860/xm-fx2800.h gcc-2.5.0/config/i860/xm-fx2800.h *** gcc-2.4.5/config/i860/xm-fx2800.h Wed Jan 6 02:14:19 1993 --- gcc-2.5.0/config/i860/xm-fx2800.h Thu Oct 7 18:41:02 1993 *************** *** 10,12 **** */ ! #define HAVE_VFPRINTF --- 10,12 ---- */ ! #define HAVE_VPRINTF diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i860/xm-i860.h gcc-2.5.0/config/i860/xm-i860.h *** gcc-2.4.5/config/i860/xm-i860.h Sat Jun 13 17:50:58 1992 --- gcc-2.5.0/config/i860/xm-i860.h Sat Jun 26 11:37:07 1993 *************** *** 1,4 **** /* Configuration for GNU C-compiler for Intel i860. ! Copyright (C) 1988 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,4 ---- /* Configuration for GNU C-compiler for Intel i860. ! Copyright (C) 1988, 1993 Free Software Foundation, Inc. This file is part of GNU CC. *************** *** 36,44 **** #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 /* target machine dependencies. --- 36,39 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i960/i960.c gcc-2.5.0/config/i960/i960.c *** gcc-2.4.5/config/i960/i960.c Mon May 3 20:23:51 1993 --- gcc-2.5.0/config/i960/i960.c Wed Jul 28 13:08:09 1993 *************** *** 2202,2206 **** (first_reg_offset, gen_rtx (MEM, BLKmode, virtual_incoming_args_rtx), ! NPARM_REGS - first_reg_offset); } *pretend_size = (NPARM_REGS - first_reg_offset) * UNITS_PER_WORD; --- 2202,2207 ---- (first_reg_offset, gen_rtx (MEM, BLKmode, virtual_incoming_args_rtx), ! NPARM_REGS - first_reg_offset, ! (NPARM_REGS - first_reg_offset) * UNITS_PER_WORD); } *pretend_size = (NPARM_REGS - first_reg_offset) * UNITS_PER_WORD; diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i960/i960.h gcc-2.5.0/config/i960/i960.h *** gcc-2.4.5/config/i960/i960.h Mon Apr 12 15:52:37 1993 --- gcc-2.5.0/config/i960/i960.h Mon Oct 11 07:36:03 1993 *************** *** 1,4 **** /* Definitions of target machine for GNU compiler, for Intel 80960 ! Copyright (C) 1992 Free Software Foundation, Inc. Contributed by Steven McGeady, Intel Corp. Additional Work by Glenn Colon-Bonet, Jonathan Shapiro, Andy Wilson --- 1,4 ---- /* Definitions of target machine for GNU compiler, for Intel 80960 ! Copyright (C) 1992, 1993 Free Software Foundation, Inc. Contributed by Steven McGeady, Intel Corp. Additional Work by Glenn Colon-Bonet, Jonathan Shapiro, Andy Wilson *************** *** 25,29 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Di960 -Di80960 -DI960 -DI80960" /* Name to predefine in the preprocessor for processor variations. */ --- 25,29 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Di960 -Di80960 -DI960 -DI80960 -Acpu(i960) -Amachine(i960)" /* Name to predefine in the preprocessor for processor variations. */ *************** *** 499,509 **** may be accessed via the stack pointer) in functions that seem suitable. This is computed in `reload', in reload1.c. */ #define FRAME_POINTER_REQUIRED (! leaf_function_p ()) /* C statement to store the difference between the frame pointer ! and the stack pointer values immediately after the function prologue. */ #define INITIAL_FRAME_POINTER_OFFSET(VAR) \ ! do { (VAR) = compute_frame_size (get_frame_size ()); } while (0) /* Base register for access to arguments of the function. */ --- 499,516 ---- may be accessed via the stack pointer) in functions that seem suitable. This is computed in `reload', in reload1.c. */ + /* ??? It isn't clear to me why this is here. Perhaps because of a bug (since + fixed) in the definition of INITIAL_FRAME_POINTER_OFFSET which would have + caused this to fail. */ #define FRAME_POINTER_REQUIRED (! leaf_function_p ()) /* C statement to store the difference between the frame pointer ! and the stack pointer values immediately after the function prologue. + Since the stack grows upward on the i960, this must be a negative number. + This includes the 64 byte hardware register save area and the size of + the frame. */ + #define INITIAL_FRAME_POINTER_OFFSET(VAR) \ ! do { (VAR) = - (64 + compute_frame_size (get_frame_size ())); } while (0) /* Base register for access to arguments of the function. */ *************** *** 1049,1055 **** #define MOVE_MAX 16 ! /* Define if normal loads of shorter-than-word items from memory clears ! the rest of the bigs in the register. */ ! #define BYTE_LOADS_ZERO_EXTEND /* Nonzero if access to memory by bytes is no faster than for words. --- 1056,1068 ---- #define MOVE_MAX 16 ! /* Define if operations between registers always perform the operation ! on the full register even if a narrower mode is specified. */ ! #define WORD_REGISTER_OPERATIONS ! ! /* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD ! will either zero-extend or sign-extend. The value of this macro should ! be the code that says which one of the two operations is implicitly ! done, NIL if none. */ ! #define LOAD_EXTEND_OP(MODE) ZERO_EXTEND /* Nonzero if access to memory by bytes is no faster than for words. *************** *** 1063,1070 **** #define STORE_FLAG_VALUE 1 ! /* 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 --- 1076,1082 ---- #define STORE_FLAG_VALUE 1 ! /* Define this to be nonzero if shift instructions ignore all but the low-order ! few bits. */ ! #define SHIFT_COUNT_TRUNCATED 1 /* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits *************** *** 1317,1321 **** fputs ("\n.comm ", (FILE)), \ assemble_name ((FILE), (NAME)), \ ! fprintf ((FILE), ",%d\n", (ROUNDED)); \ } \ } --- 1329,1333 ---- fputs ("\n.comm ", (FILE)), \ assemble_name ((FILE), (NAME)), \ ! fprintf ((FILE), ",%d\n", (SIZE)); \ } \ } *************** *** 1470,1474 **** {"arith32_operand", {SUBREG, REG, LABEL_REF, SYMBOL_REF, CONST_INT, \ CONST_DOUBLE, CONST}}, \ ! {"power2_operand", {CONST_INT}}, /* Define functions in i960.c and used in insn-output.c. */ --- 1482,1487 ---- {"arith32_operand", {SUBREG, REG, LABEL_REF, SYMBOL_REF, CONST_INT, \ CONST_DOUBLE, CONST}}, \ ! {"power2_operand", {CONST_INT}}, \ ! {"cmplpower2_operand", {CONST_INT}}, /* Define functions in i960.c and used in insn-output.c. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/i960/xm-i960.h gcc-2.5.0/config/i960/xm-i960.h *** gcc-2.4.5/config/i960/xm-i960.h Sat Jun 13 19:01:04 1992 --- gcc-2.5.0/config/i960/xm-i960.h Sat Jun 26 11:36:35 1993 *************** *** 1,4 **** /* Configuration for GNU C-compiler for Intel 960 family ! Copyright (C) 1987 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,4 ---- /* Configuration for GNU C-compiler for Intel 960 family ! Copyright (C) 1987, 1993 Free Software Foundation, Inc. This file is part of GNU CC. *************** *** 33,40 **** #define FATAL_EXIT_CODE 33 ! /* If compiled with GNU C, use the built-in alloca */ ! #ifdef __GNUC__ ! #define alloca __builtin_alloca ! #else #define USE_C_ALLOCA #endif --- 33,38 ---- #define FATAL_EXIT_CODE 33 ! /* If not compiled with GNU C, use the C alloca */ ! #ifndef __GNUC__ #define USE_C_ALLOCA #endif diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/lynx.h gcc-2.5.0/config/lynx.h *** gcc-2.4.5/config/lynx.h --- gcc-2.5.0/config/lynx.h Sat Aug 28 15:18:21 1993 *************** *** 0 **** --- 1,100 ---- + /* Target independent definitions for LynxOS. */ + + /* ??? The -C option may need to change to whatever option the GNU assembler + actually accepts. */ + #undef ASM_SPEC + #define ASM_SPEC "%{mcoff:-C}" + + #undef CPP_SPEC + #define CPP_SPEC "%{mthreads:-D_MULTITHREADED} %{mposix:-D_POSIX_SOURCE} %{msystem-v:-I/usr/include_v}" + + /* Provide required defaults for linker switches. */ + /* ??? The -k option may need to change to whatever option the GNU linker + actually accepts. This is to produce COFF output. */ + /* ??? The -V option may need to change to whatever option the GNU linker + actually accepts. This is to produce System-V magic numbers. */ + #undef LINK_SPEC + #define LINK_SPEC "-P1000 %{msystem-v:-V} %{mcoff:-k}" + + #undef LIB_SPEC + #define LIB_SPEC "%{mthreads:-L/lib/thread/}%{msystem-v:-lc_v}%{!msystem-v:%{mposix:-lc_p} -lc}" + + #undef STARTFILE_SPEC + #define STARTFILE_SPEC "%{p:%{mcoff:pinit1.o%s}%{!mcoff:pinit.o%s}}%{!p:%{msystem-v:%{mcoff:vinit1.o%s}%{!mcoff:vinit.o%s}}%{!msystem-v:%{mcoff:init1.o%s}%{!mcoff:init.o%s}}}" + + #undef ENDFILE_SPEC + #define ENDFILE_SPEC "%{mcoff:initn.o%s} %{p:_etext.o%s}" + + #undef SIZE_TYPE + #define SIZE_TYPE "unsigned int" + + #undef WCHAR_TYPE + #define WCHAR_TYPE "int" + + #undef PTRDIFF_TYPE + #define PTRDIFF_TYPE "long int" + + /* We want to output DBX debugging information. */ + + #define DBX_DEBUGGING_INFO + #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG + + /* We optionally want to be able to produce SDB debugging output so that + we can create debuggable SDB/coff files. This won't be needed when + stabs-in-coff works. */ + + #define SDB_DEBUGGING_INFO + + /* Generate calls to memcpy, memcmp and memset. */ + + #define TARGET_MEM_FUNCTIONS + + /* Handle #pragma pack and sometimes #pragma weak. */ + + #define HANDLE_SYSV_PRAGMA + + #define TARGET_THREADS (target_flags & MASK_THREADS) + #define MASK_THREADS 0x40000000 + + #define TARGET_POSIX (target_flags & MASK_POSIX) + #define MASK_POSIX 0x20000000 + + #define TARGET_SYSTEM_V (target_flags & MASK_SYSTEM_V) + #define MASK_SYSTEM_V 0x10000000 + + #define TARGET_COFF (target_flags & MASK_COFF) + #define MASK_COFF 0x08000000 + + #undef SUBTARGET_SWITCHES + #define SUBTARGET_SWITCHES \ + {"threads", MASK_THREADS}, \ + {"posix", MASK_POSIX}, \ + {"system-v", MASK_SYSTEM_V}, \ + {"coff", MASK_COFF}, + + #undef SUBTARGET_OVERRIDE_OPTIONS + #define SUBTARGET_OVERRIDE_OPTIONS \ + { if (TARGET_SYSTEM_V && profile_flag) \ + warning ("-msystem-v and -p are incompatible"); \ + if (TARGET_SYSTEM_V && TARGET_THREADS) \ + warning ("-msystem-v and -mthreads are incompatible"); } + + /* Define this so that C++ destructors will use atexit. */ + + #define HAVE_ATEXIT + + /* This is defined only so that we can find the assembler. Everything else + is in /bin. */ + + #define MD_EXEC_PREFIX "/usr/local/lib/gcc-" + + /* ??? This is needed because /bin/ld does not handle -L options correctly. + This can be deleted if GNU ld is being used. */ + + #define LINK_LIBGCC_SPECIAL_1 + + /* The Lynx linker considers __main to be a possible entry point, so we + must use a different name. */ + + #define NAME__MAIN "____main" + #define SYMBOL__MAIN ____main diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/3b1.h gcc-2.5.0/config/m68k/3b1.h *** gcc-2.4.5/config/m68k/3b1.h Thu May 13 09:49:43 1993 --- gcc-2.5.0/config/m68k/3b1.h Sat Oct 2 04:19:35 1993 *************** *** 81,85 **** #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dmc68k -Dunix -Dunixpc" #undef REGISTER_NAMES --- 81,85 ---- #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dmc68k -Dunix -Dunixpc -D__motorola__ -Asystem(unix) -Asystem(svr3) -Acpu(m68k) -Amachine(m68k)" #undef REGISTER_NAMES *************** *** 182,186 **** #define ASM_OUTPUT_SOURCE_FILENAME(FILE, FILENAME) \ ! fprintf (FILE, "\tfile\t\"%s\"\n", FILENAME) #define ASM_OUTPUT_SOURCE_LINE(FILE, LINENO) \ --- 182,189 ---- #define ASM_OUTPUT_SOURCE_FILENAME(FILE, FILENAME) \ ! do { fprintf (FILE, "\tfile\t"); \ ! output_quoted_string (FILE, FILENAME); \ ! fprintf (FILE, "\n"); \ ! } while (0) #define ASM_OUTPUT_SOURCE_LINE(FILE, LINENO) \ *************** *** 510,511 **** --- 513,521 ---- #define MULSI3_LIBCALL "*lmul" #define UMULSI3_LIBCALL "*ulmul" + + /* Definitions for collect2. */ + + #define OBJECT_FORMAT_COFF + #define NO_SYS_SIGLIST + #define MY_ISCOFF(magic) \ + ((magic) == MC68KWRMAGIC || (magic) == MC68KROMAGIC || (magic) == MC68KPGMAGIC) diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/3b1g.h gcc-2.5.0/config/m68k/3b1g.h *** gcc-2.4.5/config/m68k/3b1g.h Thu May 13 09:49:42 1993 --- gcc-2.5.0/config/m68k/3b1g.h Sat Oct 2 04:19:37 1993 *************** *** 38,42 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dmc68000 -Dmc68k -Dunix -Dunixpc" /* This is (not really) BSD, so (but) it wants DBX format. */ --- 38,42 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dmc68000 -Dmc68k -Dunix -Dunixpc -Asystem(unix) -Asystem(svr3) -Acpu(m68k) -Amachine(m68k)" /* This is (not really) BSD, so (but) it wants DBX format. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/altos3068.h gcc-2.5.0/config/m68k/altos3068.h *** gcc-2.4.5/config/m68k/altos3068.h Thu May 13 09:49:41 1993 --- gcc-2.5.0/config/m68k/altos3068.h Sat Oct 2 04:19:40 1993 *************** *** 63,67 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dmc68000 -DPORTAR -Dmc68k32 -Uvax -Dm68k -Dunix" /* Every structure or union's size must be a multiple of 2 bytes. */ --- 63,67 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dmc68000 -DPORTAR -Dmc68k32 -Uvax -Dm68k -Dunix -Asystem(unix) -Acpu(m68k) -Amachine(m68k)" /* Every structure or union's size must be a multiple of 2 bytes. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/amix.h gcc-2.5.0/config/m68k/amix.h *** gcc-2.4.5/config/m68k/amix.h Fri May 21 16:05:48 1993 --- gcc-2.5.0/config/m68k/amix.h Sun Aug 1 16:15:38 1993 *************** *** 37,41 **** #undef CPP_PREDEFINES #define CPP_PREDEFINES \ ! "-Dm68k -Dunix -DAMIX -D__svr4__ -Amachine(m68k) -Acpu(m68k) -Asystem(unix) -Alint(off)" /* At end of a switch table, define LDnnn iff the symbol LInnn was defined. --- 37,42 ---- #undef CPP_PREDEFINES #define CPP_PREDEFINES \ ! "-Dm68k -Dunix -DAMIX -D__svr4__ -D__motorola__ \ ! -Amachine(m68k) -Acpu(m68k) -Asystem(unix) -Alint(off)" /* At end of a switch table, define LDnnn iff the symbol LInnn was defined. *************** *** 123,126 **** --- 124,129 ---- } + #if 0 /* This should be unnecessary as a result of PIC_CASE_VECTOR_ADDRESS. */ + /* Override these for the sake of an assembler bug: the Amix assembler can't handle .LC0@GOT syntax. This pollutes the final *************** *** 141,142 **** --- 144,146 ---- asm_fprintf (FILE, "%0L%s%d:\n", PREFIX, NUM) + #endif /* 0 */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/apollo68.h gcc-2.5.0/config/m68k/apollo68.h *** gcc-2.4.5/config/m68k/apollo68.h Thu Mar 11 18:50:55 1993 --- gcc-2.5.0/config/m68k/apollo68.h Sat Oct 2 04:19:44 1993 *************** *** 76,80 **** GCC on other 68000 systems. */ ! #define CPP_PREDEFINES "-Dapollo -Daegis -Dunix" /* cpp has to support a #sccs directive for the /usr/include files */ --- 76,80 ---- GCC on other 68000 systems. */ ! #define CPP_PREDEFINES "-Dapollo -Daegis -Dunix -Asystem(unix) -Acpu(m68k) -Amachine(m68k)" /* cpp has to support a #sccs directive for the /usr/include files */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/crds.h gcc-2.5.0/config/m68k/crds.h *** gcc-2.4.5/config/m68k/crds.h Fri May 14 12:32:48 1993 --- gcc-2.5.0/config/m68k/crds.h Sat Oct 2 04:19:48 1993 *************** *** 34,38 **** Someone should check whether the usual compiler on the crds machine provides the equivalent behavior of STRUCTURE_SIZE_BOUNDARY. */ ! #error This doesn't define STRUCTURE_SIZE_BOUNDARY /* See m68k.h. 0 means 680[01]0 with no 68881. */ --- 34,38 ---- Someone should check whether the usual compiler on the crds machine provides the equivalent behavior of STRUCTURE_SIZE_BOUNDARY. */ ! #error This does not define STRUCTURE_SIZE_BOUNDARY /* See m68k.h. 0 means 680[01]0 with no 68881. */ *************** *** 102,106 **** #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dmc68k -DM68000 -Dmc68000 -Dunos -Dunix" /* Register in which address to store a structure value --- 102,106 ---- #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dmc68k -DM68000 -Dmc68000 -Dunos -Dunix -D__motorola__ -Asystem(unix) -Acpu(m68k) -Amachine(m68k)" /* Register in which address to store a structure value *************** *** 461,465 **** #define ASM_OUTPUT_SOURCE_FILENAME(FILE, FILENAME) \ ! fprintf (FILE, "\t; file\t\"%s\"\n", FILENAME) #define ASM_OUTPUT_SOURCE_LINE(FILE, LINENO) \ --- 461,468 ---- #define ASM_OUTPUT_SOURCE_FILENAME(FILE, FILENAME) \ ! do { fprintf (FILE, "\t; file\t"); \ ! output_quoted_string (FILE, FILENAME); \ ! fprintf (FILE, "\n"); \ ! } while (0) #define ASM_OUTPUT_SOURCE_LINE(FILE, LINENO) \ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/ctix.h gcc-2.5.0/config/m68k/ctix.h *** gcc-2.4.5/config/m68k/ctix.h Tue Jan 5 03:25:03 1993 --- gcc-2.5.0/config/m68k/ctix.h Sat Oct 2 04:19:50 1993 *************** *** 33,37 **** /* Names to predefine in the preprocessor for this target machine. */ #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dmc68000 -Dmc68k -Dunix -Dctix" /* Where to look for robotussinized startfiles. */ --- 33,37 ---- /* Names to predefine in the preprocessor for this target machine. */ #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dmc68000 -Dmc68k -Dunix -Dctix -Asystem(unix) -Acpu(m68k) -Amachine(m68k)" /* Where to look for robotussinized startfiles. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/dpx2.h gcc-2.5.0/config/m68k/dpx2.h *** gcc-2.4.5/config/m68k/dpx2.h Tue Jan 5 03:24:50 1993 --- gcc-2.5.0/config/m68k/dpx2.h Sat Oct 2 04:19:56 1993 *************** *** 1,6 **** /* ! * dpx2.h - Bull DPX/2 200 and 300 systems (m68k, SysVr3) */ #include "m68k/m68k.h" #undef SELECT_RTX_SECTION --- 1,16 ---- /* ! dpx2.h - Bull DPX/2 200 and 300 systems (m68k, SysVr3). ! ! Contributed by Frederic Pierresteguy. ! Bug reports to F.Pierresteguy@frcl.bull.fr. */ + #ifndef USE_GAS + #define MOTOROLA /* Use Motorola syntax rather than "MIT" */ + #define SGS_NO_LI /* Suppress jump table label usage */ + #define VERSADOS /* This is the name of the assembler we have */ + #define USG + #endif + #include "m68k/m68k.h" #undef SELECT_RTX_SECTION *************** *** 7,11 **** #include "svr3.h" ! /* See m68k.h. 7 means 68020 with 68881. * We really have 68030 and 68882, * but this will get us going. --- 17,21 ---- #include "svr3.h" ! /* See m68k.h. 7 means 68020 with 68881. * We really have 68030 and 68882, * but this will get us going. *************** *** 25,34 **** */ #ifdef ncl_mr ! # define CPP_PREDEFINES "-Dunix -Dbull -DDPX2 -DSVR3 -Dmc68000 -Dmc68020 -Dncl_mr=1" #else # ifdef ncl_el ! # define CPP_PREDEFINES "-Dunix -Dbull -DDPX2 -DSVR3 -Dmc68000 -Dmc68020 -Dncl_el" # else ! # define CPP_PREDEFINES "-Dunix -Dbull -DDPX2 -DSVR3 -Dmc68000 -Dmc68020" # endif #endif --- 35,44 ---- */ #ifdef ncl_mr ! # define CPP_PREDEFINES "-Dunix -Dbull -DDPX2 -DSVR3 -Dmc68000 -Dmc68020 -Dncl_mr=1 -D_BULL_SOURCE -D_POSIX_SOURCE -D_XOPEN_SOURCE -Asystem(unix) -Asystem(svr3) -Acpu(m68k) -Amachine(m68k)" #else # ifdef ncl_el ! # define CPP_PREDEFINES "-Dunix -Dbull -DDPX2 -DSVR3 -Dmc68000 -Dmc68020 -Dncl_el-D_BULL_SOURCE -D_POSIX_SOURCE -D_XOPEN_SOURCE -Asystem(unix) -Asystem(svr3) -Acpu(m68k) -Amachine(m68k)" # else ! # define CPP_PREDEFINES "-Dunix -Dbull -DDPX2 -DSVR3 -Dmc68000 -Dmc68020 -D_BULL_SOURCE -D_POSIX_SOURCE -D_XOPEN_SOURCE -Asystem(unix) -Asystem(svr3) -Acpu(m68k) -Amachine(m68k)" # endif #endif *************** *** 36,59 **** #undef CPP_SPEC /* - * use -ansi to imply POSIX and XOPEN and BULL source - * no -ansi implies _SYSV - */ - /* * you can't get a DPX/2 without a 68882 but allow it * to be ignored... */ - #if 0 - # define CPP_SPEC "%{ansi:-D_POSIX_SOURCE -D_XOPEN_SOURCE -D_BULL_SOURCE}\ - %{!ansi:-D_SYSV}" - #else # define __HAVE_68881__ 1 ! # define CPP_SPEC "%{!msoft-float:-D__HAVE_68881__ }\ ! %{ansi:-D_POSIX_SOURCE -D_XOPEN_SOURCE -D_BULL_SOURCE}\ ! %{!ansi:-D_SYSV}" ! #endif - #undef ASM_LONG - #define ASM_LONG "\t.long" - #define HAVE_ATEXIT #undef DO_GLOBAL_CTORS_BODY /* don't use svr3.h version */ --- 46,55 ---- #undef CPP_SPEC /* * you can't get a DPX/2 without a 68882 but allow it * to be ignored... */ # define __HAVE_68881__ 1 ! # define CPP_SPEC "%{!msoft-float:-D__HAVE_68881__ }" #define HAVE_ATEXIT #undef DO_GLOBAL_CTORS_BODY /* don't use svr3.h version */ *************** *** 60,84 **** #undef DO_GLOBAL_DTORS_BODY - #if 0 /* Should be no need now that svr3.h defines BSS_SECTION_FUNCTION. */ - /* - * svr3.h says to use BSS_SECTION_FUNCTION - * but no one appears to, and there is - * no definition for m68k. - */ - #ifndef BSS_SECTION_FUNCTION - # undef EXTRA_SECTION_FUNCTIONS - # define EXTRA_SECTION_FUNCTIONS \ - CONST_SECTION_FUNCTION \ - INIT_SECTION_FUNCTION \ - FINI_SECTION_FUNCTION - #endif - #endif /* 0 */ - #ifndef USE_GAS /* ! * handle the native assembler. ! * this does NOT yet work, there is much left to do. ! * use GAS for now... */ #undef ASM_OUTPUT_SOURCE_FILENAME #define ASM_OUTPUT_SOURCE_FILENAME(FILE, NA) \ --- 56,99 ---- #undef DO_GLOBAL_DTORS_BODY #ifndef USE_GAS /* ! * handle the native MOTOROLA VERSAdos assembler. ! */ ! ! /* See m68k.h. 3 means 68020 with 68881 and no bitfiled ! * bitfield instructions do not seem to work a clean way. */ + #undef TARGET_DEFAULT + #define TARGET_DEFAULT 3 + + #undef EXTRA_SECTIONS + #undef EXTRA_SECTION_FUNCTIONS + #undef READONLY_DATA_SECTION + #define READONLY_DATA_SECTION data_section + #undef SELECT_SECTION + #undef SELECT_RTX_SECTION + #define fini_section() while (0) + + #undef CTORS_SECTION_ASM_OP + #define CTORS_SECTION_ASM_OP "\tsection 15" + #undef DTORS_SECTION_ASM_OP + #define DTORS_SECTION_ASM_OP "\tsection 15" + #undef INIT_SECTION_ASM_OP + #define BSS_SECTION_ASM_OP "\tsection 14" + #undef TEXT_SECTION_ASM_OP + #define TEXT_SECTION_ASM_OP "\tsection 10" + #undef DATA_SECTION_ASM_OP + #define DATA_SECTION_ASM_OP "\tsection 15" + + + /* Don't try using XFmode. */ + #undef LONG_DOUBLE_TYPE_SIZE + #define LONG_DOUBLE_TYPE_SIZE 64 + + /* Define if you don't want extended real, but do want to use the + software floating point emulator for REAL_ARITHMETIC and + decimal <-> binary conversion. */ + #define REAL_ARITHMETIC + #undef ASM_OUTPUT_SOURCE_FILENAME #define ASM_OUTPUT_SOURCE_FILENAME(FILE, NA) \ *************** *** 85,88 **** --- 100,110 ---- do { fprintf ((FILE), "\t.file\t'%s'\n", (NA)); } while (0) + /* Assembler pseudos to introduce constants of various size. */ + + #undef ASM_BYTE_OP + #define ASM_BYTE_OP "\tdc.b" + #undef ASM_LONG + #define ASM_LONG "\tdc.l" + /* * we don't seem to support any of: *************** *** 92,99 **** * .ascii */ ! #undef ASM_GLOBALIZE_LABEL ! #define ASM_GLOBALIZE_LABEL(FILE,NAME) while (0) #undef ASM_OUTPUT_ALIGN ! #define ASM_OUTPUT_ALIGN(asm_out_file, align) while (0) #define STRING_LIMIT (0) #undef ASM_APP_ON --- 114,130 ---- * .ascii */ ! #undef ASM_OUTPUT_SKIP ! #define ASM_OUTPUT_SKIP(FILE,SIZE) \ ! fprintf (FILE, "\tdcb.b %u,0\n", (SIZE)) ! ! #undef GLOBAL_ASM_OP ! #define GLOBAL_ASM_OP "\txdef" ! #undef ASM_OUTPUT_ALIGN ! #define ASM_OUTPUT_ALIGN(FILE,LOG) \ ! if ((LOG) >= 1) \ ! fprintf (FILE, "\tds.w 0\n"); ! ! #define STRING_LIMIT (0) #undef ASM_APP_ON *************** *** 107,147 **** */ #undef ASM_OUTPUT_ASCII ! #define ASM_OUTPUT_ASCII(asm_out_file, p, thissize) \ ! do { register int i, c, f=0; \ ! for (i = 0; i < thissize; i++) { \ ! c = p[i]; \ ! if (c == '\'' || c < ' ' || c > 127) { \ ! switch(f) { \ ! case 0: /* need to output dc.b etc */ \ ! fprintf(asm_out_file, "\tdc.b %d", c); \ ! f=1; \ ! break; \ ! case 1: \ ! fprintf(asm_out_file, ",%d", c); \ ! break; \ ! default: \ ! /* close a string */ \ ! fprintf(asm_out_file, "'\n\tdc.b %d", c); \ ! f=1; \ ! break; \ ! } \ ! } else { \ ! switch(f) { \ ! case 0: \ ! fprintf(asm_out_file, "\tdc.b '%c", c); \ ! f=2; \ ! break; \ ! case 2: \ ! fprintf(asm_out_file, "%c", c); \ ! break; \ ! default: \ ! fprintf(asm_out_file, "\n\tdc.b '%c", c); \ ! f=2; \ ! break; \ ! } \ ! } \ ! } \ ! if (f==2) \ ! putc('\'', asm_out_file); \ putc('\n', asm_out_file); } while (0) --- 138,184 ---- */ #undef ASM_OUTPUT_ASCII ! #define ASM_OUTPUT_ASCII(asm_out_file, p, thissize) \ ! do { register int i, c, f=0, len=0; \ ! for (i = 0; i < thissize; i++) { \ ! c = p[i]; \ ! if (c == '\'' || c < ' ' || c > 127) { \ ! switch(f) { \ ! case 0: /* need to output dc.b etc */ \ ! fprintf(asm_out_file, "\tdc.b %d", c); \ ! f=1; \ ! break; \ ! case 1: \ ! fprintf(asm_out_file, ",%d", c); \ ! break; \ ! default: \ ! /* close a string */ \ ! fprintf(asm_out_file, "'\n\tdc.b %d", c); \ ! f=1; \ ! break; \ ! } \ ! } else { \ ! switch(f) { \ ! case 0: \ ! fprintf(asm_out_file, "\tdc.b '%c", c); \ ! f=2; \ ! break; \ ! case 2: \ ! if (len >= 79) { \ ! fprintf(asm_out_file, "'\n\tdc.b '%c", c); \ ! len = 0; } \ ! else \ ! fprintf(asm_out_file, "%c", c); \ ! break; \ ! default: \ ! len = 0; \ ! fprintf(asm_out_file, "\n\tdc.b '%c", c); \ ! f=2; \ ! break; \ ! } \ ! } \ ! len++; \ ! } \ ! if (f==2) \ ! putc('\'', asm_out_file); \ putc('\n', asm_out_file); } while (0) *************** *** 159,162 **** #define ASM_OUTPUT_REG_POP(FILE,REGNO) \ fprintf (FILE, "\tmove.l (sp)+,%s\n", reg_names[REGNO]) ! #endif /* ! use gas */ --- 196,804 ---- #define ASM_OUTPUT_REG_POP(FILE,REGNO) \ fprintf (FILE, "\tmove.l (sp)+,%s\n", reg_names[REGNO]) ! ! ! #define PUT_SDB_FUNCTION_START(LINE) \ ! fprintf (asm_out_file, \ ! "\t.def\t.bf%s\t.val\t*%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \ ! SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) ! ! #define PUT_SDB_FUNCTION_END(LINE) \ ! fprintf (asm_out_file, \ ! "\t.def\t.ef%s\t.val\t*%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \ ! SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) ! ! #define PUT_SDB_BLOCK_START(LINE) \ ! fprintf (asm_out_file, \ ! "\t.def\t.bb%s\t.val\t*%s\t.scl\t100%s\t.line\t%d%s\t.endef\n", \ ! SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) ! ! #define PUT_SDB_BLOCK_END(LINE) \ ! fprintf (asm_out_file, \ ! "\t.def\t.eb%s\t.val\t*%s\t.scl\t100%s\t.line\t%d%s\t.endef\n", \ ! SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) ! ! #define PUT_SDB_EPILOGUE_END(NAME) ! ! /* Output type in decimal not in octal as done in sdbout.c */ ! #define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\t.type\t0%d%s", a, SDB_DELIM) ! ! #undef FUNCTION_PROLOGUE ! #define FUNCTION_PROLOGUE(FILE, SIZE) \ ! { \ ! register int regno; \ ! register int mask = 0; \ ! int num_saved_regs = 0, first = 1; \ ! extern char call_used_regs[]; \ ! int fsize = ((SIZE) + 3) & -4; \ ! \ ! \ ! if (frame_pointer_needed) \ ! { \ ! /* Adding negative number is faster on the 68040. */ \ ! if (fsize < 0x8000 && !TARGET_68040) \ ! { \ ! fprintf (FILE, "\tlink %s,#%d\n", \ ! reg_names[FRAME_POINTER_REGNUM], -fsize); \ ! } \ ! else if (TARGET_68020) \ ! { \ ! fprintf (FILE, "\tlink %s,#%d\n", \ ! reg_names[FRAME_POINTER_REGNUM], -fsize); \ ! } \ ! else \ ! { \ ! fprintf (FILE, "\tlink %s,#0\n\tadd.l #%d,sp\n", \ ! reg_names[FRAME_POINTER_REGNUM], -fsize); \ ! } \ ! } \ ! else if (fsize) \ ! { \ ! /* Adding negative number is faster on the 68040. */ \ ! if (fsize + 4 < 0x8000) \ ! { \ ! fprintf (FILE, "\tadd.w #%d,sp\n", - (fsize + 4)); \ ! } \ ! else \ ! { \ ! fprintf (FILE, "\tadd.l #%d,sp\n", - (fsize + 4)); \ ! } \ ! } \ ! for (regno = 23; regno >= 16; regno--) \ ! if (regs_ever_live[regno] && ! call_used_regs[regno]) \ ! if (first) { \ ! fprintf (FILE, "\tfmovem.x %s", reg_names[regno]); \ ! first = 0; \ ! } \ ! else fprintf (FILE, "/%s", reg_names[regno]); \ ! if (!first) fprintf (FILE, ",-(sp)\n"); \ ! \ ! mask = 0; \ ! for (regno = 0; regno < 16; regno++) \ ! if (regs_ever_live[regno] && ! call_used_regs[regno]) \ ! { \ ! mask |= 1 << (15 - regno); \ ! num_saved_regs++; \ ! } \ ! if (frame_pointer_needed) \ ! { \ ! mask &= ~ (1 << (15 - FRAME_POINTER_REGNUM)); \ ! num_saved_regs--; \ ! } \ ! \ ! \ ! if (num_saved_regs <= 2) \ ! { \ ! /* Store each separately in the same order moveml uses. \ ! Using two movel instructions instead of a single moveml \ ! is about 15% faster for the 68020 and 68030 at no expense \ ! in code size */ \ ! \ ! int i; \ ! \ ! /* Undo the work from above. */ \ ! for (i = 0; i< 16; i++) \ ! if (mask & (1 << i)) \ ! fprintf (FILE, "\tmove.l %s,-(sp)\n", reg_names[15 - i]); \ ! } \ ! else if (mask) \ ! { \ ! first = 1; \ ! for (regno = 0; regno < 16; regno++) \ ! if (mask & (1 << regno)) \ ! if (first) { \ ! fprintf (FILE, "\tmovem.l %s", reg_names[15 - regno]); \ ! first = 0; \ ! } \ ! else fprintf (FILE, "/%s", reg_names[15 - regno]); \ ! fprintf (FILE, ",-(sp)\n"); \ ! } \ ! if (flag_pic && current_function_uses_pic_offset_table) \ ! { \ ! fprintf (FILE, "\tmove.l #__GLOBAL_OFFSET_TABLE_, %s\n", \ ! reg_names[PIC_OFFSET_TABLE_REGNUM]); \ ! fprintf (FILE, "\tlea.l (pc,%s.l),%s\n", \ ! reg_names[PIC_OFFSET_TABLE_REGNUM], \ ! reg_names[PIC_OFFSET_TABLE_REGNUM]); \ ! } \ ! } ! ! ! #undef FUNCTION_EPILOGUE ! #define FUNCTION_EPILOGUE(FILE, SIZE) \ ! { \ ! register int regno; \ ! register int mask, fmask; \ ! register int nregs; \ ! int offset, foffset, fpoffset, first = 1; \ ! extern char call_used_regs[]; \ ! int fsize = ((SIZE) + 3) & -4; \ ! int big = 0; \ ! rtx insn = get_last_insn (); \ ! \ ! /* If the last insn was a BARRIER, we don't have to write any code. */ \ ! if (GET_CODE (insn) == NOTE) \ ! insn = prev_nonnote_insn (insn); \ ! if (insn && GET_CODE (insn) == BARRIER) \ ! { \ ! /* Output just a no-op so that debuggers don't get confused \ ! about which function the pc is in at this address. */ \ ! fprintf (FILE, "\tnop\n"); \ ! return; \ ! } \ ! \ ! nregs = 0; fmask = 0; fpoffset = 0; \ ! for (regno = 16; regno < 24; regno++) \ ! if (regs_ever_live[regno] && ! call_used_regs[regno]) \ ! { \ ! nregs++; \ ! fmask |= 1 << (23 - regno); \ ! } \ ! foffset = fpoffset + nregs * 12; \ ! nregs = 0; mask = 0; \ ! if (frame_pointer_needed) \ ! regs_ever_live[FRAME_POINTER_REGNUM] = 0; \ ! for (regno = 0; regno < 16; regno++) \ ! if (regs_ever_live[regno] && ! call_used_regs[regno]) \ ! { \ ! nregs++; \ ! mask |= 1 << regno; \ ! } \ ! offset = foffset + nregs * 4; \ ! if (offset + fsize >= 0x8000 \ ! && frame_pointer_needed \ ! && (mask || fmask || fpoffset)) \ ! { \ ! fprintf (FILE, "\tmove.l #%d,a0\n", -fsize); \ ! fsize = 0, big = 1; \ ! } \ ! if (nregs <= 2) \ ! { \ ! /* Restore each separately in the same order moveml does. \ ! Using two movel instructions instead of a single moveml \ ! is about 15% faster for the 68020 and 68030 at no expense \ ! in code size. */ \ ! \ ! int i; \ ! \ ! /* Undo the work from above. */ \ ! for (i = 0; i< 16; i++) \ ! if (mask & (1 << i)) \ ! { \ ! if (big) \ ! { \ ! fprintf (FILE, "\tmove.l -%d(%s,a0.l),%s\n", \ ! offset + fsize, \ ! reg_names[FRAME_POINTER_REGNUM], \ ! reg_names[i]); \ ! } \ ! else if (! frame_pointer_needed) \ ! { \ ! fprintf (FILE, "\tmove.l (sp)+,%s\n", \ ! reg_names[i]); \ ! } \ ! else \ ! { \ ! fprintf (FILE, "\tmove.l -%d(%s),%s\n", \ ! offset + fsize, \ ! reg_names[FRAME_POINTER_REGNUM], \ ! reg_names[i]); \ ! } \ ! offset = offset - 4; \ ! } \ ! } \ ! else if (mask) \ ! { \ ! first = 1; \ ! for (regno = 0; regno < 16; regno++) \ ! if (mask & (1 << regno)) \ ! if (first && big) { \ ! fprintf (FILE, "\tmovem.l -%d(%s,a0.l),%s", \ ! offset + fsize, \ ! reg_names[FRAME_POINTER_REGNUM], \ ! reg_names[regno]); \ ! first = 0; \ ! } \ ! else if (first && ! frame_pointer_needed) { \ ! fprintf (FILE, "\tmovem.l (sp)+,%s", \ ! offset + fsize, \ ! reg_names[FRAME_POINTER_REGNUM], \ ! reg_names[regno]); \ ! first = 0; \ ! } \ ! else if (first) { \ ! fprintf (FILE, "\tmovem.l -%d(%s),%s", \ ! offset + fsize, \ ! reg_names[FRAME_POINTER_REGNUM], \ ! reg_names[regno]); \ ! first = 0; \ ! } \ ! else \ ! fprintf (FILE, "/%s", reg_names[regno]); \ ! fprintf (FILE, "\n"); \ ! } \ ! if (fmask) \ ! { \ ! first = 1; \ ! for (regno = 16; regno < 24; regno++) \ ! if (fmask & (1 << (23 - regno))) \ ! if (first && big) { \ ! fprintf (FILE, "\tfmovem.x -%d(%s,a0.l),%s", \ ! foffset + fsize, \ ! reg_names[FRAME_POINTER_REGNUM], \ ! reg_names[regno]); \ ! first = 0; \ ! } \ ! else if (first && ! frame_pointer_needed) { \ ! fprintf (FILE, "\tfmovem.x (sp)+,%s", \ ! foffset + fsize, \ ! reg_names[FRAME_POINTER_REGNUM], \ ! reg_names[regno]); \ ! first = 0; \ ! } \ ! else if (first) { \ ! fprintf (FILE, "\tfmovem.x -%d(%s),%s", \ ! foffset + fsize, \ ! reg_names[FRAME_POINTER_REGNUM], \ ! reg_names[regno]); \ ! first = 0; \ ! } \ ! else fprintf (FILE, "/%s", reg_names[regno]); \ ! fprintf (FILE, "\n"); \ ! } \ ! if (frame_pointer_needed) \ ! fprintf (FILE, "\tunlk %s\n", \ ! reg_names[FRAME_POINTER_REGNUM]); \ ! else if (fsize) \ ! { \ ! if (fsize + 4 < 0x8000) \ ! { \ ! fprintf (FILE, "\tadd.w #%d,sp\n", fsize + 4); \ ! } \ ! else \ ! { \ ! fprintf (FILE, "\tadd.l #%d,sp\n", fsize + 4); \ ! } \ ! } \ ! if (current_function_pops_args) \ ! fprintf (FILE, "\trtd #%d\n", current_function_pops_args); \ ! else \ ! fprintf (FILE, "\trts\n"); \ ! } ! ! /* Translate Motorola opcodes such as `jbeq' ! into VERSAdos opcodes such as `beq'. ! Change `fbeq' to `fbseq', `fbne' to `fbsneq'. ! */ ! ! #undef ASM_OUTPUT_OPCODE ! #define ASM_OUTPUT_OPCODE(FILE, PTR) \ ! { if ((PTR)[0] == 'j' && (PTR)[1] == 'b') \ ! { ++(PTR); \ ! while (*(PTR) != ' ') \ ! { putc (*(PTR), (FILE)); ++(PTR); } \ ! } \ ! else if ((PTR)[0] == 'f') \ ! { \ ! if (!strncmp ((PTR), "fbeq", 4)) \ ! { fprintf ((FILE), "fbseq"); (PTR) += 4; } \ ! else if (!strncmp ((PTR), "fbne", 4)) \ ! { fprintf ((FILE), "fbsneq"); (PTR) += 4; } \ ! } \ ! else if ((PTR)[0] == 'b' && (PTR)[1] == 'f') \ ! { \ ! char *s; \ ! if ((s = (char*)strchr ((PTR), '{'))) \ ! while (*s != '}') { \ ! if (*s == 'b') \ ! /* hack, I replace it with R ie nothing */ \ ! *s = '0'; \ ! s++; } \ ! } \ ! } ! ! /* This is how to output a `long double' extended real constant. */ ! #undef ASM_OUTPUT_LONG_DOUBLE ! #define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE) \ ! do { long l[3]; \ ! REAL_VALUE_TO_TARGET_LONG_DOUBLE (VALUE, l); \ ! if (sizeof (int) == sizeof (long)) \ ! fprintf (FILE, "\tdc.l $%x,$%x,$%x\n", l[0], l[1], l[2]); \ ! else \ ! fprintf (FILE, "\tdc.l $%lx,$%lx,$%lx\n", l[0], l[1], l[2]); \ ! } while (0) ! ! #undef ASM_OUTPUT_DOUBLE ! #if 0 ! #define ASM_OUTPUT_DOUBLE(FILE,VALUE) \ ! do { char dstr[30]; \ ! REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr); \ ! fprintf (FILE, "\tdc.d %s\n", dstr); \ ! } while (0) ! #endif ! #define ASM_OUTPUT_DOUBLE(FILE,VALUE) \ ! do { long l[2]; \ ! REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l); \ ! fprintf (FILE, "\tdc.l $%x,$%x\n", l[0], l[1]); \ ! } while (0) ! ! ! /* This is how to output an assembler line defining a `float' constant. */ ! #undef ASM_OUTPUT_FLOAT ! #define ASM_OUTPUT_FLOAT(FILE,VALUE) \ ! do { long l; \ ! REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \ ! if (sizeof (int) == sizeof (long)) \ ! fprintf (FILE, "\tdc.l $%x\n", l); \ ! else \ ! fprintf (FILE, "\tdc.l $%lx\n", l); \ ! } while (0) ! ! /* This is how to output an assembler line defining an `int' constant. */ ! #undef ASM_OUTPUT_INT ! #define ASM_OUTPUT_INT(FILE,VALUE) \ ! ( fprintf (FILE, "\tdc.l "), \ ! output_addr_const (FILE, (VALUE)), \ ! fprintf (FILE, "\n")) ! ! /* Likewise for `char' and `short' constants. */ ! #undef ASM_OUTPUT_SHORT ! #define ASM_OUTPUT_SHORT(FILE,VALUE) \ ! ( fprintf (FILE, "\tdc.w "), \ ! output_addr_const (FILE, (VALUE)), \ ! fprintf (FILE, "\n")) ! ! #undef ASM_OUTPUT_CHAR ! #define ASM_OUTPUT_CHAR(FILE,VALUE) \ ! ( fprintf (FILE, "\tdc.b "), \ ! output_addr_const (FILE, (VALUE)), \ ! fprintf (FILE, "\n")) ! ! /* This is how to output an assembler line for a numeric constant byte. */ ! #undef ASM_OUTPUT_BYTE ! #define ASM_OUTPUT_BYTE(FILE,VALUE) \ ! fprintf (FILE, "\tdc.b $%x\n", (VALUE)) ! ! /* This is how to output an element of a case-vector that is absolute. ! (The 68000 does not use such vectors, ! but we must define this macro anyway.) */ ! #undef ASM_OUTPUT_ADDR_VEC_ELT ! #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ ! asm_fprintf (FILE, "\tdc.l %LL%d\n", VALUE) ! ! /* This is how to output an element of a case-vector that is relative. */ ! #undef ASM_OUTPUT_ADDR_DIFF_ELT ! #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ ! asm_fprintf (FILE, "\tdc.w %LL%d-%LL%d\n", VALUE, REL) ! ! /* Currently, JUMP_TABLES_IN_TEXT_SECTION must be defined in order to ! keep switch tables in the text section. */ ! #define JUMP_TABLES_IN_TEXT_SECTION 1 ! ! /* Output a float value (represented as a C double) as an immediate operand. ! This macro is a 68k-specific macro. */ ! #undef ASM_OUTPUT_FLOAT_OPERAND ! #define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE) \ ! do { \ ! if (CODE == 'f') \ ! { \ ! char dstr[30]; \ ! REAL_VALUE_TO_DECIMAL (VALUE, "%.9g", dstr); \ ! asm_fprintf ((FILE), "%I%s", dstr); \ ! } \ ! else \ ! { \ ! long l; \ ! REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \ ! if (sizeof (int) == sizeof (long)) \ ! asm_fprintf ((FILE), "%I$%x", l); \ ! else \ ! asm_fprintf ((FILE), "%I$%lx", l); \ ! } \ ! } while (0) ! ! /* Output a double value (represented as a C double) as an immediate operand. ! This macro is a 68k-specific macro. */ ! #undef ASM_OUTPUT_DOUBLE_OPERAND ! #define ASM_OUTPUT_DOUBLE_OPERAND(FILE,VALUE) \ ! do { char dstr[30]; \ ! REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr); \ ! asm_fprintf (FILE, "%I%s", dstr); \ ! } while (0) ! ! /* Note, long double immediate operands are not actually ! generated by m68k.md. */ ! #undef ASM_OUTPUT_LONG_DOUBLE_OPERAND ! #define ASM_OUTPUT_LONG_DOUBLE_OPERAND(FILE,VALUE) \ ! do { char dstr[30]; \ ! REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr); \ ! asm_fprintf (FILE, "%I%s", dstr); \ ! } while (0) ! ! #undef ASM_OUTPUT_COMMON ! #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ ! ( fputs ("\t.comm ", (FILE)), \ ! assemble_name ((FILE), (NAME)), \ ! fprintf ((FILE), ",%u\n", (ROUNDED))) ! ! #undef ASM_OUTPUT_LOCAL ! #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ ! do { \ ! int align = exact_log2 (ROUNDED); \ ! /*fprintf ((FILE), "\tsection 14\n"); */ \ ! data_section (); \ ! ASM_OUTPUT_ALIGN ((FILE), align) \ ! ASM_OUTPUT_LABEL ((FILE), (NAME)); \ ! fprintf ((FILE), "\tdcb.b %u,0\n", (ROUNDED)); \ ! /* fprintf ((FILE), "\tsection 10\n"); */ \ ! } while (0) ! ! #undef PRINT_OPERAND_ADDRESS ! #define PRINT_OPERAND_ADDRESS(FILE, ADDR) \ ! { register rtx reg1, reg2, breg, ireg; \ ! register rtx addr = ADDR; \ ! rtx offset; \ ! switch (GET_CODE (addr)) \ ! { \ ! case REG: \ ! fprintf (FILE, "(%s)", reg_names[REGNO (addr)]); \ ! break; \ ! case PRE_DEC: \ ! fprintf (FILE, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]); \ ! break; \ ! case POST_INC: \ ! fprintf (FILE, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]); \ ! break; \ ! case PLUS: \ ! reg1 = 0; reg2 = 0; \ ! ireg = 0; breg = 0; \ ! offset = 0; \ ! if (CONSTANT_ADDRESS_P (XEXP (addr, 0))) \ ! { \ ! offset = XEXP (addr, 0); \ ! addr = XEXP (addr, 1); \ ! } \ ! else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))) \ ! { \ ! offset = XEXP (addr, 1); \ ! addr = XEXP (addr, 0); \ ! } \ ! if (GET_CODE (addr) != PLUS) ; \ ! else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND) \ ! { \ ! reg1 = XEXP (addr, 0); \ ! addr = XEXP (addr, 1); \ ! } \ ! else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND) \ ! { \ ! reg1 = XEXP (addr, 1); \ ! addr = XEXP (addr, 0); \ ! } \ ! 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 \ ! || GET_CODE (addr) == SIGN_EXTEND) \ ! { if (reg1 == 0) reg1 = addr; else reg2 = addr; addr = 0; } \ ! /* for OLD_INDEXING \ ! else if (GET_CODE (addr) == PLUS) \ ! { \ ! if (GET_CODE (XEXP (addr, 0)) == REG) \ ! { \ ! reg2 = XEXP (addr, 0); \ ! addr = XEXP (addr, 1); \ ! } \ ! else if (GET_CODE (XEXP (addr, 1)) == REG) \ ! { \ ! reg2 = XEXP (addr, 1); \ ! addr = XEXP (addr, 0); \ ! } \ ! } \ ! */ \ ! if (offset != 0) { if (addr != 0) abort (); addr = offset; } \ ! if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND \ ! || GET_CODE (reg1) == MULT)) \ ! || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2)))) \ ! { breg = reg2; ireg = reg1; } \ ! else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1))) \ ! { breg = reg1; ireg = reg2; } \ ! if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF) \ ! { int scale = 1; \ ! if (GET_CODE (ireg) == MULT) \ ! { scale = INTVAL (XEXP (ireg, 1)); \ ! ireg = XEXP (ireg, 0); } \ ! if (GET_CODE (ireg) == SIGN_EXTEND) \ ! fprintf (FILE, "(.L%d,pc,%s.w", \ ! CODE_LABEL_NUMBER (XEXP (addr, 0)), \ ! reg_names[REGNO (XEXP (ireg, 0))]); \ ! else \ ! fprintf (FILE, "(.L%d,pc,%s.l", \ ! CODE_LABEL_NUMBER (XEXP (addr, 0)), \ ! reg_names[REGNO (ireg)]); \ ! if (scale != 1) fprintf (FILE, "*%d", scale); \ ! putc (')', FILE); \ ! break; } \ ! if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF \ ! && ! (flag_pic && breg == pic_offset_table_rtx)) \ ! { \ ! fprintf (FILE, "(.L%d,pc,%s.l", \ ! CODE_LABEL_NUMBER (XEXP (addr, 0)), \ ! reg_names[REGNO (breg)]); \ ! putc (')', FILE); \ ! break; } \ ! if (ireg != 0 || breg != 0) \ ! { int scale = 1; \ ! if (breg == 0) \ ! abort (); \ ! putc ('(', FILE); \ ! if (addr != 0) \ ! { \ ! output_addr_const (FILE, addr); \ ! putc (',', FILE); \ ! } \ ! fprintf (FILE, "%s", reg_names[REGNO (breg)]); \ ! if (ireg != 0) \ ! putc (',', FILE); \ ! if (ireg != 0 && GET_CODE (ireg) == MULT) \ ! { scale = INTVAL (XEXP (ireg, 1)); \ ! ireg = XEXP (ireg, 0); } \ ! if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND) \ ! fprintf (FILE, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]); \ ! else if (ireg != 0) \ ! fprintf (FILE, "%s.l", reg_names[REGNO (ireg)]); \ ! if (scale != 1) fprintf (FILE, "*%d", scale); \ ! putc (')', FILE); \ ! break; \ ! } \ ! else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF) \ ! { fprintf (FILE, "(.L%d,pc,%s.w)", \ ! CODE_LABEL_NUMBER (XEXP (addr, 0)), \ ! reg_names[REGNO (reg1)]); \ ! break; } \ ! default: \ ! if (GET_CODE (addr) == CONST_INT \ ! && INTVAL (addr) < 0x8000 \ ! && INTVAL (addr) >= -0x8000) \ ! fprintf (FILE, "%d.w", INTVAL (addr)); \ ! else \ ! output_addr_const (FILE, addr); \ ! }} ! ! #endif /* ! use gas */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/dpx2cdbx.h gcc-2.5.0/config/m68k/dpx2cdbx.h *** gcc-2.4.5/config/m68k/dpx2cdbx.h --- gcc-2.5.0/config/m68k/dpx2cdbx.h Tue Jul 27 03:08:26 1993 *************** *** 0 **** --- 1,29 ---- + /* Definitions for Bull dpx/2 200 and 300 with gas + using dbx-in-coff encapsulation. + Copyright (C) 1992 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + + #include "m68k/dpx2g.h" + + /* Use STABS debugging information inside COFF. */ + #undef SDB_DEBUGGING_INFO + #ifndef DBX_DEBUGGING_INFO + #define DBX_DEBUGGING_INFO + #endif + diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/dpx2g.h gcc-2.5.0/config/m68k/dpx2g.h *** gcc-2.4.5/config/m68k/dpx2g.h Tue Jan 5 03:24:39 1993 --- gcc-2.5.0/config/m68k/dpx2g.h Mon Aug 23 18:41:40 1993 *************** *** 45,54 **** - /* GAS want's DBX debugging information. */ - #undef SDB_DEBUGGING_INFO - #ifndef DBX_DEBUGGING_INFO - #define DBX_DEBUGGING_INFO - #endif - /* * we are using GAS --- 45,48 ---- *************** *** 61,64 **** --- 55,61 ---- #undef ASM_OUTPUT_IDENT + #undef ASM_LONG + #define ASM_LONG "\t.long" + /* * put const's in the text section *************** *** 67,77 **** #define fini_section() while (0) - #if 0 /* this is fixed in 2.1 */ - #undef ASM_OUTPUT_ALIGN - #define ASM_OUTPUT_ALIGN(FILE,LOG) \ - if ((LOG) >= 1) \ - fprintf (FILE, "\t.even\n"); - #endif - #undef CTORS_SECTION_ASM_OP #define CTORS_SECTION_ASM_OP "\t.data" --- 64,67 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/hp2bsd.h gcc-2.5.0/config/m68k/hp2bsd.h *** gcc-2.4.5/config/m68k/hp2bsd.h Thu May 13 09:49:38 1993 --- gcc-2.5.0/config/m68k/hp2bsd.h Sat Oct 2 04:19:59 1993 *************** *** 42,46 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dmc68000 -Dmc68010 -Dhp200 -Dunix" /* Link with libg.a when debugging, for dbx's sake. */ --- 42,46 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dmc68000 -Dmc68010 -Dhp200 -Dunix -Asystem(unix) -Asystem(bsd) -Acpu(m68k) -Amachine(m68k)" /* Link with libg.a when debugging, for dbx's sake. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/hp320.h gcc-2.5.0/config/m68k/hp320.h *** gcc-2.4.5/config/m68k/hp320.h Fri May 14 12:33:33 1993 --- gcc-2.5.0/config/m68k/hp320.h Sat Oct 2 04:20:03 1993 *************** *** 44,47 **** --- 44,49 ---- #endif + #endif /* not USE_GAS */ + /* gcc.c should find libgcc.a itself rather than expecting linker to. */ #define LINK_LIBGCC_SPECIAL *************** *** 50,54 **** /* HP/UX doesn't have libg.a. */ #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}" - #endif /* Be compatible with system stddef.h. */ --- 52,55 ---- *************** *** 124,128 **** GCC on other 68000 systems. */ ! #define CPP_PREDEFINES "-Dhp9000s200 -Dhp9000s300 -DPWB -Dhpux -Dunix -D__hp9000s300 -D__hp9000s200 -D__PWB -D__hpux -D__unix" /* Every structure or union's size must be a multiple of 2 bytes. */ --- 125,129 ---- GCC on other 68000 systems. */ ! #define CPP_PREDEFINES "-Dhp9000s200 -Dhp9000s300 -DPWB -Dhpux -Dunix -D__hp9000s300 -D__hp9000s200 -D__PWB -D__hpux -D__unix -D__motorola__ -Asystem(unix) -Asystem(hpux) -Acpu(m68k) -Amachine(m68k)" /* Every structure or union's size must be a multiple of 2 bytes. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/hp3bsd.h gcc-2.5.0/config/m68k/hp3bsd.h *** gcc-2.4.5/config/m68k/hp3bsd.h Tue Mar 23 14:37:03 1993 --- gcc-2.5.0/config/m68k/hp3bsd.h Sat Oct 2 04:20:06 1993 *************** *** 12,16 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dmc68000 -Dmc68020 -Dhp300 -Dhp9000 -Dunix" /* Link with libg.a when debugging, for dbx's sake. */ --- 12,16 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dmc68000 -Dmc68020 -Dhp300 -Dhp9000 -Dunix -Asystem(unix) -Asystem(bsd) -Acpu(m68k) -Amachine(m68k)" /* Link with libg.a when debugging, for dbx's sake. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/hp3bsd44.h gcc-2.5.0/config/m68k/hp3bsd44.h *** gcc-2.4.5/config/m68k/hp3bsd44.h Tue Mar 23 14:37:06 1993 --- gcc-2.5.0/config/m68k/hp3bsd44.h Sat Oct 2 04:20:09 1993 *************** *** 13,17 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dmc68000 -Dmc68020 -Dhp300 -Dhp9000 -Dunix -D__BSD_4_4__" /* No more libg.a */ --- 13,17 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dmc68000 -Dmc68020 -Dhp300 -Dhp9000 -Dunix -D__BSD_4_4__ -Asystem(unix) -Asystem(bsd) -Acpu(m68k) -Amachine(m68k)" /* No more libg.a */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/isi.h gcc-2.5.0/config/m68k/isi.h *** gcc-2.4.5/config/m68k/isi.h Tue Mar 23 07:39:55 1993 --- gcc-2.5.0/config/m68k/isi.h Sat Oct 2 04:20:14 1993 *************** *** 53,57 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dunix -Dmc68000 -Dis68k" /* This is BSD, so it wants DBX format. */ --- 53,57 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dunix -Dmc68000 -Dis68k -Asystem(unix) -Asystem(bsd) -Acpu(m68k) -Amachine(m68k)" /* This is BSD, so it wants DBX format. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/lynx.h gcc-2.5.0/config/m68k/lynx.h *** gcc-2.4.5/config/m68k/lynx.h --- gcc-2.5.0/config/m68k/lynx.h Sat Oct 2 04:20:17 1993 *************** *** 0 **** --- 1,35 ---- + /* Definitions for Motorola 680X0 running LynxOS. + Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + #include "m68k/m68k.h" + #include "lynx.h" + + /* See m68k.h. 7 means 68020 with 68881. */ + + #ifndef TARGET_DEFAULT + #define TARGET_DEFAULT 7 + #endif + + /* Names to predefine in the preprocessor for this target machine. */ + #undef CPP_PREDEFINES + #define CPP_PREDEFINES "-Dunix -Dmc68000 -DM68K -DLynx -DIBITS32 -Asystem(unix) -Asystem(lynx) -Acpu(m68k) -Amachine(m68k)" + + /* Every structure or union's size must be a multiple of 2 bytes. */ + + #define STRUCTURE_SIZE_BOUNDARY 16 diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/m68k.c gcc-2.5.0/config/m68k/m68k.c *** gcc-2.4.5/config/m68k/m68k.c Mon May 10 01:15:04 1993 --- gcc-2.5.0/config/m68k/m68k.c Thu Oct 21 00:26:37 1993 *************** *** 59,62 **** --- 59,63 ---- save an address register */ + void finalize_pic () { *************** *** 885,889 **** --- 886,892 ---- rtx latehalf[2]; rtx middlehalf[2]; + rtx xops[2]; rtx addreg0 = 0, addreg1 = 0; + int dest_overlapped_low = 0; int size = GET_MODE_SIZE (GET_MODE (operands[0])); *************** *** 1067,1070 **** --- 1070,1127 ---- operands[1] = latehalf[1]; + /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)), + if the upper part of reg N does not appear in the MEM, arrange to + emit the move late-half first. Otherwise, compute the MEM address + into the upper part of N and use that as a pointer to the memory + operand. */ + if (optype0 == REGOP + && (optype1 == OFFSOP || optype1 == MEMOP)) + { + if (reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)) + && reg_overlap_mentioned_p (latehalf[0], XEXP (operands[1], 0))) + { + /* If both halves of dest are used in the src memory address, + compute the address into latehalf of dest. */ + compadr: + xops[0] = latehalf[0]; + xops[1] = XEXP (operands[1], 0); + output_asm_insn ("lea %a1,%0", xops); + if( GET_MODE (operands[1]) == XFmode ) + { + operands[1] = gen_rtx (MEM, XFmode, latehalf[0]); + middlehalf[1] = adj_offsettable_operand (operands[1], size-8); + latehalf[1] = adj_offsettable_operand (operands[1], size-4); + } + else + { + operands[1] = gen_rtx (MEM, DImode, latehalf[0]); + latehalf[1] = adj_offsettable_operand (operands[1], size-4); + } + } + else if (size == 12 + && reg_overlap_mentioned_p (middlehalf[0], + XEXP (operands[1], 0))) + { + /* Check for two regs used by both source and dest. */ + if (reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)) + || reg_overlap_mentioned_p (latehalf[0], XEXP (operands[1], 0))) + goto compadr; + + /* JRV says this can't happen: */ + if (addreg0 || addreg1) + abort (); + + /* Only the middle reg conflicts; simply put it last. */ + output_asm_insn (singlemove_string (operands), operands); + output_asm_insn (singlemove_string (latehalf), latehalf); + output_asm_insn (singlemove_string (middlehalf), middlehalf); + return ""; + } + else if (reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0))) + /* If the low half of dest is mentioned in the source memory + address, the arrange to emit the move late half first. */ + dest_overlapped_low = 1; + } + /* If one or both operands autodecrementing, do the two words, high-numbered first. */ *************** *** 1078,1082 **** || (optype0 == REGOP && optype1 == REGOP && ((middlehalf[1] && REGNO (operands[0]) == REGNO (middlehalf[1])) ! || REGNO (operands[0]) == REGNO (latehalf[1])))) { /* Make any unoffsettable addresses point at high-numbered word. */ --- 1135,1140 ---- || (optype0 == REGOP && optype1 == REGOP && ((middlehalf[1] && REGNO (operands[0]) == REGNO (middlehalf[1])) ! || REGNO (operands[0]) == REGNO (latehalf[1]))) ! || dest_overlapped_low) { /* Make any unoffsettable addresses point at high-numbered word. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/m68k.h gcc-2.5.0/config/m68k/m68k.h *** gcc-2.4.5/config/m68k/m68k.h Fri Jun 18 17:58:01 1993 --- gcc-2.5.0/config/m68k/m68k.h Tue Sep 21 22:40:16 1993 *************** *** 122,128 **** --- 122,138 ---- { "68030", 5}, \ { "68040", 01007}, \ + { "68851", 0}, /* Affects *_SPEC and/or GAS. */ \ + { "no-68851", 0}, /* Affects *_SPEC and/or GAS. */ \ + { "68302", 0}, /* Affects *_SPEC and/or GAS. */ \ + { "no-68302", 0}, /* Affects *_SPEC and/or GAS. */ \ + { "68332", 0}, /* Affects *_SPEC and/or GAS. */ \ + { "no-68332", 0}, /* Affects *_SPEC and/or GAS. */ \ + SUBTARGET_SWITCHES \ { "", TARGET_DEFAULT}} /* TARGET_DEFAULT is defined in sun*.h and isi.h, etc. */ + /* This is meant to be redefined in the host dependent files */ + #define SUBTARGET_SWITCHES + #ifdef SUPPORT_SUN_FPA /* Blow away 68881 flag silently on TARGET_FPA (since we can't clear *************** *** 133,136 **** --- 143,147 ---- if (! TARGET_68020 && flag_pic == 2) \ error("-fPIC is not currently supported on the 68000 or 68010\n"); \ + SUBTARGET_OVERRIDE_OPTIONS \ } #else *************** *** 139,144 **** --- 150,159 ---- if (! TARGET_68020 && flag_pic == 2) \ error("-fPIC is not currently supported on the 68000 or 68010\n"); \ + SUBTARGET_OVERRIDE_OPTIONS \ } #endif /* defined SUPPORT_SUN_FPA */ + + /* This is meant to be redefined in the host dependent files */ + #define SUBTARGET_OVERRIDE_OPTIONS /* target machine storage layout */ *************** *** 1121,1132 **** The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS. */ #define INDIRECTABLE_1_ADDRESS_P(X) \ ((CONSTANT_ADDRESS_P (X) && (!flag_pic || LEGITIMATE_PIC_OPERAND_P (X))) \ ! || (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) \ || ((GET_CODE (X) == PRE_DEC || GET_CODE (X) == POST_INC) \ ! && REG_P (XEXP (X, 0)) \ ! && REG_OK_FOR_BASE_P (XEXP (X, 0))) \ || (GET_CODE (X) == PLUS \ ! && REG_P (XEXP (X, 0)) && REG_OK_FOR_BASE_P (XEXP (X, 0)) \ && GET_CODE (XEXP (X, 1)) == CONST_INT \ && ((unsigned) INTVAL (XEXP (X, 1)) + 0x8000) < 0x10000) \ --- 1136,1156 ---- The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS. */ + /* Allow SUBREG everywhere we allow REG. This results in better code. It + also makes function inlining work when inline functions are called with + arguments that are SUBREGs. */ + + #define LEGITIMATE_BASE_REG_P(X) \ + ((GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) \ + || (GET_CODE (X) == SUBREG \ + && GET_CODE (SUBREG_REG (X)) == REG \ + && REG_OK_FOR_BASE_P (SUBREG_REG (X)))) + #define INDIRECTABLE_1_ADDRESS_P(X) \ ((CONSTANT_ADDRESS_P (X) && (!flag_pic || LEGITIMATE_PIC_OPERAND_P (X))) \ ! || LEGITIMATE_BASE_REG_P (X) \ || ((GET_CODE (X) == PRE_DEC || GET_CODE (X) == POST_INC) \ ! && LEGITIMATE_BASE_REG_P (XEXP (X, 0))) \ || (GET_CODE (X) == PLUS \ ! && LEGITIMATE_BASE_REG_P (XEXP (X, 0)) \ && GET_CODE (XEXP (X, 1)) == CONST_INT \ && ((unsigned) INTVAL (XEXP (X, 1)) + 0x8000) < 0x10000) \ *************** *** 1157,1161 **** || GET_CODE (PATTERN (temp)) == ADDR_DIFF_VEC)) \ goto ADDR; \ ! if (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) goto ADDR; } #define GO_IF_INDEXING(X, ADDR) \ --- 1181,1185 ---- || GET_CODE (PATTERN (temp)) == ADDR_DIFF_VEC)) \ goto ADDR; \ ! if (LEGITIMATE_BASE_REG_P (X)) goto ADDR; } #define GO_IF_INDEXING(X, ADDR) \ *************** *** 1180,1184 **** && GET_CODE (XEXP (X, 0)) == REG \ && GET_MODE (XEXP (X, 0)) == HImode \ ! && REG_OK_FOR_INDEX_P (XEXP (X, 0)))) #define LEGITIMATE_INDEX_P(X) \ --- 1204,1211 ---- && GET_CODE (XEXP (X, 0)) == REG \ && GET_MODE (XEXP (X, 0)) == HImode \ ! && REG_OK_FOR_INDEX_P (XEXP (X, 0))) \ ! || (GET_CODE (X) == SUBREG \ ! && GET_CODE (SUBREG_REG (X)) == REG \ ! && REG_OK_FOR_INDEX_P (SUBREG_REG (X)))) #define LEGITIMATE_INDEX_P(X) \ *************** *** 1191,1197 **** || INTVAL (XEXP (X, 1)) == 8))) ! #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ ! { GO_IF_NONINDEXED_ADDRESS (X, ADDR); \ ! GO_IF_INDEXED_ADDRESS (X, ADDR); } /* Try machine-dependent ways of modifying an illegitimate address --- 1218,1234 ---- || INTVAL (XEXP (X, 1)) == 8))) ! /* If pic, we accept INDEX+LABEL, which is what do_tablejump makes. */ ! #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ ! { GO_IF_NONINDEXED_ADDRESS (X, ADDR); \ ! GO_IF_INDEXED_ADDRESS (X, ADDR); \ ! if (flag_pic && MODE == CASE_VECTOR_MODE && GET_CODE (X) == PLUS \ ! && LEGITIMATE_INDEX_P (XEXP (X, 0)) \ ! && GET_CODE (XEXP (X, 1)) == LABEL_REF) \ ! goto ADDR; } ! ! /* Don't call memory_address_noforce for the address to fetch ! the switch offset. This address is ok as it stands (see above), ! but memory_address_noforce would alter it. */ ! #define PIC_CASE_VECTOR_ADDRESS(index) index /* Try machine-dependent ways of modifying an illegitimate address *************** *** 1772,1775 **** --- 1809,1960 ---- #define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR) + + /* Definitions for generating bytecode */ + + /* Just so it's known this target is supported by the bytecode generator. + If this define isn't found anywhere in the target config files, then + dummy stubs are supplied by bytecode.h, and any attempt to use + -fbytecode will result in an error message. */ + + #define TARGET_SUPPORTS_BYTECODE + + /* Minimal segment alignment within sections is 8 units. */ + #define MACHINE_SEG_ALIGN 3 + + /* Integer alignment is two units. */ + #define INT_ALIGN 2 + + /* Pointer alignment is eight units. */ + #define PTR_ALIGN 3 + + /* Global symbols begin with `_' */ + #define NAMES_HAVE_UNDERSCORES + + /* BC_xxx below are similar to their ASM_xxx counterparts above. */ + #define BC_GLOBALIZE_LABEL(FP, NAME) bc_globalize_label(NAME) + + #define BC_OUTPUT_COMMON(FP, NAME, SIZE, ROUNDED) \ + do { bc_emit_common(NAME, ROUNDED); bc_globalize_label(NAME); } while (0) + + #define BC_OUTPUT_LOCAL(FP, NAME, SIZE, ROUNDED) \ + bc_emit_common(NAME, ROUNDED) + + #define BC_OUTPUT_ALIGN(FP, ALIGN) bc_align(ALIGN) + + #define BC_OUTPUT_LABEL(FP, NAME) bc_emit_labeldef(NAME) + + #define BC_OUTPUT_SKIP(FP, SIZE) bc_emit_skip(SIZE) + + #define BC_OUTPUT_LABELREF(FP, NAME) \ + do { \ + char *foo = (char *) xmalloc(strlen(NAME) + 2); \ + strcpy(foo, "_"); \ + strcat(foo, NAME); \ + bc_emit_labelref (foo); \ + free (foo); \ + } while (0) + + #define BC_OUTPUT_FLOAT(FP, VAL) \ + do { \ + float F = VAL; \ + bc_emit ((char *) &F, sizeof F); \ + } while (0) + + #define BC_OUTPUT_DOUBLE(FP, VAL) \ + do { \ + double D = VAL; \ + bc_emit ((char *) &D, sizeof D); \ + } while (0) + + #define BC_OUTPUT_BYTE(FP, VAL) \ + do { \ + char C = VAL; \ + bc_emit (&C, 1); \ + } while (0) + + + #define BC_OUTPUT_FILE ASM_OUTPUT_FILE + #define BC_OUTPUT_ASCII ASM_OUTPUT_ASCII + #define BC_OUTPUT_IDENT ASM_OUTPUT_IDENT + + /* Same as XSTR, but for bytecode */ + #define BCXSTR(RTX) ((RTX)->bc_label) + + + /* Flush bytecode buffer onto file */ + #define BC_WRITE_FILE(FP) \ + { \ + fprintf (FP, ".text\n"); \ + bc_seg_write (bc_text_seg, FP); \ + fprintf(FP, "\n.data\n"); \ + bc_seg_write (bc_data_seg, FP); \ + bc_sym_write (FP); /* do .globl, .bss, etc. */ \ + } + + /* Write one symbol */ + #define BC_WRITE_SEGSYM(SEGSYM, FP) \ + { \ + prsym (FP, (SEGSYM)->sym->name); \ + fprintf (FP, ":\n"); \ + } + + + /* Write one reloc entry */ + #define BC_WRITE_RELOC_ENTRY(SEGRELOC, FP, OFFSET) \ + { \ + fprintf (FP, "\t.long "); \ + prsym (FP, (SEGRELOC)->sym->name); \ + fprintf (FP, " + %d\n", OFFSET); \ + } + + /* Start new line of bytecodes */ + #define BC_START_BYTECODE_LINE(FP) \ + { \ + fprintf (FP, "\t.byte"); \ + } + + /* Write one bytecode */ + #define BC_WRITE_BYTECODE(SEP, VAL, FP) \ + { \ + fprintf (FP, "%c0x%02X", (SEP), (VAL) & 0xff); \ + } + + /* Write one bytecode RTL entry */ + #define BC_WRITE_RTL(R, FP) \ + { \ + fprintf (FP, "%s+%d/0x%08X\n", (R)->label, (R)->offset, (R)->bc_label); \ + } + + + /* Emit function entry trampoline */ + #define BC_EMIT_TRAMPOLINE(TRAMPSEG, CALLINFO) \ + { \ + short insn; \ + \ + /* Push a reference to the callinfo structure. */ \ + insn = 0x4879; /* pea xxx.L */ \ + seg_data (TRAMPSEG, (char *) &insn, sizeof insn); \ + seg_refsym (TRAMPSEG, CALLINFO, 0); \ + \ + /* Call __interp, pop arguments, and return. */ \ + insn = 0x4eb9; /* jsr xxx.L */ \ + seg_data (TRAMPSEG, (char *) &insn, sizeof insn); \ + seg_refsym (TRAMPSEG, "__callint", 0); \ + insn = 0x588f; /* addql #4, sp */ \ + seg_data (TRAMPSEG, (char *) &insn, sizeof insn); \ + insn = 0x4e75; /* rts */ \ + seg_data (TRAMPSEG, (char *) &insn, sizeof insn); \ + } + + + + #if 0 + #define VALIDATE_STACK() if (stack_depth < 0) abort (); + #else + #if 0 + #define VALIDATE_STACK() \ + fprintf (stderr, " %%%d%%", stack_depth); + #endif + #endif /* Define functions defined in aux-output.c and used in templates. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/m68k.md gcc-2.5.0/config/m68k/m68k.md *** gcc-2.4.5/config/m68k/m68k.md Sat Jun 12 16:22:57 1993 --- gcc-2.5.0/config/m68k/m68k.md Wed Oct 20 23:59:47 1993 *************** *** 407,412 **** (define_insn "cmphi" [(set (cc0) ! (compare (match_operand:HI 0 "nonimmediate_operand" "rnm,d,n,m") ! (match_operand:HI 1 "general_operand" "d,rnm,m,n")))] "" "* --- 407,412 ---- (define_insn "cmphi" [(set (cc0) ! (compare (match_operand:HI 0 "nonimmediate_operand" "rnm,d,n,m,>") ! (match_operand:HI 1 "general_operand" "d,rnm,m,n,>")))] "" "* *************** *** 1110,1114 **** (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,rofE<>,rmE,y,xH,rm,x"))] ; [(set (match_operand:DF 0 "general_operand" "=rm,&rf,&rof<>") --- 1110,1114 ---- (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,rofE<>,rmE,y,xH,rm,x"))] ; [(set (match_operand:DF 0 "general_operand" "=rm,&rf,&rof<>") *************** *** 1218,1222 **** (define_insn "" ! [(set (match_operand:XF 0 "nonimmediate_operand" "=rm,&rf,&rof<>") (match_operand:XF 1 "nonimmediate_operand" "rf,m,rof<>"))] "! TARGET_68881" --- 1218,1222 ---- (define_insn "" ! [(set (match_operand:XF 0 "nonimmediate_operand" "=rm,rf,&rof<>") (match_operand:XF 1 "nonimmediate_operand" "rf,m,rof<>"))] "! TARGET_68881" *************** *** 1261,1265 **** (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"))] ; [(set (match_operand:DI 0 "general_operand" "=rm,&r,&ro<>,!&rm,!&f,y,rm,x,!x,!rm") --- 1261,1265 ---- (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"))] ; [(set (match_operand:DI 0 "general_operand" "=rm,&r,&ro<>,!&rm,!&f,y,rm,x,!x,!rm") *************** *** 1745,1749 **** (clobber (match_scratch:SI 2 "=d")) (clobber (match_scratch:SI 3 "=d"))] ! "TARGET_68040" "* { --- 1745,1749 ---- (clobber (match_scratch:SI 2 "=d")) (clobber (match_scratch:SI 3 "=d"))] ! "TARGET_68881 && TARGET_68040" "* { *************** *** 1757,1761 **** (clobber (match_scratch:SI 2 "=d")) (clobber (match_scratch:SI 3 "=d"))] ! "TARGET_68040" "* { --- 1757,1761 ---- (clobber (match_scratch:SI 2 "=d")) (clobber (match_scratch:SI 3 "=d"))] ! "TARGET_68881 && TARGET_68040" "* { *************** *** 1769,1773 **** (clobber (match_scratch:SI 2 "=d")) (clobber (match_scratch:SI 3 "=d"))] ! "TARGET_68040" "* { --- 1769,1773 ---- (clobber (match_scratch:SI 2 "=d")) (clobber (match_scratch:SI 3 "=d"))] ! "TARGET_68881 && TARGET_68040" "* { *************** *** 4856,4859 **** --- 4856,4862 ---- "flag_pic" "* + #ifdef HPUX_ASM + return \"bsr %0\"; + #else #ifdef MOTOROLA if (GET_CODE (operands[0]) == MEM *************** *** 4862,4865 **** --- 4865,4869 ---- #endif return \"jsr %0\"; + #endif ") *************** *** 4907,4910 **** --- 4911,4917 ---- "flag_pic" "* + #ifdef HPUX_ASM + return \"bsr %1\"; + #else #ifdef MOTOROLA if (GET_CODE (operands[1]) == MEM *************** *** 4913,4916 **** --- 4920,4924 ---- #endif return \"jsr %1\"; + #endif ") diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/m68kv4.h gcc-2.5.0/config/m68k/m68kv4.h *** gcc-2.4.5/config/m68k/m68kv4.h Tue Mar 23 07:40:40 1993 --- gcc-2.5.0/config/m68k/m68kv4.h Sat Oct 2 04:20:20 1993 *************** *** 55,59 **** #define CPP_PREDEFINES \ ! "-Dm68k -Dunix -D__svr4__ -Asystem(unix) -Acpu(m68k) -Amachine(m68k)" /* Test to see if the target includes a 68881 by default, and use CPP_SPEC --- 55,60 ---- #define CPP_PREDEFINES \ ! "-Dm68k -Dunix -D__svr4__ -D__motorola__ \ ! -Asystem(unix) -Asystem(svr4) -Acpu(m68k) -Amachine(m68k)" /* Test to see if the target includes a 68881 by default, and use CPP_SPEC diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/mot3300.h gcc-2.5.0/config/m68k/mot3300.h *** gcc-2.4.5/config/m68k/mot3300.h Fri May 14 12:37:05 1993 --- gcc-2.5.0/config/m68k/mot3300.h Sat Oct 2 04:20:24 1993 *************** *** 219,223 **** #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dm68k -Dunix -DsysV68" /* Specify how to pad function arguments. --- 219,223 ---- #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dm68k -Dunix -DsysV68 -D__motorola__ -Asystem(unix) -Asystem(svr3) -Acpu(m68k) -Amachine(m68k)" /* Specify how to pad function arguments. *************** *** 387,391 **** #undef ASM_OUTPUT_SOURCE_FILENAME #define ASM_OUTPUT_SOURCE_FILENAME(FILE, FILENAME) \ ! fprintf (FILE, "\tfile\t\"%s\"\n", FILENAME) #undef ASM_OUTPUT_SOURCE_LINE --- 387,394 ---- #undef ASM_OUTPUT_SOURCE_FILENAME #define ASM_OUTPUT_SOURCE_FILENAME(FILE, FILENAME) \ ! do { fprintf (FILE, "\tfile\t"); \ ! output_quoted_string (FILE, FILENAME); \ ! fprintf (FILE, "\n"); \ ! } while (0) #undef ASM_OUTPUT_SOURCE_LINE *************** *** 675,678 **** --- 678,682 ---- #define SWITCH_JUMP_MATCH "jmp 6(%%pc," + /* cliffm@netcom.com says no need for .w suffix on jumps. */ #undef ASM_OUTPUT_OPCODE #define ASM_OUTPUT_OPCODE(FILE, PTR) \ *************** *** 681,685 **** while (*(PTR) != ' ') \ { putc (*(PTR), (FILE)); ++(PTR); } \ ! fprintf ((FILE), ".w"); } \ else if ((PTR)[0] == 's') \ { \ --- 685,689 ---- while (*(PTR) != ' ') \ { putc (*(PTR), (FILE)); ++(PTR); } \ ! } \ else if ((PTR)[0] == 's') \ { \ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/news.h gcc-2.5.0/config/m68k/news.h *** gcc-2.4.5/config/m68k/news.h Fri May 14 12:35:13 1993 --- gcc-2.5.0/config/m68k/news.h Sat Oct 2 04:20:29 1993 *************** *** 39,43 **** GCC on other 68000 systems. */ ! #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dnews700" /* These conditionals tested for different submodels, --- 39,47 ---- GCC on other 68000 systems. */ ! #ifdef MOTOROLA ! #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dnews700 -D__motorola__ -Asystem(unix) -Asystem(bsd) -Acpu(m68k) -Amachine(m68k)" ! #else ! #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dnews700 -Asystem(unix) -Asystem(bsd) -Acpu(m68k) -Amachine(m68k)" ! #endif /* These conditionals tested for different submodels, *************** *** 47,66 **** #if 0 #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 #endif --- 51,70 ---- #if 0 #ifdef news800 ! #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dnews800 -Asystem(unix) -Asystem(bsd) -Acpu(m68k) -Amachine(m68k)" #endif #ifdef news900 ! #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dnews900 -Asystem(unix) -Asystem(bsd) -Acpu(m68k) -Amachine(m68k)" #endif #ifdef news1500 ! #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dmc68030 -Dnews1500 -Asystem(unix) -Asystem(bsd) -Acpu(m68k) -Amachine(m68k)" #endif #ifdef news1700 ! #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dmc68030 -Dnews1700 -Asystem(unix) -Asystem(bsd) -Acpu(m68k) -Amachine(m68k)" #endif #ifdef news1800 ! #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dmc68030 -Dnews1800 -Asystem(unix) -Asystem(bsd) -Acpu(m68k) -Amachine(m68k)" #endif #ifdef news1900 ! #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dmc68030 -Dnews1900 -Asystem(unix) -Asystem(bsd) -Acpu(m68k) -Amachine(m68k)" #endif #endif diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/next.h gcc-2.5.0/config/m68k/next.h *** gcc-2.4.5/config/m68k/next.h Wed May 12 22:52:06 1993 --- gcc-2.5.0/config/m68k/next.h Sat Oct 2 04:20:32 1993 *************** *** 34,38 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dmc68000 -Dm68k -DNeXT -Dunix -D__MACH__ -D__BIG_ENDIAN__ -D__ARCHITECTURE__=\"m68k\"" /* Every structure or union's size must be a multiple of 2 bytes. --- 34,38 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dmc68000 -Dm68k -DNeXT -Dunix -D__MACH__ -D__BIG_ENDIAN__ -D__ARCHITECTURE__=\"m68k\" -Asystem(unix) -Asystem(mach) -Acpu(m68k) -Amachine(m68k)" /* Every structure or union's size must be a multiple of 2 bytes. *************** *** 182,183 **** --- 182,206 ---- #define OBJC_FORWARDING_STACK_OFFSET 8 #define OBJC_FORWARDING_MIN_OFFSET 8 + + /* INITIALIZE_TRAMPOLINE is changed so that it also enables executable + stack. The __enable_execute_stack also clears the insn cache. */ + + /* NOTE: part of this is copied from m68k.h */ + #undef INITIALIZE_TRAMPOLINE + #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ + { \ + rtx _addr, _func; \ + emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 2)), TRAMP); \ + emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 18)), CXT); \ + emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 22)), FNADDR); \ + _addr = memory_address (SImode, (TRAMP)); \ + _func = gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"); \ + emit_library_call (_func, 0, VOIDmode, 1, _addr, Pmode); \ + } + + /* A C expression used to clear the instruction cache from + address BEG to address END. On NeXTSTEP this i a system trap. */ + + #define CLEAR_INSN_CACHE(BEG, END) \ + asm volatile ("trap #2") + diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/pbb.h gcc-2.5.0/config/m68k/pbb.h *** gcc-2.4.5/config/m68k/pbb.h Thu May 13 09:49:36 1993 --- gcc-2.5.0/config/m68k/pbb.h Sat Oct 2 04:20:35 1993 *************** *** 45,49 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dm68k -Dunix -DUnicomPBB -Dmc68k -Dmc68020 -Dmc68k32" /* We want DBX format for use with gdb under COFF. */ --- 45,49 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dm68k -Dunix -DUnicomPBB -Dmc68k -Dmc68020 -Dmc68k32 -Asystem(unix) -Acpu(m68k) -Amachine(m68k)" /* We want DBX format for use with gdb under COFF. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/plexus.h gcc-2.5.0/config/m68k/plexus.h *** gcc-2.4.5/config/m68k/plexus.h Thu May 13 09:49:35 1993 --- gcc-2.5.0/config/m68k/plexus.h Sat Oct 2 04:20:38 1993 *************** *** 49,53 **** #define CPP_SPEC "%{m68881:-D__HAVE_68881__}" ! #define CPP_PREDEFINES "-Dm68 -Dunix -Dplexus" #if TARGET_DEFAULT & 01 --- 49,53 ---- #define CPP_SPEC "%{m68881:-D__HAVE_68881__}" ! #define CPP_PREDEFINES "-Dm68 -Dunix -Dplexus -Asystem(unix) -Acpu(m68k) -Amachine(m68k)" #if TARGET_DEFAULT & 01 diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/sun2.h gcc-2.5.0/config/m68k/sun2.h *** gcc-2.4.5/config/m68k/sun2.h Thu May 13 09:49:34 1993 --- gcc-2.5.0/config/m68k/sun2.h Sat Oct 2 04:20:40 1993 *************** *** 44,48 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dmc68000 -Dsun -Dunix" /* Prevent error on `-sun2' and `-target sun2' options. */ --- 44,48 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dmc68000 -Dsun -Dunix -Asystem(unix) -Asystem(bsd) -Acpu(m68k) -Amachine(m68k)" /* Prevent error on `-sun2' and `-target sun2' options. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/sun3.h gcc-2.5.0/config/m68k/sun3.h *** gcc-2.4.5/config/m68k/sun3.h Tue May 25 23:56:01 1993 --- gcc-2.5.0/config/m68k/sun3.h Wed Oct 13 17:25:00 1993 *************** *** 62,66 **** #define PTRDIFF_TYPE "int" - #define SIZE_TYPE "int" /* We must override m68k.h. */ --- 62,65 ---- *************** *** 83,88 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dmc68000 -Dsun -Dunix" /* STARTFILE_SPEC to include sun floating point initialization --- 82,92 ---- /* Names to predefine in the preprocessor for this target machine. */ + /* For a while, -D_CROSS_TARGET_ARCH=SUN3 was included here, + but it doesn't work, partly because SUN3 etc. aren't defined + (and shouldn't be). It seems that on a native compiler _CROSS_TARGET_ARCH + should not be defined. For cross compilers, let's do things as we + normally do in GCC. -- rms. */ ! #define CPP_PREDEFINES "-Dmc68000 -Dsun -Dunix -Asystem(unix) -Asystem(bsd) -Acpu(m68k) -Amachine(m68k)" /* STARTFILE_SPEC to include sun floating point initialization *************** *** 277,278 **** --- 281,295 ---- } \ } while (0) + + #undef BLOCK_PROFILER_CODE + #define BLOCK_PROFILER_CODE \ + extern int ___tcov_init; \ + \ + __bb_init_func (blocks) \ + struct bb *blocks; \ + { \ + if (! ___tcov_init) \ + ___tcov_init_func (); \ + \ + ___bb_link (blocks->filename, blocks->counts, blocks->ncounts); \ + } diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/sun3mach.h gcc-2.5.0/config/m68k/sun3mach.h *** gcc-2.4.5/config/m68k/sun3mach.h Tue Mar 23 14:22:18 1993 --- gcc-2.5.0/config/m68k/sun3mach.h Sat Oct 2 04:20:47 1993 *************** *** 2,6 **** #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dmc68000 -Dsun -Dsun3 -Dunix -DMACH -DCMU -DMTXINU -DBIT_MSF -DBYTE_MSF" /* Specify extra dir to search for include files. */ --- 2,6 ---- #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dmc68000 -Dsun -Dsun3 -Dunix -DMACH -DCMU -DMTXINU -DBIT_MSF -DBYTE_MSF -Asystem(unix) -Asystem(mach) -Acpu(m68k) -Amachine(m68k)" /* Specify extra dir to search for include files. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/t-next gcc-2.5.0/config/m68k/t-next *** gcc-2.4.5/config/m68k/t-next Wed Nov 25 16:29:00 1992 --- gcc-2.5.0/config/m68k/t-next Thu Sep 9 16:02:34 1993 *************** *** 1,4 **** # libgcc1.c is not needed, since the standard library has these functions. ! LIBGCC1= # Specify other dirs of system header files to be fixed. --- 1,5 ---- # libgcc1.c is not needed, since the standard library has these functions. ! LIBGCC1=libgcc1.null ! CROSS_LIBGCC1=libgcc1.null # Specify other dirs of system header files to be fixed. diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/tower-as.h gcc-2.5.0/config/m68k/tower-as.h *** gcc-2.4.5/config/m68k/tower-as.h Mon May 24 12:52:18 1993 --- gcc-2.5.0/config/m68k/tower-as.h Sat Oct 2 04:20:50 1993 *************** *** 39,43 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dunix -Dtower32 -Dtower32_600" /* Define __HAVE_68881 in preprocessor only if -m68881 is specified. --- 39,43 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dunix -Dtower32 -Dtower32_600 -D__motorola__ -Asystem(unix) -Asystem(svr3) -Acpu(m68k) -Amachine(m68k)" /* Define __HAVE_68881 in preprocessor only if -m68881 is specified. *************** *** 72,76 **** #define ASM_OUTPUT_SOURCE_FILENAME(FILE, FILENAME) \ do { \ ! fprintf (FILE, "\tfile\t\"%s\"\n", FILENAME); \ fprintf (FILE, "section ~init,\"x\"\n"); \ fprintf (FILE, "section ~fini,\"x\"\n"); \ --- 72,78 ---- #define ASM_OUTPUT_SOURCE_FILENAME(FILE, FILENAME) \ do { \ ! fprintf (FILE, "\tfile\t"); \ ! output_quoted_string (FILE, FILENAME); \ ! fprintf (FILE, "\n"); \ fprintf (FILE, "section ~init,\"x\"\n"); \ fprintf (FILE, "section ~fini,\"x\"\n"); \ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/tower.h gcc-2.5.0/config/m68k/tower.h *** gcc-2.4.5/config/m68k/tower.h Thu May 13 09:49:33 1993 --- gcc-2.5.0/config/m68k/tower.h Sat Oct 2 04:20:53 1993 *************** *** 48,52 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dunix -Dtower32 -Dtower32_200" #if 0 /* It is incorrect to test these symbols. --- 48,52 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dunix -Dtower32 -Dtower32_200 -Asystem(unix) -Asystem(svr3) -Acpu(m68k) -Amachine(m68k)" #if 0 /* It is incorrect to test these symbols. *************** *** 54,67 **** It should not matter which model is specified. */ #ifdef tower32_600 ! #define CPP_PREDEFINES "-Dunix -Dtower32 -Dtower32_600" #endif #ifdef tower32_700 ! #define CPP_PREDEFINES "-Dunix -Dtower32 -Dtower32_700" #endif #ifdef tower32_800 ! #define CPP_PREDEFINES "-Dunix -Dtower32 -Dtower32_800" #endif #ifdef tower32_850 ! #define CPP_PREDEFINES "-Dunix -Dtower32 -Dtower32_850" #endif #endif --- 54,67 ---- It should not matter which model is specified. */ #ifdef tower32_600 ! #define CPP_PREDEFINES "-Dunix -Dtower32 -Dtower32_600 -Asystem(unix) -Asystem(svr3) -Acpu(m68k) -Amachine(m68k)" #endif #ifdef tower32_700 ! #define CPP_PREDEFINES "-Dunix -Dtower32 -Dtower32_700 -Asystem(unix) -Asystem(svr3) -Acpu(m68k) -Amachine(m68k)" #endif #ifdef tower32_800 ! #define CPP_PREDEFINES "-Dunix -Dtower32 -Dtower32_800 -Asystem(unix) -Asystem(svr3) -Acpu(m68k) -Amachine(m68k)" #endif #ifdef tower32_850 ! #define CPP_PREDEFINES "-Dunix -Dtower32 -Dtower32_850 -Asystem(unix) -Asystem(svr3) -Acpu(m68k) -Amachine(m68k)" #endif #endif diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/x-apollo68 gcc-2.5.0/config/m68k/x-apollo68 *** gcc-2.4.5/config/m68k/x-apollo68 Tue Mar 16 15:13:36 1993 --- gcc-2.5.0/config/m68k/x-apollo68 Sun Jun 27 18:24:36 1993 *************** *** 11,12 **** --- 11,15 ---- # target which does support debugging. There is currently no way to avoid # the -g option that doesn't break something else. + + # Apollo does not have B option. + TAROUTOPTS=xpf diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/x-dpx2 gcc-2.5.0/config/m68k/x-dpx2 *** gcc-2.4.5/config/m68k/x-dpx2 Mon Jul 27 22:57:33 1992 --- gcc-2.5.0/config/m68k/x-dpx2 Mon Aug 2 15:17:45 1993 *************** *** 12,16 **** CFLAGS=`if [ x$(OLDCC) = x$(CC) ] ; then echo -g; else echo -O; fi` # ! CLIB=-lc_s -lld -lm # tell CC whether we are a 200 or 300 ! X_CFLAGS=-D_SYSV -D__DPX2__ `if [ -d /makesys/kernel/cf/ncl_mr ]; then echo -Dncl_mr=1; else echo -Dncl_el; fi` --- 12,16 ---- CFLAGS=`if [ x$(OLDCC) = x$(CC) ] ; then echo -g; else echo -O; fi` # ! CLIB=-lmalloc -lld -lm # tell CC whether we are a 200 or 300 ! X_CFLAGS=-D_POSIX_SOURCE -D_XOPEN_SOURCE -D_BULL_SOURCE -D__DPX2__ `if [ -d /makesys/kernel/cf/ncl_mr ]; then echo -Dncl_mr=1; else echo -Dncl_el; fi` diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/xm-crds.h gcc-2.5.0/config/m68k/xm-crds.h *** gcc-2.4.5/config/m68k/xm-crds.h Tue Jan 5 03:52:31 1993 --- gcc-2.5.0/config/m68k/xm-crds.h Sat Jun 26 11:35:46 1993 *************** *** 16,21 **** #ifndef __GNUC__ #define USE_C_ALLOCA - #else - #define alloca __builtin_alloca #endif --- 16,19 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m68k/xm-m68k.h gcc-2.5.0/config/m68k/xm-m68k.h *** gcc-2.4.5/config/m68k/xm-m68k.h Sat Dec 26 17:25:51 1992 --- gcc-2.5.0/config/m68k/xm-m68k.h Sat Jun 26 11:35:21 1993 *************** *** 1,4 **** /* Configuration for GNU C-compiler for Motorola 68000 family. ! Copyright (C) 1987 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,4 ---- /* Configuration for GNU C-compiler for Motorola 68000 family. ! Copyright (C) 1987, 1993 Free Software Foundation, Inc. This file is part of GNU CC. *************** *** 39,47 **** #define SUCCESS_EXIT_CODE 0 #define FATAL_EXIT_CODE 33 - - /* If compiled with GNU C, use the built-in alloca */ - #ifdef __GNUC__ - /* Use an arg in this macro because that's what some other - system does--let's avoid conflict. */ - #define alloca(x) __builtin_alloca(x) - #endif --- 39,40 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m88k/dgux.h gcc-2.5.0/config/m88k/dgux.h *** gcc-2.4.5/config/m88k/dgux.h Fri Jan 1 07:36:17 1993 --- gcc-2.5.0/config/m88k/dgux.h Sat Oct 2 04:20:57 1993 *************** *** 71,75 **** #undef CPP_PREDEFINES #define CPP_PREDEFINES "-Dm88000 -Dm88k -Dunix -DDGUX -D__CLASSIFY_TYPE__=2\ ! -D__svr4__ -Asystem(unix) -Acpu(m88k) -Amachine(m88k)" /* If -m88100 is in effect, add -Dm88100; similarly for -m88110. --- 71,75 ---- #undef CPP_PREDEFINES #define CPP_PREDEFINES "-Dm88000 -Dm88k -Dunix -DDGUX -D__CLASSIFY_TYPE__=2\ ! -D__svr4__ -Asystem(unix) -Asystem(svr4) -Acpu(m88k) -Amachine(m88k)" /* If -m88100 is in effect, add -Dm88100; similarly for -m88110. diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m88k/luna.h gcc-2.5.0/config/m88k/luna.h *** gcc-2.4.5/config/m88k/luna.h Fri Jan 1 07:36:23 1993 --- gcc-2.5.0/config/m88k/luna.h Sat Oct 2 04:21:00 1993 *************** *** 37,41 **** #undef CPP_PREDEFINES #define CPP_PREDEFINES \ ! "-DMACH -Dm88k -Dunix -Dluna -Dluna88k -D__CLASSIFY_TYPE__=2" /* If -m88000 is in effect, add -Dmc88000; similarly for -m88100 and -m88110. --- 37,41 ---- #undef CPP_PREDEFINES #define CPP_PREDEFINES \ ! "-DMACH -Dm88k -Dunix -Dluna -Dluna88k -D__CLASSIFY_TYPE__=2 -Asystem(unix) -Asystem(mach) -Acpu(m88k) -Amachine(m88k)" /* If -m88000 is in effect, add -Dmc88000; similarly for -m88100 and -m88110. diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m88k/m88k.c gcc-2.5.0/config/m88k/m88k.c *** gcc-2.4.5/config/m88k/m88k.c Mon Feb 22 21:01:18 1993 --- gcc-2.5.0/config/m88k/m88k.c Wed Sep 8 11:14:03 1993 *************** *** 869,880 **** to ever happen. If it becomes a problem, claim that a call has two delay slots and only the second can be filled with ! a jump. */ #ifdef AS_BUG_IMMEDIATE_LABEL /* The assembler restricts immediate values. */ if (optimize < 2 ! || ! ADD_INTVAL (delta * 2)) #else if (optimize < 2 ! || ! ADD_INTVAL (delta)) #endif { operands[1] = dest; --- 869,886 ---- to ever happen. If it becomes a problem, claim that a call has two delay slots and only the second can be filled with ! a jump. ! ! The 88110 can lose when a jsr.n r1 is issued and a page fault ! occurs accessing the delay slot. So don't use jsr.n form when ! jumping thru r1. ! */ #ifdef AS_BUG_IMMEDIATE_LABEL /* The assembler restricts immediate values. */ if (optimize < 2 ! || ! ADD_INTVAL (delta * 2) #else if (optimize < 2 ! || ! ADD_INTVAL (delta) #endif + || (REG_P (addr) && REGNO (addr) == 1)) { operands[1] = dest; *************** *** 2556,2560 **** plus_constant (XEXP (addr, 0), fixed * UNITS_PER_WORD)), ! 8 - fixed); /* Return the address of the va_list constructor, but don't put it in a --- 2562,2566 ---- plus_constant (XEXP (addr, 0), fixed * UNITS_PER_WORD)), ! 8 - fixed, (8 - fixed) * UNITS_PER_WORD); /* Return the address of the va_list constructor, but don't put it in a *************** *** 2688,2691 **** --- 2694,2704 ---- the code to the unknown value. */ + /* + hassey 6/30/93 + A problem with 88110 4.1 & 4.2 makes the use of fldcr for + this purpose undesirable. Instead we will use tb1, this will + cause serialization on the 88100 but such is life. + */ + static rtx last_addr = 0; if (code == 'V' /* Only need to serialize before a load. */ *************** *** 2695,2698 **** --- 2708,2712 ---- && rtx_equal_p (XEXP (XEXP (x, 0), 1), last_addr))) fprintf (file, + #if 0 #ifdef AS_BUG_FLDCR "fldcr\t %s,%scr63\n\t", *************** *** 2701,2704 **** --- 2715,2721 ---- #endif reg_names[0], m88k_pound_sign); + #else /* 0 */ + "tb1\t 1,%s,0xff\n\t", reg_names[0]); + #endif /* 0 */ m88k_volatile_code = code; last_addr = (GET_CODE (XEXP (x, 0)) == LO_SUM diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m88k/m88k.h gcc-2.5.0/config/m88k/m88k.h *** gcc-2.4.5/config/m88k/m88k.h Tue Jun 8 09:13:11 1993 --- gcc-2.5.0/config/m88k/m88k.h Thu Oct 21 00:04:37 1993 *************** *** 1,5 **** /* Definitions of target machine for GNU compiler. Motorola m88100 in an 88open OCS/BCS environment. ! Copyright (C) 1988, 1989, 1990, 1991 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@mcc.com) Enhanced by Michael Meissner (meissner@osf.org) --- 1,5 ---- /* Definitions of target machine for GNU compiler. Motorola m88100 in an 88open OCS/BCS environment. ! Copyright (C) 1988, 1989, 1990, 1991, 1993 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@mcc.com) Enhanced by Michael Meissner (meissner@osf.org) *************** *** 208,212 **** /* Names to predefine in the preprocessor for this target machine. Redefined in m88kv3.h, m88kv4.h, m88kdgux.h, and m88kluna.h. */ ! #define CPP_PREDEFINES "-Dm88000 -Dm88k -Dunix -D__CLASSIFY_TYPE__=2" #define TARGET_VERSION fprintf (stderr, " (%s%s)", \ --- 208,212 ---- /* Names to predefine in the preprocessor for this target machine. Redefined in m88kv3.h, m88kv4.h, m88kdgux.h, and m88kluna.h. */ ! #define CPP_PREDEFINES "-Dm88000 -Dm88k -Dunix -D__CLASSIFY_TYPE__=2 -Asystem(unix) -Acpu(m88k) -Amachine(m88k)" #define TARGET_VERSION fprintf (stderr, " (%s%s)", \ *************** *** 242,247 **** #define MASK_WARN_PASS_STRUCT 0x00002000 /* Warn about passed structs */ #define MASK_OPTIMIZE_ARG_AREA 0x00004000 /* Save stack space */ ! #define MASK_SERIALIZE_VOLATILE 0x00008000 /* Serialize volatile refs */ ! #define MASK_NO_SERIALIZE_VOLATILE 0x00010000 /* Don't serialize */ #define MASK_88000 (MASK_88100 | MASK_88110) --- 242,246 ---- #define MASK_WARN_PASS_STRUCT 0x00002000 /* Warn about passed structs */ #define MASK_OPTIMIZE_ARG_AREA 0x00004000 /* Save stack space */ ! #define MASK_NO_SERIALIZE_VOLATILE 0x00008000 /* Serialize volatile refs */ #define MASK_88000 (MASK_88100 | MASK_88110) *************** *** 248,252 **** #define MASK_EITHER_LARGE_SHIFT (MASK_TRAP_LARGE_SHIFT | \ MASK_HANDLE_LARGE_SHIFT) - #define MASK_SERIALIZE (MASK_SERIALIZE_VOLATILE | MASK_NO_SERIALIZE_VOLATILE) #define TARGET_88100 ((target_flags & MASK_88000) == MASK_88100) --- 247,250 ---- *************** *** 266,270 **** #define TARGET_WARN_PASS_STRUCT (target_flags & MASK_WARN_PASS_STRUCT) #define TARGET_OPTIMIZE_ARG_AREA (target_flags & MASK_OPTIMIZE_ARG_AREA) ! #define TARGET_SERIALIZE_VOLATILE (target_flags & MASK_SERIALIZE_VOLATILE) #define TARGET_EITHER_LARGE_SHIFT (target_flags & MASK_EITHER_LARGE_SHIFT) --- 264,268 ---- #define TARGET_WARN_PASS_STRUCT (target_flags & MASK_WARN_PASS_STRUCT) #define TARGET_OPTIMIZE_ARG_AREA (target_flags & MASK_OPTIMIZE_ARG_AREA) ! #define TARGET_SERIALIZE_VOLATILE (!(target_flags & MASK_NO_SERIALIZE_VOLATILE)) #define TARGET_EITHER_LARGE_SHIFT (target_flags & MASK_EITHER_LARGE_SHIFT) *************** *** 296,301 **** { "optimize-arg-area", MASK_OPTIMIZE_ARG_AREA }, \ { "no-optimize-arg-area", -MASK_OPTIMIZE_ARG_AREA }, \ - { "serialize-volatile", MASK_SERIALIZE_VOLATILE }, \ { "no-serialize-volatile", MASK_NO_SERIALIZE_VOLATILE }, \ SUBTARGET_SWITCHES \ /* Default switches */ \ --- 294,299 ---- { "optimize-arg-area", MASK_OPTIMIZE_ARG_AREA }, \ { "no-optimize-arg-area", -MASK_OPTIMIZE_ARG_AREA }, \ { "no-serialize-volatile", MASK_NO_SERIALIZE_VOLATILE }, \ + { "serialize-volatile", -MASK_NO_SERIALIZE_VOLATILE }, \ SUBTARGET_SWITCHES \ /* Default switches */ \ *************** *** 323,332 **** : (TARGET_88100 ? CPU_M88100 : CPU_M88110)); \ \ - if (! TARGET_88100 && (target_flags & MASK_SERIALIZE) == 0) \ - target_flags |= MASK_SERIALIZE_VOLATILE; \ - \ - if ((target_flags & MASK_NO_SERIALIZE_VOLATILE) != 0) \ - target_flags &= ~MASK_SERIALIZE_VOLATILE; \ - \ if (TARGET_BIG_PIC) \ flag_pic = 2; \ --- 321,324 ---- *************** *** 1460,1463 **** --- 1452,1456 ---- {"reg_or_bbx_mask_operand", {SUBREG, REG, CONST_INT}}, \ {"real_or_0_operand", {SUBREG, REG, CONST_DOUBLE}}, \ + {"reg_or_0_operand", {SUBREG, REG, CONST_INT}}, \ {"relop", {EQ, NE, LT, LE, GE, GT, LTU, LEU, GEU, GTU}}, \ {"relop_no_unsigned", {EQ, NE, LT, LE, GE, GT}}, \ *************** *** 1516,1522 **** #define MOVE_MAX 8 ! /* Define if normal loads of shorter-than-word items from memory clears ! the rest of the bigs in the register. */ ! #define BYTE_LOADS_ZERO_EXTEND /* Zero if access to memory by bytes is faster. */ --- 1509,1521 ---- #define MOVE_MAX 8 ! /* Define if operations between registers always perform the operation ! on the full register even if a narrower mode is specified. */ ! #define WORD_REGISTER_OPERATIONS ! ! /* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD ! will either zero-extend or sign-extend. The value of this macro should ! be the code that says which one of the two operations is implicitly ! done, NIL if none. */ ! #define LOAD_EXTEND_OP(MODE) ZERO_EXTEND /* Zero if access to memory by bytes is faster. */ *************** *** 1821,1825 **** #define ASM_OUTPUT_SOURCE_FILENAME(FILE, NAME) \ ! fprintf (FILE, "\t%s\t \"%s\"\n", FILE_ASM_OP, NAME) #ifdef SDB_DEBUGGING_INFO --- 1820,1827 ---- #define ASM_OUTPUT_SOURCE_FILENAME(FILE, NAME) \ ! do { fprintf (FILE, "\t%s\t ", FILE_ASM_OP); \ ! output_quoted_string (FILE, NAME); \ ! fprintf (FILE, "\n"); \ ! } while (0) #ifdef SDB_DEBUGGING_INFO *************** *** 1911,1932 **** /* Write the extra assembler code needed to declare an object properly. */ #undef ASM_DECLARE_OBJECT_NAME ! #define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \ ! do { \ ! if (DECLARE_ASM_NAME) \ ! { \ ! fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \ ! assemble_name (FILE, NAME); \ ! putc (',', FILE); \ ! fprintf (FILE, TYPE_OPERAND_FMT, "object"); \ ! putc ('\n', FILE); \ ! if (!flag_inhibit_size_directive) \ ! { \ ! fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ ! assemble_name (FILE, NAME); \ ! fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (decl))); \ ! } \ ! } \ ! ASM_OUTPUT_LABEL(FILE, NAME); \ } while (0) /* This is how to declare the size of a function. */ --- 1913,1957 ---- /* Write the extra assembler code needed to declare an object properly. */ #undef ASM_DECLARE_OBJECT_NAME ! #define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \ ! do { \ ! if (DECLARE_ASM_NAME) \ ! { \ ! fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \ ! assemble_name (FILE, NAME); \ ! putc (',', FILE); \ ! fprintf (FILE, TYPE_OPERAND_FMT, "object"); \ ! putc ('\n', FILE); \ ! size_directive_output = 0; \ ! if (!flag_inhibit_size_directive && DECL_SIZE (DECL)) \ ! { \ ! size_directive_output = 1; \ ! fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ ! assemble_name (FILE, NAME); \ ! fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \ ! } \ ! } \ ! ASM_OUTPUT_LABEL(FILE, NAME); \ } while (0) + + /* Output the size directive for a decl in rest_of_decl_compilation + in the case where we did not do so before the initializer. + Once we find the error_mark_node, we know that the value of + size_directive_output was set + by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */ + + #define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \ + do { \ + char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \ + if (!flag_inhibit_size_directive && DECL_SIZE (DECL) \ + && DECLARE_ASM_NAME \ + && ! AT_END && TOP_LEVEL \ + && DECL_INITIAL (DECL) == error_mark_node \ + && !size_directive_output) \ + { \ + fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ + assemble_name (FILE, name); \ + fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \ + } \ + } while (0) /* This is how to declare the size of a function. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m88k/mot-sysv4.h gcc-2.5.0/config/m88k/mot-sysv4.h *** gcc-2.4.5/config/m88k/mot-sysv4.h --- gcc-2.5.0/config/m88k/mot-sysv4.h Wed Aug 25 18:32:33 1993 *************** *** 0 **** --- 1,44 ---- + /* Definitions of target machine for GNU compiler. + Motorola 88100 Delta machine running SVR4 + Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + #include "m88k/sysv4.h" + + /* The .init section preamble code on the svr4 m88k Delta system looks like: + + _init: subu r31, r31, 0x30 + st r1, r31, 0x20 + + do_global_ctors_aux in crtstuff.c emits do_global_ctors which is put + into the .init section. However, this function has its own + prolog which allocates more of the stack. The epilogue of do_global_ctors + only knows about its own stack allocation, not that in the .init + section preamble. So we must undo the allocation performed by the .init + section preamble. We use the following instruction: + + addu r31, r31, 0x30 + + which is placed immediately after the two instructions shown above + and before do_global_ctors. + + Note that this is a kludge since it depends on knowing the constant + 0x30 above. However, no better fix is known at this time. */ + + #undef INIT_SECTION_PREAMBLE + #define INIT_SECTION_PREAMBLE asm ("\taddu\t #r31,#r31,0x30") diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m88k/sysv3.h gcc-2.5.0/config/m88k/sysv3.h *** gcc-2.4.5/config/m88k/sysv3.h Fri Jan 1 07:36:27 1993 --- gcc-2.5.0/config/m88k/sysv3.h Sat Oct 2 04:21:12 1993 *************** *** 31,35 **** /* Macros to be automatically defined. */ #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dm88000 -Dm88k -Dunix -DsysV88 -D__CLASSIFY_TYPE__=2" /* Override svr3.h to link with ?crt0.o instead of ?crt1.o and ?crtn.o. --- 31,35 ---- /* Macros to be automatically defined. */ #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dm88000 -Dm88k -Dunix -DsysV88 -D__CLASSIFY_TYPE__=2 -Asystem(unix) -Asystem(svr3) -Acpu(m88k) -Amachine(m88k)" /* Override svr3.h to link with ?crt0.o instead of ?crt1.o and ?crtn.o. diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m88k/sysv4.h gcc-2.5.0/config/m88k/sysv4.h *** gcc-2.4.5/config/m88k/sysv4.h Fri Jan 1 07:36:30 1993 --- gcc-2.5.0/config/m88k/sysv4.h Sat Oct 2 04:21:15 1993 *************** *** 49,53 **** #undef CPP_PREDEFINES #define CPP_PREDEFINES \ ! "-Dm88000 -Dm88k -Dunix -D__svr4__ -Amachine(m88k) -Acpu(m88k) -Asystem(unix)" /* For the AT&T SVR4 port, the function is _mcount. */ --- 49,53 ---- #undef CPP_PREDEFINES #define CPP_PREDEFINES \ ! "-Dm88000 -Dm88k -Dunix -D__svr4__ -Amachine(m88k) -Acpu(m88k) -Asystem(unix) -Asystem(svr4)" /* For the AT&T SVR4 port, the function is _mcount. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m88k/t-dgux gcc-2.5.0/config/m88k/t-dgux *** gcc-2.4.5/config/m88k/t-dgux Tue May 4 13:21:15 1993 --- gcc-2.5.0/config/m88k/t-dgux Thu Sep 9 16:02:27 1993 *************** *** 10,13 **** --- 10,14 ---- LIB2FUNCS_EXTRA = $(MOVE_ASM) LIBGCC1 = libgcc1.null + CROSS_LIBGCC1 = libgcc1.null # For DG/UX we build crtbegin.o and crtend.o which serve to add begin and diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m88k/t-dgux-gas gcc-2.5.0/config/m88k/t-dgux-gas *** gcc-2.4.5/config/m88k/t-dgux-gas Tue Jun 8 16:20:46 1993 --- gcc-2.5.0/config/m88k/t-dgux-gas Thu Sep 9 16:02:28 1993 *************** *** 10,13 **** --- 10,14 ---- LIB2FUNCS_EXTRA = $(MOVE_ASM) LIBGCC1 = libgcc1.null + CROSS_LIBGCC1 = libgcc1.null T_CPPFLAGS = -DUSE_GAS diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m88k/t-luna gcc-2.5.0/config/m88k/t-luna *** gcc-2.4.5/config/m88k/t-luna Fri Jan 1 07:36:36 1993 --- gcc-2.5.0/config/m88k/t-luna Thu Sep 9 16:02:27 1993 *************** *** 10,11 **** --- 10,12 ---- LIB2FUNCS_EXTRA = $(MOVE_ASM) LIBGCC1 = libgcc1.null + CROSS_LIBGCC1 = libgcc1.null diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m88k/t-luna-gas gcc-2.5.0/config/m88k/t-luna-gas *** gcc-2.4.5/config/m88k/t-luna-gas Tue Jun 8 16:20:47 1993 --- gcc-2.5.0/config/m88k/t-luna-gas Thu Sep 9 16:02:29 1993 *************** *** 10,12 **** --- 10,13 ---- LIB2FUNCS_EXTRA = $(MOVE_ASM) LIBGCC1 = libgcc1.null + CROSS_LIBGCC1 = libgcc1.null T_CPPFLAGS = -DUSE_GAS diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m88k/t-m88k gcc-2.5.0/config/m88k/t-m88k *** gcc-2.4.5/config/m88k/t-m88k Fri Jan 1 07:36:40 1993 --- gcc-2.5.0/config/m88k/t-m88k Thu Sep 9 16:02:30 1993 *************** *** 10,13 **** --- 10,14 ---- LIB2FUNCS_EXTRA = $(MOVE_ASM) LIBGCC1 = libgcc1.null + CROSS_LIBGCC1 = libgcc1.null # For svr4 we build crtbegin.o and crtend.o which serve to add begin and diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m88k/t-m88k-gas gcc-2.5.0/config/m88k/t-m88k-gas *** gcc-2.4.5/config/m88k/t-m88k-gas Tue Jun 8 16:20:47 1993 --- gcc-2.5.0/config/m88k/t-m88k-gas Thu Sep 9 16:02:32 1993 *************** *** 10,13 **** --- 10,14 ---- LIB2FUNCS_EXTRA = $(MOVE_ASM) LIBGCC1 = libgcc1.null + CROSS_LIBGCC1 = libgcc1.null T_CPPFLAGS = -DUSE_GAS diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m88k/t-sysv4 gcc-2.5.0/config/m88k/t-sysv4 *** gcc-2.4.5/config/m88k/t-sysv4 Fri Jan 1 07:36:44 1993 --- gcc-2.5.0/config/m88k/t-sysv4 Thu Sep 9 16:02:34 1993 *************** *** 12,15 **** --- 12,16 ---- LIB2FUNCS_EXTRA = $(MOVE_ASM) LIBGCC1 = libgcc1.null + CROSS_LIBGCC1 = libgcc1.null # For svr4 we build crtbegin.o and crtend.o which serve to add begin and diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m88k/x-dgux gcc-2.5.0/config/m88k/x-dgux *** gcc-2.4.5/config/m88k/x-dgux Sun Jun 28 10:06:00 1992 --- gcc-2.5.0/config/m88k/x-dgux Tue Aug 3 21:49:24 1993 *************** *** 2,4 **** BISONFLAGS = -l X_CFLAGS = -D_M88KBCS_TARGET ! INSTALL_HEADERS = --- 2,4 ---- BISONFLAGS = -l X_CFLAGS = -D_M88KBCS_TARGET ! diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m88k/x-sysv3 gcc-2.5.0/config/m88k/x-sysv3 *** gcc-2.4.5/config/m88k/x-sysv3 --- gcc-2.5.0/config/m88k/x-sysv3 Wed Jul 28 09:42:43 1993 *************** *** 0 **** --- 1,7 ---- + # this is m88k/x-sysv3 + + # native compiler does not provide alloca + + ALLOCA = alloca.o + + # end m88k/x-sysv3 diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/m88k/xm-m88k.h gcc-2.5.0/config/m88k/xm-m88k.h *** gcc-2.4.5/config/m88k/xm-m88k.h Sat Dec 26 17:23:12 1992 --- gcc-2.5.0/config/m88k/xm-m88k.h Sat Jun 26 11:34:37 1993 *************** *** 1,5 **** /* Configuration for GNU compiler. Motorola m88100 in an 88open OCS/BCS environment. ! Copyright (C) 1988, 1989, 1990, 1991 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,5 ---- /* Configuration for GNU compiler. Motorola m88100 in an 88open OCS/BCS environment. ! Copyright (C) 1988, 1989, 1990, 1991, 1993 Free Software Foundation, Inc. This file is part of GNU CC. *************** *** 55,62 **** #define HAVE_VPRINTF ! /* If compiled with GNU C, use the built-in alloca */ ! #ifdef __GNUC__ ! #define alloca __builtin_alloca ! #else #define USE_C_ALLOCA #endif --- 55,60 ---- #define HAVE_VPRINTF ! /* If not compiled with GNU C, use the C alloca */ ! #ifndef __GNUC__ #define USE_C_ALLOCA #endif diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/bsd-4.h gcc-2.5.0/config/mips/bsd-4.h *** gcc-2.4.5/config/mips/bsd-4.h Mon May 31 18:13:45 1993 --- gcc-2.5.0/config/mips/bsd-4.h Sat Oct 2 04:21:18 1993 *************** *** 20,25 **** #define MIPS_BSD43 ! #define CPP_PREDEFINES "-Dmips -Dunix -Dhost_mips -DMIPSEB -DR3000 -DSYSTYPE_BSD43 \ ! -D_mips -D_unix -D_host_mips -D_MIPSEB -D_R3000 -D_SYSTYPE_BSD43" #define STANDARD_INCLUDE_DIR "/bsd43/usr/include" --- 20,27 ---- #define MIPS_BSD43 ! #define CPP_PREDEFINES "\ ! -Dmips -Dunix -Dhost_mips -DMIPSEB -DR3000 -DSYSTYPE_BSD43 \ ! -D_mips -D_unix -D_host_mips -D_MIPSEB -D_R3000 -D_SYSTYPE_BSD43 \ ! -Asystem(unix) -Asystem(bsd) -Acpu(mips) -Amachine(mips)" #define STANDARD_INCLUDE_DIR "/bsd43/usr/include" *************** *** 31,35 **** %{.m: -D__LANGUAGE_OBJECTIVE_C -D_LANGUAGE_OBJECTIVE_C} \ %{.S: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{!.S: -D__LANGUAGE_C -D_LANGUAGE_C %{!ansi:-DLANGUAGE_C}}" #define LINK_SPEC "\ --- 33,38 ---- %{.m: -D__LANGUAGE_OBJECTIVE_C -D_LANGUAGE_OBJECTIVE_C} \ %{.S: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{.s: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{!.S:%{!.s: -D__LANGUAGE_C -D_LANGUAGE_C %{!ansi:-DLANGUAGE_C}}}" #define LINK_SPEC "\ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/bsd-5.h gcc-2.5.0/config/mips/bsd-5.h *** gcc-2.4.5/config/mips/bsd-5.h Mon May 31 18:13:47 1993 --- gcc-2.5.0/config/mips/bsd-5.h Sat Oct 2 04:21:21 1993 *************** *** 20,25 **** #define MIPS_BSD43 ! #define CPP_PREDEFINES "-Dmips -Dunix -Dhost_mips -DMIPSEB -DR3000 -DSYSTYPE_BSD43 \ ! -D_mips -D_unix -D_host_mips -D_MIPSEB -D_R3000 -D_SYSTYPE_BSD43" #define STANDARD_INCLUDE_DIR "/bsd43/usr/include" --- 20,27 ---- #define MIPS_BSD43 ! #define CPP_PREDEFINES "\ ! -Dmips -Dunix -Dhost_mips -DMIPSEB -DR3000 -DSYSTYPE_BSD43 \ ! -D_mips -D_unix -D_host_mips -D_MIPSEB -D_R3000 -D_SYSTYPE_BSD43 \ ! -Asystem(unix) -Asystem(bsd) -Acpu(mips) -Amachine(mips)" #define STANDARD_INCLUDE_DIR "/bsd43/usr/include" *************** *** 31,35 **** %{.m: -D__LANGUAGE_OBJECTIVE_C -D_LANGUAGE_OBJECTIVE_C} \ %{.S: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{!.S: -D__LANGUAGE_C -D_LANGUAGE_C %{!ansi:-DLANGUAGE_C}}" #define LINK_SPEC "\ --- 33,38 ---- %{.m: -D__LANGUAGE_OBJECTIVE_C -D_LANGUAGE_OBJECTIVE_C} \ %{.S: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{.s: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{!.S:%{!.s: -D__LANGUAGE_C -D_LANGUAGE_C %{!ansi:-DLANGUAGE_C}}}" #define LINK_SPEC "\ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/dec-bsd.h gcc-2.5.0/config/mips/dec-bsd.h *** gcc-2.4.5/config/mips/dec-bsd.h --- gcc-2.5.0/config/mips/dec-bsd.h Wed Oct 20 01:27:42 1993 *************** *** 0 **** --- 1,71 ---- + /* Definitions for DECstation running BSD as target machine for GNU compiler. + Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + #define DECSTATION + + #ifndef CPP_PREDEFINES + #define CPP_PREDEFINES "-D__ANSI_COMPAT \ + -DMIPSEL -DR3000 -DSYSTYPE_BSD -D_SYSTYPE_BSD -Dbsd4_4 -Dhost_mips -Dmips \ + -Dunix -D_mips -D_unix -D_host_mips -D_MIPSEB -D_R3000 \ + -Asystem(unix) -Asystem(bsd) -Amachine(mips)" + #endif + + #ifndef ASM_SPEC + #define ASM_SPEC "%{G*}" + #endif + + #ifndef CPP_SPEC + #define CPP_SPEC "\ + %{.S: -D__LANGUAGE_ASSEMBLY__ -D__LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ + %{.cc: -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS} \ + %{.cxx: -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS} \ + %{.C: -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS} \ + %{.m: -D__LANGUAGE_OBJECTIVE_C__ -D__LANGUAGE_OBJECTIVE_C} \ + %{.s: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ + %{!.S:%{!.s: -D__LANGUAGE_C -D_LANGUAGE_C %{!ansi:-DLANGUAGE_C}}}" + #endif + + #ifndef LINK_SPEC + #define LINK_SPEC "%{G*}" + #endif + + #define LIB_SPEC "" + #define STARTFILE_SPEC "" + + /* For compatibility with types.h. */ + #ifndef SIZE_TYPE + #define SIZE_TYPE "unsigned int" + #endif + + #ifndef MACHINE_TYPE + #define MACHINE_TYPE "DECstation running BSD 4.4" + #endif + + #define TARGET_DEFAULT MASK_GAS + #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG + + #include "mips/mips.h" + + /* Since gas and gld are standard on 4.4 BSD, we don't need these */ + #undef MD_EXEC_PREFIX + #undef MD_STARTFILE_PREFIX + #undef ASM_FINAL_SPEC + #undef LIB_SPEC + #undef STARTFILE_SPEC + diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/dec-osf1.h gcc-2.5.0/config/mips/dec-osf1.h *** gcc-2.4.5/config/mips/dec-osf1.h Tue Jan 5 15:08:25 1993 --- gcc-2.5.0/config/mips/dec-osf1.h Sat Oct 2 04:21:23 1993 *************** *** 20,25 **** #define DEC_OSF1 ! #define CPP_PREDEFINES "-D__ANSI_COMPAT \ ! -DMIPSEL -DR3000 -DSYSTYPE_BSD -D_SYSTYPE_BSD -Dbsd4_2 -Dhost_mips -Dmips -Dosf -Dunix" #define LINK_SPEC "\ --- 20,27 ---- #define DEC_OSF1 ! #define CPP_PREDEFINES "\ ! -D__ANSI_COMPAT -DMIPSEL -DR3000 -DSYSTYPE_BSD -D_SYSTYPE_BSD \ ! -Dbsd4_2 -Dhost_mips -Dmips -Dosf -Dunix \ ! -Asystem(unix) -Asystem(xpg4) -Acpu(mips) -Amachine(mips)" #define LINK_SPEC "\ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/iris3.h gcc-2.5.0/config/mips/iris3.h *** gcc-2.4.5/config/mips/iris3.h Sun May 23 01:24:58 1993 --- gcc-2.5.0/config/mips/iris3.h Tue Oct 5 16:22:52 1993 *************** *** 22,26 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dunix -Dmips -Dsgi -DSVR3 -Dhost_mips -DMIPSEB -DSYSTYPE_SYSV" #define STARTFILE_SPEC "%{pg:gcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}" --- 22,28 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "\ ! -Dunix -Dmips -Dsgi -DSVR3 -Dhost_mips -DMIPSEB -DSYSTYPE_SYSV \ ! -Asystem(unix) -Asystem(svr3) -Acpu(mips) -Amachine(mips)" #define STARTFILE_SPEC "%{pg:gcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}" *************** *** 29,32 **** --- 31,35 ---- %{!ansi:-D__EXTENSIONS__} -D_MIPSEB -D_SYSTYPE_SYSV \ %{.S: -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ + %{.s: -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ %{.cc: -D_LANGUAGE_C_PLUS_PLUS} \ %{.cxx: -D_LANGUAGE_C_PLUS_PLUS} \ *************** *** 33,37 **** %{.C: -D_LANGUAGE_C_PLUS_PLUS} \ %{.m: -D_LANGUAGE_OBJECTIVE_C} \ ! %{!.S: %{!.cc: %{!.cxx: %{!.C: %{!.m: -D_LANGUAGE_C %{!ansi:-DLANGUAGE_C}}}}}}" #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} crtn.o%s" --- 36,40 ---- %{.C: -D_LANGUAGE_C_PLUS_PLUS} \ %{.m: -D_LANGUAGE_OBJECTIVE_C} \ ! %{!.S: %{!.s: %{!.cc: %{!.cxx: %{!.C: %{!.m: -D_LANGUAGE_C %{!ansi:-DLANGUAGE_C}}}}}}}" #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} crtn.o%s" *************** *** 101,135 **** /* Plain char is unsigned in the SGI compiler. */ #define DEFAULT_SIGNED_CHAR 0 - - - /* A C statement to initialize the variable parts of a trampoline. - ADDR is an RTX for the address of the trampoline; FNADDR is an - RTX for the address of the nested function; STATIC_CHAIN is an - RTX for the static chain value that should be passed to the - function when it is called. - - Silicon Graphics machines are supposed to not have a mprotect - function to enable execute protection, but the stack already - has execute protection turned on. Because the MIPS chips have - no method to flush the icache without a system call, this can lose - if the same address is used for multiple trampolines. */ - - #define INITIALIZE_TRAMPOLINE(ADDR, FUNC, CHAIN) \ - { \ - rtx addr = ADDR; \ - emit_move_insn (gen_rtx (MEM, SImode, plus_constant (addr, 28)), FUNC); \ - emit_move_insn (gen_rtx (MEM, SImode, plus_constant (addr, 32)), CHAIN); \ - } - - - /* Attempt to turn on access permissions for the stack. */ - - #define TRANSFER_FROM_TRAMPOLINE \ - \ - void \ - __enable_execute_stack (addr) \ - char *addr; \ - { \ - } #include "mips/mips.h" --- 104,107 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/iris5.h gcc-2.5.0/config/mips/iris5.h *** gcc-2.4.5/config/mips/iris5.h --- gcc-2.5.0/config/mips/iris5.h Thu Oct 21 14:36:26 1993 *************** *** 0 **** --- 1,43 ---- + /* Definitions of target machine for GNU compiler. Iris version 5. + Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + #define TARGET_DEFAULT MASK_ABICALLS + #define ABICALLS_ASM_OP ".option pic2" + + #include "mips/iris4.h" + + /* mips-tfile doesn't work yet. No debugging is supported. */ + #undef ASM_FINAL_SPEC + #undef SDB_DEBUGGING_INFO + #undef DBX_DEBUGGING_INFO + + #undef CPP_PREDEFINES + #define CPP_PREDEFINES "\ + -D_MIPS_FPSET=16 -D_MIPS_ISA=_MIPS_ISA_MIPS1 -D_MIPS_SIM_ABI32 \ + -Dunix -Dmips -Dsgi -DSVR3 -Dhost_mips -DMIPSEB -DSYSTYPE_SYSV \ + -D_SYSTYPE_SVR4 -D_LONGLONG -D_MIPSEB -D_SGI_SOURCE -D__SDO__ \ + -D_MIPS_SZLONG=32 -D_MIPS_SZINT=32 -D_MIPS_SZPTR=32 -D_SVR4_SOURCE \ + -Asystem(unix) -Asystem(svr3) -Acpu(mips) -Amachine(mips)" + + #undef ASM_SPEC + #define ASM_SPEC "-elf -KPIC -EB %{O*:-O2 -fullasopt} %{!O*:-O1}" + + #undef LINK_SPEC + #define LINK_SPEC "-elf -_SYSTYPE_SVR4 -require_dynamic_link \ + _rld_new_interface -no_unresolved -KPIC -call_shared -transitive_link" diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/mips-5.h gcc-2.5.0/config/mips/mips-5.h *** gcc-2.4.5/config/mips/mips-5.h Tue Jan 5 15:08:27 1993 --- gcc-2.5.0/config/mips/mips-5.h Wed Jul 28 13:45:41 1993 *************** *** 28,30 **** --- 28,32 ---- %{!shared: %{!non_shared: %{!call_shared: -non_shared}}}}" + #define STARTFILE_SPEC "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt1.o%s crtn.o%s}}" + #include "mips/mips.h" diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/mips.c gcc-2.5.0/config/mips/mips.c *** gcc-2.4.5/config/mips/mips.c Fri Jun 18 13:36:53 1993 --- gcc-2.5.0/config/mips/mips.c Thu Oct 21 17:11:53 1993 *************** *** 1661,1668 **** : new > INTVAL (cmp1)) != (p_info->const_add > 0)) ! /* 1 is the right value in the LE and LEU case. ! In the GT and GTU case, *p_invert is already set, ! so this is effectively 0. */ ! return force_reg (SImode, const1_rtx); else cmp1 = GEN_INT (new); --- 1661,1671 ---- : new > INTVAL (cmp1)) != (p_info->const_add > 0)) ! { ! /* This test is always true, but if INVERT is true then ! the result of the test needs to be inverted so 0 should ! be returned instead. */ ! emit_move_insn (result, invert ? const0_rtx : const_true_rtx); ! return result; ! } else cmp1 = GEN_INT (new); *************** *** 2575,2581 **** case DFmode: cum->arg_words += (cum->arg_words & 1); ! regbase = (cum->gp_reg_found || TARGET_SOFT_FLOAT) ! ? GP_ARG_FIRST ! : FP_ARG_FIRST; break; --- 2578,2584 ---- case DFmode: cum->arg_words += (cum->arg_words & 1); ! regbase = (cum->gp_reg_found || TARGET_SOFT_FLOAT || cum->arg_number >= 2 ! ? GP_ARG_FIRST ! : FP_ARG_FIRST); break; *************** *** 2626,2632 **** of the adjustments. */ ! if (struct_p && (mode == QImode || mode == HImode)) { ! rtx amount = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (mode)); rtx reg = gen_rtx (REG, SImode, regbase + cum->arg_words + bias); cum->adjust[ cum->num_adjusts++ ] = gen_ashlsi3 (reg, reg, amount); --- 2629,2640 ---- of the adjustments. */ ! /* ??? function_arg can be called more than once for each argument. ! As a result, we compute more adjustments than we need here. ! See the CUMULATIVE_ARGS definition in mips.h. */ ! ! if (struct_p && int_size_in_bytes (type) < 4) { ! rtx amount = GEN_INT (BITS_PER_WORD ! - int_size_in_bytes (type) * BITS_PER_UNIT); rtx reg = gen_rtx (REG, SImode, regbase + cum->arg_words + bias); cum->adjust[ cum->num_adjusts++ ] = gen_ashlsi3 (reg, reg, amount); *************** *** 3505,3509 **** SET_FILE_NUMBER (); current_function_file = name; ! fprintf (stream, "\t.file\t%d \"%s\"\n", num_source_filenames, name); if (!TARGET_GAS && write_symbols == DBX_DEBUG) fprintf (stream, "\t#@stabs\n"); --- 3513,3520 ---- SET_FILE_NUMBER (); current_function_file = name; ! fprintf (stream, "\t.file\t%d ", num_source_filenames); ! output_quoted_string (stream, name); ! fprintf (stream, "\n"); ! /* This tells mips-tfile that stabs will follow. */ if (!TARGET_GAS && write_symbols == DBX_DEBUG) fprintf (stream, "\t#@stabs\n"); *************** *** 3510,3518 **** } ! else if (!TARGET_GAS && write_symbols == DBX_DEBUG) { ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0); ! fprintf (stream, "%s \"%s\",%d,0,0,%s\n", ASM_STABS_OP, ! name, N_SOL, <ext_label_name[1]); } --- 3521,3530 ---- } ! else if (write_symbols == DBX_DEBUG) { ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0); ! fprintf (stream, "%s ", ASM_STABS_OP); ! output_quoted_string (stream, name); ! fprintf (stream, ",%d,0,0,%s\n", N_SOL, <ext_label_name[1]); } *************** *** 3529,3533 **** } ! fprintf (stream, "\t#.file\t%d \"%s\"\n", num_source_filenames, name); } --- 3541,3545 ---- } ! fprintf (stream, "\t#.file\t%d ", num_source_filenames); } *************** *** 3536,3541 **** SET_FILE_NUMBER (); current_function_file = name; ! fprintf (stream, "\t.file\t%d \"%s\"\n", num_source_filenames, name); } } } --- 3548,3555 ---- SET_FILE_NUMBER (); current_function_file = name; ! fprintf (stream, "\t.file\t%d ", num_source_filenames); } + output_quoted_string (stream, name); + fprintf (stream, "\n"); } } *************** *** 3552,3556 **** int line; { ! if (!TARGET_GAS && write_symbols == DBX_DEBUG) { ++sym_lineno; --- 3566,3570 ---- int line; { ! if (write_symbols == DBX_DEBUG) { ++sym_lineno; *************** *** 3651,3656 **** /* Generate the pseudo ops that the Pyramid based System V.4 wants. */ if (TARGET_ABICALLS) ! fprintf (stream, "\t.abicalls\n"); if (TARGET_GP_OPT) --- 3665,3673 ---- /* Generate the pseudo ops that the Pyramid based System V.4 wants. */ + #ifndef ABICALLS_ASM_OP + #define ABICALLS_ASM_OP ".abicalls" + #endif if (TARGET_ABICALLS) ! fprintf (stream, "\t%s\n", ABICALLS_ASM_OP); if (TARGET_GP_OPT) *************** *** 4304,4307 **** --- 4321,4336 ---- tree cur_arg; CUMULATIVE_ARGS args_so_far; + + /* If struct value address is treated as the first argument, make it so. */ + if (aggregate_value_p (DECL_RESULT (fndecl)) + && ! current_function_returns_pcc_struct + && struct_value_incoming_rtx == 0) + { + tree type = build_pointer_type (fntype); + tree function_result_decl = build_decl (PARM_DECL, NULL_TREE, type); + DECL_ARG_TYPE (function_result_decl) = type; + TREE_CHAIN (function_result_decl) = fnargs; + fnargs = function_result_decl; + } /* Determine the last argument, and get its name. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/mips.h gcc-2.5.0/config/mips/mips.h *** gcc-2.4.5/config/mips/mips.h Wed May 26 00:36:03 1993 --- gcc-2.5.0/config/mips/mips.h Thu Oct 21 17:12:05 1993 *************** *** 1,6 **** /* Definitions of target machine for GNU compiler. MIPS version. Contributed by A. Lichnewsky, lich@inria.inria.fr Changed by Michael Meissner, meissner@osf.org - Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,6 ---- /* Definitions of target machine for GNU compiler. MIPS version. + Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. Contributed by A. Lichnewsky, lich@inria.inria.fr Changed by Michael Meissner, meissner@osf.org This file is part of GNU CC. *************** *** 207,211 **** /* Functions in the standard library that we reference. */ - extern void abort (); extern int atoi (); extern char *getenv (); --- 207,210 ---- *************** *** 485,489 **** flag_omit_frame_pointer = TRUE; \ flag_schedule_insns_after_reload = TRUE; \ ! target_flags &= MASK_GPOPT; \ } \ } --- 484,488 ---- flag_omit_frame_pointer = TRUE; \ flag_schedule_insns_after_reload = TRUE; \ ! target_flags |= MASK_GPOPT; \ } \ } *************** *** 537,541 **** #ifndef CPP_PREDEFINES #define CPP_PREDEFINES "-Dmips -Dunix -Dhost_mips -DMIPSEB -DR3000 -DSYSTYPE_BSD43 \ ! -D_mips -D_unix -D_host_mips -D_MIPSEB -D_R3000 -D_SYSTYPE_BSD43" #endif --- 536,541 ---- #ifndef CPP_PREDEFINES #define CPP_PREDEFINES "-Dmips -Dunix -Dhost_mips -DMIPSEB -DR3000 -DSYSTYPE_BSD43 \ ! -D_mips -D_unix -D_host_mips -D_MIPSEB -D_R3000 -D_SYSTYPE_BSD43 \ ! -Asystem(unix) -Asystem(bsd) -Acpu(mips) -Amachine(mips)" #endif *************** *** 634,638 **** %{.m: -D__LANGUAGE_OBJECTIVE_C -D_LANGUAGE_OBJECTIVE_C} \ %{.S: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{!.S: -D__LANGUAGE_C -D_LANGUAGE_C %{!ansi:-DLANGUAGE_C}}" #endif --- 634,639 ---- %{.m: -D__LANGUAGE_OBJECTIVE_C -D_LANGUAGE_OBJECTIVE_C} \ %{.S: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{.s: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{!.S:%{!.s: -D__LANGUAGE_C -D_LANGUAGE_C %{!ansi:-DLANGUAGE_C}}}" #endif *************** *** 1050,1059 **** #define PROMOTE_PROTOTYPES ! /* Define this macro if an instruction to load a value narrower ! than a word from memory into a register also zero-extends the ! value to the whole register. */ ! ! #define BYTE_LOADS_ZERO_EXTEND ! /* Standard register usage. */ --- 1051,1063 ---- #define PROMOTE_PROTOTYPES ! /* Define if operations between registers always perform the operation ! on the full register even if a narrower mode is specified. */ ! #define WORD_REGISTER_OPERATIONS ! ! /* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD ! will either zero-extend or sign-extend. The value of this macro should ! be the code that says which one of the two operations is implicitly ! done, NIL if none. */ ! #define LOAD_EXTEND_OP(MODE) ZERO_EXTEND /* Standard register usage. */ *************** *** 1469,1481 **** needed to represent mode MODE in a register of class CLASS. */ ! #define CLASS_UNITS(mode, num) \ ! ((GET_MODE_SIZE (mode) + ((num) * UNITS_PER_WORD) - 1) / ((num) * UNITS_PER_WORD)) #define CLASS_MAX_NREGS(CLASS, MODE) \ ! (((CLASS) == FP_REGS && TARGET_FLOAT64) \ ! ? CLASS_UNITS (MODE, 2) \ ! : (((CLASS) == FP_REGS) \ ! ? (2*CLASS_UNITS (MODE, 1)) \ ! : CLASS_UNITS (MODE, 1))) /* If defined, this is a C expression whose value should be --- 1473,1485 ---- needed to represent mode MODE in a register of class CLASS. */ ! #define CLASS_UNITS(mode, size) \ ! ((GET_MODE_SIZE (mode) + (size) - 1) / (size)) #define CLASS_MAX_NREGS(CLASS, MODE) \ ! ((CLASS) == FP_REGS \ ! ? (TARGET_FLOAT64 \ ! ? CLASS_UNITS (MODE, 8) \ ! : 2 * CLASS_UNITS (MODE, 8)) \ ! : CLASS_UNITS (MODE, UNITS_PER_WORD)) /* If defined, this is a C expression whose value should be *************** *** 1811,1815 **** int num_adjusts; /* number of adjustments made */ /* Adjustments made to args pass in regs. */ ! struct rtx_def *adjust[MAX_ARGS_IN_REGISTERS]; } CUMULATIVE_ARGS; --- 1815,1822 ---- int num_adjusts; /* number of adjustments made */ /* Adjustments made to args pass in regs. */ ! /* ??? The size is doubled to work around a ! bug in the code that sets the adjustments ! in function_arg. */ ! struct rtx_def *adjust[MAX_ARGS_IN_REGISTERS*2]; } CUMULATIVE_ARGS; *************** *** 1979,1983 **** function when it is called. */ - #ifndef INITIALIZE_TRAMPOLINE #define INITIALIZE_TRAMPOLINE(ADDR, FUNC, CHAIN) \ { \ --- 1986,1989 ---- *************** *** 1986,2021 **** emit_move_insn (gen_rtx (MEM, SImode, plus_constant (addr, 32)), CHAIN); \ \ ! /* Attempt to make stack executable */ \ ! emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"), \ 0, VOIDmode, 1, addr, Pmode); \ } - #endif /* INITIALIZE_TRAMPOLINE */ - ! /* Attempt to turn on access permissions for the stack. */ - #ifndef TRANSFER_FROM_TRAMPOLINE #define TRANSFER_FROM_TRAMPOLINE \ \ void \ ! __enable_execute_stack (addr) \ char *addr; \ { \ - int size = getpagesize (); \ - int mask = ~(size-1); \ - char *page = (char *) (((int) addr) & mask); \ - char *end = (char *) ((((int) (addr + TRAMPOLINE_SIZE)) & mask) + size); \ - \ - /* 7 is PROT_READ | PROT_WRITE | PROT_EXEC */ \ - if (mprotect (page, end - page, 7) < 0) \ - perror ("mprotect of trampoline code"); \ - \ - /* \ if (cacheflush (addr, TRAMPOLINE_SIZE, 1) < 0) \ perror ("cacheflush of trampoline code"); \ - */ \ } - #endif /* TRANSFER_FROM_TRAMPOLINE */ - /* Addressing modes, and classification of registers for them. */ --- 1992,2011 ---- emit_move_insn (gen_rtx (MEM, SImode, plus_constant (addr, 32)), CHAIN); \ \ ! /* Flush the instruction cache. */ \ ! emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__gcc_flush_cache"), \ 0, VOIDmode, 1, addr, Pmode); \ } ! /* Flush the instruction cache. */ #define TRANSFER_FROM_TRAMPOLINE \ \ void \ ! __gcc_flush_cache (addr) \ char *addr; \ { \ if (cacheflush (addr, TRAMPOLINE_SIZE, 1) < 0) \ perror ("cacheflush of trampoline code"); \ } /* Addressing modes, and classification of registers for them. */ *************** *** 2403,2414 **** #define SLOW_ZERO_EXTEND ! /* Define if shifts truncate the shift count ! which implies one can omit a sign-extension or zero-extension ! of a shift count. - Only 5 bits are used in SLLV and SRLV */ - - #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. */ --- 2393,2400 ---- #define SLOW_ZERO_EXTEND ! /* Define this to be nonzero if shift instructions ignore all but the low-order ! few bits. */ ! #define SHIFT_COUNT_TRUNCATED 1 /* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits is done just by pretending it is already truncated. */ *************** *** 2727,2730 **** --- 2713,2718 ---- LTU, LEU }}, \ {"fcmp_op", { EQ, NE, GT, GE, LT, LE }}, \ + {"pc_or_label_operand", { PC, LABEL_REF }}, \ + {"call_insn_operand", { MEM }}, \ {"uns_cmp_op", { GTU, GEU, LTU, LEU }}, *************** *** 3448,3453 **** #define SELECT_SECTION(DECL, RELOC) \ { \ ! if (int_size_in_bytes (TREE_TYPE (DECL)) <= mips_section_threshold \ ! && mips_section_threshold > 0) \ sdata_section (); \ \ --- 3436,3442 ---- #define SELECT_SECTION(DECL, RELOC) \ { \ ! int size = int_size_in_bytes (TREE_TYPE (DECL)); \ ! \ ! if (size > 0 && size <= mips_section_threshold) \ sdata_section (); \ \ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/mips.md gcc-2.5.0/config/mips/mips.md *** gcc-2.4.5/config/mips/mips.md Sun May 9 12:35:08 1993 --- gcc-2.5.0/config/mips/mips.md Fri Oct 8 18:31:50 1993 *************** *** 1048,1052 **** (set_attr "length" "1")]) ! (define_expand "negdi3" [(parallel [(set (match_operand:DI 0 "register_operand" "=d") (neg:DI (match_operand:DI 1 "register_operand" "d"))) --- 1048,1052 ---- (set_attr "length" "1")]) ! (define_expand "negdi2" [(parallel [(set (match_operand:DI 0 "register_operand" "=d") (neg:DI (match_operand:DI 1 "register_operand" "d"))) *************** *** 1055,1059 **** "operands[2] = gen_reg_rtx (SImode);") ! (define_insn "negdi3_internal" [(set (match_operand:DI 0 "register_operand" "=d") (neg:DI (match_operand:DI 1 "register_operand" "d"))) --- 1055,1059 ---- "operands[2] = gen_reg_rtx (SImode);") ! (define_insn "negdi2_internal" [(set (match_operand:DI 0 "register_operand" "=d") (neg:DI (match_operand:DI 1 "register_operand" "d"))) *************** *** 1476,1483 **** ;; .................... (define_insn "fix_truncdfsi2" [(set (match_operand:SI 0 "general_operand" "=d,*f,R,o") (fix:SI (match_operand:DF 1 "register_operand" "f,*f,f,f"))) ! (clobber (match_scratch:SI 2 "=d,*d,d,d")) (clobber (match_scratch:DF 3 "=f,*X,f,f"))] "TARGET_HARD_FLOAT" --- 1476,1487 ---- ;; .................... + ;; The SImode scratch register can not be shared with address regs used for + ;; operand zero, because then the address in the move instruction will be + ;; clobbered. We mark the scratch register as early clobbered to prevent this. + (define_insn "fix_truncdfsi2" [(set (match_operand:SI 0 "general_operand" "=d,*f,R,o") (fix:SI (match_operand:DF 1 "register_operand" "f,*f,f,f"))) ! (clobber (match_scratch:SI 2 "=d,*d,&d,&d")) (clobber (match_scratch:DF 3 "=f,*X,f,f"))] "TARGET_HARD_FLOAT" *************** *** 1504,1508 **** [(set (match_operand:SI 0 "general_operand" "=d,*f,R,o") (fix:SI (match_operand:SF 1 "register_operand" "f,*f,f,f"))) ! (clobber (match_scratch:SI 2 "=d,*d,d,d")) (clobber (match_scratch:SF 3 "=f,*X,f,f"))] "TARGET_HARD_FLOAT" --- 1508,1512 ---- [(set (match_operand:SI 0 "general_operand" "=d,*f,R,o") (fix:SI (match_operand:SF 1 "register_operand" "f,*f,f,f"))) ! (clobber (match_scratch:SI 2 "=d,*d,&d,&d")) (clobber (match_scratch:SF 3 "=f,*X,f,f"))] "TARGET_HARD_FLOAT" *************** *** 1661,1665 **** " { ! /* Handle loads. */ if (GET_CODE (operands[0]) == MEM) { --- 1665,1669 ---- " { ! /* Handle stores. */ if (GET_CODE (operands[0]) == MEM) { diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/news4.h gcc-2.5.0/config/mips/news4.h *** gcc-2.4.5/config/mips/news4.h Tue May 11 17:08:25 1993 --- gcc-2.5.0/config/mips/news4.h Sat Oct 2 04:21:41 1993 *************** *** 20,25 **** #define MIPS_NEWS ! #define CPP_PREDEFINES "-Dr3000 -Dnews3700 -DLANGUAGE_C -DMIPSEB -DSYSTYPE_BSD \ ! -Dsony_news -Dsony -Dunix -Dmips -Dhost_mips" #define ASM_SPEC "\ --- 20,27 ---- #define MIPS_NEWS ! #define CPP_PREDEFINES "\ ! -Dr3000 -Dnews3700 -DLANGUAGE_C -DMIPSEB -DSYSTYPE_BSD \ ! -Dsony_news -Dsony -Dunix -Dmips -Dhost_mips \ ! -Asystem(unix) -Asystem(bsd) -Acpu(mips) -Amachine(mips)" #define ASM_SPEC "\ *************** *** 46,50 **** %{.m: -D__LANGUAGE_OBJECTIVE_C -D_LANGUAGE_OBJECTIVE_C} \ %{.S: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{!.S: -D__LANGUAGE_C -D_LANGUAGE_C %{!ansi:-DLANGUAGE_C}}" #define LINK_SPEC "\ --- 48,53 ---- %{.m: -D__LANGUAGE_OBJECTIVE_C -D_LANGUAGE_OBJECTIVE_C} \ %{.S: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{.s: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{!.S:%{!.s: -D__LANGUAGE_C -D_LANGUAGE_C %{!ansi:-DLANGUAGE_C}}}" #define LINK_SPEC "\ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/news5.h gcc-2.5.0/config/mips/news5.h *** gcc-2.4.5/config/mips/news5.h Tue Jan 5 15:08:29 1993 --- gcc-2.5.0/config/mips/news5.h Sat Oct 2 04:21:43 1993 *************** *** 20,24 **** #define MIPS_SYSV ! #define CPP_PREDEFINES "-Dmips -Dunix -Dhost_mips -Dsony -Dsonyrisc -DMIPSEB -DSYSTYPE_SYSV" #define MD_STARTFILE_PREFIX "/usr/ccs/lib/" --- 20,26 ---- #define MIPS_SYSV ! #define CPP_PREDEFINES "\ ! -Dmips -Dunix -Dhost_mips -Dsony -Dsonyrisc -DMIPSEB -DSYSTYPE_SYSV \ ! -Asystem(unix) -Asystem(svr3) -Acpu(mips) -Amachine(mips)" #define MD_STARTFILE_PREFIX "/usr/ccs/lib/" *************** *** 30,34 **** %{.m: -D__LANGUAGE_OBJECTIVE_C -D_LANGUAGE_OBJECTIVE_C} \ %{.S: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{!.S: -D__LANGUAGE_C -D_LANGUAGE_C %{!ansi:-DLANGUAGE_C}}" #define LINK_SPEC "\ --- 32,37 ---- %{.m: -D__LANGUAGE_OBJECTIVE_C -D_LANGUAGE_OBJECTIVE_C} \ %{.S: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{.s: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{!.S:%{!.s: -D__LANGUAGE_C -D_LANGUAGE_C %{!ansi:-DLANGUAGE_C}}}" #define LINK_SPEC "\ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/nws3250v4.h gcc-2.5.0/config/mips/nws3250v4.h *** gcc-2.4.5/config/mips/nws3250v4.h Tue May 11 17:08:26 1993 --- gcc-2.5.0/config/mips/nws3250v4.h Sat Oct 2 04:21:46 1993 *************** *** 20,25 **** #define MIPS_NEWS ! #define CPP_PREDEFINES "-Dmips -Dhost_mips -Dsony -Dsonyrisc -Dunix \ ! -DLANGUAGE_C -DMIPSEB -DSYSTYPE_SYSV" #define MD_STARTFILE_PREFIX "/usr/ccs/lib/" --- 20,27 ---- #define MIPS_NEWS ! #define CPP_PREDEFINES "\ ! -Dmips -Dhost_mips -Dsony -Dsonyrisc -Dunix \ ! -DLANGUAGE_C -DMIPSEB -DSYSTYPE_SYSV \ ! -Asystem(unix) -Asystem(svr3) -Acpu(mips) -Amachine(mips)" #define MD_STARTFILE_PREFIX "/usr/ccs/lib/" *************** *** 45,49 **** %{.m: -D__LANGUAGE_OBJECTIVE_C -D_LANGUAGE_OBJECTIVE_C} \ %{.S: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{!.S: -D__LANGUAGE_C -D_LANGUAGE_C %{!ansi:-DLANGUAGE_C}}" #define LINK_SPEC "\ --- 47,52 ---- %{.m: -D__LANGUAGE_OBJECTIVE_C -D_LANGUAGE_OBJECTIVE_C} \ %{.S: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{.s: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{!.S:%{!.s: -D__LANGUAGE_C -D_LANGUAGE_C %{!ansi:-DLANGUAGE_C}}}" #define LINK_SPEC "\ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/osfrose.h gcc-2.5.0/config/mips/osfrose.h *** gcc-2.4.5/config/mips/osfrose.h Wed Apr 28 15:18:15 1993 --- gcc-2.5.0/config/mips/osfrose.h Sat Oct 2 04:21:49 1993 *************** *** 30,34 **** (DEFAULT_WORD_SWITCH_TAKES_ARG (STR) || !strcmp (STR, "pic-names")) ! #define CPP_PREDEFINES "-DOSF -DOSF1 -Dbsd4_2 -DMIPSEL -Dhost_mips -Dmips -Dunix -DR3000 -DSYSTYPE_BSD" #define ASM_SPEC "\ --- 30,36 ---- (DEFAULT_WORD_SWITCH_TAKES_ARG (STR) || !strcmp (STR, "pic-names")) ! #define CPP_PREDEFINES "\ ! -DOSF -DOSF1 -Dbsd4_2 -DMIPSEL -Dhost_mips -Dmips -Dunix -DR3000 -DSYSTYPE_BSD \ ! -Asystem(unix) -Asystem(xpg4) -Acpu(mips) -Amachine(mips)" #define ASM_SPEC "\ *************** *** 68,71 **** --- 70,76 ---- %{.S: -D__LANGUAGE_ASSEMBLY__ -D__LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY} \ -ULANGUAGE_C -U__LANGUAGE_C__} \ + %{.s: %{!ansi:%{!traditional:%{!traditional-cpp:%{!ftraditional: -traditional}}}}} \ + %{.s: -D__LANGUAGE_ASSEMBLY__ -D__LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY} \ + -ULANGUAGE_C -U__LANGUAGE_C__} \ %{.cc: -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS} \ %{.cxx: -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS} \ *************** *** 72,76 **** %{.C: -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS} \ %{.m: -D__LANGUAGE_OBJECTIVE_C__ -D__LANGUAGE_OBJECTIVE_C} \ ! %{!.S: -D__LANGUAGE_C__ -D__LANGUAGE_C %{!ansi:-DLANGUAGE_C}}" #define LINK_SPEC "\ --- 77,81 ---- %{.C: -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS} \ %{.m: -D__LANGUAGE_OBJECTIVE_C__ -D__LANGUAGE_OBJECTIVE_C} \ ! %{!.S:%{!.s: -D__LANGUAGE_C__ -D__LANGUAGE_C %{!ansi:-DLANGUAGE_C}}}" #define LINK_SPEC "\ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/svr3-4.h gcc-2.5.0/config/mips/svr3-4.h *** gcc-2.4.5/config/mips/svr3-4.h Mon May 31 18:13:50 1993 --- gcc-2.5.0/config/mips/svr3-4.h Sat Oct 2 04:21:52 1993 *************** *** 20,25 **** #define MIPS_SYSV ! #define CPP_PREDEFINES "-Dmips -Dunix -Dhost_mips -DMIPSEB -DR3000 -DSYSTYPE_SYSV \ ! -D_mips -D_unix -D_host_mips -D_MIPSEB -D_R3000 -D_SYSTYPE_SYSV" #define STANDARD_INCLUDE_DIR "/sysv/usr/include" --- 20,27 ---- #define MIPS_SYSV ! #define CPP_PREDEFINES "\ ! -Dmips -Dunix -Dhost_mips -DMIPSEB -DR3000 -DSYSTYPE_SYSV \ ! -D_mips -D_unix -D_host_mips -D_MIPSEB -D_R3000 -D_SYSTYPE_SYSV \ ! -Asystem(unix) -Asystem(svr3) -Acpu(mips) -Amachine(mips)" #define STANDARD_INCLUDE_DIR "/sysv/usr/include" *************** *** 31,35 **** %{.m: -D__LANGUAGE_OBJECTIVE_C -D_LANGUAGE_OBJECTIVE_C} \ %{.S: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{!.S: -D__LANGUAGE_C -D_LANGUAGE_C %{!ansi:-DLANGUAGE_C}}" #define LINK_SPEC "\ --- 33,38 ---- %{.m: -D__LANGUAGE_OBJECTIVE_C -D_LANGUAGE_OBJECTIVE_C} \ %{.S: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{.s: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{!.S:%{!.s: -D__LANGUAGE_C -D_LANGUAGE_C %{!ansi:-DLANGUAGE_C}}}" #define LINK_SPEC "\ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/svr3-5.h gcc-2.5.0/config/mips/svr3-5.h *** gcc-2.4.5/config/mips/svr3-5.h Mon May 31 18:13:53 1993 --- gcc-2.5.0/config/mips/svr3-5.h Sat Oct 2 04:21:55 1993 *************** *** 20,25 **** #define MIPS_SYSV ! #define CPP_PREDEFINES "-Dmips -Dunix -Dhost_mips -DMIPSEB -DR3000 -DSYSTYPE_SYSV \ ! -D_mips -D_unix -D_host_mips -D_MIPSEB -D_R3000 -D_SYSTYPE_SYSV" #define STANDARD_INCLUDE_DIR "/sysv/usr/include" --- 20,27 ---- #define MIPS_SYSV ! #define CPP_PREDEFINES "\ ! -Dmips -Dunix -Dhost_mips -DMIPSEB -DR3000 -DSYSTYPE_SYSV \ ! -D_mips -D_unix -D_host_mips -D_MIPSEB -D_R3000 -D_SYSTYPE_SYSV \ ! -Asystem(unix) -Asystem(svr3) -Acpu(mips) -Amachine(mips)" #define STANDARD_INCLUDE_DIR "/sysv/usr/include" *************** *** 31,35 **** %{.m: -D__LANGUAGE_OBJECTIVE_C -D_LANGUAGE_OBJECTIVE_C} \ %{.S: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{!.S: -D__LANGUAGE_C -D_LANGUAGE_C %{!ansi:-DLANGUAGE_C}}" #define LINK_SPEC "\ --- 33,38 ---- %{.m: -D__LANGUAGE_OBJECTIVE_C -D_LANGUAGE_OBJECTIVE_C} \ %{.S: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{.s: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{!.S:%{!.s: -D__LANGUAGE_C -D_LANGUAGE_C %{!ansi:-DLANGUAGE_C}}}" #define LINK_SPEC "\ *************** *** 60,63 **** --- 63,72 ---- #include #include + + /* In at least 5.0 and 5.01, there is no _SC_PAGE_SIZE macro, only a + _SC_PAGESIZE macro. */ + #ifdef _SC_PAGESIZE + #define _SC_PAGE_SIZE _SC_PAGESIZE + #endif #ifdef _SC_PAGE_SIZE diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/svr4-4.h gcc-2.5.0/config/mips/svr4-4.h *** gcc-2.4.5/config/mips/svr4-4.h Mon May 31 18:13:56 1993 --- gcc-2.5.0/config/mips/svr4-4.h Sat Oct 2 04:21:58 1993 *************** *** 20,25 **** #define MIPS_SVR4 ! #define CPP_PREDEFINES "-Dmips -Dunix -Dhost_mips -DMIPSEB -DR3000 -DSYSTYPE_SVR4 \ ! -D_mips -D_unix -D_host_mips -D_MIPSEB -D_R3000 -D_SYSTYPE_SVR4" #define STANDARD_INCLUDE_DIR "/svr4/usr/include" --- 20,27 ---- #define MIPS_SVR4 ! #define CPP_PREDEFINES "\ ! -Dmips -Dunix -Dhost_mips -DMIPSEB -DR3000 -DSYSTYPE_SVR4 \ ! -D_mips -D_unix -D_host_mips -D_MIPSEB -D_R3000 -D_SYSTYPE_SVR4 \ ! -Asystem(unix) -Asystem(svr4) -Acpu(mips) -Amachine(mips)" #define STANDARD_INCLUDE_DIR "/svr4/usr/include" *************** *** 31,35 **** %{.m: -D__LANGUAGE_OBJECTIVE_C -D_LANGUAGE_OBJECTIVE_C} \ %{.S: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{!.S: -D__LANGUAGE_C -D_LANGUAGE_C %{!ansi:-DLANGUAGE_C}}" #define LINK_SPEC "\ --- 33,38 ---- %{.m: -D__LANGUAGE_OBJECTIVE_C -D_LANGUAGE_OBJECTIVE_C} \ %{.S: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{.s: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{!.S:%{!.s: -D__LANGUAGE_C -D_LANGUAGE_C %{!ansi:-DLANGUAGE_C}}}" #define LINK_SPEC "\ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/svr4-5.h gcc-2.5.0/config/mips/svr4-5.h *** gcc-2.4.5/config/mips/svr4-5.h Fri Jun 4 00:59:21 1993 --- gcc-2.5.0/config/mips/svr4-5.h Sat Oct 2 04:22:01 1993 *************** *** 23,27 **** "-Dmips -Dunix -Dhost_mips -DMIPSEB -DR3000 -DSYSTYPE_SVR4 \ -D_mips -D_unix -D_host_mips -D_MIPSEB -D_R3000 -D_SYSTYPE_SVR4 \ ! -D_MIPS_SZINT=32 -D_MIPS_SZLONG=32 -D_MIPS_SZPTR=32" #define STANDARD_INCLUDE_DIR "/svr4/usr/include" --- 23,28 ---- "-Dmips -Dunix -Dhost_mips -DMIPSEB -DR3000 -DSYSTYPE_SVR4 \ -D_mips -D_unix -D_host_mips -D_MIPSEB -D_R3000 -D_SYSTYPE_SVR4 \ ! -D_MIPS_SZINT=32 -D_MIPS_SZLONG=32 -D_MIPS_SZPTR=32 \ ! -Asystem(unix) -Asystem(svr4) -Acpu(mips) -Amachine(mips)" #define STANDARD_INCLUDE_DIR "/svr4/usr/include" *************** *** 33,37 **** %{.m: -D__LANGUAGE_OBJECTIVE_C -D_LANGUAGE_OBJECTIVE_C} \ %{.S: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{!.S: -D__LANGUAGE_C -D_LANGUAGE_C %{!ansi:-DLANGUAGE_C}}" #define LINK_SPEC "\ --- 34,39 ---- %{.m: -D__LANGUAGE_OBJECTIVE_C -D_LANGUAGE_OBJECTIVE_C} \ %{.S: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{.s: -D__LANGUAGE_ASSEMBLY -D_LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ ! %{!.S:%{!.s: -D__LANGUAGE_C -D_LANGUAGE_C %{!ansi:-DLANGUAGE_C}}}" #define LINK_SPEC "\ *************** *** 61,64 **** --- 63,72 ---- #ifdef L_trampoline #include + + /* In at least 5.0 and 5.01, there is no _SC_PAGE_SIZE macro, only a + _SC_PAGESIZE macro. */ + #ifdef _SC_PAGESIZE + #define _SC_PAGE_SIZE _SC_PAGESIZE + #endif #define getpagesize() sysconf(_SC_PAGE_SIZE) diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/t-bsd gcc-2.5.0/config/mips/t-bsd *** gcc-2.4.5/config/mips/t-bsd --- gcc-2.5.0/config/mips/t-bsd Fri Oct 8 07:41:09 1993 *************** *** 0 **** --- 1,12 ---- + # Exactly the same as t-mips, except we must define SYSTEM_HEADER_DIR + # to point to the bsd43 include files. + SYSTEM_HEADER_DIR = /bsd43/usr/include + + # We have a premade insn-attrtab.c to save the hour it takes to run genattrtab. + # PREMADE_ATTRTAB = $(srcdir)/config/mips/mips-at.c + # PREMADE_ATTRTAB_MD = $(srcdir)/config/mips/mips-at.md + + # Suppress building libgcc1.a, since the MIPS compiler port is complete + # and does not need anything from libgcc1.a. + LIBGCC1 = libgcc1.null + CROSS_LIBGCC1 = libgcc1.null diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/t-bsd-gas gcc-2.5.0/config/mips/t-bsd-gas *** gcc-2.4.5/config/mips/t-bsd-gas --- gcc-2.5.0/config/mips/t-bsd-gas Thu Sep 9 16:02:36 1993 *************** *** 0 **** --- 1,8 ---- + # Exactly the same as t-mips-gas, except we must define SYSTEM_HEADER_DIR + # to point to the bsd43 include files. + SYSTEM_HEADER_DIR = /bsd43/usr/include + + # Suppress building libgcc1.a, since the MIPS compiler port is complete + # and does not need anything from libgcc1.a. + LIBGCC1 = libgcc1.null + CROSS_LIBGCC1 = libgcc1.null diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/t-mips gcc-2.5.0/config/mips/t-mips *** gcc-2.4.5/config/mips/t-mips Fri Apr 16 16:40:20 1993 --- gcc-2.5.0/config/mips/t-mips Fri Oct 8 07:41:13 1993 *************** *** 1,4 **** - EXTRA_PASSES = mips-tfile mips-tdump - # We have a premade insn-attrtab.c to save the hour it takes to run genattrtab. # PREMADE_ATTRTAB = $(srcdir)/config/mips/mips-at.c --- 1,2 ---- *************** *** 8,19 **** # and does not need anything from libgcc1.a. LIBGCC1 = libgcc1.null ! ! mips-tfile: mips-tfile.o version.o $(LIBDEPS) ! $(CC) $(CFLAGS) $(LDFLAGS) -o mips-tfile mips-tfile.o version.o $(LIBS) ! ! mips-tfile.o : mips-tfile.c $(CONFIG_H) $(CONFIG2_H) $(RTL_H) ! ! mips-tdump: mips-tdump.o version.o $(LIBDEPS) ! $(CC) $(CFLAGS) $(LDFLAGS) -o mips-tdump mips-tdump.o version.o $(LIBS) ! ! mips-tdump.o : mips-tdump.c $(CONFIG_H) $(CONFIG2_H) $(RTL_H) --- 6,8 ---- # and does not need anything from libgcc1.a. LIBGCC1 = libgcc1.null ! CROSS_LIBGCC1 = libgcc1.null diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/t-mips-gas gcc-2.5.0/config/mips/t-mips-gas *** gcc-2.4.5/config/mips/t-mips-gas Fri May 7 17:37:36 1993 --- gcc-2.5.0/config/mips/t-mips-gas Thu Sep 9 16:02:37 1993 *************** *** 2,3 **** --- 2,4 ---- # and does not need anything from libgcc1.a. LIBGCC1 = libgcc1.null + CROSS_LIBGCC1 = libgcc1.null diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/t-osfrose gcc-2.5.0/config/mips/t-osfrose *** gcc-2.4.5/config/mips/t-osfrose Fri Apr 16 16:40:17 1993 --- gcc-2.5.0/config/mips/t-osfrose Fri Oct 8 08:03:21 1993 *************** *** 1,4 **** EXTRA_OBJS = halfpic.o - LIMITS_H = # We have a premade insn-attrtab.c to save the hour it takes to run genattrtab. --- 1,3 ---- *************** *** 9,12 **** --- 8,12 ---- # and does not need anything from libgcc1.a. LIBGCC1 = libgcc1.null + CROSS_LIBGCC1 = libgcc1.null halfpic.o: halfpic.c $(CONFIG_H) $(CONFIG2_H) $(RTL_H) $(TREE_H) diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/t-svr3 gcc-2.5.0/config/mips/t-svr3 *** gcc-2.4.5/config/mips/t-svr3 --- gcc-2.5.0/config/mips/t-svr3 Fri Oct 8 07:41:16 1993 *************** *** 0 **** --- 1,12 ---- + # Exactly the same as t-mips, except we must define SYSTEM_HEADER_DIR + # to point to the svr3 include files. + SYSTEM_HEADER_DIR = /sysv/usr/include + + # We have a premade insn-attrtab.c to save the hour it takes to run genattrtab. + # PREMADE_ATTRTAB = $(srcdir)/config/mips/mips-at.c + # PREMADE_ATTRTAB_MD = $(srcdir)/config/mips/mips-at.md + + # Suppress building libgcc1.a, since the MIPS compiler port is complete + # and does not need anything from libgcc1.a. + LIBGCC1 = libgcc1.null + CROSS_LIBGCC1 = libgcc1.null diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/t-svr3-gas gcc-2.5.0/config/mips/t-svr3-gas *** gcc-2.4.5/config/mips/t-svr3-gas --- gcc-2.5.0/config/mips/t-svr3-gas Thu Sep 9 16:02:39 1993 *************** *** 0 **** --- 1,8 ---- + # Exactly the same as t-mips-gas, except we must define SYSTEM_HEADER_DIR + # to point to the svr3 include files. + SYSTEM_HEADER_DIR = /sysv/usr/include + + # Suppress building libgcc1.a, since the MIPS compiler port is complete + # and does not need anything from libgcc1.a. + LIBGCC1 = libgcc1.null + CROSS_LIBGCC1 = libgcc1.null diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/t-svr4 gcc-2.5.0/config/mips/t-svr4 *** gcc-2.4.5/config/mips/t-svr4 --- gcc-2.5.0/config/mips/t-svr4 Fri Oct 8 07:41:20 1993 *************** *** 0 **** --- 1,12 ---- + # Exactly the same as t-mips, except we must define SYSTEM_HEADER_DIR + # to point to the svr4 include files. + SYSTEM_HEADER_DIR = /svr4/usr/include + + # We have a premade insn-attrtab.c to save the hour it takes to run genattrtab. + # PREMADE_ATTRTAB = $(srcdir)/config/mips/mips-at.c + # PREMADE_ATTRTAB_MD = $(srcdir)/config/mips/mips-at.md + + # Suppress building libgcc1.a, since the MIPS compiler port is complete + # and does not need anything from libgcc1.a. + LIBGCC1 = libgcc1.null + CROSS_LIBGCC1 = libgcc1.null diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/t-svr4-gas gcc-2.5.0/config/mips/t-svr4-gas *** gcc-2.4.5/config/mips/t-svr4-gas --- gcc-2.5.0/config/mips/t-svr4-gas Thu Sep 9 16:02:41 1993 *************** *** 0 **** --- 1,8 ---- + # Exactly the same as t-mips-gas, except we must define SYSTEM_HEADER_DIR + # to point to the svr4 include files. + SYSTEM_HEADER_DIR = /svr4/usr/include + + # Suppress building libgcc1.a, since the MIPS compiler port is complete + # and does not need anything from libgcc1.a. + LIBGCC1 = libgcc1.null + CROSS_LIBGCC1 = libgcc1.null diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/t-ultrix gcc-2.5.0/config/mips/t-ultrix *** gcc-2.4.5/config/mips/t-ultrix Fri Apr 16 16:40:20 1993 --- gcc-2.5.0/config/mips/t-ultrix Fri Oct 8 07:41:23 1993 *************** *** 1,3 **** - EXTRA_PASSES = mips-tfile mips-tdump CONFIG2_H = $(srcdir)/config/mips/mips.h --- 1,2 ---- *************** *** 9,20 **** # and does not need anything from libgcc1.a. LIBGCC1 = libgcc1.null ! ! mips-tfile: mips-tfile.o version.o $(LIBDEPS) ! $(CC) $(CFLAGS) $(LDFLAGS) -o mips-tfile mips-tfile.o version.o $(LIBS) ! ! mips-tfile.o : mips-tfile.c $(CONFIG_H) $(CONFIG2_H) $(RTL_H) ! ! mips-tdump: mips-tdump.o version.o $(LIBDEPS) ! $(CC) $(CFLAGS) $(LDFLAGS) -o mips-tdump mips-tdump.o version.o $(LIBS) ! ! mips-tdump.o : mips-tdump.c $(CONFIG_H) $(CONFIG2_H) $(RTL_H) --- 8,10 ---- # and does not need anything from libgcc1.a. LIBGCC1 = libgcc1.null ! CROSS_LIBGCC1 = libgcc1.null diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/ultrix.h gcc-2.5.0/config/mips/ultrix.h *** gcc-2.4.5/config/mips/ultrix.h Tue May 11 17:08:27 1993 --- gcc-2.5.0/config/mips/ultrix.h Sat Oct 2 04:22:04 1993 *************** *** 21,26 **** #ifndef CPP_PREDEFINES ! #define CPP_PREDEFINES "-D__ANSI_COMPAT \ ! -DMIPSEL -DR3000 -DSYSTYPE_BSD -D_SYSTYPE_BSD -Dbsd4_2 -Dhost_mips -Dmips -Dultrix -Dunix" #endif --- 21,28 ---- #ifndef CPP_PREDEFINES ! #define CPP_PREDEFINES "\ ! -D__ANSI_COMPAT -DMIPSEL -DR3000 -DSYSTYPE_BSD -D_SYSTYPE_BSD \ ! -Dbsd4_2 -Dhost_mips -Dmips -Dultrix -Dunix \ ! -Asystem(unix) -Asystem(bsd) -Acpu(mips) -Amachine(mips)" #endif *************** *** 45,48 **** --- 47,51 ---- #define CPP_SPEC "\ %{.S: -D__LANGUAGE_ASSEMBLY__ -D__LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ + %{.s: -D__LANGUAGE_ASSEMBLY__ -D__LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ %{.cc: -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS} \ %{.cxx: -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS} \ *************** *** 49,53 **** %{.C: -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS} \ %{.m: -D__LANGUAGE_OBJECTIVE_C__ -D__LANGUAGE_OBJECTIVE_C} \ ! %{!.S: -D__LANGUAGE_C__ -D__LANGUAGE_C %{!ansi:-DLANGUAGE_C}}" #endif --- 52,56 ---- %{.C: -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS} \ %{.m: -D__LANGUAGE_OBJECTIVE_C__ -D__LANGUAGE_OBJECTIVE_C} \ ! %{!.S:%{!.s: -D__LANGUAGE_C__ -D__LANGUAGE_C %{!ansi:-DLANGUAGE_C}}}" #endif diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/x-iris3 gcc-2.5.0/config/mips/x-iris3 *** gcc-2.4.5/config/mips/x-iris3 --- gcc-2.5.0/config/mips/x-iris3 Wed Jul 28 13:57:38 1993 *************** *** 0 **** --- 1,28 ---- + # Define CC and OLDCC as the same, so that the tests: + # if [ x"$(OLDCC)" = x"$(CC)" ] ... + # + # will succeed (if OLDCC != CC, it is assumed that GCC is + # being used in secondary stage builds). We need to pass + # the -Wf,-XNg1500 option so the compiler can compile the + # G++ file cp-parse.c. Otherwise it complains about + # too many case statements. -Olimit is so the user + # can use -O2. Down with fixed size tables! + + # In at least one version of Irix, v3.3.2, the compiler does not accept + # the -cckr option, so, lets try without it for all versions of Irix 3.x. + # The -cckr is to turn off strict ANSI checking. + + CC = $(OLDCC) + OPT = -O1 + OLDCC = cc -Wf,-XNh1500,-XNg1500 -Olimit 3000 $(OPT) + + # The bison output files are machine-indep, + # so different flags for a particular machine are not useful. + #BISONFLAGS = -l + + # -lmld is so we can link collect2 running native. + # -lmalloc is supposed to be faster than the normal malloc + CLIB = -lmld -lmalloc + + # Show we need to use the C version of ALLOCA + ALLOCA = alloca.o diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/x-osfrose gcc-2.5.0/config/mips/x-osfrose *** gcc-2.4.5/config/mips/x-osfrose Sat Aug 15 11:15:17 1992 --- gcc-2.5.0/config/mips/x-osfrose Fri Oct 1 16:07:30 1993 *************** *** 16,20 **** DEBUG = DEBUG_COLLECT = # -DDEBUG ! GCC_CFLAGS = $(INTERNAL_CFLAGS) $(X_CFLAGS) $(T_CFLAGS) $(CFLAGS) -B./ -DPOSIX INSTALL = installbsd -c LIBGCC2_CFLAGS = -O2 $(GCC_CFLAGS) -g1 -pic-extern --- 16,21 ---- DEBUG = DEBUG_COLLECT = # -DDEBUG ! CCLIBFLAGS = -O -DNO_HALF_PIC ! GCC_CFLAGS = $(INTERNAL_CFLAGS) $(X_CFLAGS) $(T_CFLAGS) $(CFLAGS) -B./ -DPOSIX -DNO_HALF_PIC INSTALL = installbsd -c LIBGCC2_CFLAGS = -O2 $(GCC_CFLAGS) -g1 -pic-extern diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/x-sysv gcc-2.5.0/config/mips/x-sysv *** gcc-2.4.5/config/mips/x-sysv Sun Jul 19 11:30:43 1992 --- gcc-2.5.0/config/mips/x-sysv Wed Jul 28 13:45:39 1993 *************** *** 19,20 **** --- 19,25 ---- # This enables collect2 to link. CLIB= -L/usr/lib/cmplrs/cc2.11 -lmld + + # Show we need to use the C version of ALLOCA + # The SVR3 configurations have it, but the SVR4 configurations don't. + # For now, just try using it for all SVR* configurations. + ALLOCA = alloca.o diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/xm-mips.h gcc-2.5.0/config/mips/xm-mips.h *** gcc-2.4.5/config/mips/xm-mips.h Sat Sep 26 18:38:42 1992 --- gcc-2.5.0/config/mips/xm-mips.h Wed Oct 20 16:03:42 1993 *************** *** 1,4 **** /* Configuration for GNU C-compiler for MIPS Rx000 family ! Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,4 ---- /* Configuration for GNU C-compiler for MIPS Rx000 family ! Copyright (C) 1989, 1990, 1991, 1993 Free Software Foundation, Inc. This file is part of GNU CC. *************** *** 61,70 **** #ifndef MIPS_OVERRIDE_ALLOCA ! /* If compiled with GNU C, use the built-in alloca */ ! #ifdef __GNUC__ ! #define alloca __builtin_alloca ! ! #else #define USE_C_ALLOCA extern char * alloca (); --- 61,67 ---- #ifndef MIPS_OVERRIDE_ALLOCA ! #ifndef __GNUC__ #define USE_C_ALLOCA + extern char * alloca (); *************** *** 75,80 **** /* Say if we have vprintf. BSD Mips targets probably don't have vfprintf. */ ! #if defined(__OSF1__) || defined(__OSF__) || defined(__osf__) ! #define HAVE_VFPRINTF #define HAVE_PUTENV --- 72,77 ---- /* Say if we have vprintf. BSD Mips targets probably don't have vfprintf. */ ! #if defined(__OSF1__) || defined(__OSF__) || defined(__osf__) || defined(bsd4_4) ! #define HAVE_VPRINTF #define HAVE_PUTENV diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/mips/xm-sysv4.h gcc-2.5.0/config/mips/xm-sysv4.h *** gcc-2.4.5/config/mips/xm-sysv4.h --- gcc-2.5.0/config/mips/xm-sysv4.h Sun Aug 8 18:42:08 1993 *************** *** 0 **** --- 1,5 ---- + #include "mips/xm-sysv.h" + + /* SVR4 provides no sys_siglist, + but does offer the same data under another name. */ + #define sys_siglist _sys_siglist diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/ns32k/encore.h gcc-2.5.0/config/ns32k/encore.h *** gcc-2.4.5/config/ns32k/encore.h Tue Jan 5 00:51:30 1993 --- gcc-2.5.0/config/ns32k/encore.h Wed Oct 13 16:00:32 1993 *************** *** 55,59 **** /* Note Encore does not standardly do -Dencore. */ /* budd: should have a -ns32332 (or -apc) switch! but no harm for now */ ! #define CPP_PREDEFINES "-Dns32000 -Dn16 -Dns16000 -Dns32332 -Dunix" /* Ignore certain cpp directives used in header files on sysV. */ --- 55,59 ---- /* Note Encore does not standardly do -Dencore. */ /* budd: should have a -ns32332 (or -apc) switch! but no harm for now */ ! #define CPP_PREDEFINES "-Dns32000 -Dn16 -Dns16000 -Dns32332 -Dunix -Asystem(unix) -Acpu(ns32k) -Amachine(ns32k)" /* Ignore certain cpp directives used in header files on sysV. */ *************** *** 76,79 **** --- 76,85 ---- fprintf (FILE, "\t.align %d\n", 1 << (LOG)) + /* The Encore assembler doesn't seem to accept the usual second argument + and warns that .align may not work in the text section if optimization + is on. */ + #undef ASM_OUTPUT_ALIGN_CODE + #define ASM_OUTPUT_ALIGN_CODE(FILE) + /* * Internal labels are prefixed with a period. *************** *** 85,89 **** fprintf (FILE, ".%s%d:\n", PREFIX, NUM) #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ ! fprintf (FILE, "\t.word .L%d-.LI%d\n", VALUE, REL) /* --- 91,95 ---- fprintf (FILE, ".%s%d:\n", PREFIX, NUM) #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ ! fprintf (FILE, "\t.double .L%d-.LI%d\n", VALUE, REL) /* diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/ns32k/merlin.h gcc-2.5.0/config/ns32k/merlin.h *** gcc-2.4.5/config/ns32k/merlin.h Tue Jan 5 00:51:01 1993 --- gcc-2.5.0/config/ns32k/merlin.h Sat Oct 2 04:22:10 1993 *************** *** 47,51 **** #undef CPP_PREDEFINES #define CPP_PREDEFINES \ ! "-Dns32000 -Dns32k -Dns16000 -Dmerlin -Dunix -DUtek -Dbsd" /* This is how to align the code that follows an unconditional branch. --- 47,52 ---- #undef CPP_PREDEFINES #define CPP_PREDEFINES \ ! "-Dns32000 -Dns32k -Dns16000 -Dmerlin -Dunix -DUtek -Dbsd \ ! -Asystem(unix) -Asystem(bsd) -Acpu(ns32k) -Amachine(ns32k)" /* This is how to align the code that follows an unconditional branch. diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/ns32k/ns32k.c gcc-2.5.0/config/ns32k/ns32k.c *** gcc-2.4.5/config/ns32k/ns32k.c Sun Sep 6 17:23:28 1992 --- gcc-2.5.0/config/ns32k/ns32k.c Tue Sep 28 23:16:20 1993 *************** *** 245,249 **** rtx *operands; { ! enum anon1 { REGOP, OFFSOP, POPOP, CNSTOP, RNDOP } optype0, optype1; rtx latehalf[2]; --- 245,249 ---- rtx *operands; { ! enum anon1 { REGOP, OFFSOP, PUSHOP, CNSTOP, RNDOP } optype0, optype1; rtx latehalf[2]; *************** *** 255,259 **** optype0 = OFFSOP; else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) ! optype0 = POPOP; else optype0 = RNDOP; --- 255,259 ---- optype0 = OFFSOP; else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) ! optype0 = PUSHOP; else optype0 = RNDOP; *************** *** 267,271 **** optype1 = OFFSOP; else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC) ! optype1 = POPOP; else optype1 = RNDOP; --- 267,271 ---- optype1 = OFFSOP; else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC) ! optype1 = PUSHOP; else optype1 = RNDOP; *************** *** 308,321 **** latehalf[1] = operands[1]; /* If one or both operands autodecrementing, do the two words, high-numbered first. */ ! if (optype0 == POPOP || optype1 == POPOP) { output_asm_insn (singlemove_string (latehalf), latehalf); return singlemove_string (operands); } ! /* Not autodecrementing. Do the two words, low-numbered first. */ output_asm_insn (singlemove_string (operands), operands); --- 308,371 ---- latehalf[1] = operands[1]; + /* If insn is effectively movd N(sp),tos then we will do the + high word first. We should use the adjusted operand 1 (which is N+4(sp)) + for the low word as well, to compensate for the first decrement of sp. + Given this, it doesn't matter which half we do "first". */ + if (optype0 == PUSHOP + && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM + && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1])) + operands[1] = latehalf[1]; + /* If one or both operands autodecrementing, do the two words, high-numbered first. */ + else if (optype0 == PUSHOP || optype1 == PUSHOP) + { + output_asm_insn (singlemove_string (latehalf), latehalf); + return singlemove_string (operands); + } + + /* If the first move would clobber the source of the second one, + do them in the other order. */ ! /* Overlapping registers. */ ! if (optype0 == REGOP && optype1 == REGOP ! && REGNO (operands[0]) == REGNO (latehalf[1])) { + /* Do that word. */ output_asm_insn (singlemove_string (latehalf), latehalf); + /* Do low-numbered word. */ return singlemove_string (operands); } + /* Loading into a register which overlaps a register used in the address. */ + else if (optype0 == REGOP && optype1 != REGOP + && reg_overlap_mentioned_p (operands[0], operands[1])) + { + if (reg_mentioned_p (operands[0], XEXP (operands[1], 0)) + && reg_mentioned_p (latehalf[0], XEXP (operands[1], 0))) + { + /* If both halves of dest are used in the src memory address, + add the two regs and put them in the low reg (operands[0]). + Then it works to load latehalf first. */ + rtx xops[2]; + xops[0] = latehalf[0]; + xops[1] = operands[0]; + output_asm_insn ("addd %0,%1", xops); + operands[1] = gen_rtx (MEM, DImode, operands[0]); + latehalf[1] = adj_offsettable_operand (operands[1], 4); + /* The first half has the overlap, Do the late half first. */ + output_asm_insn (singlemove_string (latehalf), latehalf); + /* Then clobber. */ + return singlemove_string (operands); + } + if (reg_mentioned_p (operands[0], XEXP (operands[1], 0))) + { + /* The first half has the overlap, 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); diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/ns32k/ns32k.h gcc-2.5.0/config/ns32k/ns32k.h *** gcc-2.4.5/config/ns32k/ns32k.h Thu Apr 8 19:26:41 1993 --- gcc-2.5.0/config/ns32k/ns32k.h Thu Oct 7 15:47:27 1993 *************** *** 27,31 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dns32000 -Dunix" /* Print subsidiary information on the compiler version in use. */ --- 27,31 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dns32000 -Dunix -Asystem(unix) -Acpu(ns32k) -Amachine(ns32k)" /* Print subsidiary information on the compiler version in use. */ *************** *** 512,515 **** --- 512,520 ---- * * If a frame pointer is not needed we need assembler of the form + * + * # Make space on the stack + * + * adjspd + * * # Save any general purpose registers necessary * *************** *** 530,541 **** if (regs_ever_live[regno] \ && ! call_used_regs[regno]) \ ! { \ ! *bufp++ = regno; g_regs_used++; \ ! } \ *bufp = -1; \ for (; regno < 16; regno++) \ ! if (regs_ever_live[regno] && !call_used_regs[regno]) { \ ! *fbufp++ = regno; \ ! } \ *fbufp = -1; \ bufp = used_regs_buf; \ --- 535,547 ---- if (regs_ever_live[regno] \ && ! call_used_regs[regno]) \ ! { \ ! *bufp++ = regno; g_regs_used++; \ ! } \ *bufp = -1; \ for (; regno < 16; regno++) \ ! if (regs_ever_live[regno] && !call_used_regs[regno]) \ ! { \ ! *fbufp++ = regno; \ ! } \ *fbufp = -1; \ bufp = used_regs_buf; \ *************** *** 542,547 **** if (frame_pointer_needed) \ fprintf (FILE, "\tenter ["); \ ! else if (g_regs_used) \ ! fprintf (FILE, "\tsave ["); \ while (*bufp >= 0) \ { \ --- 548,564 ---- if (frame_pointer_needed) \ fprintf (FILE, "\tenter ["); \ ! else \ ! { \ ! if (SIZE) \ ! fprintf (FILE, "\tadjspd %$%d\n", SIZE + 4); \ ! if (g_regs_used && g_regs_used > 4) \ ! fprintf (FILE, "\tsave ["); \ ! else \ ! { \ ! while (*bufp >= 0) \ ! fprintf (FILE, "\tmovd r%d,tos\n", *bufp++); \ ! g_regs_used = 0; \ ! } \ ! } \ while (*bufp >= 0) \ { \ *************** *** 611,615 **** . . ! restore [] */ #define FUNCTION_EPILOGUE(FILE, SIZE) \ --- 628,637 ---- . . ! restore [] ! ! # reclaim space allocated on stack ! ! adjspd <-(local stack space + 4)> */ ! #define FUNCTION_EPILOGUE(FILE, SIZE) \ *************** *** 620,626 **** *fbufp++ = -2; \ for (regno = 8; regno < 16; regno++) \ ! if (regs_ever_live[regno] && !call_used_regs[regno]) { \ *fbufp++ = regno; f_regs_used++; \ ! } \ fbufp--; \ for (regno = 0; regno < 8; regno++) \ --- 642,649 ---- *fbufp++ = -2; \ for (regno = 8; regno < 16; regno++) \ ! if (regs_ever_live[regno] && !call_used_regs[regno]) \ ! { \ *fbufp++ = regno; f_regs_used++; \ ! } \ fbufp--; \ for (regno = 0; regno < 8; regno++) \ *************** *** 627,633 **** if (regs_ever_live[regno] \ && ! call_used_regs[regno]) \ ! { \ ! *bufp++ = regno; g_regs_used++; \ ! } \ while (fbufp > used_fregs_buf) \ { \ --- 650,656 ---- if (regs_ever_live[regno] \ && ! call_used_regs[regno]) \ ! { \ ! *bufp++ = regno; g_regs_used++; \ ! } \ while (fbufp > used_fregs_buf) \ { \ *************** *** 641,646 **** if (frame_pointer_needed) \ fprintf (FILE, "\texit ["); \ ! else if (g_regs_used) \ ! fprintf (FILE, "\trestore ["); \ while (bufp > used_regs_buf) \ { \ --- 664,678 ---- if (frame_pointer_needed) \ fprintf (FILE, "\texit ["); \ ! else \ ! { \ ! if (g_regs_used && g_regs_used > 4) \ ! fprintf (FILE, "\trestore ["); \ ! else \ ! { \ ! while (bufp > used_regs_buf) \ ! fprintf (FILE, "\tmovd tos,r%d\n", *--bufp); \ ! g_regs_used = 0; \ ! } \ ! } \ while (bufp > used_regs_buf) \ { \ *************** *** 651,654 **** --- 683,688 ---- if (g_regs_used || frame_pointer_needed) \ fprintf (FILE, "]\n"); \ + if (SIZE && !frame_pointer_needed) \ + fprintf (FILE, "\tadjspd %$%d\n", -(SIZE + 4)); \ if (current_function_pops_args) \ fprintf (FILE, "\tret %d\n", current_function_pops_args); \ *************** *** 667,671 **** if (regs_ever_live[regno] && ! call_used_regs[regno]) \ offset += 4; \ ! (DEPTH) = offset - get_frame_size (); \ } --- 701,706 ---- if (regs_ever_live[regno] && ! call_used_regs[regno]) \ offset += 4; \ ! (DEPTH) = (offset + get_frame_size () \ ! + (get_frame_size () == 0 ? 0 : 4)); \ } *************** *** 960,965 **** /* Specify the machine mode that this machine uses for the index in the tablejump instruction. ! Can do SImode, but HI mode is more efficient. */ ! #define CASE_VECTOR_MODE HImode /* Define this if the tablejump instruction expects the table --- 995,1001 ---- /* Specify the machine mode that this machine uses for the index in the tablejump instruction. ! HI mode is more efficient but the range is not wide enough for ! all programs. */ ! #define CASE_VECTOR_MODE SImode /* Define this if the tablejump instruction expects the table *************** *** 1275,1279 **** /* ** Notice that the second element is LI format! */ #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ ! fprintf (FILE, "\t.word L%d-LI%d\n", VALUE, REL) /* This is how to output an assembler line --- 1311,1315 ---- /* ** Notice that the second element is LI format! */ #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ ! fprintf (FILE, "\t.double L%d-LI%d\n", VALUE, REL) /* This is how to output an assembler line diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/ns32k/ns32k.md gcc-2.5.0/config/ns32k/ns32k.md *** gcc-2.4.5/config/ns32k/ns32k.md Tue Mar 23 07:41:45 1993 --- gcc-2.5.0/config/ns32k/ns32k.md Tue Sep 28 20:10:01 1993 *************** *** 191,195 **** (define_insn "movdf" ! [(set (match_operand:DF 0 "general_operand" "=&fg<") (match_operand:DF 1 "general_operand" "fFg"))] "" --- 191,195 ---- (define_insn "movdf" ! [(set (match_operand:DF 0 "general_operand" "=fg<") (match_operand:DF 1 "general_operand" "fFg"))] "" *************** *** 274,278 **** (define_insn "movdi" ! [(set (match_operand:DI 0 "general_operand" "=&g<,*f,g") (match_operand:DI 1 "general_operand" "gF,g,*f"))] "" --- 274,278 ---- (define_insn "movdi" ! [(set (match_operand:DI 0 "general_operand" "=g<,*f,g") (match_operand:DI 1 "general_operand" "gF,g,*f"))] "" *************** *** 889,894 **** if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) >-9 && INTVAL(operands[1]) < 8) ! return \"addqw %1,%0\"; ! return \"addw %1,%0\"; }") --- 889,894 ---- if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) >-9 && INTVAL(operands[1]) < 8) ! return \"addqw %2,%0\"; ! return \"addw %2,%0\"; }") *************** *** 917,922 **** if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) >-9 && INTVAL(operands[1]) < 8) ! return \"addqb %1,%0\"; ! return \"addb %1,%0\"; }") --- 917,922 ---- if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) >-9 && INTVAL(operands[1]) < 8) ! return \"addqb %2,%0\"; ! return \"addb %2,%0\"; }") *************** *** 946,951 **** if (GET_CODE(operands[0]) == CONST_INT && INTVAL(operands[0]) < 64 && INTVAL(operands[0]) > -64 && ! TARGET_32532) ! return \"adjspb %0\"; ! return \"adjspd %0\"; }") --- 946,951 ---- if (GET_CODE(operands[0]) == CONST_INT && INTVAL(operands[0]) < 64 && INTVAL(operands[0]) > -64 && ! TARGET_32532) ! return \"adjspb %$%0\"; ! return \"adjspd %$%0\"; }") *************** *** 991,996 **** if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) >-8 && INTVAL(operands[1]) < 9) ! return \"addqw %$%n1,%0\"; ! return \"subw %1,%0\"; }") --- 991,996 ---- if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) >-8 && INTVAL(operands[1]) < 9) ! return \"addqw %$%n2,%0\"; ! return \"subw %2,%0\"; }") *************** *** 1020,1025 **** if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) >-8 && INTVAL(operands[1]) < 9) ! return \"addqb %$%n1,%0\"; ! return \"subb %1,%0\"; }") --- 1020,1025 ---- if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) >-8 && INTVAL(operands[1]) < 9) ! return \"addqb %$%n2,%0\"; ! return \"subb %2,%0\"; }") *************** *** 2356,2369 **** "jump %0") - ;;(define_insn "tablejump" - ;; [(set (pc) - ;; (plus:SI (match_operand:SI 0 "general_operand" "g") - ;; (pc)))] - ;; "" - ;; "cased %0") - (define_insn "tablejump" [(set (pc) ! (plus:SI (pc) (match_operand:HI 0 "general_operand" "g"))) (use (label_ref (match_operand 1 "" "")))] "" --- 2356,2362 ---- "jump %0") (define_insn "tablejump" [(set (pc) ! (plus:SI (pc) (match_operand:SI 0 "general_operand" "g"))) (use (label_ref (match_operand 1 "" "")))] "" *************** *** 2372,2385 **** ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"LI\", CODE_LABEL_NUMBER (operands[1])); ! return \"casew %0\"; }") - ;;(define_insn "" - ;; [(set (pc) - ;; (plus:SI (match_operand:QI 0 "general_operand" "g") - ;; (pc)))] - ;; "" - ;; "caseb %0") - ;; Scondi instructions (define_insn "seq" --- 2365,2371 ---- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"LI\", CODE_LABEL_NUMBER (operands[1])); ! return \"cased %0\"; }") ;; Scondi instructions (define_insn "seq" *************** *** 2598,2599 **** --- 2584,2613 ---- "" "slsb %0") + + ;; Speed up stack adjust followed by a fullword fixedpoint push. + + (define_peephole + [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int 4))) + (set (match_operand:SI 0 "push_operand" "=m") + (match_operand:SI 1 "general_operand" "g"))] + "! reg_mentioned_p (stack_pointer_rtx, operands[1])" + "* + { + return \"movd %1,0(sp)\"; + }") + + ;; Speed up stack adjust followed by two fullword fixedpoint pushes. + + (define_peephole + [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int 8))) + (set (match_operand:SI 0 "push_operand" "=m") + (match_operand:SI 1 "general_operand" "g")) + (set (match_operand:SI 2 "push_operand" "=m") + (match_operand:SI 3 "general_operand" "g"))] + "! reg_mentioned_p (stack_pointer_rtx, operands[1]) + && ! reg_mentioned_p (stack_pointer_rtx, operands[3])" + "* + { + return \"movd %1,4(sp); movd %3,0(sp)\"; + }") + diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/ns32k/pc532-mach.h gcc-2.5.0/config/ns32k/pc532-mach.h *** gcc-2.4.5/config/ns32k/pc532-mach.h Tue Mar 23 14:22:55 1993 --- gcc-2.5.0/config/ns32k/pc532-mach.h Sat Oct 2 04:22:13 1993 *************** *** 22,26 **** #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dns32532 -DPC532 -DMACH=1" /* Don't default to pcc-struct-return, because gcc is the only compiler, and --- 22,26 ---- #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dns32532 -DPC532 -DMACH=1 -Asystem(unix) -Asystem(mach) -Acpu(ns32k) -Amachine(ns32k)" /* Don't default to pcc-struct-return, because gcc is the only compiler, and diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/ns32k/pc532.h gcc-2.5.0/config/ns32k/pc532.h *** gcc-2.4.5/config/ns32k/pc532.h Tue Jan 5 00:50:31 1993 --- gcc-2.5.0/config/ns32k/pc532.h Wed Oct 13 15:58:29 1993 *************** *** 36,39 **** --- 36,44 ---- #undef PCC_STATIC_STRUCT_RETURN + /* There's a bug in the setjmp implementation that strikes + if the caller of setjmp doesn't have a frame pointer. */ + #undef FRAME_POINTER_REQUIRED + #define FRAME_POINTER_REQUIRED current_function_calls_setjmp + /* 32-bit alignment for efficiency */ #undef POINTER_BOUNDARY *************** *** 55,59 **** #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dns32000 -Dns32532 -Dpc532 -Dunix" /* Use pc relative addressing whenever possible, --- 60,64 ---- #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dns32000 -Dns32532 -Dpc532 -Dunix -Asystem(unix) -Acpu(ns32k) -Amachine(ns32k)" /* Use pc relative addressing whenever possible, diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/ns32k/sequent.h gcc-2.5.0/config/ns32k/sequent.h *** gcc-2.4.5/config/ns32k/sequent.h Tue Jan 5 00:50:19 1993 --- gcc-2.5.0/config/ns32k/sequent.h Sat Oct 2 04:22:19 1993 *************** *** 37,41 **** #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dns32000 -Dsequent -Dunix" /* Link with libg.a when debugging, for dbx's sake. */ --- 37,41 ---- #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dns32000 -Dsequent -Dunix -Asystem(unix) -Asystem(bsd) -Acpu(ns32k) -Amachine(ns32k)" /* Link with libg.a when debugging, for dbx's sake. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/ns32k/tek6000.h gcc-2.5.0/config/ns32k/tek6000.h *** gcc-2.4.5/config/ns32k/tek6000.h Tue Jan 5 00:53:08 1993 --- gcc-2.5.0/config/ns32k/tek6000.h Sat Oct 2 04:22:22 1993 *************** *** 96,102 **** #define CPP_PREDEFINES_Tek6000 \ ! "-Dns16000 -Dns32000 -Dns32k -Dns32016 -DUTek -DUTEK -Dbsd -DBSD" #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "CPP_PREDEFINES_Tek6000" /* This is how to align the code that follows an unconditional branch. --- 96,103 ---- #define CPP_PREDEFINES_Tek6000 \ ! "-Dns16000 -Dns32000 -Dns32k -Dns32016 -DUTek -DUTEK -Dbsd -DBSD \ ! -Asystem(unix) -Asystem(bsd) -Acpu(ns32k) -Amachine(ns32k)" #undef CPP_PREDEFINES ! #define CPP_PREDEFINES CPP_PREDEFINES_Tek6000 /* This is how to align the code that follows an unconditional branch. diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/ns32k/tek6100.h gcc-2.5.0/config/ns32k/tek6100.h *** gcc-2.4.5/config/ns32k/tek6100.h Tue Jan 5 00:49:53 1993 --- gcc-2.5.0/config/ns32k/tek6100.h Sat Oct 2 04:22:24 1993 *************** *** 3,6 **** #undef CPP_PREDEFINES #define CPP_PREDEFINES \ ! "-Dns32000 -Dns32k -Dns16000 -Dns32016 -DUTek -DUTEK -Dbsd -DBSD -Dstratos" --- 3,7 ---- #undef CPP_PREDEFINES #define CPP_PREDEFINES \ ! "-Dns32000 -Dns32k -Dns16000 -Dns32016 -DUTek -DUTEK -Dbsd -DBSD -Dstratos \ ! -Asystem(unix) -Asystem(bsd) -Acpu(ns32k) -Amachine(ns32k)" diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/ns32k/tek6200.h gcc-2.5.0/config/ns32k/tek6200.h *** gcc-2.4.5/config/ns32k/tek6200.h Tue Jan 5 00:49:43 1993 --- gcc-2.5.0/config/ns32k/tek6200.h Sat Oct 2 04:22:27 1993 *************** *** 3,6 **** #undef CPP_PREDEFINES #define CPP_PREDEFINES \ ! "-Dns32000 -Dns32k -Dns16000 -Dns32016 -DUTek -DUTEK -Dbsd -DBSD -Dmerlin" --- 3,7 ---- #undef CPP_PREDEFINES #define CPP_PREDEFINES \ ! "-Dns32000 -Dns32k -Dns16000 -Dns32016 -DUTek -DUTEK -Dbsd -DBSD -Dmerlin \ ! -Asystem(unix) -Asystem(bsd) -Acpu(ns32k) -Amachine(ns32k)" diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/ns32k/xm-ns32k.h gcc-2.5.0/config/ns32k/xm-ns32k.h *** gcc-2.4.5/config/ns32k/xm-ns32k.h Sat Dec 26 17:23:29 1992 --- gcc-2.5.0/config/ns32k/xm-ns32k.h Sat Jun 26 11:32:28 1993 *************** *** 1,4 **** /* Configuration for GNU C-compiler for Vax. ! Copyright (C) 1987 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,4 ---- /* Configuration for GNU C-compiler for Vax. ! Copyright (C) 1987, 1993 Free Software Foundation, Inc. This file is part of GNU CC. *************** *** 40,46 **** #define memset gcc_memset #define memcmp(left,right,len) bcmp ((left),(right),(len)) - - /* If compiled with GNU C, use the built-in alloca */ - #ifdef __GNUC__ - #define alloca __builtin_alloca - #endif --- 40,41 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/pa/pa-ghpux.h gcc-2.5.0/config/pa/pa-ghpux.h *** gcc-2.4.5/config/pa/pa-ghpux.h Mon Apr 26 18:14:00 1993 --- gcc-2.5.0/config/pa/pa-ghpux.h Sat Oct 2 04:22:32 1993 *************** *** 19,23 **** #ifndef TARGET_DEFAULT ! #define TARGET_DEFAULT 0 #endif --- 19,23 ---- #ifndef TARGET_DEFAULT ! #define TARGET_DEFAULT 128 /* TARGET_GAS */ #endif *************** *** 36,44 **** /* Like the default, except no -lg. */ ! #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-L/lib/libp/ -lc}%{pg:-L/lib/libp/ -lc}" #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -DPWB -Dhpux -Dunix -D_HPUX_SOURCE" #undef LINK_SPEC ! #define LINK_SPEC "-u main -a archive" --- 36,44 ---- /* Like the default, except no -lg. */ ! #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p: -L/lib/libp/ -lc}%{pg: -L/lib/libp/ -lc}" #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -DPWB -Dhpux -Dunix -D_HPUX_SOURCE -Asystem(unix) -Asystem(hpux) -Acpu(hppa) -Amachine(hppa)" #undef LINK_SPEC ! #define LINK_SPEC "-u main %{static: -a archive}%{g: -a archive}" diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/pa/pa-gux7.h gcc-2.5.0/config/pa/pa-gux7.h *** gcc-2.4.5/config/pa/pa-gux7.h Mon Apr 26 18:14:20 1993 --- gcc-2.5.0/config/pa/pa-gux7.h Sat Oct 2 04:22:35 1993 *************** *** 19,23 **** #ifndef TARGET_DEFAULT ! #define TARGET_DEFAULT 0 #endif --- 19,23 ---- #ifndef TARGET_DEFAULT ! #define TARGET_DEFAULT 128 /* TARGET_GAS */ #endif *************** *** 36,41 **** /* Like the default, except no -lg. */ ! #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-L/lib/libp/ -lc}%{pg:-L/lib/libp/ -lc}" #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -DPWB -Dhpux -Dunix -D_HPUX_SOURCE" --- 36,41 ---- /* Like the default, except no -lg. */ ! #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p: -L/lib/libp/ -lc}%{pg: -L/lib/libp/ -lc}" #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -DPWB -Dhpux -Dunix -D_HPUX_SOURCE -Asystem(unix) -Asystem(hpux) -Acpu(hppa) -Amachine(hppa)" diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/pa/pa-hpux.h gcc-2.5.0/config/pa/pa-hpux.h *** gcc-2.4.5/config/pa/pa-hpux.h Mon Apr 26 18:14:27 1993 --- gcc-2.5.0/config/pa/pa-hpux.h Sat Oct 2 04:22:38 1993 *************** *** 37,47 **** /* HPUX doesn't use any debugging format that GCC knows about. */ #undef DBX_DEBUGGING_INFO /* Like the default, except no -lg. */ ! #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-L/lib/libp/ -lc}%{pg:-L/lib/libp/ -lc}" #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -DPWB -Dhpux -Dunix -D_HPUX_SOURCE" #undef LINK_SPEC ! #define LINK_SPEC "-u main -a archive" --- 37,49 ---- /* HPUX doesn't use any debugging format that GCC knows about. */ #undef DBX_DEBUGGING_INFO + #undef DEFAULT_GDB_EXTENSIONS + #define DEFAULT_GDB_EXTENSIONS 0 /* Like the default, except no -lg. */ ! #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p: -L/lib/libp/ -lc}%{pg: -L/lib/libp/ -lc}" #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -DPWB -Dhpux -Dunix -D_HPUX_SOURCE -Asystem(unix) -Asystem(hpux) -Acpu(hppa) -Amachine(hppa)" #undef LINK_SPEC ! #define LINK_SPEC "-u main %{static: -a archive}%{g: -a archive}" diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/pa/pa-hpux7.h gcc-2.5.0/config/pa/pa-hpux7.h *** gcc-2.4.5/config/pa/pa-hpux7.h Mon Apr 26 18:14:36 1993 --- gcc-2.5.0/config/pa/pa-hpux7.h Sat Oct 2 04:22:40 1993 *************** *** 22,25 **** --- 22,28 ---- #endif + /* HPUX 7 has the old assembler. */ + #define HP_FP_ARG_DESCRIPTOR_REVERSED + #include "pa/pa.h" *************** *** 37,44 **** /* HPUX doesn't use any debugging format that GCC knows about. */ #undef DBX_DEBUGGING_INFO /* Like the default, except no -lg. */ ! #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-L/lib/libp/ -lc}%{pg:-L/lib/libp/ -lc}" #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -DPWB -Dhpux -Dunix -D_HPUX_SOURCE" --- 40,49 ---- /* HPUX doesn't use any debugging format that GCC knows about. */ #undef DBX_DEBUGGING_INFO + #undef DEFAULT_GDB_EXTENSIONS + #define DEFAULT_GDB_EXTENSIONS 0 /* Like the default, except no -lg. */ ! #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p: -L/lib/libp/ -lc}%{pg: -L/lib/libp/ -lc}" #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -DPWB -Dhpux -Dunix -D_HPUX_SOURCE -Asystem(unix) -Asystem(hpux) -Acpu(hppa) -Amachine(hppa)" diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/pa/pa-oldas.h gcc-2.5.0/config/pa/pa-oldas.h *** gcc-2.4.5/config/pa/pa-oldas.h --- gcc-2.5.0/config/pa/pa-oldas.h Tue Sep 21 19:25:38 1993 *************** *** 0 **** --- 1,29 ---- + /* Definitions of target machine for GNU compiler, for HP PA-RISC 1.1 + Copyright (C) 1991 Free Software Foundation, Inc. + Contributed by Tim Moore (moore@defmacro.cs.utah.edu) + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + /* This is the same as pa-hpux.h, except that we generate snake code by + default and emits assembly code accepted by the 8.02 assembler. */ + + + #define TARGET_DEFAULT 0 + #define HP_FP_ARG_DESCRIPTOR_REVERSED + + #include "pa/pa-hpux.h" + diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/pa/pa-utahmach.h gcc-2.5.0/config/pa/pa-utahmach.h *** gcc-2.4.5/config/pa/pa-utahmach.h Tue Mar 23 14:22:58 1993 --- gcc-2.5.0/config/pa/pa-utahmach.h Sat Oct 2 04:22:43 1993 *************** *** 19,32 **** the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! /* This is the same as pa-hpux.h, except that we generate snake code by ! default and we have to deal with assembler weirdness. */ - #define HP_FP_ARG_DESCRIPTOR_REVERSED - - #define TARGET_DEFAULT 32 /* TARGET_DISABLE_INDEXING */ - #include "pa/pa.h" #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -Dunix -D_HPUX_SOURCE -Dhp9000 -Dhp800 -Dspectrum -DREVARGV -Dhp700 -DHP700 -Dparisc -D__pa_risc -DPARISC -DBYTE_MSF -DBIT_MSF" /* Don't default to pcc-struct-return, because gcc is the only compiler, and --- 19,27 ---- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! #define TARGET_DEFAULT 128 /* TARGET_GAS */ #include "pa/pa.h" #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -Dunix -Dhp9000 -Dhp800 -Dspectrum -DREVARGV -Dparisc -D__pa_risc -DPARISC -DBYTE_MSF -DBIT_MSF -Asystem(unix) -Asystem(mach) -Acpu(hppa) -Amachine(hppa)" /* Don't default to pcc-struct-return, because gcc is the only compiler, and diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/pa/pa.c gcc-2.5.0/config/pa/pa.c *** gcc-2.4.5/config/pa/pa.c Fri Jun 4 02:52:07 1993 --- gcc-2.5.0/config/pa/pa.c Thu Oct 21 01:51:02 1993 *************** *** 47,50 **** --- 47,54 ---- int hp_profile_labelno; + /* Counts for the number of callee-saved general and floating point + registers which were saved by the current function's prologue. */ + static int gr_saved, fr_saved; + static rtx find_addr_reg (); *************** *** 59,62 **** --- 63,71 ---- } + /* Return non-zero if OP is suitable for use in a call to a named + function. + + (???) For 2.5 try to eliminate either call_operand_address or + function_label_operand, they perform very similar functions. */ int call_operand_address (op, mode) *************** *** 64,69 **** enum machine_mode mode; { ! return (REG_P (op) ! || (CONSTANT_P (op) && ! TARGET_LONG_CALLS)); } --- 73,77 ---- enum machine_mode mode; { ! return (CONSTANT_P (op) && ! TARGET_LONG_CALLS); } *************** *** 477,481 **** else if (GET_CODE (orig) == CONST) { ! rtx base, offset; if (GET_CODE (XEXP (orig, 0)) == PLUS --- 485,489 ---- else if (GET_CODE (orig) == CONST) { ! rtx base; if (GET_CODE (XEXP (orig, 0)) == PLUS *************** *** 647,653 **** return plus_constant (ptr_reg, offset - newoffset); } if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT ! && shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1)))) { int val = INTVAL (XEXP (XEXP (x, 0), 1)); --- 655,673 ---- return plus_constant (ptr_reg, offset - newoffset); } + + /* Try to arrange things so that indexing modes can be used, but + only do so if indexing is safe. + + Indexing is safe when the second operand for the outer PLUS + is a REG, SUBREG, SYMBOL_REF or the like. + + For 2.5, indexing is also safe for (plus (symbol_ref) (const_int)) + if the integer is > 0. */ if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT ! && shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1))) ! && (GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == 'o' ! || GET_CODE (XEXP (x, 1)) == SUBREG) ! && GET_CODE (XEXP (x, 1)) != CONST) { int val = INTVAL (XEXP (XEXP (x, 0), 1)); *************** *** 662,665 **** --- 682,720 ---- reg1)); } + + /* Uh-oh. We might have an address for x[n-100000]. This needs + special handling. */ + + if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == MULT + && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT + && shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1)))) + { + /* Ugly. We modify things here so that the address offset specified + by the index expression is computed first, then added to x to form + the entire address. + + For 2.5, it might be profitable to set things up so that we + compute the raw (unscaled) index first, then use scaled indexing + to access memory, or better yet have the MI parts of the compiler + handle this. */ + + rtx regx1, regy1, regy2, y; + + /* Strip off any CONST. */ + y = XEXP (x, 1); + if (GET_CODE (y) == CONST) + y = XEXP (y, 0); + + /* 'y' had better be a PLUS or MINUS expression at this point. */ + if (GET_CODE (y) != PLUS && GET_CODE (y) != MINUS) + abort(); + + regx1 = force_reg (Pmode, force_operand (XEXP (x, 0), 0)); + regy1 = force_reg (Pmode, force_operand (XEXP (y, 0), 0)); + regy2 = force_reg (Pmode, force_operand (XEXP (y, 1), 0)); + regx1 = force_reg (Pmode, gen_rtx (GET_CODE (y), Pmode, regx1, regy2)); + return force_reg (Pmode, gen_rtx (PLUS, Pmode, regx1, regy1)); + } + if (flag_pic) return legitimize_pic_address (x, mode, gen_reg_rtx (Pmode)); *************** *** 792,796 **** return 1; } ! if (! reload_in_progress) { operands[0] = validize_mem (operand0); --- 847,851 ---- return 1; } ! if (! (reload_in_progress || reload_completed)) { operands[0] = validize_mem (operand0); *************** *** 800,807 **** /* Simplify the source if we need to. */ ! if (GET_CODE (operand1) != HIGH && immediate_operand (operand1, mode) || (GET_CODE (operand1) == HIGH ! && symbolic_operand (XEXP (operand1, 0), mode) ! && TARGET_KERNEL)) { int ishighonly = 0; --- 855,861 ---- /* Simplify the source if we need to. */ ! if ((GET_CODE (operand1) != HIGH && immediate_operand (operand1, mode)) || (GET_CODE (operand1) == HIGH ! && symbolic_operand (XEXP (operand1, 0), mode))) { int ishighonly = 0; *************** *** 816,820 **** if (flag_pic) { ! rtx temp = reload_in_progress ? operand0 : gen_reg_rtx (Pmode); operands[1] = legitimize_pic_address (operand1, mode, temp); emit_insn (gen_rtx (SET, VOIDmode, operand0, operands[1])); --- 870,880 ---- if (flag_pic) { ! rtx temp; ! ! if (reload_in_progress || reload_completed) ! temp = operand0; ! else ! temp = gen_reg_rtx (Pmode); ! operands[1] = legitimize_pic_address (operand1, mode, temp); emit_insn (gen_rtx (SET, VOIDmode, operand0, operands[1])); *************** *** 827,831 **** rtx temp, set; ! if (reload_in_progress) temp = scratch_reg ? scratch_reg : operand0; else --- 887,891 ---- rtx temp, set; ! if (reload_in_progress || reload_completed) temp = scratch_reg ? scratch_reg : operand0; else *************** *** 842,850 **** temp, gen_rtx (HIGH, mode, operand1))); ! if (TARGET_SHARED_LIBS ! && function_label_operand (operand1, mode)) { ! rtx temp = reload_in_progress ? scratch_reg ! : gen_reg_rtx (mode); if (!temp) abort (); --- 902,914 ---- temp, gen_rtx (HIGH, mode, operand1))); ! if (function_label_operand (operand1, mode)) { ! rtx temp; ! ! if (reload_in_progress || reload_completed) ! temp = scratch_reg; ! else ! temp = gen_reg_rtx (mode); ! if (!temp) abort (); *************** *** 862,870 **** } else if (GET_CODE (operand1) != CONST_INT ! || (! INT_14_BITS (operand1) ! && ! ((INTVAL (operand1) & 0x7ff) == 0) ! && ! zdepi_cint_p (INTVAL (operand1)))) { ! rtx temp = reload_in_progress ? operand0 : gen_reg_rtx (mode); emit_insn (gen_rtx (SET, VOIDmode, temp, gen_rtx (HIGH, mode, operand1))); --- 926,938 ---- } else if (GET_CODE (operand1) != CONST_INT ! || ! cint_ok_for_move (INTVAL (operand1))) { ! rtx temp; ! ! if (reload_in_progress || reload_completed) ! temp = operand0; ! else ! temp = gen_reg_rtx (mode); ! emit_insn (gen_rtx (SET, VOIDmode, temp, gen_rtx (HIGH, mode, operand1))); *************** *** 892,901 **** /* Return the best assembler insn template ! for moving operands[1] into operands[0] as a fullword. ! ! For CONST_DOUBLE and CONST_INT we should also check for ! other values we can load directly via zdepi, ldil, etc. ! ??? Do this for 2.5. */ ! char * singlemove_string (operands) --- 960,964 ---- /* Return the best assembler insn template ! for moving operands[1] into operands[0] as a fullword. */ char * singlemove_string (operands) *************** *** 919,924 **** operands[1] = gen_rtx (CONST_INT, VOIDmode, i); ! if (INT_14_BITS (operands[1])) ! return (INTVAL (operands[1]) == 0 ? "copy 0,%0" : "ldi %1,%0"); else return "ldil L'%1,%0\n\tldo R'%1(%0),%0"; --- 982,999 ---- operands[1] = gen_rtx (CONST_INT, VOIDmode, i); ! /* See if we can handle this constant in a single instruction. */ ! if (cint_ok_for_move (INTVAL (operands[1]))) ! { ! int intval = INTVAL (operands[1]); ! ! if (intval == 0) ! return "copy 0,%0"; ! else if (VAL_14_BITS_P (intval)) ! return "ldi %1,%0"; ! else if ((intval & 0x7ff) == 0) ! return "ldil L'%1,%0"; ! else if (zdepi_cint_p (intval)) ! return "zdepi %Z1,%0"; ! } else return "ldil L'%1,%0\n\tldo R'%1(%0),%0"; *************** *** 927,932 **** else if (GET_CODE (operands[1]) == CONST_INT) { ! if (INT_14_BITS (operands[1])) ! return (INTVAL (operands[1]) == 0 ? "copy 0,%0" : "ldi %1,%0"); else return "ldil L'%1,%0\n\tldo R'%1(%0),%0"; --- 1002,1019 ---- else if (GET_CODE (operands[1]) == CONST_INT) { ! /* See if we can handle this in a single instruction. */ ! if (cint_ok_for_move (INTVAL (operands[1]))) ! { ! int intval = INTVAL (operands[1]); ! ! if (intval == 0) ! return "copy 0,%0"; ! else if (VAL_14_BITS_P (intval)) ! return "ldi %1,%0"; ! else if ((intval & 0x7ff) == 0) ! return "ldil L'%1,%0"; ! else if (zdepi_cint_p (intval)) ! return "zdepi %Z1,%0"; ! } else return "ldil L'%1,%0\n\tldo R'%1(%0),%0"; *************** *** 1307,1311 **** if (size_is_constant) { - unsigned long n_items; unsigned long offset; rtx temp; --- 1394,1397 ---- *************** *** 1481,1487 **** if (size_is_constant) { - unsigned long n_items; unsigned long offset; - rtx temp; if (n_bytes == 0) --- 1567,1571 ---- *************** *** 1503,1507 **** /* Count last store or partial store. */ insn_count += 1; ! return insn_count; } --- 1587,1591 ---- /* Count last store or partial store. */ insn_count += 1; ! return insn_count * 4; } *************** *** 1522,1526 **** insn_count += 1; ! return insn_count; } --- 1606,1610 ---- insn_count += 1; ! return insn_count * 4; } *************** *** 1535,1539 **** insn_count += 1; ! return insn_count; } --- 1619,1623 ---- insn_count += 1; ! return insn_count * 4; } *************** *** 1559,1563 **** else insn_count += 4; ! return insn_count; } --- 1643,1647 ---- else insn_count += 4; ! return insn_count * 4; } *************** *** 1619,1623 **** { unsigned mask = INTVAL (operands[2]); ! int bs0, bs1, bs2, p, len; if (INTVAL (operands[2]) == 0) --- 1703,1707 ---- { unsigned mask = INTVAL (operands[2]); ! int bs0, bs1, p, len; if (INTVAL (operands[2]) == 0) *************** *** 1644,1647 **** --- 1728,1732 ---- /* Output an ascii string. */ + void output_ascii (file, p, size) FILE *file; *************** *** 1913,1917 **** if (! leaf_function_p () || fsize) fsize += 32; ! return TARGET_SNAKE ? (fsize + 63 & ~63) : fsize; } --- 1998,2002 ---- if (! leaf_function_p () || fsize) fsize += 32; ! return (fsize + 63) & ~63; } *************** *** 1929,1937 **** fprintf (file, "\t.PROC\n\t.CALLINFO FRAME=%d", actual_fsize); if (regs_ever_live[2] || profile_flag) ! fprintf (file, ",CALLS,SAVE_RP\n"); else ! fprintf (file, ",NO_CALLS\n"); ! fprintf (file, "\t.ENTRY\n"); /* Horrid hack. emit_function_prologue will modify this RTL in place to get the expected results. */ --- 2014,2040 ---- fprintf (file, "\t.PROC\n\t.CALLINFO FRAME=%d", actual_fsize); if (regs_ever_live[2] || profile_flag) ! fprintf (file, ",CALLS,SAVE_RP"); else ! fprintf (file, ",NO_CALLS"); ! ! if (frame_pointer_needed) ! fprintf (file, ",SAVE_SP"); ! ! /* Pass on information about the number of callee register saves ! performed in the prologue. ! ! The compiler is supposed to pass the highest register number ! saved, the assembler then has to adjust that number before ! entering it into the unwind descriptor (to account for any ! caller saved registers with lower register numbers than the ! first callee saved register). */ ! if (gr_saved) ! fprintf (file, ",ENTRY_GR=%d", gr_saved + 2); ! ! if (fr_saved) ! fprintf (file, ",ENTRY_FR=%d", fr_saved + 11); + fprintf (file, "\n\t.ENTRY\n"); + /* Horrid hack. emit_function_prologue will modify this RTL in place to get the expected results. */ *************** *** 1940,1943 **** --- 2043,2047 ---- } + void hppa_expand_prologue() { *************** *** 1950,1953 **** --- 2054,2059 ---- + gr_saved = 0; + fr_saved = 0; save_fregs = 0; local_fsize = size + (size || frame_pointer_needed ? 8 : 0); *************** *** 2081,2085 **** --- 2187,2194 ---- store_reg (i, offset, FRAME_POINTER_REGNUM); offset += 4; + gr_saved++; } + /* Account for %r4 which is saved in a special place. */ + gr_saved++; } /* No frame pointer needed. */ *************** *** 2102,2105 **** --- 2211,2215 ---- store_reg (i, offset, STACK_POINTER_REGNUM); offset += 4; + gr_saved++; } *************** *** 2130,2139 **** { for (i = 43; i >= 40; i--) ! { ! if (regs_ever_live[i]) emit_move_insn (gen_rtx (MEM, DFmode, gen_rtx (POST_INC, DFmode, tmpreg)), gen_rtx (REG, DFmode, i)); ! } } else --- 2240,2250 ---- { for (i = 43; i >= 40; i--) ! if (regs_ever_live[i]) ! { emit_move_insn (gen_rtx (MEM, DFmode, gen_rtx (POST_INC, DFmode, tmpreg)), gen_rtx (REG, DFmode, i)); ! fr_saved++; ! } } else *************** *** 2145,2148 **** --- 2256,2260 ---- gen_rtx (POST_INC, DFmode, tmpreg)), gen_rtx (REG, DFmode, i)); + fr_saved++; } } *************** *** 2467,2481 **** computed as LENGTH. Return zero if no adjustment is necessary. ! For the PA: function calls, millicode calls, and short conditional branches ! with unfilled delay slots need an adjustment by +1 (to account for ! the NOP which will be inserted into the instruction stream). Also compute the length of an inline block move here as it is too ! complicated to express as a length attribute in pa.md. ! ! (For 2.5) Indirect calls do not need length adjustment as their ! delay slot is filled internally in the output template. ! ! (For 2.5) No adjustment is necessary for jump tables or casesi insns. */ int pa_adjust_insn_length (insn, length) --- 2579,2588 ---- computed as LENGTH. Return zero if no adjustment is necessary. ! For the PA: function calls, millicode calls, and backwards short ! conditional branches with unfilled delay slots need an adjustment by +1 ! (to account for the NOP which will be inserted into the instruction stream). Also compute the length of an inline block move here as it is too ! complicated to express as a length attribute in pa.md. */ int pa_adjust_insn_length (insn, length) *************** *** 2485,2491 **** rtx pat = PATTERN (insn); ! /* Call insn with an unfilled delay slot. */ if (GET_CODE (insn) == CALL_INSN) ! return 1; /* Millicode insn with an unfilled delay slot. */ else if (GET_CODE (insn) == INSN --- 2592,2609 ---- rtx pat = PATTERN (insn); ! /* Call insns which are *not* indirect and have unfilled delay slots. */ if (GET_CODE (insn) == CALL_INSN) ! { ! ! if (GET_CODE (XVECEXP (pat, 0, 0)) == CALL ! && GET_CODE (XEXP (XEXP (XVECEXP (pat, 0, 0), 0), 0)) == SYMBOL_REF) ! return 4; ! else if (GET_CODE (XVECEXP (pat, 0, 0)) == SET ! && GET_CODE (XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0)) ! == SYMBOL_REF) ! return 4; ! else ! return 0; ! } /* Millicode insn with an unfilled delay slot. */ else if (GET_CODE (insn) == INSN *************** *** 2494,2498 **** && GET_CODE (pat) != CLOBBER && get_attr_type (insn) == TYPE_MILLI) ! return 1; /* Block move pattern. */ else if (GET_CODE (insn) == INSN --- 2612,2616 ---- && GET_CODE (pat) != CLOBBER && get_attr_type (insn) == TYPE_MILLI) ! return 4; /* Block move pattern. */ else if (GET_CODE (insn) == INSN *************** *** 2502,2510 **** && GET_MODE (XEXP (XVECEXP (pat, 0, 0), 0)) == BLKmode && GET_MODE (XEXP (XVECEXP (pat, 0, 0), 1)) == BLKmode) ! return compute_movstrsi_length (insn) - 1; /* Conditional branch with an unfilled delay slot. */ ! else if (GET_CODE (insn) == JUMP_INSN && ! simplejump_p (insn) ! && length != 2 && length != 4) ! return 1; else return 0; --- 2620,2645 ---- && GET_MODE (XEXP (XVECEXP (pat, 0, 0), 0)) == BLKmode && GET_MODE (XEXP (XVECEXP (pat, 0, 0), 1)) == BLKmode) ! return compute_movstrsi_length (insn) - 4; /* Conditional branch with an unfilled delay slot. */ ! else if (GET_CODE (insn) == JUMP_INSN && ! simplejump_p (insn)) ! { ! /* Adjust a short backwards conditional with an unfilled delay slot. */ ! if (GET_CODE (pat) == SET ! && length == 4 ! && ! forward_branch_p (insn)) ! return 4; ! /* Adjust dbra insn with short backwards conditional branch with ! unfilled delay slot -- only for case where counter is in a ! general register register. */ ! else if (GET_CODE (pat) == PARALLEL ! && GET_CODE (XVECEXP (pat, 0, 1)) == SET ! && GET_CODE (XEXP (XVECEXP (pat, 0, 1), 0)) == REG ! && ! FP_REG_P (XEXP (XVECEXP (pat, 0, 1), 0)) ! && length == 4 ! && ! forward_branch_p (insn)) ! return 4; ! else ! return 0; ! } else return 0; *************** *** 2887,2891 **** #define MILLI_START 10 ! static int import_milli (code) enum millicodes code; --- 3022,3026 ---- #define MILLI_START 10 ! static void import_milli (code) enum millicodes code; *************** *** 2906,2916 **** char * ! output_mul_insn (unsignedp) int unsignedp; { if (unsignedp) { import_milli (mulU); ! return "bl $$mulU,31%#"; } else --- 3041,3054 ---- char * ! output_mul_insn (unsignedp, insn) int unsignedp; + rtx insn; { + if (unsignedp) { import_milli (mulU); ! return output_call (insn, gen_rtx (SYMBOL_REF, SImode, "$$mulU"), ! gen_rtx (REG, SImode, 31)); } else *************** *** 2917,2921 **** { import_milli (mulI); ! return "bl $$mulI,31%#"; } } --- 3055,3060 ---- { import_milli (mulI); ! return output_call (insn, gen_rtx (SYMBOL_REF, SImode, "$$mulI"), ! gen_rtx (REG, SImode, 31)); } } *************** *** 2978,2984 **** char * ! output_div_insn (operands, unsignedp) rtx *operands; int unsignedp; { int divisor; --- 3117,3124 ---- char * ! output_div_insn (operands, unsignedp, insn) rtx *operands; int unsignedp; + rtx insn; { int divisor; *************** *** 2988,2994 **** --- 3128,3136 ---- if (GET_CODE (operands[0]) == CONST_INT) { + static char buf[100]; divisor = INTVAL (operands[0]); if (!div_milli[divisor][unsignedp]) { + div_milli[divisor][unsignedp] = 1; if (unsignedp) output_asm_insn (".IMPORT $$divU_%0,MILLICODE", operands); *************** *** 2995,3003 **** else output_asm_insn (".IMPORT $$divI_%0,MILLICODE", operands); - div_milli[divisor][unsignedp] = 1; } if (unsignedp) ! return "bl $$divU_%0,31%#"; ! return "bl $$divI_%0,31%#"; } /* Divisor isn't a special constant. */ --- 3137,3153 ---- else output_asm_insn (".IMPORT $$divI_%0,MILLICODE", operands); } if (unsignedp) ! { ! sprintf (buf, "$$divU_%d", INTVAL (operands[0])); ! return output_call (insn, gen_rtx (SYMBOL_REF, SImode, buf), ! gen_rtx (REG, SImode, 31)); ! } ! else ! { ! sprintf (buf, "$$divI_%d", INTVAL (operands[0])); ! return output_call (insn, gen_rtx (SYMBOL_REF, SImode, buf), ! gen_rtx (REG, SImode, 31)); ! } } /* Divisor isn't a special constant. */ *************** *** 3007,3011 **** { import_milli (divU); ! return "bl $$divU,31%#"; } else --- 3157,3162 ---- { import_milli (divU); ! return output_call (insn, gen_rtx (SYMBOL_REF, SImode, "$$divU"), ! gen_rtx (REG, SImode, 31)); } else *************** *** 3012,3016 **** { import_milli (divI); ! return "bl $$divI,31%#"; } } --- 3163,3168 ---- { import_milli (divI); ! return output_call (insn, gen_rtx (SYMBOL_REF, SImode, "$$divI"), ! gen_rtx (REG, SImode, 31)); } } *************** *** 3020,3025 **** char * ! output_mod_insn (unsignedp) int unsignedp; { if (unsignedp) --- 3172,3178 ---- char * ! output_mod_insn (unsignedp, insn) int unsignedp; + rtx insn; { if (unsignedp) *************** *** 3026,3030 **** { import_milli (remU); ! return "bl $$remU,31%#"; } else --- 3179,3184 ---- { import_milli (remU); ! return output_call (insn, gen_rtx (SYMBOL_REF, SImode, "$$remU"), ! gen_rtx (REG, SImode, 31)); } else *************** *** 3031,3035 **** { import_milli (remI); ! return "bl $$remI,31%#"; } } --- 3185,3190 ---- { import_milli (remI); ! return output_call (insn, gen_rtx (SYMBOL_REF, SImode, "$$remI"), ! gen_rtx (REG, SImode, 31)); } } *************** *** 3051,3058 **** prev_insn = PREV_INSN (prev_insn)) { ! if (!(GET_CODE (PATTERN (prev_insn)) == USE && ! GET_CODE (XEXP (PATTERN (prev_insn), 0)) == REG && ! FUNCTION_ARG_REGNO_P (REGNO (XEXP (PATTERN (prev_insn), 0))))) break; arg_mode = GET_MODE (XEXP (PATTERN (prev_insn), 0)); regno = REGNO (XEXP (PATTERN (prev_insn), 0)); --- 3206,3227 ---- prev_insn = PREV_INSN (prev_insn)) { ! /* Terminate search for arguments if a non-USE insn is encountered ! or a USE insn which does not specify an argument, STATIC_CHAIN, ! or STRUCT_VALUE register. */ ! if (!(GET_CODE (PATTERN (prev_insn)) == USE ! && GET_CODE (XEXP (PATTERN (prev_insn), 0)) == REG ! && (FUNCTION_ARG_REGNO_P (REGNO (XEXP (PATTERN (prev_insn), 0))) ! || REGNO (XEXP (PATTERN (prev_insn), 0)) == STATIC_CHAIN_REGNUM ! || REGNO (XEXP (PATTERN (prev_insn), 0)) ! == STRUCT_VALUE_REGNUM))) break; + + /* If this is a USE for the STATIC_CHAIN or STRUCT_VALUE register, + then skip it and continue the loop since those are not encoded + in the argument relocation bits. */ + if (REGNO (XEXP (PATTERN (prev_insn), 0)) == STATIC_CHAIN_REGNUM + || REGNO (XEXP (PATTERN (prev_insn), 0)) == STRUCT_VALUE_REGNUM) + continue; + arg_mode = GET_MODE (XEXP (PATTERN (prev_insn), 0)); regno = REGNO (XEXP (PATTERN (prev_insn), 0)); *************** *** 3069,3073 **** else { ! #ifdef HP_FP_ARG_DESCRIPTOR_REVERSED arg_regs[regno - 33] = "FR"; arg_regs[regno - 32] = "FU"; --- 3238,3242 ---- else { ! #ifndef HP_FP_ARG_DESCRIPTOR_REVERSED arg_regs[regno - 33] = "FR"; arg_regs[regno - 32] = "FU"; *************** *** 3084,3088 **** else { ! #ifdef HP_FP_ARG_DESCRIPTOR_REVERSED arg_regs[(regno - 46) / 2] = "FR"; arg_regs[(regno - 46) / 2 + 1] = "FU"; --- 3253,3257 ---- else { ! #ifndef HP_FP_ARG_DESCRIPTOR_REVERSED arg_regs[(regno - 46) / 2] = "FR"; arg_regs[(regno - 46) / 2 + 1] = "FU"; *************** *** 3118,3122 **** int regno = true_regnum (in); ! if ((TARGET_SHARED_LIBS && function_label_operand (in, mode)) || ((regno >= FIRST_PSEUDO_REGISTER || regno == -1) && GET_MODE_CLASS (mode) == MODE_INT --- 3287,3291 ---- int regno = true_regnum (in); ! if (function_label_operand (in, mode) || ((regno >= FIRST_PSEUDO_REGISTER || regno == -1) && GET_MODE_CLASS (mode) == MODE_INT *************** *** 3128,3132 **** in = XEXP (in, 0); ! if (TARGET_KERNEL && class != R1_REGS && symbolic_operand (in, VOIDmode)) return R1_REGS; --- 3297,3301 ---- in = XEXP (in, 0); ! if (class != R1_REGS && symbolic_operand (in, VOIDmode)) return R1_REGS; *************** *** 3169,3173 **** tree arglist; { ! rtx block, float_addr, offset, float_mem; tree fntype = TREE_TYPE (current_function_decl); int argadj = ((!(TYPE_ARG_TYPES (fntype) != 0 --- 3338,3342 ---- tree arglist; { ! rtx offset; tree fntype = TREE_TYPE (current_function_decl); int argadj = ((!(TYPE_ARG_TYPES (fntype) != 0 *************** *** 3186,3190 **** plus_constant (current_function_internal_arg_pointer, -16)), ! 4); return copy_to_reg (expand_binop (Pmode, add_optab, current_function_internal_arg_pointer, --- 3355,3359 ---- plus_constant (current_function_internal_arg_pointer, -16)), ! 4, 4 * UNITS_PER_WORD); return copy_to_reg (expand_binop (Pmode, add_optab, current_function_internal_arg_pointer, *************** *** 3204,3217 **** int nullify, length, negated; rtx insn; ! { static char buf[100]; int useskip = 0; /* A forward branch over a single nullified insn can be done with a comclr instruction. This avoids a single cycle penalty due to mis-predicted branch if we fall through (branch not taken). */ ! ! if (length == 1 ! && JUMP_LABEL (insn) == next_nonnote_insn (NEXT_INSN (insn)) && nullify) useskip = 1; --- 3373,3405 ---- int nullify, length, negated; rtx insn; ! { static char buf[100]; int useskip = 0; + /* A conditional branch to the following instruction (eg the delay slot) is + asking for a disaster. This can happen when not optimizing. + + In such cases it is safe to emit nothing. */ + + if (JUMP_LABEL (insn) == next_nonnote_insn (insn)) + return ""; + + /* If this is a long branch with its delay slot unfilled, set `nullify' + as it can nullify the delay slot and save a nop. */ + if (length == 8 && dbr_sequence_length () == 0) + nullify = 1; + + /* If this is a short forward conditional branch which did not get + its delay slot filled, the delay slot can still be nullified. */ + if (! nullify && length == 4 && dbr_sequence_length () == 0) + nullify = forward_branch_p (insn); + /* A forward branch over a single nullified insn can be done with a comclr instruction. This avoids a single cycle penalty due to mis-predicted branch if we fall through (branch not taken). */ ! if (length == 4 ! && next_real_insn (insn) != 0 ! && get_attr_length (next_real_insn (insn)) == 4 ! && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn)) && nullify) useskip = 1; *************** *** 3219,3225 **** switch (length) { ! ! /* Short conditional branch. May nullify either direction. */ ! case 1: if (useskip) strcpy (buf, "com%I2clr,"); --- 3407,3413 ---- switch (length) { ! /* All short conditional branches except backwards with an unfilled ! delay slot. */ ! case 4: if (useskip) strcpy (buf, "com%I2clr,"); *************** *** 3235,3268 **** strcat (buf, ",n %2,%1,%0"); else ! strcat (buf, " %2,%1,%0%#"); ! break; ! ! /* Long conditional branch, possible forward nullification. Also ! note all conditional branches have a length of 4 when not ! optimizing! */ ! case 2: ! case 4: ! strcpy (buf, "com%I2clr,"); ! if (negated) ! strcat (buf, "%S3"); ! else ! strcat (buf, "%B3"); ! /* Nullify the delay slot if the delay slot was explicitly ! nullified by the delay branch scheduler or if no insn ! could be placed in the delay slot. */ ! if (nullify) ! strcat (buf, " %2,%1,0\n\tbl,n %0,0"); ! else ! strcat (buf, " %2,%1,0\n\tbl%* %0,0"); break; ! /* Long backward conditional branch with nullification. */ ! case 3: ! strcpy (buf, "com%I2b,"); ! if (negated) ! strcat (buf, "%S3"); else ! strcat (buf, "%B3"); ! strcat (buf, " %2,%1,.+16\n\tnop\n\t bl %0,0"); break; --- 3423,3458 ---- strcat (buf, ",n %2,%1,%0"); else ! strcat (buf, " %2,%1,%0"); break; ! /* All long conditionals. Note an short backward branch with an ! unfilled delay slot is treated just like a long backward branch ! with an unfilled delay slot. */ ! case 8: ! /* Handle weird backwards branch with a filled delay slot ! with is nullified. */ ! if (dbr_sequence_length () != 0 ! && ! forward_branch_p (insn) ! && nullify) ! { ! strcpy (buf, "com%I2b,"); ! if (negated) ! strcat (buf, "%S3"); ! else ! strcat (buf, "%B3"); ! strcat (buf, ",n %2,%1,.+12\n\tbl %0,0"); ! } else ! { ! strcpy (buf, "com%I2clr,"); ! if (negated) ! strcat (buf, "%S3"); ! else ! strcat (buf, "%B3"); ! if (nullify) ! strcat (buf, " %2,%1,0\n\tbl,n %0,0"); ! else ! strcat (buf, " %2,%1,0\n\tbl %0,0"); ! } break; *************** *** 3269,3273 **** default: abort(); ! } return buf; } --- 3459,3463 ---- default: abort(); ! } return buf; } *************** *** 3284,3291 **** rtx insn; int which; ! { static char buf[100]; int useskip = 0; /* A forward branch over a single nullified insn can be done with a extrs instruction. This avoids a single cycle penalty due to --- 3474,3499 ---- rtx insn; int which; ! { static char buf[100]; int useskip = 0; + /* A conditional branch to the following instruction (eg the delay slot) is + asking for a disaster. I do not think this can happen as this pattern + is only used when optimizing; jump optimization should eliminate the + jump. But be prepared just in case. */ + + if (JUMP_LABEL (insn) == next_nonnote_insn (insn)) + return ""; + + /* If this is a long branch with its delay slot unfilled, set `nullify' + as it can nullify the delay slot and save a nop. */ + if (length == 8 && dbr_sequence_length () == 0) + nullify = 1; + + /* If this is a short forward conditional branch which did not get + its delay slot filled, the delay slot can still be nullified. */ + if (! nullify && length == 4 && dbr_sequence_length () == 0) + nullify = forward_branch_p (insn); + /* A forward branch over a single nullified insn can be done with a extrs instruction. This avoids a single cycle penalty due to *************** *** 3292,3297 **** mis-predicted branch if we fall through (branch not taken). */ ! if (length == 1 ! && JUMP_LABEL (insn) == next_nonnote_insn (NEXT_INSN (insn)) && nullify) useskip = 1; --- 3500,3507 ---- mis-predicted branch if we fall through (branch not taken). */ ! if (length == 4 ! && next_real_insn (insn) != 0 ! && get_attr_length (next_real_insn (insn)) == 4 ! && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn)) && nullify) useskip = 1; *************** *** 3300,3305 **** { ! /* Short conditional branch. May nullify either direction. */ ! case 1: if (useskip) strcpy (buf, "extrs,"); --- 3510,3516 ---- { ! /* All short conditional branches except backwards with an unfilled ! delay slot. */ ! case 4: if (useskip) strcpy (buf, "extrs,"); *************** *** 3318,3362 **** strcat (buf, ",n %0,%1,%2"); else if (! nullify && negated) ! strcat (buf, "%0,%1,%3%#"); else if (! nullify && ! negated) ! strcat (buf, " %0,%1,%2%#"); ! break; ! ! /* Long conditional branch, possible forward nullification. Also ! note all conditional branches have a length of 4 when not ! optimizing! */ ! case 2: ! case 4: ! strcpy (buf, "extrs,"); ! if ((which == 0 && negated) ! || (which == 1 && ! negated)) ! strcat (buf, "<"); ! else ! strcat (buf, ">="); ! /* Nullify the delay slot if the delay slot was explicitly ! nullified by the delay branch scheduler or if no insn ! could be placed in the delay slot. */ ! if (nullify && negated) ! strcat (buf, " %0,%1,1,0\n\tbl,n %3,0"); ! else if (nullify && ! negated) ! strcat (buf, " %0,%1,1,0\n\tbl,n %2,0"); ! else if (negated) ! strcat (buf, " %0,%1,1,0\n\tbl%* %3,0"); ! else ! strcat (buf, " %0,%1,1,0\n\tbl%* %2,0"); break; ! /* Long backward conditional branch with nullification. */ ! case 3: ! strcpy (buf, "bb,"); ! if ((which == 0 && negated) ! || (which == 1 && ! negated)) ! strcat (buf, "<"); ! else ! strcat (buf, ">="); ! if (negated) ! strcat (buf, " %0,%1,.+16\n\tnop\n\t bl %3,0"); else ! strcat (buf, " %0,%1,.+16\n\tnop\n\t bl %2,0"); break; --- 3529,3575 ---- strcat (buf, ",n %0,%1,%2"); else if (! nullify && negated) ! strcat (buf, "%0,%1,%3"); else if (! nullify && ! negated) ! strcat (buf, " %0,%1,%2"); break; ! /* All long conditionals. Note an short backward branch with an ! unfilled delay slot is treated just like a long backward branch ! with an unfilled delay slot. */ ! case 8: ! /* Handle weird backwards branch with a filled delay slot ! with is nullified. */ ! if (dbr_sequence_length () != 0 ! && ! forward_branch_p (insn) ! && nullify) ! { ! strcpy (buf, "bb,"); ! if ((which == 0 && negated) ! || (which == 1 && ! negated)) ! strcat (buf, "<"); ! else ! strcat (buf, ">="); ! if (negated) ! strcat (buf, " %0,%1,.+12\n\tbl %3,0"); ! else ! strcat (buf, " %0,%1,.+12\n\tbl %2,0"); ! } else ! { ! strcpy (buf, "extrs,"); ! if ((which == 0 && negated) ! || (which == 1 && ! negated)) ! strcat (buf, "<"); ! else ! strcat (buf, ">="); ! if (nullify && negated) ! strcat (buf, " %0,%1,1,0\n\tbl,n %3,0"); ! else if (nullify && ! negated) ! strcat (buf, " %0,%1,1,0\n\tbl,n %2,0"); ! else if (negated) ! strcat (buf, " %0,%1,1,0\n\tbl %3,0"); ! else ! strcat (buf, " %0,%1,1,0\n\tbl %2,0"); ! } break; *************** *** 3363,3370 **** default: abort(); ! } return buf; } extern struct obstack *saveable_obstack; --- 3576,3837 ---- default: abort(); ! } return buf; } + /* Return the output template for emitting a dbra type insn. + + Note it may perform some output operations on its own before + returning the final output string. */ + char * + output_dbra (operands, insn, which_alternative) + rtx *operands; + rtx insn; + int which_alternative; + { + + /* A conditional branch to the following instruction (eg the delay slot) is + asking for a disaster. Be prepared! */ + + if (JUMP_LABEL (insn) == next_nonnote_insn (insn)) + { + if (which_alternative == 0) + return "ldo %1(%0),%0"; + else if (which_alternative == 1) + { + output_asm_insn ("fstws %0,-16(0,%%r30)",operands); + output_asm_insn ("ldw -16(0,%%r30),%4",operands); + output_asm_insn ("ldo %1(%4),%4\n\tstw %4,-16(0,%%r30)", operands); + return "fldws -16(0,%%r30),%0"; + } + else + { + output_asm_insn ("ldw %0,%4", operands); + return "ldo %1(%4),%4\n\tstw %4,%0"; + } + } + + if (which_alternative == 0) + { + int nullify = INSN_ANNULLED_BRANCH_P (insn); + int length = get_attr_length (insn); + + /* If this is a long branch with its delay slot unfilled, set `nullify' + as it can nullify the delay slot and save a nop. */ + if (length == 8 && dbr_sequence_length () == 0) + nullify = 1; + + /* If this is a short forward conditional branch which did not get + its delay slot filled, the delay slot can still be nullified. */ + if (! nullify && length == 4 && dbr_sequence_length () == 0) + nullify = forward_branch_p (insn); + + /* Handle short versions first. */ + if (length == 4 && nullify) + return "addib,%C2,n %1,%0,%3"; + else if (length == 4 && ! nullify) + return "addib,%C2 %1,%0,%3"; + else if (length == 8) + { + /* Handle weird backwards branch with a fulled delay slot + which is nullified. */ + if (dbr_sequence_length () != 0 + && ! forward_branch_p (insn) + && nullify) + return "addib,%N2,n %1,%0,.+12\n\tbl %3,0"; + + /* Handle normal cases. */ + if (nullify) + return "addi,%N2 %1,%0,%0\n\tbl,n %3,0"; + else + return "addi,%N2 %1,%0,%0\n\tbl %3,0"; + } + else + abort(); + } + /* Deal with gross reload from FP register case. */ + else if (which_alternative == 1) + { + /* Move loop counter from FP register to MEM then into a GR, + increment the GR, store the GR into MEM, and finally reload + the FP register from MEM from within the branch's delay slot. */ + output_asm_insn ("fstws %0,-16(0,%%r30)\n\tldw -16(0,%%r30),%4",operands); + output_asm_insn ("ldo %1(%4),%4\n\tstw %4,-16(0,%%r30)", operands); + if (get_attr_length (insn) == 24) + return "comb,%S2 0,%4,%3\n\tfldws -16(0,%%r30),%0"; + else + return "comclr,%B2 0,%4,0\n\tbl %3,0\n\tfldws -16(0,%%r30),%0"; + } + /* Deal with gross reload from memory case. */ + else + { + /* Reload loop counter from memory, the store back to memory + happens in the branch's delay slot. */ + output_asm_insn ("ldw %0,%4", operands); + if (get_attr_length (insn) == 12) + return "addib,%C2 %1,%4,%3\n\tstw %4,%0"; + else + return "addi,%N2 %1,%4,%0\n\tbl %3,0\n\tstw %4,%0"; + } + } + + /* Return the output template for emitting a dbra type insn. + + Note it may perform some output operations on its own before + returning the final output string. */ + char * + output_movb (operands, insn, which_alternative, reverse_comparison) + rtx *operands; + rtx insn; + int which_alternative; + int reverse_comparison; + { + + /* A conditional branch to the following instruction (eg the delay slot) is + asking for a disaster. Be prepared! */ + + if (JUMP_LABEL (insn) == next_nonnote_insn (insn)) + { + if (which_alternative == 0) + return "copy %1,%0"; + else if (which_alternative == 1) + { + output_asm_insn ("stw %1,-16(0,%%r30)",operands); + return "fldws -16(0,%%r30),%0"; + } + else + return "stw %1,%0"; + } + + /* Support the second variant. */ + if (reverse_comparison) + PUT_CODE (operands[2], reverse_condition (GET_CODE (operands[2]))); + + if (which_alternative == 0) + { + int nullify = INSN_ANNULLED_BRANCH_P (insn); + int length = get_attr_length (insn); + + /* If this is a long branch with its delay slot unfilled, set `nullify' + as it can nullify the delay slot and save a nop. */ + if (length == 8 && dbr_sequence_length () == 0) + nullify = 1; + + /* If this is a short forward conditional branch which did not get + its delay slot filled, the delay slot can still be nullified. */ + if (! nullify && length == 4 && dbr_sequence_length () == 0) + nullify = forward_branch_p (insn); + + /* Handle short versions first. */ + if (length == 4 && nullify) + return "movb,%C2,n %1,%0,%3"; + else if (length == 4 && ! nullify) + return "movb,%C2 %1,%0,%3"; + else if (length == 8) + { + /* Handle weird backwards branch with a fulled delay slot + which is nullified. */ + if (dbr_sequence_length () != 0 + && ! forward_branch_p (insn) + && nullify) + return "movb,%N2,n %1,%0,.+12\n\ttbl %3,0"; + + /* Handle normal cases. */ + if (nullify) + return "or,%N2 %1,%%r0,%0\n\tbl,n %3,0"; + else + return "or,%N2 %1,%%r0,%0\n\tbl %3,0"; + } + else + abort(); + } + /* Deal with gross reload from FP register case. */ + else if (which_alternative == 1) + { + /* Move loop counter from FP register to MEM then into a GR, + increment the GR, store the GR into MEM, and finally reload + the FP register from MEM from within the branch's delay slot. */ + output_asm_insn ("stw %1,-16(0,%%r30)",operands); + if (get_attr_length (insn) == 12) + return "comb,%S2 0,%1,%3\n\tfldws -16(0,%%r30),%0"; + else + return "comclr,%B2 0,%1,0\n\tbl %3,0\n\tfldws -16(0,%%r30),%0"; + } + /* Deal with gross reload from memory case. */ + else + { + /* Reload loop counter from memory, the store back to memory + happens in the branch's delay slot. */ + if (get_attr_length (insn) == 8) + return "comb,%S2 0,%1,%3\n\tstw %1,%0"; + else + return "comclr,%B2 0,%1,0\n\tbl %3,0\n\tstw %1,%0"; + } + } + + + /* INSN is either a function call or a millicode call. It may have an + unconditional jump in its delay slot. + + CALL_DEST is the routine we are calling. + + RETURN_POINTER is the register which will hold the return address. + %r2 for most calls, %r31 for millicode calls. */ + char * + output_call (insn, call_dest, return_pointer) + rtx insn; + rtx call_dest; + rtx return_pointer; + + { + int distance; + rtx xoperands[4]; + rtx seq_insn; + + /* Handle common case -- empty delay slot or no jump in the delay slot. */ + if (dbr_sequence_length () == 0 + || (dbr_sequence_length () != 0 + && GET_CODE (NEXT_INSN (insn)) != JUMP_INSN)) + { + xoperands[0] = call_dest; + xoperands[1] = return_pointer; + output_asm_insn ("bl %0,%r1%#", xoperands); + return ""; + } + + /* This call has an unconditional jump in its delay slot. */ + + /* Use the containing sequence insn's address. */ + seq_insn = NEXT_INSN (PREV_INSN (XVECEXP (final_sequence, 0, 0))); + + distance = insn_addresses[INSN_UID (JUMP_LABEL (NEXT_INSN (insn)))] + - insn_addresses[INSN_UID (seq_insn)] - 8; + + /* If the branch was too far away, emit a normal call followed + by a nop, followed by the unconditional branch. + + If the branch is close, then adjust %r2 from within the + call's delay slot. */ + + xoperands[0] = call_dest; + xoperands[1] = XEXP (PATTERN (NEXT_INSN (insn)), 1); + xoperands[2] = return_pointer; + if (! VAL_14_BITS_P (distance)) + output_asm_insn ("bl %0,%r2\n\tnop\n\tbl,n %1,%%r0", xoperands); + else + { + xoperands[3] = gen_label_rtx (); + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", + CODE_LABEL_NUMBER (xoperands[3])); + output_asm_insn ("\n\tbl %0,%r2\n\tldo %1-%3-8(%r2),%r2", xoperands); + } + + /* Delete the jump. */ + PUT_CODE (NEXT_INSN (insn), NOTE); + NOTE_LINE_NUMBER (NEXT_INSN (insn)) = NOTE_INSN_DELETED; + NOTE_SOURCE_FILE (NEXT_INSN (insn)) = 0; + return ""; + } + extern struct obstack *saveable_obstack; *************** *** 3509,3510 **** --- 3976,4039 ---- return (GET_CODE (op) == CONST_INT && shadd_constant_p (INTVAL (op))); } + + /* Return 1 if INSN branches forward. Should be using insn_addresses + to avoid walking through all the insns... */ + int + forward_branch_p (insn) + rtx insn; + { + rtx label = JUMP_LABEL (insn); + + while (insn) + { + if (insn == label) + break; + else + insn = NEXT_INSN (insn); + } + + return (insn == label); + } + + /* Return 1 if OP is an equality comparison, else return 0. */ + int + eq_neq_comparison_operator (op, mode) + rtx op; + enum machine_mode mode; + { + return (GET_CODE (op) == EQ || GET_CODE (op) == NE); + } + + /* Return 1 if OP is an operator suitable for use in a movb instruction. */ + int + movb_comparison_operator (op, mode) + rtx op; + enum machine_mode mode; + { + return (GET_CODE (op) == EQ || GET_CODE (op) == NE + || GET_CODE (op) == LT || GET_CODE (op) == GE); + } + + /* Return 1 if INSN is in the delay slot of a call instruction. */ + int + jump_in_call_delay (insn) + rtx insn; + { + + if (GET_CODE (insn) != JUMP_INSN) + return 0; + + if (PREV_INSN (insn) + && PREV_INSN (PREV_INSN (insn)) + && GET_CODE (next_active_insn (PREV_INSN (PREV_INSN (insn)))) == INSN) + { + rtx test_insn = next_active_insn (PREV_INSN (PREV_INSN (insn))); + + return (GET_CODE (PATTERN (test_insn)) == SEQUENCE + && XVECEXP (PATTERN (test_insn), 0, 1) == insn); + + } + else + return 0; + } + diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/pa/pa.h gcc-2.5.0/config/pa/pa.h *** gcc-2.4.5/config/pa/pa.h Thu Jun 17 03:14:46 1993 --- gcc-2.5.0/config/pa/pa.h Wed Oct 20 18:08:40 1993 *************** *** 48,63 **** #define TARGET_DISABLE_FPREGS (target_flags & 2) ! /* Force gcc to only use instructions which are safe when compiling kernels. ! Specifically, avoid using add instructions with dp (r27) as an argument. ! Use addil instructions instead. Doing so avoids a nasty bug in the ! HPUX linker. When HP fixes their linker take this option out. */ - #define TARGET_KERNEL (target_flags & 4) - - /* Generate code that will link against HPUX 8.0 shared libraries. - Older linkers and assemblers might not support this. */ - - #define TARGET_SHARED_LIBS 1 /* was (target_flags & 8) */ - /* Force all function calls to indirect addressing via a register. This avoids lossage when the function is very far away from the current PC. --- 48,54 ---- #define TARGET_DISABLE_FPREGS (target_flags & 2) ! /* Allow unconditional jumps in the delay slots of call instructions. */ ! #define TARGET_JUMP_IN_DELAY (target_flags & 8) /* Force all function calls to indirect addressing via a register. This avoids lossage when the function is very far away from the current PC. *************** *** 68,83 **** #define TARGET_LONG_CALLS (target_flags & 16) ! /* Disable indexed addressing modes. Necessary under MACH. ! ! ??? Some problem with a high bit being set in an address having ! special meaning to the PA MACH ports. */ #define TARGET_DISABLE_INDEXING (target_flags & 32) ! /* Force a colon to be tacked onto the end of local and global ! labels. An option because the HP assembler croaks on them. */ ! #define TARGET_TRAILING_COLON (target_flags & 64) /* Macro to define tables used to set the flags. This is a list in braces of pairs in braces, --- 59,75 ---- #define TARGET_LONG_CALLS (target_flags & 16) ! /* Disable indexed addressing modes. */ #define TARGET_DISABLE_INDEXING (target_flags & 32) ! /* Emit directives only understood by GAS. This allows parameter ! relocations to work for static functions. There is no way ! to make them work the HP assembler at this time. ! Also forces a colon to be tacked onto the end of local and ! global labes. */ + #define TARGET_GAS (target_flags & 128) + /* Macro to define tables used to set the flags. This is a list in braces of pairs in braces, *************** *** 87,109 **** #define TARGET_SWITCHES \ ! {{"snake", 1}, \ ! {"nosnake", -1}, \ ! {"pa-risc-1-0", -1}, \ ! {"pa-risc-1-1", 1}, \ ! {"disable-fpregs", 2},\ ! {"kernel", 4}, \ ! {"shared-libs", 8}, \ ! {"no-shared-libs", -8},\ ! {"long-calls", 16}, \ ! {"disable-indexing", 32},\ ! {"trailing-colon", 64},\ { "", TARGET_DEFAULT}} #ifndef TARGET_DEFAULT ! #define TARGET_DEFAULT 0 #endif #define DBX_DEBUGGING_INFO ! #define DEFAULT_GDB_EXTENSIONS 0 #if (TARGET_DEFAULT & 1) == 0 --- 79,104 ---- #define TARGET_SWITCHES \ ! {{"snake", 1}, \ ! {"nosnake", -1}, \ ! {"pa-risc-1-0", -1}, \ ! {"pa-risc-1-1", 1}, \ ! {"disable-fpregs", 2}, \ ! {"no-disable-fpregs", 2}, \ ! {"jump-in-delay", 8}, \ ! {"no-jump-in-delay", -8}, \ ! {"long-calls", 16}, \ ! {"no-long-calls", -16}, \ ! {"disable-indexing", 32}, \ ! {"no-disable-indexing", -32},\ ! {"gas", 128}, \ ! {"no-gas", -128}, \ { "", TARGET_DEFAULT}} #ifndef TARGET_DEFAULT ! #define TARGET_DEFAULT 128 /* TARGET_GAS + TARGET_JUMP_IN_DELAY */ #endif #define DBX_DEBUGGING_INFO ! #define DEFAULT_GDB_EXTENSIONS 1 #if (TARGET_DEFAULT & 1) == 0 *************** *** 120,123 **** --- 115,121 ---- #define LINK_SPEC "-u main" + /* Allow $ in identifiers. */ + #define DOLLARS_IN_IDENTIFIERS 2 + /* Make gcc agree with */ *************** *** 127,130 **** --- 125,143 ---- #define WCHAR_TYPE_SIZE 16 + /* Sometimes certain combinations of command options do not make sense + on a particular target machine. You can define a macro + `OVERRIDE_OPTIONS' to take account of this. This macro, if + defined, is executed once just after all the command options have + been parsed. + + On the PA, it is used to explicitly warn the user that -fpic and -fPIC + do not work. */ + + #define OVERRIDE_OPTIONS \ + { \ + if (flag_pic != 0) \ + warning ("-fpic and -fPIC are not supported on the PA."); \ + } + /* Omit frame pointer at high optimization levels. */ *************** *** 137,141 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -Dunix -D_HPUX_SOURCE -Dhp9000 -Dhp800 -Dspectrum -DREVARGV" /* target machine storage layout */ --- 150,154 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -Dunix -D_HPUX_SOURCE -Dhp9000 -Dhp800 -Dspectrum -DREVARGV -Asystem(unix) -Asystem(bsd) -Acpu(hppa) -Amachine(hppa)" /* target machine storage layout */ *************** *** 179,183 **** /* Boundary (in *bits*) on which stack pointer should be aligned. */ ! #define STACK_BOUNDARY (TARGET_SNAKE ? 512 : 64) /* Allocation boundary (in *bits*) for the code of a function. */ --- 192,196 ---- /* Boundary (in *bits*) on which stack pointer should be aligned. */ ! #define STACK_BOUNDARY 512 /* Allocation boundary (in *bits*) for the code of a function. */ *************** *** 789,793 **** ? gen_rtx (REG, (MODE), \ (FUNCTION_ARG_SIZE ((MODE), (TYPE)) > 1 \ ! ? ((! (TARGET_SHARED_LIBS && current_call_is_indirect) \ && (MODE) == DFmode) \ ? ((CUM) ? (TARGET_SNAKE ? 50 : 35) \ --- 802,806 ---- ? gen_rtx (REG, (MODE), \ (FUNCTION_ARG_SIZE ((MODE), (TYPE)) > 1 \ ! ? ((! current_call_is_indirect \ && (MODE) == DFmode) \ ? ((CUM) ? (TARGET_SNAKE ? 50 : 35) \ *************** *** 794,798 **** : (TARGET_SNAKE ? 46 : 33)) \ : ((CUM) ? 23 : 25)) \ ! : ((! (TARGET_SHARED_LIBS && current_call_is_indirect) \ && (MODE) == SFmode) \ ? (TARGET_SNAKE ? 44 + 2 * (CUM) : 32 + (CUM)) \ --- 807,811 ---- : (TARGET_SNAKE ? 46 : 33)) \ : ((CUM) ? 23 : 25)) \ ! : ((! current_call_is_indirect \ && (MODE) == SFmode) \ ? (TARGET_SNAKE ? 44 + 2 * (CUM) : 32 + (CUM)) \ *************** *** 834,838 **** /* Output the label for a function definition. */ ! #ifdef HP_FP_ARG_DESCRIPTOR_REVERSED #define ASM_DOUBLE_ARG_DESCRIPTORS(FILE, ARG0, ARG1) \ do { fprintf (FILE, ",ARGW%d=FR", (ARG0)); \ --- 847,851 ---- /* Output the label for a function definition. */ ! #ifndef HP_FP_ARG_DESCRIPTOR_REVERSED #define ASM_DOUBLE_ARG_DESCRIPTORS(FILE, ARG0, ARG1) \ do { fprintf (FILE, ",ARGW%d=FR", (ARG0)); \ *************** *** 849,856 **** tree parm; \ int i; \ ! if (TREE_PUBLIC (DECL)) \ { extern int current_function_varargs; \ ! fputs ("\t.EXPORT ", FILE); assemble_name (FILE, NAME); \ ! fputs (",ENTRY,PRIV_LEV=3", FILE); \ for (parm = DECL_ARGUMENTS (DECL), i = 0; parm && i < 4; \ parm = TREE_CHAIN (parm)) \ --- 862,878 ---- tree parm; \ int i; \ ! if (TREE_PUBLIC (DECL) || TARGET_GAS) \ { extern int current_function_varargs; \ ! if (TREE_PUBLIC (DECL)) \ ! { \ ! fputs ("\t.EXPORT ", FILE); \ ! assemble_name (FILE, NAME); \ ! fputs (",ENTRY,PRIV_LEV=3", FILE); \ ! } \ ! else \ ! { \ ! fputs ("\t.PARAM ", FILE); \ ! assemble_name (FILE, NAME); \ ! } \ for (parm = DECL_ARGUMENTS (DECL), i = 0; parm && i < 4; \ parm = TREE_CHAIN (parm)) \ *************** *** 979,989 **** #define TRAMPOLINE_TEMPLATE(FILE) \ ! { \ ! fprintf (FILE, "\tldw 12(0,%%r22),%%r21\n"); \ ! fprintf (FILE, "\tbe 0(4,%%r21)\n"); \ ! fprintf (FILE, "\tldw 16(0,%%r22),%%r29\n"); \ ! fprintf (FILE, "\t.word 0\n"); \ ! fprintf (FILE, "\t.word 0\n"); \ ! } /* Length in units of the trampoline for entering a nested function. --- 1001,1017 ---- #define TRAMPOLINE_TEMPLATE(FILE) \ ! { \ ! fprintf (FILE, "\tldw 36(0,%%r22),%%r21\n"); \ ! fprintf (FILE, "\tbb,>=,n %%r21,30,.+16\n"); \ ! fprintf (FILE, "\tdepi 0,31,2,%%r21\n"); \ ! fprintf (FILE, "\tldw 4(0,%%r21),%%r19\n"); \ ! fprintf (FILE, "\tldw 0(0,%%r21),%%r21\n"); \ ! fprintf (FILE, "\tldsid (0,%%r21),%%r1\n"); \ ! fprintf (FILE, "\tmtsp %%r1,%%sr0\n"); \ ! fprintf (FILE, "\tbe 0(%%sr0,%%r21)\n"); \ ! fprintf (FILE, "\tldw 40(0,%%r22),%%r29\n"); \ ! fprintf (FILE, "\t.word 0\n"); \ ! fprintf (FILE, "\t.word 0\n"); \ ! } /* Length in units of the trampoline for entering a nested function. *************** *** 993,1000 **** cache lines. ! If the trampoline ever grows to > 32 bytes, then it will become ! necessary to hack on the cacheflush pattern in pa.md. */ ! #define TRAMPOLINE_SIZE (5 * 4) /* Emit RTL insns to initialize the variable parts of a trampoline. --- 1021,1028 ---- cache lines. ! If the code part of the trampoline ever grows to > 32 bytes, then it ! will become necessary to hack on the cacheflush pattern in pa.md. */ ! #define TRAMPOLINE_SIZE (11 * 4) /* Emit RTL insns to initialize the variable parts of a trampoline. *************** *** 1006,1021 **** #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ ! { \ ! rtx start_addr, end_addr, mem; \ ! \ ! start_addr = memory_address (Pmode, plus_constant ((TRAMP), 12));\ ! emit_move_insn (gen_rtx (MEM, Pmode, start_addr), (FNADDR)); \ ! start_addr = memory_address (Pmode, plus_constant ((TRAMP), 16));\ ! emit_move_insn (gen_rtx (MEM, Pmode, start_addr), (CXT)); \ ! /* fdc and fic only use registers for the address to flush, \ ! they do not accept integer displacements. */ \ ! start_addr = force_reg (SImode, (TRAMP)); \ ! end_addr = force_reg (SImode, plus_constant ((TRAMP), 8)); \ ! emit_insn (gen_cacheflush (start_addr, end_addr)); \ } --- 1034,1055 ---- #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ ! { \ ! rtx start_addr, end_addr, masked_start_addr; \ ! \ ! start_addr = memory_address (Pmode, plus_constant ((TRAMP), 36)); \ ! emit_move_insn (gen_rtx (MEM, Pmode, start_addr), (FNADDR)); \ ! start_addr = memory_address (Pmode, plus_constant ((TRAMP), 40)); \ ! emit_move_insn (gen_rtx (MEM, Pmode, start_addr), (CXT)); \ ! /* fdc and fic only use registers for the address to flush, \ ! they do not accept integer displacements. */ \ ! start_addr = force_reg (SImode, (TRAMP)); \ ! end_addr = force_reg (SImode, plus_constant ((TRAMP), 32)); \ ! emit_insn (gen_dcacheflush (start_addr, end_addr)); \ ! masked_start_addr = gen_reg_rtx (SImode); \ ! emit_insn (gen_andsi3 (masked_start_addr, start_addr, \ ! GEN_INT (0x3fffffff))); \ ! end_addr = force_reg (SImode, plus_constant (masked_start_addr, 32)); \ ! emit_insn (gen_icacheflush (masked_start_addr, end_addr, start_addr, \ ! gen_reg_rtx (SImode), gen_reg_rtx (SImode)));\ } *************** *** 1113,1117 **** `R' is unused. ! `S' handles constraints for calls. `T' is for fp loads and stores. */ --- 1147,1151 ---- `R' is unused. ! `S' is unused. `T' is for fp loads and stores. */ *************** *** 1128,1140 **** /* Using DFmode forces only short displacements \ to be recognized as valid in reg+d addresses. */\ ! && memory_address_p (DFmode, XEXP (OP, 0))) \ ! : ((C) == 'S' ? \ ! ((CONSTANT_P (OP) && ! TARGET_LONG_CALLS) \ ! || (reload_in_progress \ ! ? strict_memory_address_p (Pmode, OP) \ ! : memory_address_p (Pmode, OP)) \ ! || (reload_in_progress \ ! && GET_CODE (OP) == REG \ ! && reg_renumber[REGNO (OP)] > 0)) : 0))) /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx --- 1162,1166 ---- /* Using DFmode forces only short displacements \ to be recognized as valid in reg+d addresses. */\ ! && memory_address_p (DFmode, XEXP (OP, 0))) : 0)) /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx *************** *** 1333,1337 **** /* 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 --- 1359,1363 ---- /* Specify the machine mode that this machine uses for the index in the tablejump instruction. */ ! #define CASE_VECTOR_MODE DImode /* Define this if the tablejump instruction expects the table *************** *** 1354,1360 **** #define MOVE_MAX 8 ! /* Define if normal loads of shorter-than-word items from memory clears ! the rest of the bigs in the register. */ ! #define BYTE_LOADS_ZERO_EXTEND /* Nonzero if access to memory by bytes is slow and undesirable. */ --- 1380,1392 ---- #define MOVE_MAX 8 ! /* Define if operations between registers always perform the operation ! on the full register even if a narrower mode is specified. */ ! #define WORD_REGISTER_OPERATIONS ! ! /* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD ! will either zero-extend or sign-extend. The value of this macro should ! be the code that says which one of the two operations is implicitly ! done, NIL if none. */ ! #define LOAD_EXTEND_OP(MODE) ZERO_EXTEND /* Nonzero if access to memory by bytes is slow and undesirable. */ *************** *** 1408,1414 **** #define NO_FUNCTION_CSE ! /* Define this if shift instructions ignore all but the low-order few bits. */ ! #define SHIFT_COUNT_TRUNCATED /* Use atexit for static constructors/destructors, instead of defining --- 1440,1446 ---- #define NO_FUNCTION_CSE ! /* Define this to be nonzero if shift instructions ignore all but the low-order few bits. */ ! #define SHIFT_COUNT_TRUNCATED 1 /* Use atexit for static constructors/destructors, instead of defining *************** *** 1553,1556 **** --- 1585,1607 ---- #define TEXT_SECTION_ASM_OP "\t.SPACE $TEXT$\n\t.SUBSPA $CODE$\n" + /* Output before read-only data. */ + + /* Supposedly the assembler rejects the command if there is no tab! */ + #define READONLY_DATA_ASM_OP "\t.SPACE $TEXT$\n\t.SUBSPA $LIT$\n" + + #if 0 + /* This has apparently triggered a latent GAS bug which manifests itself + as numerous warnings from the debugger of the form: + + During symbol reading, inner block not inside outer block in ... + inner block not inside outer block in ... + + Or as local variables not being accessable from the debugger. + + Disable $LIT$ for now. Try it with GAS-2 when it is functional (I + am not even going to try to fix this in GAS-1). */ + #define READONLY_DATA_SECTION readonly_data + #endif + /* Output before writable data. */ *************** *** 1564,1568 **** /* Define the .bss section for ASM_OUTPUT_LOCAL to use. */ ! #define EXTRA_SECTIONS in_bss #define EXTRA_SECTION_FUNCTIONS \ --- 1615,1619 ---- /* Define the .bss section for ASM_OUTPUT_LOCAL to use. */ ! #define EXTRA_SECTIONS in_bss, in_readonly_data #define EXTRA_SECTION_FUNCTIONS \ *************** *** 1575,1578 **** --- 1626,1638 ---- in_section = in_bss; \ } \ + } \ + void \ + readonly_data () \ + { \ + if (in_section != in_readonly_data) \ + { \ + fprintf (asm_out_file, "%s\n", READONLY_DATA_ASM_OP); \ + in_section = in_readonly_data; \ + } \ } *************** *** 1606,1610 **** #define ASM_OUTPUT_LABEL(FILE, NAME) \ do { assemble_name (FILE, NAME); \ ! if (TARGET_TRAILING_COLON) \ fputc (':', FILE); \ fputc ('\n', FILE); } while (0) --- 1666,1670 ---- #define ASM_OUTPUT_LABEL(FILE, NAME) \ do { assemble_name (FILE, NAME); \ ! if (TARGET_GAS) \ fputc (':', FILE); \ fputc ('\n', FILE); } while (0) *************** *** 1663,1667 **** #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ {fprintf (FILE, "%s$%04d", PREFIX, NUM); \ ! if (TARGET_TRAILING_COLON) \ fputs (":\n", FILE); \ else \ --- 1723,1727 ---- #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ {fprintf (FILE, "%s$%04d", PREFIX, NUM); \ ! if (TARGET_GAS) \ fputs (":\n", FILE); \ else \ *************** *** 1697,1702 **** #define ASM_OUTPUT_INT(FILE,VALUE) \ { fprintf (FILE, "\t.word "); \ ! if (TARGET_SHARED_LIBS \ ! && function_label_operand (VALUE, VOIDmode))\ fprintf (FILE, "P%%"); \ output_addr_const (FILE, (VALUE)); \ --- 1757,1761 ---- #define ASM_OUTPUT_INT(FILE,VALUE) \ { fprintf (FILE, "\t.word "); \ ! if (function_label_operand (VALUE, VOIDmode)) \ fprintf (FILE, "P%%"); \ output_addr_const (FILE, (VALUE)); \ *************** *** 1761,1765 **** { bss_section (); \ assemble_name ((FILE), (NAME)); \ ! if (TARGET_TRAILING_COLON) \ fputc (':', (FILE)); \ fputs ("\t.comm ", (FILE)); \ --- 1820,1824 ---- { bss_section (); \ assemble_name ((FILE), (NAME)); \ ! if (TARGET_GAS) \ fputc (':', (FILE)); \ fputs ("\t.comm ", (FILE)); \ *************** *** 1773,1777 **** fprintf ((FILE), "\t.align %d\n", (SIZE) <= 4 ? 4 : 8); \ assemble_name ((FILE), (NAME)); \ ! if (TARGET_TRAILING_COLON) \ fputc (':', (FILE)); \ fprintf ((FILE), "\n\t.block %d\n", (ROUNDED));} --- 1832,1836 ---- fprintf ((FILE), "\t.align %d\n", (SIZE) <= 4 ? 4 : 8); \ assemble_name ((FILE), (NAME)); \ ! if (TARGET_GAS) \ fputc (':', (FILE)); \ fprintf ((FILE), "\n\t.block %d\n", (ROUNDED));} *************** *** 1865,1869 **** --- 1924,1931 ---- extern char *output_cbranch (); extern char *output_bb (); + extern char *output_dbra (); + extern char *output_movb (); extern char *output_return (); + extern char *output_call (); extern char *output_floatsisf2 (); extern char *output_floatsidf2 (); diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/pa/pa.md gcc-2.5.0/config/pa/pa.md *** gcc-2.4.5/config/pa/pa.md Thu Jun 17 17:56:47 1993 --- gcc-2.5.0/config/pa/pa.md Wed Oct 20 18:08:52 1993 *************** *** 31,35 **** (define_attr "type" ! "move,unary,binary,compare,load,store,branch,cbranch,fbranch,call,dyncall,fpload,fpstore,fpalu,fpcc,fpmul,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,multi,misc,milli" (const_string "binary")) --- 31,35 ---- (define_attr "type" ! "move,unary,binary,compare,load,store,uncond_branch,branch,cbranch,fbranch,call,dyncall,fpload,fpstore,fpalu,fpcc,fpmul,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,multi,misc,milli" (const_string "binary")) *************** *** 38,59 **** (cond [(eq_attr "type" "load,fpload") (if_then_else (match_operand 1 "symbolic_memory_operand" "") ! (const_int 2) (const_int 1)) (eq_attr "type" "store,fpstore") (if_then_else (match_operand 0 "symbolic_memory_operand" "") ! (const_int 2) (const_int 1)) (eq_attr "type" "binary") (if_then_else (match_operand 2 "arith_operand" "") ! (const_int 1) (const_int 3)) (eq_attr "type" "move,unary") (if_then_else (match_operand 1 "arith_operand" "") ! (const_int 1) (const_int 2))] ! (const_int 1))) (define_asm_attributes ! [(set_attr "length" "1") (set_attr "type" "multi")]) --- 38,59 ---- (cond [(eq_attr "type" "load,fpload") (if_then_else (match_operand 1 "symbolic_memory_operand" "") ! (const_int 8) (const_int 4)) (eq_attr "type" "store,fpstore") (if_then_else (match_operand 0 "symbolic_memory_operand" "") ! (const_int 8) (const_int 4)) (eq_attr "type" "binary") (if_then_else (match_operand 2 "arith_operand" "") ! (const_int 4) (const_int 12)) (eq_attr "type" "move,unary") (if_then_else (match_operand 1 "arith_operand" "") ! (const_int 4) (const_int 8))] ! (const_int 4))) (define_asm_attributes ! [(set_attr "length" "4") (set_attr "type" "multi")]) *************** *** 60,66 **** ;; Attributes for instruction and branch scheduling (define_attr "in_branch_delay" "false,true" ! (if_then_else (and (eq_attr "type" "!branch,cbranch,fbranch,call,dyncall,multi,milli") ! (eq_attr "length" "1")) (const_string "true") (const_string "false"))) --- 60,67 ---- ;; Attributes for instruction and branch scheduling + ;; For conditional branches. (define_attr "in_branch_delay" "false,true" ! (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli") ! (eq_attr "length" "4")) (const_string "true") (const_string "false"))) *************** *** 69,79 **** ;; even if the instruction is nullified. (define_attr "in_nullified_branch_delay" "false,true" ! (if_then_else (and (eq_attr "type" "!branch,cbranch,fbranch,call,dyncall,multi,milli,fpcc,fpalu,fpmul,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl") ! (eq_attr "length" "1")) (const_string "true") (const_string "false"))) ;; Unconditional branch, call, and millicode call delay slot description. ! (define_delay (eq_attr "type" "branch,call,milli") [(eq_attr "in_branch_delay" "true") (nil) (nil)]) --- 70,99 ---- ;; even if the instruction is nullified. (define_attr "in_nullified_branch_delay" "false,true" ! (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,fpcc,fpalu,fpmul,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl") ! (eq_attr "length" "4")) (const_string "true") (const_string "false"))) + ;; For calls and millicode calls. Allow unconditional branches in the + ;; delay slot. + (define_attr "in_call_delay" "false,true" + (cond [(and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli") + (eq_attr "length" "4")) + (const_string "true") + (eq_attr "type" "uncond_branch") + (if_then_else (ne (symbol_ref "TARGET_JUMP_IN_DELAY") + (const_int 0)) + (const_string "true") + (const_string "false"))] + (const_string "false"))) + + + ;; Unconditional branch, call, and millicode call delay slot description. ! (define_delay (eq_attr "type" "uncond_branch,branch,call,milli") ! [(eq_attr "in_call_delay" "true") (nil) (nil)]) ! ! ;; Unconditional branch, return and other similar instructions. ! (define_delay (eq_attr "type" "uncond_branch,branch") [(eq_attr "in_branch_delay" "true") (nil) (nil)]) *************** *** 86,93 **** ;; Integer conditional branch delay slot description. ;; Nullification of conditional branches on the PA is dependent on the ! ;; direction of the branch. Forward branches nullify true (direction > 0), ! ;; and backward branches nullify false (direction < 0). ! ;; If direction == 0, then the direction is unknown and we do not allow ! ;; any nullification. (define_delay (eq_attr "type" "cbranch") [(eq_attr "in_branch_delay" "true") --- 106,112 ---- ;; Integer conditional branch delay slot description. ;; Nullification of conditional branches on the PA is dependent on the ! ;; direction of the branch. Forward branches nullify true and ! ;; backward branches nullify false. If the direction is unknown ! ;; then nullification is not allowed. (define_delay (eq_attr "type" "cbranch") [(eq_attr "in_branch_delay" "true") *************** *** 365,369 **** "com%I2clr,%B3 %2,%1,%0\;ldi 1,%0" [(set_attr "type" "binary") ! (set_attr "length" "2")]) ;; Combiner patterns for common operations performed with the output --- 384,388 ---- "com%I2clr,%B3 %2,%1,%0\;ldi 1,%0" [(set_attr "type" "binary") ! (set_attr "length" "8")]) ;; Combiner patterns for common operations performed with the output *************** *** 377,381 **** "com%I2clr,%B3 %2,%1,%0\;ldi -1,%0" [(set_attr "type" "binary") ! (set_attr "length" "2")]) ;; Patterns for adding/subtracting the result of a boolean expression from --- 396,400 ---- "com%I2clr,%B3 %2,%1,%0\;ldi -1,%0" [(set_attr "type" "binary") ! (set_attr "length" "8")]) ;; Patterns for adding/subtracting the result of a boolean expression from *************** *** 393,397 **** "sub%I3 %3,%2,0\;addc 0,%1,%0" [(set_attr "type" "binary") ! (set_attr "length" "2")]) ; This need only accept registers for op3, since canonicalization --- 412,416 ---- "sub%I3 %3,%2,0\;addc 0,%1,%0" [(set_attr "type" "binary") ! (set_attr "length" "8")]) ; This need only accept registers for op3, since canonicalization *************** *** 405,409 **** "sub %2,%3,0\;addc 0,%1,%0" [(set_attr "type" "binary") ! (set_attr "length" "2")]) ; Match only integers for op3 here. This is used as canonical form of the --- 424,428 ---- "sub %2,%3,0\;addc 0,%1,%0" [(set_attr "type" "binary") ! (set_attr "length" "8")]) ; Match only integers for op3 here. This is used as canonical form of the *************** *** 418,422 **** "addi %k3,%2,0\;addc 0,%1,%0" [(set_attr "type" "binary") ! (set_attr "length" "2")]) (define_insn "incscc" --- 437,441 ---- "addi %k3,%2,0\;addc 0,%1,%0" [(set_attr "type" "binary") ! (set_attr "length" "8")]) (define_insn "incscc" *************** *** 431,435 **** com%I3clr,%B4 %3,%2,0\;addi,tr 1,%1,%0\;copy %1,%0" [(set_attr "type" "binary,binary") ! (set_attr "length" "2,3")]) (define_insn "" --- 450,454 ---- com%I3clr,%B4 %3,%2,0\;addi,tr 1,%1,%0\;copy %1,%0" [(set_attr "type" "binary,binary") ! (set_attr "length" "8,12")]) (define_insn "" *************** *** 441,445 **** "sub%I3 %3,%2,0\;subb %1,0,%0" [(set_attr "type" "binary") ! (set_attr "length" "2")]) ; This need only accept registers for op3, since canonicalization --- 460,464 ---- "sub%I3 %3,%2,0\;subb %1,0,%0" [(set_attr "type" "binary") ! (set_attr "length" "8")]) ; This need only accept registers for op3, since canonicalization *************** *** 453,457 **** "sub %2,%3,0\;subb %1,0,%0" [(set_attr "type" "binary") ! (set_attr "length" "2")]) ; Match only integers for op3 here. This is used as canonical form of the --- 472,476 ---- "sub %2,%3,0\;subb %1,0,%0" [(set_attr "type" "binary") ! (set_attr "length" "8")]) ; Match only integers for op3 here. This is used as canonical form of the *************** *** 466,470 **** "addi %k3,%2,0\;subb %1,0,%0" [(set_attr "type" "binary") ! (set_attr "length" "2")]) (define_insn "decscc" --- 485,489 ---- "addi %k3,%2,0\;subb %1,0,%0" [(set_attr "type" "binary") ! (set_attr "length" "8")]) (define_insn "decscc" *************** *** 479,483 **** com%I3clr,%B4 %3,%2,0\;addi,tr -1,%1,%0\;copy %1,%0" [(set_attr "type" "binary,binary") ! (set_attr "length" "2,3")]) ; Patterns for max and min. (There is no need for an earlyclobber in the --- 498,502 ---- com%I3clr,%B4 %3,%2,0\;addi,tr -1,%1,%0\;copy %1,%0" [(set_attr "type" "binary,binary") ! (set_attr "length" "8,12")]) ; Patterns for max and min. (There is no need for an earlyclobber in the *************** *** 494,498 **** comclr,> %1,%2,%0\;copy %1,%0" [(set_attr "type" "multi,multi,multi") ! (set_attr "length" "2,2,2")]) (define_insn "uminsi3" --- 513,517 ---- comclr,> %1,%2,%0\;copy %1,%0" [(set_attr "type" "multi,multi,multi") ! (set_attr "length" "8,8,8")]) (define_insn "uminsi3" *************** *** 505,509 **** comiclr,>> %2,%0,0\;ldi %2,%0" [(set_attr "type" "multi,multi") ! (set_attr "length" "2,2")]) (define_insn "smaxsi3" --- 524,528 ---- comiclr,>> %2,%0,0\;ldi %2,%0" [(set_attr "type" "multi,multi") ! (set_attr "length" "8,8")]) (define_insn "smaxsi3" *************** *** 517,521 **** comclr,< %1,%2,%0\;copy %1,%0" [(set_attr "type" "multi,multi,multi") ! (set_attr "length" "2,2,2")]) (define_insn "umaxsi3" --- 536,540 ---- comclr,< %1,%2,%0\;copy %1,%0" [(set_attr "type" "multi,multi,multi") ! (set_attr "length" "8,8,8")]) (define_insn "umaxsi3" *************** *** 528,532 **** comiclr,<< %2,%0,0\;ldi %2,%0" [(set_attr "type" "multi,multi") ! (set_attr "length" "2,2")]) ;;; Experimental conditional move patterns --- 547,551 ---- comiclr,<< %2,%0,0\;ldi %2,%0" [(set_attr "type" "multi,multi") ! (set_attr "length" "8,8")]) ;;; Experimental conditional move patterns *************** *** 549,553 **** com%I4clr,%B5 %4,%3,%0\;zdepi %Z1,%0" [(set_attr "type" "multi,multi,multi,multi,multi") ! (set_attr "length" "2,2,2,2,2")]) (define_insn "" --- 568,572 ---- com%I4clr,%B5 %4,%3,%0\;zdepi %Z1,%0" [(set_attr "type" "multi,multi,multi,multi,multi") ! (set_attr "length" "8,8,8,8,8")]) (define_insn "" *************** *** 570,574 **** com%I4clr,%B5 %4,%3,0\;zdepi %Z1,%0" [(set_attr "type" "multi,multi,multi,multi,multi,multi,multi,multi") ! (set_attr "length" "2,2,2,2,2,2,2,2")]) ;; Conditional Branches --- 589,593 ---- com%I4clr,%B5 %4,%3,0\;zdepi %Z1,%0" [(set_attr "type" "multi,multi,multi,multi,multi,multi,multi,multi") ! (set_attr "length" "8,8,8,8,8,8,8,8")]) ;; Conditional Branches *************** *** 744,748 **** ;; Note a long backward conditional branch with an annulled delay slot ! ;; has a length of 3. (define_insn "" [(set (pc) --- 763,767 ---- ;; Note a long backward conditional branch with an annulled delay slot ! ;; has a length of 12. (define_insn "" [(set (pc) *************** *** 761,772 **** [(set_attr "type" "cbranch") (set (attr "length") ! (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 2)))) ! (const_int 1023)) ! (const_int 1) ! (and (lt (match_dup 0) (pc)) ! (eq (symbol_ref "INSN_ANNULLED_BRANCH_P (insn)") ! (const_int 1))) ! (const_int 3)] ! (const_int 2)))]) ;; Match the negated branch. --- 780,787 ---- [(set_attr "type" "cbranch") (set (attr "length") ! (if_then_else (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) ! (const_int 8188)) ! (const_int 4) ! (const_int 8)))]) ;; Match the negated branch. *************** *** 788,799 **** [(set_attr "type" "cbranch") (set (attr "length") ! (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 2)))) ! (const_int 1023)) ! (const_int 1) ! (and (lt (match_dup 0) (pc)) ! (eq (symbol_ref "INSN_ANNULLED_BRANCH_P (insn)") ! (const_int 1))) ! (const_int 3)] ! (const_int 2)))]) ;; Branch on Bit patterns. --- 803,810 ---- [(set_attr "type" "cbranch") (set (attr "length") ! (if_then_else (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) ! (const_int 8188)) ! (const_int 4) ! (const_int 8)))]) ;; Branch on Bit patterns. *************** *** 817,828 **** [(set_attr "type" "cbranch") (set (attr "length") ! (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 2)))) ! (const_int 1023)) ! (const_int 1) ! (and (lt (match_dup 0) (pc)) ! (eq (symbol_ref "INSN_ANNULLED_BRANCH_P (insn)") ! (const_int 1))) ! (const_int 3)] ! (const_int 2)))]) (define_insn "" --- 828,835 ---- [(set_attr "type" "cbranch") (set (attr "length") ! (if_then_else (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) ! (const_int 8188)) ! (const_int 4) ! (const_int 8)))]) (define_insn "" *************** *** 845,859 **** [(set_attr "type" "cbranch") (set (attr "length") ! (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 2)))) ! (const_int 1023)) ! (const_int 1) ! (and (lt (match_dup 0) (pc)) ! (eq (symbol_ref "INSN_ANNULLED_BRANCH_P (insn)") ! (const_int 1))) ! (const_int 3)] ! (const_int 2)))]) ;; Floating point branches - (define_insn "" [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0)) --- 852,861 ---- [(set_attr "type" "cbranch") (set (attr "length") ! (if_then_else (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) ! (const_int 8188)) ! (const_int 4) ! (const_int 8)))]) ;; Floating point branches (define_insn "" [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0)) *************** *** 869,873 **** }" [(set_attr "type" "fbranch") ! (set_attr "length" "2")]) (define_insn "" --- 871,875 ---- }" [(set_attr "type" "fbranch") ! (set_attr "length" "8")]) (define_insn "" *************** *** 884,888 **** }" [(set_attr "type" "fbranch") ! (set_attr "length" "3")]) ;; Move instructions --- 886,890 ---- }" [(set_attr "type" "fbranch") ! (set_attr "length" "12")]) ;; Move instructions *************** *** 940,944 **** "ldw T'%2(%1),%0" [(set_attr "type" "load") ! (set_attr "length" "1")]) (define_insn "" --- 942,946 ---- "ldw T'%2(%1),%0" [(set_attr "type" "load") ! (set_attr "length" "4")]) (define_insn "" *************** *** 961,965 **** fstws%F0 %1,%0" [(set_attr "type" "move,move,move,move,load,store,move,fpalu,fpload,fpstore") ! (set_attr "length" "1,1,1,1,1,1,1,1,1,1")]) ;; Load indexed. We don't use unscaled modes since they can't be used --- 963,967 ---- fstws%F0 %1,%0" [(set_attr "type" "move,move,move,move,load,store,move,fpalu,fpload,fpstore") ! (set_attr "length" "4,4,4,4,4,4,4,4,4,4")]) ;; Load indexed. We don't use unscaled modes since they can't be used *************** *** 976,980 **** "ldwx,s %1(0,%2),%0" [(set_attr "type" "load") ! (set_attr "length" "1")]) ;; Load or store with base-register modification. --- 978,1003 ---- "ldwx,s %1(0,%2),%0" [(set_attr "type" "load") ! (set_attr "length" "4")]) ! ! ;; This variant of the above insn can occur if the second operand ! ;; is the frame pointer. This is a kludge, but there doesn't ! ;; seem to be a way around it. Only recognize it while reloading. ! (define_insn "" ! [(set (match_operand:SI 0 "register_operand" "&=r") ! (mem:SI (plus:SI (plus:SI ! (mult:SI (match_operand:SI 1 "register_operand" "r") ! (const_int 4)) ! (match_operand:SI 2 "register_operand" "r")) ! (match_operand:SI 3 "const_int_operand" "rI"))))] ! "! TARGET_DISABLE_INDEXING && reload_in_progress" ! "* ! { ! if (GET_CODE (operands[3]) == CONST_INT) ! return \"sh2add %1,%2,%0\;ldw %3(0,%0),%0\"; ! else ! return \"sh2add %1,%2,%0\;ldwx %3(0,%0),%0\"; ! }" ! [(set_attr "type" "load") ! (set_attr "length" "8")]) ;; Load or store with base-register modification. *************** *** 994,998 **** }" [(set_attr "type" "load") ! (set_attr "length" "1")]) (define_insn "pre_stwm" --- 1017,1021 ---- }" [(set_attr "type" "load") ! (set_attr "length" "4")]) (define_insn "pre_stwm" *************** *** 1010,1014 **** }" [(set_attr "type" "store") ! (set_attr "length" "1")]) (define_insn "post_ldwm" --- 1033,1037 ---- }" [(set_attr "type" "store") ! (set_attr "length" "4")]) (define_insn "post_ldwm" *************** *** 1026,1030 **** }" [(set_attr "type" "load") ! (set_attr "length" "1")]) (define_insn "post_stwm" --- 1049,1053 ---- }" [(set_attr "type" "load") ! (set_attr "length" "4")]) (define_insn "post_stwm" *************** *** 1042,1046 **** }" [(set_attr "type" "store") ! (set_attr "length" "1")]) ;; For pic --- 1065,1069 ---- }" [(set_attr "type" "store") ! (set_attr "length" "4")]) ;; For pic *************** *** 1066,1077 **** " [(set_attr "type" "multi") ! (set_attr "length" "3")]) ! ;; For kernel code always use addil; else we can lose due to a linker ! ;; bug involving absolute symbols and "ldil;add" style relocations (define_insn "" [(set (match_operand:SI 0 "register_operand" "=a") (high:SI (match_operand 1 "" "")))] ! "TARGET_KERNEL && symbolic_operand(operands[1], Pmode) && ! function_label_operand (operands[1]) && ! read_only_operand (operands[1])" --- 1089,1101 ---- " [(set_attr "type" "multi") ! (set_attr "length" "12")]) ! ;; Always use addil rather than ldil;add sequences. This allows the ! ;; HP linker to eliminate the dp relocation if the symbolic operand ! ;; lives in the TEXT space. (define_insn "" [(set (match_operand:SI 0 "register_operand" "=a") (high:SI (match_operand 1 "" "")))] ! "symbolic_operand(operands[1], Pmode) && ! function_label_operand (operands[1]) && ! read_only_operand (operands[1])" *************** *** 1079,1109 **** addil L'%G1,%%r27" [(set_attr "type" "binary") ! (set_attr "length" "1")]) ! ! ;; For all symbolic operands *except* function addresses and read-only ! ;; operands (which live in TEXT space and do not require relocation). ! ;; ! ;; The constraints are a little strange. ! ;; The basic idea is to prefer %r1 as much as possible for register ! ;; allocation (hence we do not allow regclass to know about the general ! ;; register case (via *r). ! ;; We also want to avoid spilling %r1 as that will cause every use ! ;; of %r1 to be reloaded, so we make the %r1 case very expensive ! ;; as far as reload is concerned (via !a). ! ;; ! ;; The real solution is to not spill all pseudos allocated to %r1 ! ;; when %r1 is needed as a spill register, but that is considerably ! ;; more difficult than coercing decent behavior via constraints. ! (define_insn "" ! [(set (match_operand:SI 0 "register_operand" "=!a,*r") ! (high:SI (match_operand 1 "" "")))] ! "! TARGET_KERNEL && symbolic_operand(operands[1], Pmode) ! && ! function_label_operand (operands[1]) ! && ! read_only_operand (operands[1])" ! "@ ! addil L'%G1,%%r27 ! ldil L'%G1,%0\;add %0,%%r27,%0" ! [(set_attr "type" "binary,binary") ! (set_attr "length" "1,2")]) ;; This is for use in the prologue/epilogue code. We need it --- 1103,1107 ---- addil L'%G1,%%r27" [(set_attr "type" "binary") ! (set_attr "length" "4")]) ;; This is for use in the prologue/epilogue code. We need it *************** *** 1121,1134 **** ldil L'%G2,%0\;add %0,%1,%0" [(set_attr "type" "binary,binary") ! (set_attr "length" "1,2")]) ! ;; For function addresses when TARGET_SHARED_LIBS (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") (high:SI (match_operand:SI 1 "function_label_operand" "")))] ! "TARGET_SHARED_LIBS" "ldil LP'%G1,%0" [(set_attr "type" "move") ! (set_attr "length" "1")]) (define_insn "" --- 1119,1132 ---- ldil L'%G2,%0\;add %0,%1,%0" [(set_attr "type" "binary,binary") ! (set_attr "length" "4,8")]) ! ;; For function addresses. (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") (high:SI (match_operand:SI 1 "function_label_operand" "")))] ! "" "ldil LP'%G1,%0" [(set_attr "type" "move") ! (set_attr "length" "4")]) (define_insn "" *************** *** 1138,1144 **** "ldil L'%G1,%0" [(set_attr "type" "move") ! (set_attr "length" "1")]) ! ;; lo_sum of a function address when TARGET_SHARED_LIBS (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") --- 1136,1142 ---- "ldil L'%G1,%0" [(set_attr "type" "move") ! (set_attr "length" "4")]) ! ;; lo_sum of a function address. (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") *************** *** 1146,1153 **** (match_operand:SI 2 "function_label_operand" ""))) (clobber (match_operand:SI 3 "register_operand" "=r"))] ! "TARGET_SHARED_LIBS" "ldo RP'%G2(%1),%0\;extru,= %0,31,1,%3\;ldw -4(0,%%r27),%3\;add %0,%3,%0" [(set_attr "type" "multi") ! (set_attr "length" "4")]) (define_insn "" --- 1144,1151 ---- (match_operand:SI 2 "function_label_operand" ""))) (clobber (match_operand:SI 3 "register_operand" "=r"))] ! "" "ldo RP'%G2(%1),%0\;extru,= %0,31,1,%3\;ldw -4(0,%%r27),%3\;add %0,%3,%0" [(set_attr "type" "multi") ! (set_attr "length" "16")]) (define_insn "" *************** *** 1157,1161 **** "" "ldo R'%G2(%1),%0" ! [(set_attr "length" "1")]) ;; Now that a symbolic_address plus a constant is broken up early --- 1155,1159 ---- "" "ldo R'%G2(%1),%0" ! [(set_attr "length" "4")]) ;; Now that a symbolic_address plus a constant is broken up early *************** *** 1198,1202 **** fcpy,sgl %r1,%0" [(set_attr "type" "move,move,move,move,load,store,move,fpalu") ! (set_attr "length" "1,1,1,1,1,1,1,1")]) (define_insn "" --- 1196,1200 ---- fcpy,sgl %r1,%0" [(set_attr "type" "move,move,move,move,load,store,move,fpalu") ! (set_attr "length" "4,4,4,4,4,4,4,4")]) (define_insn "" *************** *** 1208,1212 **** "ldhx,s %2(0,%1),%0" [(set_attr "type" "load") ! (set_attr "length" "1")]) (define_insn "" --- 1206,1231 ---- "ldhx,s %2(0,%1),%0" [(set_attr "type" "load") ! (set_attr "length" "4")]) ! ! ;; This variant of the above insn can occur if the second operand ! ;; is the frame pointer. This is a kludge, but there doesn't ! ;; seem to be a way around it. Only recognize it while reloading. ! (define_insn "" ! [(set (match_operand:HI 0 "register_operand" "=&r") ! (mem:HI (plus:SI (plus:SI ! (mult:SI (match_operand:SI 2 "register_operand" "r") ! (const_int 2)) ! (match_operand:SI 1 "register_operand" "r")) ! (match_operand:SI 3 "const_int_operand" "rI"))))] ! "! TARGET_DISABLE_INDEXING && reload_in_progress" ! "* ! { ! if (GET_CODE (operands[3]) == CONST_INT) ! return \"sh1add %2,%1,%0\;ldh %3(0,%0),%0\"; ! else ! return \"sh1add %2,%1,%0\;ldhx %3(0,%0),%0\"; ! }" ! [(set_attr "type" "load") ! (set_attr "length" "8")]) (define_insn "" *************** *** 1219,1223 **** "ldhs,mb %2(0,%0),%3" [(set_attr "type" "load") ! (set_attr "length" "1")]) (define_insn "" --- 1238,1242 ---- "ldhs,mb %2(0,%0),%3" [(set_attr "type" "load") ! (set_attr "length" "4")]) (define_insn "" *************** *** 1230,1234 **** "sths,mb %r3,%2(0,%0)" [(set_attr "type" "store") ! (set_attr "length" "1")]) (define_insn "" --- 1249,1253 ---- "sths,mb %r3,%2(0,%0)" [(set_attr "type" "store") ! (set_attr "length" "4")]) (define_insn "" *************** *** 1238,1242 **** "ldil L'%G1,%0" [(set_attr "type" "move") ! (set_attr "length" "1")]) (define_insn "" --- 1257,1261 ---- "ldil L'%G1,%0" [(set_attr "type" "move") ! (set_attr "length" "4")]) (define_insn "" *************** *** 1246,1250 **** "" "ldo R'%G2(%1),%0" ! [(set_attr "length" "1")]) (define_expand "movqi" --- 1265,1269 ---- "" "ldo R'%G2(%1),%0" ! [(set_attr "length" "4")]) (define_expand "movqi" *************** *** 1273,1277 **** fcpy,sgl %r1,%0" [(set_attr "type" "move,move,move,move,load,store,move,fpalu") ! (set_attr "length" "1,1,1,1,1,1,1,1")]) (define_insn "" --- 1292,1296 ---- fcpy,sgl %r1,%0" [(set_attr "type" "move,move,move,move,load,store,move,fpalu") ! (set_attr "length" "4,4,4,4,4,4,4,4")]) (define_insn "" *************** *** 1284,1288 **** "ldbs,mb %2(0,%0),%3" [(set_attr "type" "load") ! (set_attr "length" "1")]) (define_insn "" --- 1303,1307 ---- "ldbs,mb %2(0,%0),%3" [(set_attr "type" "load") ! (set_attr "length" "4")]) (define_insn "" *************** *** 1295,1299 **** "stbs,mb %r3,%2(0,%0)" [(set_attr "type" "store") ! (set_attr "length" "1")]) ;; The definition of this insn does not really explain what it does, --- 1314,1318 ---- "stbs,mb %r3,%2(0,%0)" [(set_attr "type" "store") ! (set_attr "length" "4")]) ;; The definition of this insn does not really explain what it does, *************** *** 1365,1369 **** : \" fldds%F1 %1,%0\");" [(set_attr "type" "move,fpload") ! (set_attr "length" "4,1")]) (define_expand "movdf" --- 1384,1388 ---- : \" fldds%F1 %1,%0\");" [(set_attr "type" "move,fpload") ! (set_attr "length" "16,4")]) (define_expand "movdf" *************** *** 1379,1385 **** (define_insn "" [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" ! "=fx,*r,Q,?Q,fx,*&r") (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand" ! "fxG,*rG,fx,*r,Q,Q"))] "register_operand (operands[0], DFmode) || reg_or_0_operand (operands[1], DFmode)" --- 1398,1404 ---- (define_insn "" [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" ! "=fx,*r,Q,?o,?Q,fx,*&r,*&r") (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand" ! "fxG,*rG,fx,*r,*r,Q,o,Q"))] "register_operand (operands[0], DFmode) || reg_or_0_operand (operands[1], DFmode)" *************** *** 1391,1396 **** return output_move_double (operands); }" ! [(set_attr "type" "fpalu,move,fpstore,store,fpload,load") ! (set_attr "length" "1,2,1,2,1,2")]) (define_insn "" --- 1410,1415 ---- return output_move_double (operands); }" ! [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load") ! (set_attr "length" "4,8,4,8,16,4,8,16")]) (define_insn "" *************** *** 1402,1406 **** "flddx,s %1(0,%2),%0" [(set_attr "type" "fpload") ! (set_attr "length" "1")]) (define_insn "" --- 1421,1449 ---- "flddx,s %1(0,%2),%0" [(set_attr "type" "fpload") ! (set_attr "length" "4")]) ! ! ;; This variant of the above insn can occur if the second operand ! ;; is the frame pointer. This is a kludge, but there doesn't ! ;; seem to be a way around it. Only recognize it while reloading. ! ;; Ugh. Output is a FP register; so we need to earlyclobber something ! ;; else as a temporary. ! (define_insn "" ! [(set (match_operand:DF 0 "register_operand" "=fx") ! (mem:DF (plus:SI ! (plus:SI ! (mult:SI (match_operand:SI 1 "register_operand" "+&r") ! (const_int 8)) ! (match_operand:SI 2 "register_operand" "r")) ! (match_operand:SI 3 "const_int_operand" "rL"))))] ! "! TARGET_DISABLE_INDEXING && reload_in_progress" ! "* ! { ! if (GET_CODE (operands[3]) == CONST_INT) ! return \"sh3add %1,%2,%1\;fldds %3(0,%1),%0\"; ! else ! return \"sh3add %1,%2,%1\;flddx %3(0,%1),%0\"; ! }" ! [(set_attr "type" "fpload") ! (set_attr "length" "8")]) (define_insn "" *************** *** 1412,1416 **** "fstdx,s %0,%1(0,%2)" [(set_attr "type" "fpstore") ! (set_attr "length" "1")]) (define_expand "movdi" --- 1455,1483 ---- "fstdx,s %0,%1(0,%2)" [(set_attr "type" "fpstore") ! (set_attr "length" "4")]) ! ! ;; This variant of the above insn can occur if the second operand ! ;; is the frame pointer. This is a kludge, but there doesn't ! ;; seem to be a way around it. Only recognize it while reloading. ! ;; Ugh. Output is a FP register; so we need to earlyclobber something ! ;; else as a temporary. ! (define_insn "" ! [(set (mem:DF (plus:SI ! (plus:SI ! (mult:SI (match_operand:SI 1 "register_operand" "+&r") ! (const_int 8)) ! (match_operand:SI 2 "register_operand" "r")) ! (match_operand:SI 3 "const_int_operand" "rL"))) ! (match_operand:DF 0 "register_operand" "=fx"))] ! "! TARGET_DISABLE_INDEXING && reload_in_progress" ! "* ! { ! if (GET_CODE (operands[3]) == CONST_INT) ! return \"sh3add %1,%2,%1\;fstds %3(0,%1),%0\"; ! else ! return \"sh3add %1,%2,%1\;fstdx %3(0,%1),%0\"; ! }" ! [(set_attr "type" "fpstore") ! (set_attr "length" "8")]) (define_expand "movdi" *************** *** 1490,1494 **** }" [(set_attr "type" "move") ! (set_attr "length" "2")]) ;;; Experimental --- 1557,1561 ---- }" [(set_attr "type" "move") ! (set_attr "length" "8")]) ;;; Experimental *************** *** 1496,1502 **** (define_insn "" [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" ! "=r,Q,&r,&r,x,x,*T") (match_operand:DI 1 "general_operand" ! "rM,r,Q,i,xM,*T,x"))] "register_operand (operands[0], DImode) || reg_or_0_operand (operands[1], DImode)" --- 1563,1569 ---- (define_insn "" [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" ! "=r,o,Q,&r,&r,&r,x,x,*T") (match_operand:DI 1 "general_operand" ! "rM,r,r,o,Q,i,xM,*T,x"))] "register_operand (operands[0], DImode) || reg_or_0_operand (operands[1], DImode)" *************** *** 1508,1513 **** return output_move_double (operands); }" ! [(set_attr "type" "move,store,load,misc,fpalu,fpload,fpstore") ! (set_attr "length" "2,3,3,3,1,1,1")]) (define_insn "" --- 1575,1580 ---- return output_move_double (operands); }" ! [(set_attr "type" "move,store,store,load,load,misc,fpalu,fpload,fpstore") ! (set_attr "length" "8,8,16,8,16,16,4,4,4")]) (define_insn "" *************** *** 1528,1532 **** ;; Need to set length for this arith insn because operand2 ;; is not an "arith_operand". ! [(set_attr "length" "1,2")]) ;; This pattern forces (set (reg:SF ...) (const_double ...)) --- 1595,1599 ---- ;; Need to set length for this arith insn because operand2 ;; is not an "arith_operand". ! [(set_attr "length" "4,8")]) ;; This pattern forces (set (reg:SF ...) (const_double ...)) *************** *** 1547,1551 **** : \" fldws%F1 %1,%0\");" [(set_attr "type" "move,fpload") ! (set_attr "length" "2,1")]) (define_expand "movsf" --- 1614,1618 ---- : \" fldws%F1 %1,%0\");" [(set_attr "type" "move,fpload") ! (set_attr "length" "8,4")]) (define_expand "movsf" *************** *** 1574,1578 **** stw%M0 %r1,%0" [(set_attr "type" "fpalu,move,fpload,load,fpstore,store") ! (set_attr "length" "1,1,1,1,1,1")]) (define_insn "" --- 1641,1645 ---- stw%M0 %r1,%0" [(set_attr "type" "fpalu,move,fpload,load,fpstore,store") ! (set_attr "length" "4,4,4,4,4,4")]) (define_insn "" *************** *** 1584,1588 **** "fldwx,s %1(0,%2),%0" [(set_attr "type" "fpload") ! (set_attr "length" "1")]) (define_insn "" --- 1651,1679 ---- "fldwx,s %1(0,%2),%0" [(set_attr "type" "fpload") ! (set_attr "length" "4")]) ! ! ;; This variant of the above insn can occur if the second operand ! ;; is the frame pointer. This is a kludge, but there doesn't ! ;; seem to be a way around it. Only recognize it while reloading. ! ;; Ugh. Output is a FP register; so we need to earlyclobber something ! ;; else as a temporary. ! (define_insn "" ! [(set (match_operand:SF 0 "register_operand" "=fx") ! (mem:SF (plus:SI ! (plus:SI ! (mult:SI (match_operand:SI 1 "register_operand" "+&r") ! (const_int 4)) ! (match_operand:SI 2 "register_operand" "r")) ! (match_operand:SI 3 "const_int_operand" "rL"))))] ! "! TARGET_DISABLE_INDEXING && reload_in_progress" ! "* ! { ! if (GET_CODE (operands[3]) == CONST_INT) ! return \"sh2add %1,%2,%1\;fldws %3(0,%1),%0\"; ! else ! return \"sh2add %1,%2,%1\;fldwx %3(0,%1),%0\"; ! }" ! [(set_attr "type" "fpload") ! (set_attr "length" "8")]) (define_insn "" *************** *** 1594,1598 **** "fstwx,s %0,%1(0,%2)" [(set_attr "type" "fpstore") ! (set_attr "length" "1")]) ;;- zero extension instructions --- 1685,1713 ---- "fstwx,s %0,%1(0,%2)" [(set_attr "type" "fpstore") ! (set_attr "length" "4")]) ! ! ;; This variant of the above insn can occur if the second operand ! ;; is the frame pointer. This is a kludge, but there doesn't ! ;; seem to be a way around it. Only recognize it while reloading. ! ;; Ugh. Output is a FP register; so we need to earlyclobber something ! ;; else as a temporary. ! (define_insn "" ! [(set (mem:SF (plus:SI ! (plus:SI ! (mult:SI (match_operand:SI 1 "register_operand" "+&r") ! (const_int 4)) ! (match_operand:SI 2 "register_operand" "r")) ! (match_operand:SI 3 "const_int_operand" "rL"))) ! (match_operand:SF 0 "register_operand" "=fx"))] ! "! TARGET_DISABLE_INDEXING && reload_in_progress" ! "* ! { ! if (GET_CODE (operands[3]) == CONST_INT) ! return \"sh2add %1,%2,%1\;fstds %3(0,%1),%0\"; ! else ! return \"sh2add %1,%2,%1\;fstdx %3(0,%1),%0\"; ! }" ! [(set_attr "type" "fpstore") ! (set_attr "length" "8")]) ;;- zero extension instructions *************** *** 1616,1621 **** extru %1,31,8,%0 ldb%M1 %1,%0" ! [(set_attr "type" "unary,load") ! (set_attr "length" "1,1")]) (define_insn "zero_extendqisi2" --- 1731,1735 ---- extru %1,31,8,%0 ldb%M1 %1,%0" ! [(set_attr "type" "unary,load")]) (define_insn "zero_extendqisi2" *************** *** 1627,1632 **** extru %1,31,8,%0 ldb%M1 %1,%0" ! [(set_attr "type" "unary,load") ! (set_attr "length" "1,1")]) ;;- sign extension instructions --- 1741,1745 ---- extru %1,31,8,%0 ldb%M1 %1,%0" ! [(set_attr "type" "unary,load")]) ;;- sign extension instructions *************** *** 1688,1692 **** "fldws %1,%0\;fcnvxf,sgl,sgl %0,%0" [(set_attr "type" "fpalu") ! (set_attr "length" "2")]) (define_insn "floatsisf2" --- 1801,1805 ---- "fldws %1,%0\;fcnvxf,sgl,sgl %0,%0" [(set_attr "type" "fpalu") ! (set_attr "length" "8")]) (define_insn "floatsisf2" *************** *** 1695,1700 **** "" "fcnvxf,sgl,sgl %1,%0" ! [(set_attr "type" "fpalu") ! (set_attr "length" "1")]) ;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...))) --- 1808,1812 ---- "" "fcnvxf,sgl,sgl %1,%0" ! [(set_attr "type" "fpalu")]) ;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...))) *************** *** 1707,1711 **** "fldws %1,%0\;fcnvxf,sgl,dbl %0,%0" [(set_attr "type" "fpalu") ! (set_attr "length" "2")]) (define_insn "floatsidf2" --- 1819,1823 ---- "fldws %1,%0\;fcnvxf,sgl,dbl %0,%0" [(set_attr "type" "fpalu") ! (set_attr "length" "8")]) (define_insn "floatsidf2" *************** *** 1714,1719 **** "" "fcnvxf,sgl,dbl %1,%0" ! [(set_attr "type" "fpalu") ! (set_attr "length" "1")]) (define_expand "floatunssisf2" --- 1826,1830 ---- "" "fcnvxf,sgl,dbl %1,%0" ! [(set_attr "type" "fpalu")]) (define_expand "floatunssisf2" *************** *** 1742,1747 **** "TARGET_SNAKE" "fcnvxf,dbl,sgl %1,%0" ! [(set_attr "type" "fpalu") ! (set_attr "length" "1")]) (define_insn "floatdidf2" --- 1853,1857 ---- "TARGET_SNAKE" "fcnvxf,dbl,sgl %1,%0" ! [(set_attr "type" "fpalu")]) (define_insn "floatdidf2" *************** *** 1750,1755 **** "TARGET_SNAKE" "fcnvxf,dbl,dbl %1,%0" ! [(set_attr "type" "fpalu") ! (set_attr "length" "1")]) ;; Convert a float to an actual integer. --- 1860,1864 ---- "TARGET_SNAKE" "fcnvxf,dbl,dbl %1,%0" ! [(set_attr "type" "fpalu")]) ;; Convert a float to an actual integer. *************** *** 1761,1766 **** "" "fcnvfxt,sgl,sgl %1,%0" ! [(set_attr "type" "fpalu") ! (set_attr "length" "1")]) (define_insn "fix_truncdfsi2" --- 1870,1874 ---- "" "fcnvfxt,sgl,sgl %1,%0" ! [(set_attr "type" "fpalu")]) (define_insn "fix_truncdfsi2" *************** *** 1769,1774 **** "" "fcnvfxt,dbl,sgl %1,%0" ! [(set_attr "type" "fpalu") ! (set_attr "length" "1")]) (define_insn "fix_truncsfdi2" --- 1877,1881 ---- "" "fcnvfxt,dbl,sgl %1,%0" ! [(set_attr "type" "fpalu")]) (define_insn "fix_truncsfdi2" *************** *** 1777,1782 **** "TARGET_SNAKE" "fcnvfxt,sgl,dbl %1,%0" ! [(set_attr "type" "fpalu") ! (set_attr "length" "1")]) (define_insn "fix_truncdfdi2" --- 1884,1888 ---- "TARGET_SNAKE" "fcnvfxt,sgl,dbl %1,%0" ! [(set_attr "type" "fpalu")]) (define_insn "fix_truncdfdi2" *************** *** 1785,1790 **** "TARGET_SNAKE" "fcnvfxt,dbl,dbl %1,%0" ! [(set_attr "type" "fpalu") ! (set_attr "length" "1")]) ;;- arithmetic instructions --- 1891,1895 ---- "TARGET_SNAKE" "fcnvfxt,dbl,dbl %1,%0" ! [(set_attr "type" "fpalu")]) ;;- arithmetic instructions *************** *** 1807,1811 **** return \"add %R2,%R1,%R0\;addc %2,%1,%0\"; }" ! [(set_attr "length" "2")]) (define_insn "" --- 1912,1916 ---- return \"add %R2,%R1,%R0\;addc %2,%1,%0\"; }" ! [(set_attr "length" "8")]) (define_insn "" *************** *** 1887,1891 **** "" "sub %R1,%R2,%R0\;subb %1,%2,%0" ! [(set_attr "length" "2")]) (define_insn "subsi3" --- 1992,1996 ---- "" "sub %R1,%R2,%R0\;subb %1,%2,%0" ! [(set_attr "length" "8")]) (define_insn "subsi3" *************** *** 1944,1948 **** (clobber (reg:SI 31))] "" ! "* return output_mul_insn (0);" [(set_attr "type" "milli")]) --- 2049,2053 ---- (clobber (reg:SI 31))] "" ! "* return output_mul_insn (0, insn);" [(set_attr "type" "milli")]) *************** *** 1990,1994 **** "" "* ! return output_div_insn (operands, 0);" [(set_attr "type" "milli")]) --- 2095,2099 ---- "" "* ! return output_div_insn (operands, 0, insn);" [(set_attr "type" "milli")]) *************** *** 2035,2039 **** "" "* ! return output_div_insn (operands, 1);" [(set_attr "type" "milli")]) --- 2140,2144 ---- "" "* ! return output_div_insn (operands, 1, insn);" [(set_attr "type" "milli")]) *************** *** 2076,2080 **** "" "* ! return output_mod_insn (0);" [(set_attr "type" "milli")]) --- 2181,2185 ---- "" "* ! return output_mod_insn (0, insn);" [(set_attr "type" "milli")]) *************** *** 2117,2121 **** "" "* ! return output_mod_insn (1);" [(set_attr "type" "milli")]) --- 2222,2226 ---- "" "* ! return output_mod_insn (1, insn);" [(set_attr "type" "milli")]) *************** *** 2143,2147 **** "" "and %1,%2,%0\;and %R1,%R2,%R0" ! [(set_attr "length" "2")]) (define_insn "andsi3" --- 2248,2252 ---- "" "and %1,%2,%0\;and %R1,%R2,%R0" ! [(set_attr "length" "8")]) (define_insn "andsi3" *************** *** 2152,2156 **** "* return output_and (operands); " [(set_attr "type" "binary") ! (set_attr "length" "1")]) (define_insn "" --- 2257,2261 ---- "* return output_and (operands); " [(set_attr "type" "binary") ! (set_attr "length" "4")]) (define_insn "" *************** *** 2160,2164 **** "" "andcm %2,%1,%0\;andcm %R2,%R1,%R0" ! [(set_attr "length" "2")]) (define_insn "" --- 2265,2269 ---- "" "andcm %2,%1,%0\;andcm %R2,%R1,%R0" ! [(set_attr "length" "8")]) (define_insn "" *************** *** 2188,2192 **** "" "or %1,%2,%0\;or %R1,%R2,%R0" ! [(set_attr "length" "2")]) ;; Need a define_expand because we've run out of CONST_OK... characters. --- 2293,2297 ---- "" "or %1,%2,%0\;or %R1,%R2,%R0" ! [(set_attr "length" "8")]) ;; Need a define_expand because we've run out of CONST_OK... characters. *************** *** 2209,2213 **** "* return output_ior (operands); " [(set_attr "type" "binary") ! (set_attr "length" "1")]) (define_insn "" --- 2314,2318 ---- "* return output_ior (operands); " [(set_attr "type" "binary") ! (set_attr "length" "4")]) (define_insn "" *************** *** 2237,2241 **** "" "xor %1,%2,%0\;xor %R1,%R2,%R0" ! [(set_attr "length" "2")]) (define_insn "xorsi3" --- 2342,2346 ---- "" "xor %1,%2,%0\;xor %R1,%R2,%R0" ! [(set_attr "length" "8")]) (define_insn "xorsi3" *************** *** 2252,2256 **** "sub 0,%R1,%R0\;subb 0,%1,%0" [(set_attr "type" "unary") ! (set_attr "length" "2")]) (define_insn "negsi2" --- 2357,2361 ---- "sub 0,%R1,%R0\;subb 0,%1,%0" [(set_attr "type" "unary") ! (set_attr "length" "8")]) (define_insn "negsi2" *************** *** 2277,2281 **** "uaddcm 0,%1,%0\;uaddcm 0,%R1,%R0" [(set_attr "type" "unary") ! (set_attr "length" "2")]) (define_insn "one_cmplsi2" --- 2382,2386 ---- "uaddcm 0,%1,%0\;uaddcm 0,%R1,%R0" [(set_attr "type" "unary") ! (set_attr "length" "8")]) (define_insn "one_cmplsi2" *************** *** 2405,2409 **** "ldb%M1 %1,%0" [(set_attr "type" "load") ! (set_attr "length" "1")]) (define_insn "" --- 2510,2514 ---- "ldb%M1 %1,%0" [(set_attr "type" "load") ! (set_attr "length" "4")]) (define_insn "" *************** *** 2414,2418 **** "ldh%M1 %1,%0" [(set_attr "type" "load") ! (set_attr "length" "1")]) (define_insn "" --- 2519,2523 ---- "ldh%M1 %1,%0" [(set_attr "type" "load") ! (set_attr "length" "4")]) (define_insn "" *************** *** 2426,2430 **** ;; This variant of the above insn can occur if the first operand ;; is the frame pointer. This is a kludge, but there doesn't ! ;; seem to be a way around it. Only recognize them while reloading. (define_insn "" --- 2531,2535 ---- ;; This variant of the above insn can occur if the first operand ;; is the frame pointer. This is a kludge, but there doesn't ! ;; seem to be a way around it. Only recognize it while reloading. (define_insn "" *************** *** 2437,2441 **** "sh%O4add %2,%1,%0\;add%I3 %3,%0,%0" [(set_attr "type" "multi") ! (set_attr "length" "2")]) (define_expand "ashlsi3" --- 2542,2546 ---- "sh%O4add %2,%1,%0\;add%I3 %3,%0,%0" [(set_attr "type" "multi") ! (set_attr "length" "8")]) (define_expand "ashlsi3" *************** *** 2468,2472 **** "zdep %1,%P2,%L2,%0" [(set_attr "type" "binary") ! (set_attr "length" "1")]) ; Match cases of op1 a CONST_INT here that zvdep_imm doesn't handle. --- 2573,2577 ---- "zdep %1,%P2,%L2,%0" [(set_attr "type" "binary") ! (set_attr "length" "4")]) ; Match cases of op1 a CONST_INT here that zvdep_imm doesn't handle. *************** *** 2523,2527 **** "extrs %1,%P2,%L2,%0" [(set_attr "type" "binary") ! (set_attr "length" "1")]) (define_insn "vextrs32" --- 2628,2632 ---- "extrs %1,%P2,%L2,%0" [(set_attr "type" "binary") ! (set_attr "length" "4")]) (define_insn "vextrs32" *************** *** 2542,2546 **** extru %1,%P2,%L2,%0" [(set_attr "type" "binary") ! (set_attr "length" "1")]) (define_insn "rotrsi3" --- 2647,2651 ---- extru %1,%P2,%L2,%0" [(set_attr "type" "binary") ! (set_attr "length" "4")]) (define_insn "rotrsi3" *************** *** 2560,2564 **** }" [(set_attr "type" "binary") ! (set_attr "length" "1")]) (define_insn "rotlsi3" --- 2665,2669 ---- }" [(set_attr "type" "binary") ! (set_attr "length" "4")]) (define_insn "rotlsi3" *************** *** 2573,2577 **** }" [(set_attr "type" "binary") ! (set_attr "length" "1")]) (define_insn "" --- 2678,2682 ---- }" [(set_attr "type" "binary") ! (set_attr "length" "4")]) (define_insn "" *************** *** 2585,2589 **** "shd %1,%2,%4,%0" [(set_attr "type" "binary") ! (set_attr "length" "1")]) (define_insn "" --- 2690,2694 ---- "shd %1,%2,%4,%0" [(set_attr "type" "binary") ! (set_attr "length" "4")]) (define_insn "" *************** *** 2597,2601 **** "shd %1,%2,%4,%0" [(set_attr "type" "binary") ! (set_attr "length" "1")]) (define_insn "" --- 2702,2706 ---- "shd %1,%2,%4,%0" [(set_attr "type" "binary") ! (set_attr "length" "4")]) (define_insn "" *************** *** 2613,2617 **** }" [(set_attr "type" "binary") ! (set_attr "length" "1")]) ;; Unconditional and other jump instructions. --- 2718,2722 ---- }" [(set_attr "type" "binary") ! (set_attr "length" "4")]) ;; Unconditional and other jump instructions. *************** *** 2662,2666 **** "" "bl _mcount,%%r2\;ldo %0(%%r2),%%r25" ! [(set_attr "length" "2")]) (define_insn "blockage" --- 2767,2771 ---- "" "bl _mcount,%%r2\;ldo %0(%%r2),%%r25" ! [(set_attr "length" "8")]) (define_insn "blockage" *************** *** 2674,2678 **** "" "bl%* %l0,0" ! [(set_attr "type" "branch")]) ;; Subroutines of "casesi". --- 2779,2793 ---- "" "bl%* %l0,0" ! [(set_attr "type" "uncond_branch") ! (set (attr "length") ! (cond [(eq (symbol_ref "jump_in_call_delay (insn)") (const_int 0)) ! (const_int 4) ! ;; If the jump is in the delay slot of a call, then its length depends ! ;; on whether or not we can add the proper offset to %r2 with an ldo ! ;; instruction. ! (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) ! (const_int 8188)) ! (const_int 4)] ! (const_int 8)))]) ;; Subroutines of "casesi". *************** *** 2736,2740 **** } }" ! [(set_attr "length" "3")]) ;; Need nops for the calls because execution is supposed to continue --- 2851,2855 ---- } }" ! [(set_attr "length" "12")]) ;; Need nops for the calls because execution is supposed to continue *************** *** 2755,2759 **** else op = XEXP (operands[0], 0); ! emit_call_insn (gen_call_internal (op, operands[1])); if (flag_pic) { --- 2870,2884 ---- else op = XEXP (operands[0], 0); ! ! /* Use two different patterns for calls to explicitly named functions ! and calls through function pointers. This is necessary as these two ! types of calls use different calling conventions, and CSE might try ! to change the named call into an indirect call in some cases (using ! two patterns keeps CSE from performing this optimization). */ ! if (GET_CODE (op) == SYMBOL_REF) ! emit_call_insn (gen_call_internal_symref (op, operands[1])); ! else ! emit_call_insn (gen_call_internal_reg (op, operands[1])); ! if (flag_pic) { *************** *** 2766,2786 **** }") ! (define_insn "call_internal" ! [(call (mem:SI (match_operand:SI 0 "call_operand_address" "r,S")) ! (match_operand 1 "" "i,i")) ! (clobber (reg:SI 2))] ! "" "* { ! if (which_alternative == 0) ! return \"copy %0,22\;.CALL\\tARGW0=GR\;bl $$dyncall,31\;copy 31,2\"; ! else ! { ! output_arg_descriptor (insn); ! return \"bl %0,2%#\"; ! } }" ! [(set_attr "type" "dyncall,call") ! (set_attr "length" "3,1")]) (define_expand "call_value" --- 2891,2917 ---- }") ! (define_insn "call_internal_symref" ! [(call (mem:SI (match_operand:SI 0 "call_operand_address" "")) ! (match_operand 1 "" "i")) ! (clobber (reg:SI 2)) ! (use (const_int 0))] ! "! TARGET_LONG_CALLS" "* { ! output_arg_descriptor (insn); ! return output_call (insn, operands[0], gen_rtx (REG, SImode, 2)); }" ! [(set_attr "type" "call") ! (set_attr "length" "4")]) ! ! (define_insn "call_internal_reg" ! [(call (mem:SI (match_operand:SI 0 "register_operand" "r")) ! (match_operand 1 "" "i")) ! (clobber (reg:SI 2)) ! (use (const_int 1))] ! "" ! "copy %r0,%%r22\;.CALL\\tARGW0=GR\;bl $$dyncall,%%r31\;copy %%r31,%%r2" ! [(set_attr "type" "dyncall") ! (set_attr "length" "12")]) (define_expand "call_value" *************** *** 2799,2803 **** else op = XEXP (operands[1], 0); ! emit_call_insn (gen_call_value_internal (operands[0], op, operands[2])); if (flag_pic) { --- 2930,2945 ---- else op = XEXP (operands[1], 0); ! ! /* Use two different patterns for calls to explicitly named functions ! and calls through function pointers. This is necessary as these two ! types of calls use different calling conventions, and CSE might try ! to change the named call into an indirect call in some cases (using ! two patterns keeps CSE from performing this optimization). */ ! if (GET_CODE (op) == SYMBOL_REF) ! emit_call_insn (gen_call_value_internal_symref (operands[0], op, ! operands[2])); ! else ! emit_call_insn (gen_call_value_internal_reg (operands[0], op, operands[2])); ! if (flag_pic) { *************** *** 2810,2833 **** }") ! (define_insn "call_value_internal" ! [(set (match_operand 0 "" "=rfx,rfx") ! (call (mem:SI (match_operand:SI 1 "call_operand_address" "r,S")) ! (match_operand 2 "" "i,i"))) ! (clobber (reg:SI 2))] ;;- Don't use operand 1 for most machines. ! "" "* { ! if (which_alternative == 0) ! return \"copy %1,22\;.CALL\\tARGW0=GR\;bl $$dyncall,31\;copy 31,2\"; ! else { ! output_arg_descriptor (insn); ! return \"bl %1,2%#\"; } - }" - [(set_attr "type" "dyncall,call") - (set_attr "length" "3,1")]) (define_insn "nop" [(const_int 0)] --- 2952,3011 ---- }") ! (define_insn "call_value_internal_symref" ! [(set (match_operand 0 "" "=rfx") ! (call (mem:SI (match_operand:SI 1 "call_operand_address" "")) ! (match_operand 2 "" "i"))) ! (clobber (reg:SI 2)) ! (use (const_int 0))] ;;- Don't use operand 1 for most machines. ! "! TARGET_LONG_CALLS" "* { ! output_arg_descriptor (insn); ! return output_call (insn, operands[1], gen_rtx (REG, SImode, 2)); ! }" ! [(set_attr "type" "call") ! (set_attr "length" "4")]) ! ! (define_insn "call_value_internal_reg" ! [(set (match_operand 0 "" "=rfx") ! (call (mem:SI (match_operand:SI 1 "register_operand" "r")) ! (match_operand 2 "" "i"))) ! (clobber (reg:SI 2)) ! (use (const_int 1))] ! ;;- Don't use operand 1 for most machines. ! "" ! "copy %r1,%%r22\;.CALL\\tARGW0=GR\;bl $$dyncall,%%r31\;copy %%r31,%%r2" ! [(set_attr "type" "dyncall") ! (set_attr "length" "12")]) ! ! ;; Call subroutine returning any type. ! ! (define_expand "untyped_call" ! [(parallel [(call (match_operand 0 "" "") ! (const_int 0)) ! (match_operand 1 "" "") ! (match_operand 2 "" "")])] ! "" ! " ! { ! int i; ! ! emit_call_insn (gen_call (operands[0], const0_rtx)); ! ! for (i = 0; i < XVECLEN (operands[2], 0); i++) { ! rtx set = XVECEXP (operands[2], 0, i); ! emit_move_insn (SET_DEST (set), SET_SRC (set)); } + /* The optimizer does not know that the call sets the function value + registers we stored in the result block. We avoid problems by + claiming that all hard registers are used and clobbered at this + point. */ + emit_insn (gen_blockage ()); + + DONE; + }") (define_insn "nop" [(const_int 0)] *************** *** 2882,2886 **** }") - ;; The dbra pattern from hell. ;; This insn is used for some loop tests, typically loops reversed when ;; strength reduction is used. It is actually created when the instruction --- 3060,3063 ---- *************** *** 2893,2898 **** (if_then_else (match_operator 2 "comparison_operator" ! [(plus:SI (match_operand:SI 0 "register_operand" "+!r,m") ! (match_operand:SI 1 "int5_operand" "L,L")) (const_int 0)]) (label_ref (match_operand 3 "" "")) --- 3070,3075 ---- (if_then_else (match_operator 2 "comparison_operator" ! [(plus:SI (match_operand:SI 0 "register_operand" "+!r,!*f*x,!*m") ! (match_operand:SI 1 "int5_operand" "L,L,L")) (const_int 0)]) (label_ref (match_operand 3 "" "")) *************** *** 2900,3003 **** (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1))) ! (clobber (match_scratch:SI 4 "=X,r"))] ! "0" ! "* ! { ! if (INSN_ANNULLED_BRANCH_P (insn)) ! { ! /* Loop counter is in a register. */ ! if (which_alternative == 0) ! /* Short branch. Normal handling of nullification. */ ! if (get_attr_length (insn) == 1) ! return \"addib,%C2,n %1,%0,%3\"; ! /* Long Conditional branch forward with delay slot nullified if ! branch is taken. */ ! else if (get_attr_length (insn) == 2) ! return \"addi,%N2 %1,%0,%0\;bl,n %3,0\"; ! /* Long Conditional branch backwards with delay slot nullified ! if branch is not taken. */ ! else ! return \"addib,%N2 %1,%0,.+16\;nop\;bl %3,0\"; ! else ! { ! /* Must reload loop counter from memory. Ugly. */ ! output_asm_insn (\"ldw %0,%4\;ldo %1(%4),%4\;stw %4,%0\", operands); ! /* Short branch. Normal handling of nullification. */ ! if (get_attr_length (insn) == 4) ! return \"comb,%S2,n 0,%4,%3\"; ! /* Long Conditional branch forward with delay slot nullified if ! branch is taken. */ ! else if (get_attr_length (insn) == 5) ! return \"comclr,%B2 0,%4,0\;bl,n %3,0\"; ! else ! /* Long Conditional branch backwards with delay slot nullified ! if branch is not taken. */ ! return \"comb,%B2 0,%4,.+16\;nop\;bl %3,0\"; ! } ! } ! else ! { ! /* We are not nullifying the delay slot. Much simpler. */ ! if (which_alternative == 0) ! if (get_attr_length (insn) == 1) ! /* Short form. */ ! return \"addib,%C2 %1,%0,%3%#\"; ! else ! /* Long form. */ ! return \"addi,%N2 %1,%0,%0\;bl%* %3,0\"; ! else ! { ! /* Reload loop counter from memory. */ ! output_asm_insn (\"ldw %0,%4\;ldo %1(%4),%4\;stw %4,%0\", operands); ! /* Short form. */ ! if (get_attr_length (insn) == 4) ! return \"comb,%S2 0,%4,%3%#\"; ! /* Long form. */ ! else ! return \"comclr,%B2 0,%4,0\;bl%* %3,0\"; ! } ! } ! }" ;; Do not expect to understand this the first time through. ! [(set_attr "type" "cbranch") (set (attr "length") ! (if_then_else ! (eq_attr "alternative" "0") ! ;; Loop counter in register case. ! (cond [(lt (abs (minus (match_dup 1) (plus (pc) (const_int 2)))) ! (const_int 1023)) ! ;; Short branch has a length of 1. ! (const_int 1) ! ;; Long backward branch with nullified delay slot has length of 3. ! (and (lt (match_dup 1) (pc)) ! (eq (symbol_ref "INSN_ANNULLED_BRANCH_P (insn)") ! (const_int 1))) ! (const_int 3)] ! ;; Default others to 2. ! ;; Long branches with unfilled delay slots --or-- ! ;; Long forward with nullified delay slot. ! (const_int 2)) ! ;; Loop counter in memory case. Similar to above except we pay ! ;; 3 extra insns in each case for reloading the counter into a register. ! (if_then_else (lt (match_dup 1) (pc)) ! (cond [(lt (abs (minus (match_dup 1) (plus (pc) (const_int 5)))) ! (const_int 1023)) ! ;; Short branch has length of 4 (the reloading costs 3 insns) ! (const_int 4) ! (and (lt (match_dup 1) (pc)) ! (eq (symbol_ref "INSN_ANNULLED_BRANCH_P (insn)") ! (const_int 1))) ! ;; Long backward branch with nullified delay slot has length of 6. ! (const_int 6)] ! ;; Default others to 5. ! ;; Long branches with unfilled delay slots --or-- ! ;; Long forward with nullified delay slot. ! (const_int 5)) ! (if_then_else (lt (abs (minus (match_dup 1) ! (plus (pc) (const_int 2)))) ! (const_int 1023)) ! (const_int 4) ! (const_int 5)))))]) ;; The next four peepholes take advantage of the new 5 operand --- 3077,3269 ---- (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1))) ! (clobber (match_scratch:SI 4 "=X,r,r"))] ! "" ! "* output_dbra (operands, insn, which_alternative); " ;; Do not expect to understand this the first time through. ! [(set_attr "type" "cbranch,multi,multi") ! (set (attr "length") ! (if_then_else (eq_attr "alternative" "0") ! ;; Loop counter in register case ! ;; Short branch has length of 4 ! ;; Long branch has length of 8 ! (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) ! (const_int 8188)) ! (const_int 4) ! (const_int 8)) ! ! ;; Loop counter in FP reg case. ! ;; Extra goo to deal with additional reload insns. ! (if_then_else (eq_attr "alternative" "1") ! (if_then_else (lt (match_dup 3) (pc)) ! (if_then_else ! (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24)))) ! (const_int 8188)) ! (const_int 24) ! (const_int 28)) ! (if_then_else ! (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) ! (const_int 8188)) ! (const_int 24) ! (const_int 28))) ! ;; Loop counter in memory case. ! ;; Extra goo to deal with additional reload insns. ! (if_then_else (lt (match_dup 3) (pc)) ! (if_then_else ! (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12)))) ! (const_int 8188)) ! (const_int 12) ! (const_int 16)) ! (if_then_else ! (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) ! (const_int 8188)) ! (const_int 12) ! (const_int 16))))))]) ! ! ;; Simply another variant of the dbra pattern. More restrictive ! ;; in testing the comparison operator as it must worry about overflow ! ;; problems. ! (define_insn "" ! [(set (pc) ! (if_then_else ! (match_operator 2 "eq_neq_comparison_operator" ! [(match_operand:SI 0 "register_operand" "+!r,!*f*x,!*m") ! (match_operand:SI 5 "const_int_operand" "")]) ! (label_ref (match_operand 3 "" "")) ! (pc))) ! (set (match_dup 0) ! (plus:SI (match_dup 0) (match_operand:SI 1 "int5_operand" "L,L,L"))) ! (clobber (match_scratch:SI 4 "=X,r,r"))] ! "INTVAL (operands[5]) == - INTVAL (operands[1])" ! "* return output_dbra (operands, insn, which_alternative);" ! ;; Do not expect to understand this the first time through. ! [(set_attr "type" "cbranch,multi,multi") ! (set (attr "length") ! (if_then_else (eq_attr "alternative" "0") ! ;; Loop counter in register case ! ;; Short branch has length of 4 ! ;; Long branch has length of 8 ! (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) ! (const_int 8188)) ! (const_int 4) ! (const_int 8)) ! ! ;; Loop counter in FP reg case. ! ;; Extra goo to deal with additional reload insns. ! (if_then_else (eq_attr "alternative" "1") ! (if_then_else (lt (match_dup 3) (pc)) ! (if_then_else ! (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24)))) ! (const_int 8188)) ! (const_int 24) ! (const_int 28)) ! (if_then_else ! (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) ! (const_int 8188)) ! (const_int 24) ! (const_int 28))) ! ;; Loop counter in memory case. ! ;; Extra goo to deal with additional reload insns. ! (if_then_else (lt (match_dup 3) (pc)) ! (if_then_else ! (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12)))) ! (const_int 8188)) ! (const_int 12) ! (const_int 16)) ! (if_then_else ! (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) ! (const_int 8188)) ! (const_int 12) ! (const_int 16))))))]) ! ! (define_insn "" ! [(set (pc) ! (if_then_else ! (match_operator 2 "movb_comparison_operator" ! [(match_operand:SI 1 "register_operand" "r,r,r") (const_int 0)]) ! (label_ref (match_operand 3 "" "")) ! (pc))) ! (set (match_operand:SI 0 "register_operand" "=!r,!*f*x,!*m") ! (match_dup 1))] ! "" ! "* return output_movb (operands, insn, which_alternative, 0); " ! ;; Do not expect to understand this the first time through. ! [(set_attr "type" "cbranch,multi,multi") (set (attr "length") ! (if_then_else (eq_attr "alternative" "0") ! ;; Loop counter in register case ! ;; Short branch has length of 4 ! ;; Long branch has length of 8 ! (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) ! (const_int 8188)) ! (const_int 4) ! (const_int 8)) ! ! ;; Loop counter in FP reg case. ! ;; Extra goo to deal with additional reload insns. ! (if_then_else (eq_attr "alternative" "1") ! (if_then_else (lt (match_dup 3) (pc)) ! (if_then_else ! (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12)))) ! (const_int 8188)) ! (const_int 12) ! (const_int 16)) ! (if_then_else ! (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) ! (const_int 8188)) ! (const_int 12) ! (const_int 16))) ! ;; Loop counter in memory case. ! ;; Extra goo to deal with additional reload insns. ! (if_then_else ! (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) ! (const_int 8188)) ! (const_int 8) ! (const_int 12)))))]) + ;; Handle negated branch. + (define_insn "" + [(set (pc) + (if_then_else + (match_operator 2 "movb_comparison_operator" + [(match_operand:SI 1 "register_operand" "r,r,r") (const_int 0)]) + (pc) + (label_ref (match_operand 3 "" "")))) + (set (match_operand:SI 0 "register_operand" "=!r,!*f*x,!*m") + (match_dup 1))] + "" + "* return output_movb (operands, insn, which_alternative, 1); " + ;; Do not expect to understand this the first time through. + [(set_attr "type" "cbranch,multi,multi") + (set (attr "length") + (if_then_else (eq_attr "alternative" "0") + ;; Loop counter in register case + ;; Short branch has length of 4 + ;; Long branch has length of 8 + (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) + (const_int 8188)) + (const_int 4) + (const_int 8)) + + ;; Loop counter in FP reg case. + ;; Extra goo to deal with additional reload insns. + (if_then_else (eq_attr "alternative" "1") + (if_then_else (lt (match_dup 3) (pc)) + (if_then_else + (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12)))) + (const_int 8188)) + (const_int 12) + (const_int 16)) + (if_then_else + (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) + (const_int 8188)) + (const_int 12) + (const_int 16))) + ;; Loop counter in memory case. + ;; Extra goo to deal with additional reload insns. + (if_then_else + (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) + (const_int 8188)) + (const_int 8) + (const_int 12)))))]) ;; The next four peepholes take advantage of the new 5 operand *************** *** 3097,3101 **** ;; So long as the trampoline itself is less than 32 bytes this ;; is sufficient. ! (define_insn "cacheflush" [(unspec_volatile [(const_int 1)] 0) (use (mem:SI (match_operand:SI 0 "register_operand" "r"))) --- 3363,3368 ---- ;; So long as the trampoline itself is less than 32 bytes this ;; is sufficient. ! ! (define_insn "dcacheflush" [(unspec_volatile [(const_int 1)] 0) (use (mem:SI (match_operand:SI 0 "register_operand" "r"))) *************** *** 3102,3105 **** (use (mem:SI (match_operand:SI 1 "register_operand" "r")))] "" ! "fdc 0(0,%0)\;sync\;fic 0(0,%0)\;sync\;fdc 0(0,%1)\;sync\;fic 0(0,%1)\;sync\;nop\;nop\;nop\;nop\;nop\;nop\;nop" ! [(set_attr "length" "15")]) --- 3369,3383 ---- (use (mem:SI (match_operand:SI 1 "register_operand" "r")))] "" ! "fdc 0(0,%0)\;fdc 0(0,%1)\;sync" ! [(set_attr "length" "12")]) ! ! (define_insn "icacheflush" ! [(unspec_volatile [(const_int 2)] 0) ! (use (mem:SI (match_operand:SI 0 "register_operand" "r"))) ! (use (mem:SI (match_operand:SI 1 "register_operand" "r"))) ! (use (match_operand:SI 2 "register_operand" "r")) ! (clobber (match_operand:SI 3 "register_operand" "=&r")) ! (clobber (match_operand:SI 4 "register_operand" "=&r"))] ! "" ! "mfsp %%sr0,%4\;ldsid (0,%2),%3\;mtsp %3,%%sr0\;fic 0(%%sr0,%0)\;fic 0(%%sr0,%1)\;sync\;mtsp %4,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop" ! [(set_attr "length" "52")]) diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/pa/pa1-ghpux.h gcc-2.5.0/config/pa/pa1-ghpux.h *** gcc-2.4.5/config/pa/pa1-ghpux.h Thu Jun 17 01:08:46 1993 --- gcc-2.5.0/config/pa/pa1-ghpux.h Tue Sep 21 19:25:43 1993 *************** *** 19,28 **** the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! /* This is the same as pa-hpux.h, except that we generate snake code by ! default and we have to deal with assembler weirdness. */ ! ! #define HP_FP_ARG_DESCRIPTOR_REVERSED ! ! #define TARGET_DEFAULT 1 /* TARGET_SNAKE */ #include "pa/pa-ghpux.h" --- 19,23 ---- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! #define TARGET_DEFAULT 129 /* TARGET_SNAKE + TARGET_GAS */ #include "pa/pa-ghpux.h" diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/pa/pa1-hpux.h gcc-2.5.0/config/pa/pa1-hpux.h *** gcc-2.4.5/config/pa/pa1-hpux.h Thu Jun 17 01:03:25 1993 --- gcc-2.5.0/config/pa/pa1-hpux.h Tue Sep 21 19:25:44 1993 *************** *** 19,27 **** the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - /* This is the same as pa-hpux.h, except that we generate snake code by - default and have to deal with assembler weirdness. */ - - #define HP_FP_ARG_DESCRIPTOR_REVERSED - #define TARGET_DEFAULT 1 /* TARGET_SNAKE */ --- 19,22 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/pa/pa1-oldas.h gcc-2.5.0/config/pa/pa1-oldas.h *** gcc-2.4.5/config/pa/pa1-oldas.h Fri May 14 13:41:24 1993 --- gcc-2.5.0/config/pa/pa1-oldas.h Tue Sep 21 19:25:45 1993 *************** *** 23,27 **** ! #define TARGET_DEFAULT 9 /* TARGET_SNAKE */ #include "pa/pa-hpux.h" --- 23,28 ---- ! #define TARGET_DEFAULT 1 /* TARGET_SNAKE */ ! #define HP_FP_ARG_DESCRIPTOR_REVERSED #include "pa/pa-hpux.h" diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/pa/pa1-utahmach.h gcc-2.5.0/config/pa/pa1-utahmach.h *** gcc-2.4.5/config/pa/pa1-utahmach.h Tue Mar 23 14:23:01 1993 --- gcc-2.5.0/config/pa/pa1-utahmach.h Sat Oct 2 04:22:53 1993 *************** *** 19,32 **** the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! /* This is the same as pa-hpux.h, except that we generate snake code by ! default and we have to deal with assembler weirdness. */ - #define HP_FP_ARG_DESCRIPTOR_REVERSED - - #define TARGET_DEFAULT 33 /* TARGET_SNAKE + TARGET_DISABLE_INDEXING */ - #include "pa/pa.h" #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -Dunix -D_HPUX_SOURCE -Dhp9000 -Dhp800 -Dspectrum -DREVARGV -Dhp700 -DHP700 -Dparisc -D__pa_risc -DPARISC -DBYTE_MSF -DBIT_MSF" /* Don't default to pcc-struct-return, because gcc is the only compiler, and --- 19,27 ---- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! #define TARGET_DEFAULT 129 /* TARGET_SNAKE + TARGET_GAS */ #include "pa/pa.h" #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dhppa -Dunix -Dhp9000 -Dspectrum -DREVARGV -Dhp700 -DHP700 -Dparisc -D__pa_risc -DPARISC -DBYTE_MSF -DBIT_MSF -Asystem(unix) -Asystem(mach) -Acpu(hppa) -Amachine(hppa)" /* Don't default to pcc-struct-return, because gcc is the only compiler, and diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/pa/pa1.h gcc-2.5.0/config/pa/pa1.h *** gcc-2.4.5/config/pa/pa1.h Tue Jan 5 23:51:17 1993 --- gcc-2.5.0/config/pa/pa1.h Tue Sep 21 19:25:46 1993 *************** *** 19,23 **** the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! #define TARGET_DEFAULT 1 /* TARGET_SNAKE */ /* This is the same as pa.h, except that we generate snake code by --- 19,23 ---- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! #define TARGET_DEFAULT 129 /* TARGET_SNAKE + TARGET_GAS */ /* This is the same as pa.h, except that we generate snake code by diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/pa/t-pa gcc-2.5.0/config/pa/t-pa *** gcc-2.4.5/config/pa/t-pa Thu Sep 17 14:52:30 1992 --- gcc-2.5.0/config/pa/t-pa Tue Sep 21 19:25:46 1993 *************** *** 1,2 **** --- 1,3 ---- LIBGCC1=libgcc1.null + CROSS_LIBGCC1=libgcc1.null INSTALLED_H = float.h stdarg.h varargs.h $(USER_H) limits.h diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/pyr/pyr.h gcc-2.5.0/config/pyr/pyr.h *** gcc-2.4.5/config/pyr/pyr.h Wed Mar 31 15:01:10 1993 --- gcc-2.5.0/config/pyr/pyr.h Mon Oct 11 07:36:32 1993 *************** *** 42,46 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dpyr -Dunix" /* Print subsidiary information on the compiler version in use. */ --- 42,46 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dpyr -Dunix -Asystem(unix) -Acpu(pyr) -Amachine(pyr)" /* Print subsidiary information on the compiler version in use. */ *************** *** 628,633 **** For a library call, FNTYPE is 0. */ ! #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME) \ ! ((CUM) = (FNTYPE && !flag_pcc_struct_return && aggregate_value_p (FNTYPE))) /* Determine where to put an argument to a function. --- 628,634 ---- For a library call, FNTYPE is 0. */ ! #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME) \ ! ((CUM) = (FNTYPE && !flag_pcc_struct_return \ ! && aggregate_value_p (TREE_TYPE (FNTYPE)))) /* Determine where to put an argument to a function. *************** *** 1029,1036 **** #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 --- 1030,1036 ---- #define SLOW_BYTE_ACCESS 0 ! /* Define this to be nonzero if shift instructions ignore all but the low-order ! few bits. */ ! #define SHIFT_COUNT_TRUNCATED 1 /* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/pyr/xm-pyr.h gcc-2.5.0/config/pyr/xm-pyr.h *** gcc-2.4.5/config/pyr/xm-pyr.h Sat Dec 26 17:23:43 1992 --- gcc-2.5.0/config/pyr/xm-pyr.h Sat Jun 26 11:31:44 1993 *************** *** 1,4 **** /* Configuration for GNU compiler, for Pyramid 90x, 9000, and MIServer Series. ! Copyright (C) 1989 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,4 ---- /* Configuration for GNU compiler, for Pyramid 90x, 9000, and MIServer Series. ! Copyright (C) 1989, 1993 Free Software Foundation, Inc. This file is part of GNU CC. *************** *** 38,44 **** #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 --- 38,39 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/romp/romp.c gcc-2.5.0/config/romp/romp.c *** gcc-2.4.5/config/romp/romp.c Mon May 31 21:45:36 1993 --- gcc-2.5.0/config/romp/romp.c Wed Jun 23 07:55:17 1993 *************** *** 1077,1081 **** int first_reg; int reg_save_offset; - rtx insn; int fp_save = size + current_function_outgoing_args_size; --- 1077,1080 ---- *************** *** 1124,1128 **** --- 1123,1181 ---- plus_constant (stack_pointer_rtx, fp_save)); } + + /* Output the offset information used by debuggers. + This is the exactly the total_size value of output_epilog + which is added to the frame pointer. However the value in the debug + table is encoded in a space-saving way as follows: + + The first byte contains two fields: a 2-bit size field and the first + 6 bits of an offset value. The 2-bit size field is in the high-order + position and specifies how many subsequent bytes follow after + this one. An offset value is at most 4-bytes long. + + The last 6 bits of the first byte initialize the offset value. In many + cases where procedures have small local storage, this is enough and, in + this case, the high-order size field is zero so the byte can (almost) be + used as is (see below). Thus, the byte value of 0x0d is encodes a offset + size of 13 words, or 52 bytes. + + For procedures with a local space larger than 60 bytes, the 6 bits + are the high-order 6 bits. The remaining bytes follow as necessary, + in Big Endian order. Thus, the short value of 16907 (= 16384+523) + encodes an offset of 2092 bytes (523 words). + + The total offset value is in words (not bytes), so the final value has to + be multiplied by 4 before it can be used in address computations by a + debugger. */ + + void + output_encoded_offset (file, reg_offset) + FILE *file; + unsigned reg_offset; + { + /* Convert the offset value to 4-byte words rather than bytes. */ + reg_offset = (reg_offset + 3) / 4; + /* Now output 1-4 bytes in encoded form. */ + if (reg_offset < (1 << 6)) + /* Fits into one byte */ + fprintf (file, "\t.byte %d\n", reg_offset); + else if (reg_offset < (1 << (6 + 8))) + /* Fits into two bytes */ + fprintf (file, "\t.short %d\n", (1 << (6 + 8)) + reg_offset); + else if (reg_offset < (1 << (6 + 8 + 8))) + { + /* Fits in three bytes */ + fprintf (file, "\t.byte %d\n", (2 << 6) + (reg_offset >> ( 6+ 8))); + fprintf (file, "\t.short %d\n", reg_offset % (1 << (6 + 8))); + } + else + { + /* Use 4 bytes. */ + fprintf (file, "\t.short %d", (3 << (6 + 8)) + (reg_offset >> (6 + 8))); + fprintf (file, "\t.short %d\n", reg_offset % (1 << (6 + 8))); + } + } + /* Write function epilogue. */ *************** *** 1196,1206 **** fprintf (file, "\tbrx r15\n\tcal r1,%d(r1)\n", total_size); } fprintf (file, "\t.long 0x%x\n", 0xdf07df08 + first_reg * 0x10); if (nargs > 15) nargs = 15; ! if (frame_pointer_needed) ! fprintf (file, "\t.byte 0x%xd, 53\n", nargs); ! else ! fprintf (file, "\t.short 0x%x100\n", nargs); } else --- 1249,1284 ---- fprintf (file, "\tbrx r15\n\tcal r1,%d(r1)\n", total_size); } + + /* Table header (0xdf), usual-type stack frame (0x07), + table header (0xdf), and first register saved. + + The final 0x08 means that there is a byte following this one + describing the number of parameter words and the register used as + stack pointer. + + If GCC passed floating-point parameters in floating-point registers, + it would be necessary to change the final byte from 0x08 to 0x0c. + Also an additional entry byte would be need to be emitted to specify + the first floating-point register. + + (See also Section 11 (Trace Tables) in ``IBM/4.3 Linkage Convention,'' + pages IBM/4.3-PSD:5-7 of Volume III of the IBM Academic Operating + System Manual dated July 1987.) */ + fprintf (file, "\t.long 0x%x\n", 0xdf07df08 + first_reg * 0x10); if (nargs > 15) nargs = 15; ! ! /* The number of parameter words and the register used as the stack ! pointer (encoded here as r1). ! ! Note: The MetWare Hich C Compiler R2.1y actually gets this wrong; ! it erroneously lists r13 but uses r1 as the stack too. But a bug in ! dbx 1.5 nullifies this mistake---most of the time. ! (Dbx retrieves the value of r13 saved on the stack which is often ! the value of r1 before the call.) */ ! ! fprintf (file, "\t.byte 0x%x1\n", nargs); ! output_encoded_offset (file, total_size); } else *************** *** 1208,1211 **** --- 1286,1297 ---- if (write_code) fprintf (file, "\tbr r15\n"); + + /* Table header (0xdf), no stack frame (0x02), + table header (0xdf) and no parameters saved (0x00). + + If GCC passed floating-point parameters in floating-point registers, + it might be necessary to change the final byte from 0x00 to 0x04. + Also a byte would be needed to specify the first floating-point + register. */ fprintf (file, "\t.long 0xdf02df00\n"); } *************** *** 1905,1907 **** --- 1991,2036 ---- for (i = 0; i < FP_HASH_SIZE; i++) fp_hash_table[i] = 0; + } + + /* Return the offset value of an automatic variable (N_LSYM) having + the given offset. Basically, we correct by going from a frame pointer to + stack pointer value. + */ + + int + romp_debugger_auto_correction(offset) + int offset; + { + int fp_to_sp; + + /* We really want to go from STACK_POINTER_REGNUM to + FRAME_POINTER_REGNUM, but this isn't defined. So go the other + direction and negate. */ + INITIAL_ELIMINATION_OFFSET (FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM, + fp_to_sp); + + /* The offset value points somewhere between the frame pointer and + the stack pointer. What is up from the frame pointer is down from the + stack pointer. Therefore the negation in the offset value too. */ + + return -(offset+fp_to_sp+4); + } + + /* Return the offset value of an argument having + the given offset. Basically, we correct by going from a arg pointer to + stack pointer value. */ + + int + romp_debugger_arg_correction (offset) + int offset; + { + int fp_to_argp; + + INITIAL_ELIMINATION_OFFSET (ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM, + fp_to_argp); + + /* Actually, something different happens if offset is from a floating-point + register argument, but we don't handle it here. */ + + return (offset - fp_to_argp); } diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/romp/romp.h gcc-2.5.0/config/romp/romp.h *** gcc-2.4.5/config/romp/romp.h Sun Apr 25 06:26:33 1993 --- gcc-2.5.0/config/romp/romp.h Sat Oct 2 04:23:05 1993 *************** *** 1,4 **** /* Definitions of target machine for GNU compiler, for ROMP chip. ! Copyright (C) 1989, 1991 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@nyu.edu) --- 1,4 ---- /* Definitions of target machine for GNU compiler, for ROMP chip. ! Copyright (C) 1989, 1991, 1993 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@nyu.edu) *************** *** 22,26 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dibm032 -Dunix" /* Print subsidiary information on the compiler version in use. */ --- 22,26 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dibm032 -Dunix -Asystem(unix) -Asystem(bsd) -Acpu(ibm032) -Amachine(ibm032)" /* Print subsidiary information on the compiler version in use. */ *************** *** 688,692 **** plus_constant (virtual_incoming_args_rtx, \ first_reg_offset * 4)), \ ! 4 - first_reg_offset); \ PRETEND_SIZE = (4 - first_reg_offset) * UNITS_PER_WORD; \ } \ --- 688,692 ---- plus_constant (virtual_incoming_args_rtx, \ first_reg_offset * 4)), \ ! 4 - first_reg_offset, (4 - first_reg_offset) * UNITS_PER_WORD); \ PRETEND_SIZE = (4 - first_reg_offset) * UNITS_PER_WORD; \ } \ *************** *** 1187,1196 **** #define SLOW_BYTE_ACCESS 1 ! /* Define if normal loads of shorter-than-word items from memory clears ! the rest of the bigs in the register. */ ! #define BYTE_LOADS_ZERO_EXTEND /* This is BSD, so it wants DBX format. */ #define DBX_DEBUGGING_INFO /* We don't have GAS for the RT yet, so don't write out special --- 1187,1229 ---- #define SLOW_BYTE_ACCESS 1 ! /* Define if operations between registers always perform the operation ! on the full register even if a narrower mode is specified. */ ! #define WORD_REGISTER_OPERATIONS ! ! /* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD ! will either zero-extend or sign-extend. The value of this macro should ! be the code that says which one of the two operations is implicitly ! done, NIL if none. */ ! #define LOAD_EXTEND_OP(MODE) ZERO_EXTEND /* This is BSD, so it wants DBX format. */ #define DBX_DEBUGGING_INFO + + /* Define the letter code used in a stabs entry for parameters passed + with the register attribute. + + GCC's default value, 'P', is used by dbx to refers to an external + procedure. The section 5 manual page for dbx implies that 'R' would be the + right letter, but dbx 1.5 has a bug in it that precludes its use. + Probably that is why neither hc or pcc use this. pcc puts in two + stabs entries: one for the parameter location and one for the register + location. The letter `r' (register) + would be okay, but it loses parameter attribute of the stabs entry. */ + #define DBX_REGPARM_STABS_LETTER 'R' + + /* A C expression for the integer offset value of an automatic variable + (N_LSYM) having address X (an RTX). This gets used in .stabs entries + for the local variables. Compare with the default definition. */ + extern int romp_debugger_auto_correction(); + #define DEBUGGER_AUTO_OFFSET(X) \ + (GET_CODE (X) == PLUS \ + ? romp_debugger_auto_correction (INTVAL (XEXP (X, 1)) ) \ + : 0 ) + + /* A C expression for the integer offset value of an argument (N_PSYM) + having address X (an RTX). The nominal offset is OFFSET. */ + extern int romp_debugger_arg_correction(); + #define DEBUGGER_ARG_OFFSET(OFFSET, X) \ + romp_debugger_arg_correction (OFFSET); /* We don't have GAS for the RT yet, so don't write out special diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/romp/romp.md gcc-2.5.0/config/romp/romp.md *** gcc-2.4.5/config/romp/romp.md Fri Apr 16 20:24:48 1993 --- gcc-2.5.0/config/romp/romp.md Mon Jul 5 17:43:00 1993 *************** *** 1,4 **** ;;- Machine description for ROMP chip for GNU C compiler ! ;; Copyright (C) 1988, 1991 Free Software Foundation, Inc. ;; Contributed by Richard Kenner (kenner@nyu.edu) --- 1,4 ---- ;;- Machine description for ROMP chip for GNU C compiler ! ;; Copyright (C) 1988, 1991, 1993 Free Software Foundation, Inc. ;; Contributed by Richard Kenner (kenner@nyu.edu) *************** *** 336,339 **** --- 336,343 ---- [(set_attr "type" "load")]) + + ;; use cal16 instead of cal for constant source because combine requires + ;; the high bits of the register to be 0 after a HImode load of a constant + (define_insn "" [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,b,Q") *************** *** 344,348 **** cas %0,%1,r0 lis %0,%1 ! cal %0,%L1(r0) get %0,$%1 lh%N1 %0,%1 --- 348,352 ---- cas %0,%1,r0 lis %0,%1 ! cal16 %0,%L1(r0) get %0,$%1 lh%N1 %0,%1 diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/romp/xm-romp.h gcc-2.5.0/config/romp/xm-romp.h *** gcc-2.4.5/config/romp/xm-romp.h Sat Dec 26 17:23:47 1992 --- gcc-2.5.0/config/romp/xm-romp.h Sat Jun 26 11:31:16 1993 *************** *** 1,4 **** /* Configuration for GNU C-compiler for IBM RT PC. ! Copyright (C) 1989, 1991 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,4 ---- /* Configuration for GNU C-compiler for IBM RT PC. ! Copyright (C) 1989, 1991, 1993 Free Software Foundation, Inc. This file is part of GNU CC. *************** *** 39,47 **** #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 /* If compiled with hc, use the built-in alloca and memcpy. --- 39,42 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/rs6000/aix31.h gcc-2.5.0/config/rs6000/aix31.h *** gcc-2.4.5/config/rs6000/aix31.h --- gcc-2.5.0/config/rs6000/aix31.h Wed Oct 20 21:56:49 1993 *************** *** 0 **** --- 1,31 ---- + /* Definitions of target machine for GNU compiler, + for IBM RS/6000 running AIX version 3.1. + Copyright (C) 1993 Free Software Foundation, Inc. + Contributed by Richard Kenner (kenner@nyu.edu) + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + + #include "rs6000/rs6000.h" + + /* AIX 3.2 defined _AIX32, but older versions do not. */ + #undef CPP_PREDEFINES + #define CPP_PREDEFINES "-D_IBMR2 -D_AIX -Asystem(unix) -Asystem(aix) -Acpu(rs6000) -Amachine(rs6000)" + + /* AIX 3.1 uses bit 15 in CROR as the magic nop. */ + #undef RS6000_CALL_GLUE + #define RS6000_CALL_GLUE "cror 15,15,15" Only in gcc-2.4.5/config/rs6000: aix32.h diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/rs6000/mach.h gcc-2.5.0/config/rs6000/mach.h *** gcc-2.4.5/config/rs6000/mach.h Tue Mar 23 14:23:07 1993 --- gcc-2.5.0/config/rs6000/mach.h Sat Oct 2 04:23:10 1993 *************** *** 25,29 **** /* We don't define AIX under MACH; instead we define `unix'. */ #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Drios -D_IBMR2 -Dunix" /* Define different binder options for MACH. */ --- 25,29 ---- /* We don't define AIX under MACH; instead we define `unix'. */ #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Drios -D_IBMR2 -Dunix -Asystem(unix) -Asystem(mach) -Acpu(rs6000) -Amachine(rs6000)" /* Define different binder options for MACH. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/rs6000/powerpc.h gcc-2.5.0/config/rs6000/powerpc.h *** gcc-2.4.5/config/rs6000/powerpc.h --- gcc-2.5.0/config/rs6000/powerpc.h Tue Oct 12 08:00:05 1993 *************** *** 0 **** --- 1,32 ---- + /* Definitions of target machine for GNU compiler, + for IBM RS/6000 PowerPC running AIX version 3.2. + Copyright (C) 1993 Free Software Foundation, Inc. + Contributed by David Edelsohn (edelsohn@npac.syr.edu). + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + + #include "rs6000/rs6000.h" + + #undef ASM_SPEC + #define ASM_SPEC "-u -m601" + + #undef TARGET_DEFAULT + #define TARGET_DEFAULT (MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS) + + #undef PROCESSOR_DEFAULT + #define PROCESSOR_DEFAULT PROCESSOR_PPC601 diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/rs6000/rs6000.c gcc-2.5.0/config/rs6000/rs6000.c *** gcc-2.4.5/config/rs6000/rs6000.c Fri Jun 11 21:44:40 1993 --- gcc-2.5.0/config/rs6000/rs6000.c Wed Oct 20 21:56:55 1993 *************** *** 37,40 **** --- 37,41 ---- extern char *language_string; + extern int profile_block_flag; #define min(A,B) ((A) < (B) ? (A) : (B)) *************** *** 41,44 **** --- 42,50 ---- #define max(A,B) ((A) > (B) ? (A) : (B)) + /* Target cpu type */ + + enum processor_type rs6000_cpu; + char *rs6000_cpu_string; + /* Set to non-zero by "fix" operation to indicate that itrunc and uitrunc must be defined. */ *************** *** 56,59 **** --- 62,157 ---- int rs6000_compare_fp_p; + /* Override command line options. Mostly we process the processor + type and sometimes adjust other TARGET_ options. */ + + void + rs6000_override_options () + { + int i; + + /* Simplify the entries below by making a mask for any POWER + variant and any PowerPC variant. */ + + #define POWER_MASKS (MASK_POWER | MASK_POWER2) + #define POWERPC_MASKS (MASK_POWERPC | MASK_POWERPCSQR | MASK_POWERPC64) + + static struct ptt + { + char *name; /* Canonical processor name. */ + enum processor_type processor; /* Processor type enum value. */ + int target_enable; /* Target flags to enable. */ + int target_disable; /* Target flags to disable. */ + } processor_target_table[] + = {{"all", PROCESSOR_DEFAULT, 0, POWER_MASKS | POWERPC_MASKS}, + {"rios", PROCESSOR_RIOS1, MASK_POWER, MASK_POWER2 | POWERPC_MASKS}, + {"rios1", PROCESSOR_RIOS1, MASK_POWER, MASK_POWER2 | POWERPC_MASKS}, + {"rios2", PROCESSOR_RIOS2, MASK_POWER | MASK_POWER2 , POWERPC_MASKS}, + {"601", PROCESSOR_PPC601, + MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS, + MASK_POWER2 | MASK_POWERPCSQR | MASK_POWERPC64}, + {"mpc601", PROCESSOR_PPC601, + MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS, + MASK_POWER2 | MASK_POWERPCSQR | MASK_POWERPC64}, + {"ppc601", PROCESSOR_PPC601, + MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS, + MASK_POWER2 | MASK_POWERPCSQR | MASK_POWERPC64}, + {"603", PROCESSOR_PPC603, + MASK_POWERPC | MASK_POWERPCSQR | MASK_NEW_MNEMONICS, + POWER_MASKS | MASK_POWERPC64}, + {"mpc603", PROCESSOR_PPC603, + MASK_POWERPC | MASK_POWERPCSQR | MASK_NEW_MNEMONICS, + POWER_MASKS | MASK_POWERPC64}, + {"ppc603", PROCESSOR_PPC603, + MASK_POWERPC | MASK_POWERPCSQR | MASK_NEW_MNEMONICS, + POWER_MASKS | MASK_POWERPC64}, + {"604", PROCESSOR_PPC604, + MASK_POWERPC | MASK_POWERPCSQR | MASK_NEW_MNEMONICS, + POWER_MASKS | MASK_POWERPC64}, + {"mpc604", PROCESSOR_PPC604, + MASK_POWERPC | MASK_POWERPCSQR | MASK_NEW_MNEMONICS, + POWER_MASKS | MASK_POWERPC64}, + {"ppc604", PROCESSOR_PPC604, + MASK_POWERPC | MASK_POWERPCSQR | MASK_NEW_MNEMONICS, + POWER_MASKS | MASK_POWERPC64}, + {"620", PROCESSOR_PPC620, + (MASK_POWERPC | MASK_POWERPCSQR | MASK_POWERPC64 + | MASK_NEW_MNEMONICS), + POWER_MASKS}, + {"mpc620", PROCESSOR_PPC620, + (MASK_POWERPC | MASK_POWERPCSQR | MASK_POWERPC64 + | MASK_NEW_MNEMONICS), + POWER_MASKS}, + {"ppc620", PROCESSOR_PPC620, + (MASK_POWERPC | MASK_POWERPCSQR | MASK_POWERPC64 + | MASK_NEW_MNEMONICS), + POWER_MASKS}}; + + int ptt_size = sizeof (processor_target_table) / sizeof (struct ptt); + + profile_block_flag = 0; + + /* Identify the processor type */ + if (rs6000_cpu_string == 0) + rs6000_cpu = PROCESSOR_DEFAULT; + else + { + for (i = 0; i < ptt_size; i++) + if (! strcmp (rs6000_cpu_string, processor_target_table[i].name)) + { + rs6000_cpu = processor_target_table[i].processor; + target_flags |= processor_target_table[i].target_enable; + target_flags &= ~processor_target_table[i].target_disable; + break; + } + + if (i == ptt_size) + { + error ("bad value (%s) for -mcpu= switch", rs6000_cpu_string); + rs6000_cpu_string = "default"; + rs6000_cpu = PROCESSOR_DEFAULT; + } + } + } + /* Return non-zero if this function is known to have a null epilogue. */ *************** *** 145,152 **** enum machine_mode mode; { ! if (GET_CODE (op) == CONST_INT) ! return short_cint_operand (op, mode); ! ! return gpc_reg_operand (op, mode); } --- 243,247 ---- enum machine_mode mode; { ! return short_cint_operand (op, mode) || gpc_reg_operand (op, mode); } *************** *** 384,387 **** --- 479,497 ---- } + + /* Return 1 if the operand is a SYMBOL_REF for a function known to be in + this file. */ + + int + current_file_function_operand (op, mode) + register rtx op; + enum machine_mode mode; + { + return (GET_CODE (op) == SYMBOL_REF + && (SYMBOL_REF_FLAG (op) + || op == XEXP (DECL_RTL (current_function_decl), 0))); + } + + /* Return 1 if this operand is a valid input for a move insn. */ *************** *** 391,402 **** enum machine_mode mode; { if (memory_operand (op, mode)) return 1; ! /* For floating-point or multi-word mode, only register or memory ! is valid. */ if (GET_MODE_CLASS (mode) == MODE_FLOAT || GET_MODE_SIZE (mode) > UNITS_PER_WORD) ! return gpc_reg_operand (op, mode); /* The only cases left are integral modes one word or smaller (we --- 501,519 ---- enum machine_mode mode; { + /* Memory is always valid. */ if (memory_operand (op, mode)) return 1; ! /* For floating-point, easy constants are valid. */ ! if (GET_MODE_CLASS (mode) == MODE_FLOAT ! && CONSTANT_P (op) ! && easy_fp_constant (op, mode)) ! return 1; ! ! /* For floating-point or multi-word mode, the only remaining valid type ! is a register. */ if (GET_MODE_CLASS (mode) == MODE_FLOAT || GET_MODE_SIZE (mode) > UNITS_PER_WORD) ! return register_operand (op, mode); /* The only cases left are integral modes one word or smaller (we *************** *** 404,408 **** register. */ if (register_operand (op, mode)) ! return; /* For HImode and QImode, any constant is valid. */ --- 521,525 ---- register. */ if (register_operand (op, mode)) ! return 1; /* For HImode and QImode, any constant is valid. */ *************** *** 710,722 **** switch (code) { case 'A': /* If X is a constant integer whose low-order 5 bits are zero, write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug ! in the RS/6000 assembler where "sri" with a zero shift count write a trash instruction. */ if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0) ! fprintf (file, "l"); else ! fprintf (file, "r"); return; --- 827,845 ---- switch (code) { + case '.': + /* Write out an instruction after the call which may be replaced + with glue code by the loader. This depends on the AIX version. */ + asm_fprintf (file, RS6000_CALL_GLUE); + return; + case 'A': /* If X is a constant integer whose low-order 5 bits are zero, write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug ! in the AIX assembler where "sri" with a zero shift count write a trash instruction. */ if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0) ! putc ('l', file); else ! putc ('r', file); return; *************** *** 771,775 **** fprintf(file, "%d", 4 * (REGNO (x) - 68) + 3); ! break; case 'f': --- 894,898 ---- fprintf(file, "%d", 4 * (REGNO (x) - 68) + 3); ! return; case 'f': *************** *** 797,803 **** output_operand_lossage ("invalid %%G value"); else if (INTVAL (x) >= 0) ! fprintf (file, "z"); else ! fprintf (file, "m"); return; --- 920,926 ---- output_operand_lossage ("invalid %%G value"); else if (INTVAL (x) >= 0) ! putc ('z', file); else ! putc ('m', file); return; *************** *** 822,826 **** /* Print `i' if this is a constant, else nothing. */ if (INT_P (x)) ! fprintf (file, "i"); return; --- 945,949 ---- /* Print `i' if this is a constant, else nothing. */ if (INT_P (x)) ! putc ('i', file); return; *************** *** 841,845 **** output_operand_lossage ("invalid %%J code"); else ! fprintf (file, "%d", i + 1); return; --- 964,969 ---- output_operand_lossage ("invalid %%J code"); else ! /* If we want bit 31, write a shift count of zero, not 32. */ ! fprintf (file, "%d", i == 31 ? 0 : i + 1); return; *************** *** 917,921 **** if ((val & 1) && val >= 0) { ! fprintf (file, "31"); return; } --- 1041,1045 ---- if ((val & 1) && val >= 0) { ! fputs ("31", file); return; } *************** *** 1012,1018 **** || GET_CODE (x) == LT || GET_CODE (x) == GT || GET_CODE (x) == LTU || GET_CODE (x) == GTU) ! fprintf (file, "12"); else ! fprintf (file, "4"); return; --- 1136,1142 ---- || GET_CODE (x) == LT || GET_CODE (x) == GT || GET_CODE (x) == LTU || GET_CODE (x) == GTU) ! fputs ("12", file); else ! putc ('4', file); return; *************** *** 1028,1034 **** || GET_CODE (x) == LT || GET_CODE (x) == GT || GET_CODE (x) == LTU || GET_CODE (x) == GTU) ! fprintf (file, "4"); else ! fprintf (file, "12"); return; --- 1152,1158 ---- || GET_CODE (x) == LT || GET_CODE (x) == GT || GET_CODE (x) == LTU || GET_CODE (x) == GTU) ! putc ('4', file); else ! fputs ("12", file); return; *************** *** 1038,1042 **** output_operand_lossage ("invalid %%u value"); ! fprintf (file, "%d", (INT_LOWPART (x) >> 16) & 0xffff); return; --- 1162,1166 ---- output_operand_lossage ("invalid %%u value"); ! fprintf (file, "0x%x", (INT_LOWPART (x) >> 16) & 0xffff); return; *************** *** 1046,1050 **** && (GET_CODE (XEXP (x, 0)) == PRE_INC || GET_CODE (XEXP (x, 0)) == PRE_DEC)) ! fprintf (file, "u"); return; --- 1170,1174 ---- && (GET_CODE (XEXP (x, 0)) == PRE_INC || GET_CODE (XEXP (x, 0)) == PRE_DEC)) ! putc ('u', file); return; *************** *** 1071,1075 **** if (GET_CODE (x) == MEM && LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0))) ! fprintf (file, "x"); return; --- 1195,1199 ---- if (GET_CODE (x) == MEM && LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0))) ! putc ('x', file); return; *************** *** 1095,1099 **** abort (); ! fprintf (file, "."); RS6000_OUTPUT_BASENAME (file, XSTR (x, 0)); return; --- 1219,1223 ---- abort (); ! putc ('.', file); RS6000_OUTPUT_BASENAME (file, XSTR (x, 0)); return; *************** *** 1131,1135 **** else output_addr_const (file, x); ! break; default: --- 1255,1259 ---- else output_addr_const (file, x); ! return; default: *************** *** 1150,1154 **** { output_addr_const (file, x); ! fprintf (file, "(2)"); } else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG) --- 1274,1283 ---- { output_addr_const (file, x); ! /* When TARGET_MINIMAL_TOC, use the indirected toc table pointer instead ! of the toc pointer. */ ! if (TARGET_MINIMAL_TOC) ! fprintf (file, "(30)"); ! else ! fprintf (file, "(2)"); } else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG) *************** *** 1223,1227 **** { int size; - int i; /* We have the six fixed words, plus the size of the register save --- 1352,1355 ---- *************** *** 1305,1328 **** /* If we use the link register, get it into r0. */ if (regs_ever_live[65]) ! fprintf (file, "\tmflr 0\n"); /* If we need to save CR, put it into r12. */ if (must_save_cr ()) ! fprintf (file, "\tmfcr 12\n"); /* Do any required saving of fpr's. If only one or two to save, do it ! ourself. Otherwise, call function. */ if (first_fp_reg == 62) ! fprintf (file, "\tstfd 30,-16(1)\n\tstfd 31,-8(1)\n"); else if (first_fp_reg == 63) ! fprintf (file, "\tstfd 31,-8(1)\n"); else if (first_fp_reg != 64) ! fprintf (file, "\tbl ._savef%d\n\tcror 15,15,15\n", first_fp_reg - 32); /* Now save gpr's. */ ! if (first_reg == 31) ! fprintf (file, "\tst 31,%d(1)\n", -4 - (64 - first_fp_reg) * 8); else if (first_reg != 32) ! fprintf (file, "\tstm %d,%d(1)\n", first_reg, - (32 - first_reg) * 4 - (64 - first_fp_reg) * 8); --- 1433,1466 ---- /* If we use the link register, get it into r0. */ if (regs_ever_live[65]) ! asm_fprintf (file, "\tmflr 0\n"); /* If we need to save CR, put it into r12. */ if (must_save_cr ()) ! asm_fprintf (file, "\tmfcr 12\n"); /* Do any required saving of fpr's. If only one or two to save, do it ! ourself. Otherwise, call function. Note that since they are statically ! linked, we do not need a nop following them. */ if (first_fp_reg == 62) ! asm_fprintf (file, "\tstfd 30,-16(1)\n\tstfd 31,-8(1)\n"); else if (first_fp_reg == 63) ! asm_fprintf (file, "\tstfd 31,-8(1)\n"); else if (first_fp_reg != 64) ! asm_fprintf (file, "\tbl ._savef%d\n", first_fp_reg - 32); /* Now save gpr's. */ ! if (! TARGET_POWER || first_reg == 31) ! { ! int regno, loc; ! ! for (regno = first_reg, ! loc = - (32 - first_reg) * 4 - (64 - first_fp_reg) * 8; ! regno < 32; ! regno++, loc += 4) ! asm_fprintf (file, "\t{st|stw} %d,%d(1)\n", regno, loc); ! } ! else if (first_reg != 32) ! asm_fprintf (file, "\t{stm|stmw} %d,%d(1)\n", first_reg, - (32 - first_reg) * 4 - (64 - first_fp_reg) * 8); *************** *** 1329,1337 **** /* Save lr if we used it. */ if (regs_ever_live[65]) ! fprintf (file, "\tst 0,8(1)\n"); /* Save CR if we use any that must be preserved. */ if (must_save_cr ()) ! fprintf (file, "\tst 12,4(1)\n"); /* Update stack and set back pointer. */ --- 1467,1475 ---- /* Save lr if we used it. */ if (regs_ever_live[65]) ! asm_fprintf (file, "\t{st|stw} 0,8(1)\n"); /* Save CR if we use any that must be preserved. */ if (must_save_cr ()) ! asm_fprintf (file, "\t{st|stw} 12,4(1)\n"); /* Update stack and set back pointer. */ *************** *** 1339,1348 **** { if (total_size < 32767) ! fprintf (file, "\tstu 1,%d(1)\n", - total_size); else { ! fprintf (file, "\tcau 0,0,%d\n\toril 0,0,%d\n", (total_size >> 16) & 0xffff, total_size & 0xffff); ! fprintf (file, "\tsf 12,0,1\n\tst 1,0(12)\n\toril 1,12,0\n"); } } --- 1477,1487 ---- { if (total_size < 32767) ! asm_fprintf (file, "\t{stu|stwu} 1,%d(1)\n", - total_size); else { ! asm_fprintf (file, "\t{cau|addis} 0,0,%d\n\t{oril|ori} 0,0,%d\n", (total_size >> 16) & 0xffff, total_size & 0xffff); ! asm_fprintf (file, "\t{sf|subfc} 12,0,1\n"); ! asm_fprintf (file, "\t{st|stw} 1,0(12)\n\t{oril|ori} 1,12,0\n"); } } *************** *** 1350,1354 **** /* Set frame pointer, if needed. */ if (frame_pointer_needed) ! fprintf (file, "\toril 31,1,0\n"); } --- 1489,1498 ---- /* Set frame pointer, if needed. */ if (frame_pointer_needed) ! asm_fprintf (file, "\t{oril|ori} 31,1,0\n"); ! ! /* If TARGET_MINIMAL_TOC, and the constant pool is needed, then load the ! TOC_TABLE address into register 30. */ ! if (TARGET_MINIMAL_TOC && get_pool_size () != 0) ! asm_fprintf (file, "\t{l|lwz} 30,LCTOC..0(2)\n"); } *************** *** 1381,1412 **** if (frame_pointer_needed || current_function_calls_alloca || total_size > 32767) ! fprintf (file, "\tl 1,0(1)\n"); else if (must_push) ! fprintf (file, "\tai 1,1,%d\n", total_size); /* Get the old lr if we saved it. */ if (regs_ever_live[65]) ! fprintf (file, "\tl 0,8(1)\n"); /* Get the old cr if we saved it. */ if (must_save_cr ()) ! fprintf (file, "\tl 12,4(1)\n"); /* Set LR here to try to overlap restores below. */ if (regs_ever_live[65]) ! fprintf (file, "\tmtlr 0\n"); /* Restore gpr's. */ ! if (first_reg == 31) ! fprintf (file, "\tl 31,%d(1)\n", -4 - (64 - first_fp_reg) * 8); else if (first_reg != 32) ! fprintf (file, "\tlm %d,%d(1)\n", first_reg, ! - (32 - first_reg) * 4 - (64 - first_fp_reg) * 8); /* Restore fpr's if we can do it without calling a function. */ if (first_fp_reg == 62) ! fprintf (file, "\tlfd 30,-16(1)\n\tlfd 31,-8(1)\n"); else if (first_fp_reg == 63) ! fprintf (file, "\tlfd 31,-8(1)\n"); /* If we saved cr, restore it here. Just those of cr2, cr3, and cr4 --- 1525,1565 ---- if (frame_pointer_needed || current_function_calls_alloca || total_size > 32767) ! asm_fprintf (file, "\t{l|lwz} 1,0(1)\n"); else if (must_push) ! asm_fprintf (file, "\t{ai|addic} 1,1,%d\n", total_size); /* Get the old lr if we saved it. */ if (regs_ever_live[65]) ! asm_fprintf (file, "\t{l|lwz} 0,8(1)\n"); /* Get the old cr if we saved it. */ if (must_save_cr ()) ! asm_fprintf (file, "\t{l|lwz} 12,4(1)\n"); /* Set LR here to try to overlap restores below. */ if (regs_ever_live[65]) ! asm_fprintf (file, "\tmtlr 0\n"); /* Restore gpr's. */ ! if (! TARGET_POWER || first_reg == 31) ! { ! int regno, loc; ! ! for (regno = first_reg, ! loc = - (32 - first_reg) * 4 - (64 - first_fp_reg) * 8; ! regno < 32; ! regno++, loc += 4) ! asm_fprintf (file, "\t{l|lwz} %d,%d(1)\n", regno, loc); ! } ! else if (first_reg != 32) ! asm_fprintf (file, "\t{lm|lmw} %d,%d(1)\n", first_reg, ! - (32 - first_reg) * 4 - (64 - first_fp_reg) * 8); /* Restore fpr's if we can do it without calling a function. */ if (first_fp_reg == 62) ! asm_fprintf (file, "\tlfd 30,-16(1)\n\tlfd 31,-8(1)\n"); else if (first_fp_reg == 63) ! asm_fprintf (file, "\tlfd 31,-8(1)\n"); /* If we saved cr, restore it here. Just those of cr2, cr3, and cr4 *************** *** 1413,1420 **** that were used. */ if (must_save_cr ()) ! fprintf (file, "\tmtcrf %d,12\n", ! (regs_ever_live[70] != 0) * 0x20 ! + (regs_ever_live[71] != 0) * 0x10 ! + (regs_ever_live[72] != 0) * 0x8); /* If we have to restore more than two FP registers, branch to the --- 1566,1573 ---- that were used. */ if (must_save_cr ()) ! asm_fprintf (file, "\tmtcrf %d,12\n", ! (regs_ever_live[70] != 0) * 0x20 ! + (regs_ever_live[71] != 0) * 0x10 ! + (regs_ever_live[72] != 0) * 0x8); /* If we have to restore more than two FP registers, branch to the *************** *** 1421,1427 **** restore function. It will return to our caller. */ if (first_fp_reg < 62) ! fprintf (file, "\tb ._restf%d\n\tcror 15,15,15\n", first_fp_reg - 32); else ! fprintf (file, "\tbr\n"); } --- 1574,1580 ---- restore function. It will return to our caller. */ if (first_fp_reg < 62) ! asm_fprintf (file, "\tb ._restf%d\n", first_fp_reg - 32); else ! asm_fprintf (file, "\t{br|blr}\n"); } *************** *** 1615,1619 **** ASM_OUTPUT_INTERNAL_LABEL (file, "LC", labelno); ! /* Handle FP constants specially. */ if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode --- 1768,1774 ---- ASM_OUTPUT_INTERNAL_LABEL (file, "LC", labelno); ! /* Handle FP constants specially. Note that if we have a minimal ! TOC, things we put here aren't actually in the TOC, so we can allow ! FP constants. */ if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode *************** *** 1620,1632 **** && TARGET_FLOAT_FORMAT == HOST_FLOAT_FORMAT && BITS_PER_WORD == HOST_BITS_PER_INT ! && TARGET_FP_IN_TOC) { ! fprintf (file, "\t.tc FD_%x_%x[TC],%d,%d\n", ! CONST_DOUBLE_LOW (x), CONST_DOUBLE_HIGH (x), ! CONST_DOUBLE_LOW (x), CONST_DOUBLE_HIGH (x)); return; } else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode ! && TARGET_FP_IN_TOC) { rtx val = operand_subword (x, 0, 0, SFmode); --- 1775,1791 ---- && TARGET_FLOAT_FORMAT == HOST_FLOAT_FORMAT && BITS_PER_WORD == HOST_BITS_PER_INT ! && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) { ! if (TARGET_MINIMAL_TOC) ! fprintf (file, "\t.long %d\n\t.long %d\n", ! CONST_DOUBLE_LOW (x), CONST_DOUBLE_HIGH (x)); ! else ! fprintf (file, "\t.tc FD_%x_%x[TC],%d,%d\n", ! CONST_DOUBLE_LOW (x), CONST_DOUBLE_HIGH (x), ! CONST_DOUBLE_LOW (x), CONST_DOUBLE_HIGH (x)); return; } else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode ! && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) { rtx val = operand_subword (x, 0, 0, SFmode); *************** *** 1635,1639 **** abort (); ! fprintf (file, "\t.tc FS_%x[TC],%d\n", INTVAL (val), INTVAL (val)); return; } --- 1794,1801 ---- abort (); ! if (TARGET_MINIMAL_TOC) ! fprintf (file, "\t.long %d\n", INTVAL (val)); ! else ! fprintf (file, "\t.tc FS_%x[TC],%d\n", INTVAL (val), INTVAL (val)); return; } *************** *** 1654,1666 **** abort (); ! fprintf (file, "\t.tc "); ! RS6000_OUTPUT_BASENAME (file, name); ! if (offset < 0) ! fprintf (file, ".N%d", - offset); ! else if (offset) ! fprintf (file, ".P%d", offset); ! fprintf (file, "[TC],"); output_addr_const (file, x); fprintf (file, "\n"); --- 1816,1833 ---- abort (); ! if (TARGET_MINIMAL_TOC) ! fprintf (file, "\t.long "); ! else ! { ! fprintf (file, "\t.tc "); ! RS6000_OUTPUT_BASENAME (file, name); ! if (offset < 0) ! fprintf (file, ".N%d", - offset); ! else if (offset) ! fprintf (file, ".P%d", offset); ! fprintf (file, "[TC],"); ! } output_addr_const (file, x); fprintf (file, "\n"); diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/rs6000/rs6000.h gcc-2.5.0/config/rs6000/rs6000.h *** gcc-2.4.5/config/rs6000/rs6000.h Wed May 19 18:07:47 1993 --- gcc-2.5.0/config/rs6000/rs6000.h Thu Oct 21 21:54:54 1993 *************** *** 1,4 **** /* Definitions of target machine for GNU compiler, for IBM RS/6000. ! Copyright (C) 1992 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@nyu.edu) --- 1,4 ---- /* Definitions of target machine for GNU compiler, for IBM RS/6000. ! Copyright (C) 1992, 1993 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@nyu.edu) *************** *** 26,30 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-D_IBMR2 -D_AIX" /* Print subsidiary information on the compiler version in use. */ --- 26,30 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-D_IBMR2 -D_AIX -D_AIX32 -Asystem(unix) -Asystem(aix) -Acpu(rs6000) -Amachine(rs6000)" /* Print subsidiary information on the compiler version in use. */ *************** *** 52,56 **** #define LINK_SPEC "-T512 -H512 -btextro -bhalt:4 -bnodelcsect\ ! %{static:-bnso -bI:/lib/syscalls.exp}" /* Profiled library versions are used by linking with special directories. */ --- 52,56 ---- #define LINK_SPEC "-T512 -H512 -btextro -bhalt:4 -bnodelcsect\ ! %{static:-bnso -bI:/lib/syscalls.exp} %{g*:-bexport:/usr/lib/libg.exp}" /* Profiled library versions are used by linking with special directories. */ *************** *** 64,77 **** #define RELATIVE_PREFIX_NOT_LINKDIR ! /* Run-time compilation parameters selecting different hardware subsets. */ ! /* Flag to allow putting fp constants in the TOC; can be turned off when ! the TOC overflows. */ ! #define TARGET_FP_IN_TOC (target_flags & 1) ! extern int target_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 } --- 64,114 ---- #define RELATIVE_PREFIX_NOT_LINKDIR ! /* Architecture type. */ ! extern int target_flags; ! /* Use POWER architecture instructions and MQ register. */ ! #define MASK_POWER 0x01 ! /* Use POWER2 extensions to POWER architecture. */ ! #define MASK_POWER2 0x02 ! ! /* Use PowerPC architecture instructions. */ ! #define MASK_POWERPC 0x04 ! ! /* Use PowerPC square root instructions. */ ! #define MASK_POWERPCSQR 0x08 ! ! /* Use PowerPC-64 architecture instructions. */ ! #define MASK_POWERPC64 0x10 ! ! /* Use revised mnemonic names defined for PowerPC architecture. */ ! #define MASK_NEW_MNEMONICS 0x20 ! ! /* Disable placing fp constants in the TOC; can be turned on when the ! TOC overflows. */ ! #define MASK_NO_FP_IN_TOC 0x40 ! ! /* Output only one TOC entry per module. Normally linking fails if ! there are more than 16K unique variables/constants in an executable. With ! this option, linking fails only if there are more than 16K modules, or ! if there are more than 16K unique variables/constant in a single module. ! This is at the cost of having 2 extra loads and one extra store per ! function, and one less allocatable register. */ ! #define MASK_MINIMAL_TOC 0x80 ! ! #define TARGET_POWER (target_flags & MASK_POWER) ! #define TARGET_POWER2 (target_flags & MASK_POWER2) ! #define TARGET_POWERPC (target_flags & MASK_POWERPC) ! #define TARGET_POWERPCSQR (target_flags & MASK_POWERPCSQR) ! #define TARGET_POWERPC64 (target_flags & MASK_POWERPC64) ! #define TARGET_NEW_MNEMONICS (target_flags & MASK_NEW_MNEMONICS) ! #define TARGET_NO_FP_IN_TOC (target_flags & MASK_NO_FP_IN_TOC) ! #define TARGET_MINIMAL_TOC (target_flags & MASK_MINIMAL_TOC) ! ! /* Run-time compilation parameters selecting different hardware subsets. ! ! Macro to define tables used to set the flags. This is a list in braces of pairs in braces, each pair being { "NAME", VALUE } *************** *** 79,90 **** An empty string NAME is used to identify the default VALUE. */ ! #define TARGET_SWITCHES \ ! {{"fp-in-toc", 1}, \ ! {"no-fp-in-toc", -1}, \ ! { "", TARGET_DEFAULT}} ! #define TARGET_DEFAULT 1 ! /* On the RS/6000, we turn on various flags if optimization is selected. */ #define OPTIMIZATION_OPTIONS(LEVEL) \ --- 116,193 ---- An empty string NAME is used to identify the default VALUE. */ ! #define TARGET_SWITCHES \ ! {{"power", MASK_POWER}, \ ! {"power2", MASK_POWER | MASK_POWER2}, \ ! {"no-power2", - MASK_POWER2}, \ ! {"no-power", - (MASK_POWER | MASK_POWER2)}, \ ! {"powerpc", MASK_POWERPC}, \ ! {"no-powerpc", - (MASK_POWERPC | MASK_POWERPCSQR | MASK_POWERPC64)}, \ ! {"powerpc-sqr", MASK_POWERPC | MASK_POWERPCSQR}, \ ! {"no-powerpc-sqr", - MASK_POWERPCSQR}, \ ! {"powerpc64", MASK_POWERPC | MASK_POWERPC64}, \ ! {"no-powerpc64", -MASK_POWERPC64}, \ ! {"new-mnemonics", MASK_NEW_MNEMONICS}, \ ! {"old-mnemonics", -MASK_NEW_MNEMONICS}, \ ! {"normal-toc", - (MASK_NO_FP_IN_TOC | MASK_MINIMAL_TOC)}, \ ! {"fp-in-toc", - MASK_NO_FP_IN_TOC}, \ ! {"no-fp-in-toc", MASK_NO_FP_IN_TOC}, \ ! {"minimal-toc", MASK_MINIMAL_TOC}, \ ! {"no-minimal-toc", - MASK_MINIMAL_TOC}, \ ! {"", TARGET_DEFAULT}} ! ! #define TARGET_DEFAULT MASK_POWER ! ! /* Processor type. */ ! enum processor_type ! {PROCESSOR_RIOS1, ! PROCESSOR_RIOS2, ! PROCESSOR_PPC601, ! PROCESSOR_PPC603, ! PROCESSOR_PPC604, ! PROCESSOR_PPC620}; ! ! extern enum processor_type rs6000_cpu; ! ! /* Recast the processor type to the cpu attribute. */ ! #define rs6000_cpu_attr ((enum attr_cpu)rs6000_cpu) ! ! /* Define the default processor. This is overridden by other tm.h files. */ ! #define PROCESSOR_DEFAULT PROCESSOR_RIOS1 ! ! /* Specify the dialect of assembler to use. New mnemonics is dialect one ! and the old mnemonics are dialect zero. */ ! #define ASSEMBLER_DIALECT TARGET_NEW_MNEMONICS ? 1 : 0 ! ! /* This macro is similar to `TARGET_SWITCHES' but defines names of ! command options that have values. Its definition is an ! initializer with a subgrouping for each command option. ! ! Each subgrouping contains a string constant, that defines the ! fixed part of the option name, and the address of a variable. ! The variable, type `char *', is set to the variable part of the ! given option if the fixed part matches. The actual option name ! is made by appending `-m' to the specified name. ! ! Here is an example which defines `-mshort-data-NUMBER'. If the ! given option is `-mshort-data-512', the variable `m88k_short_data' ! will be set to the string `"512"'. ! ! extern char *m88k_short_data; ! #define TARGET_OPTIONS { { "short-data-", &m88k_short_data } } */ ! ! #define TARGET_OPTIONS \ ! { {"cpu=", &rs6000_cpu_string}} ! ! extern char *rs6000_cpu_string; ! ! /* Sometimes certain combinations of command options do not make sense ! on a particular target machine. You can define a macro ! `OVERRIDE_OPTIONS' to take account of this. This macro, if ! defined, is executed once just after all the command options have ! been parsed. ! On the RS/6000 this is used to define the target cpu type. */ ! #define OVERRIDE_OPTIONS rs6000_override_options () #define OPTIMIZATION_OPTIONS(LEVEL) \ *************** *** 96,106 **** } \ } - - /* Define this to modify the options specified by the user. */ - - #define OVERRIDE_OPTIONS \ - { \ - profile_block_flag = 0; \ - } /* target machine storage layout */ --- 199,202 ---- *************** *** 309,313 **** (FP_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_FLOAT \ : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC \ ! : ! INT_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_INT \ : 1) --- 405,410 ---- (FP_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_FLOAT \ : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC \ ! : ! INT_REGNO_P (REGNO) ? (GET_MODE_CLASS (MODE) == MODE_INT \ ! && GET_MODE_SIZE (MODE) <= UNITS_PER_WORD) \ : 1) *************** *** 365,368 **** --- 462,474 ---- (COST) = 0; /* Anti or output dependence. */ + /* Define this macro to change register usage conditional on target flags. + Set MQ register fixed (already call_used) if not POWER architecture + (RIOS1, RIOS2, and PPC601) so that it will not be allocated. + Provide alternate register names for ppcas assembler */ + + #define CONDITIONAL_REGISTER_USAGE \ + if (!TARGET_POWER) \ + fixed_regs[64] = 1; + /* Specify the registers used for certain standard purposes. The values of these macros are register numbers. */ *************** *** 548,551 **** --- 654,663 ---- secondary_reload_class (CLASS, MODE, IN) + /* If we are copying between FP registers and anything else, we need a memory + location. */ + + #define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \ + ((CLASS1) != (CLASS2) && ((CLASS1) == FLOAT_REGS || (CLASS2) == FLOAT_REGS)) + /* Return the maximum number of consecutive registers needed to represent mode MODE in a register of class CLASS. *************** *** 800,804 **** plus_constant (virtual_incoming_args_rtx, \ first_reg_offset * 4)), \ ! 8 - first_reg_offset); \ PRETEND_SIZE = (8 - first_reg_offset) * UNITS_PER_WORD; \ } \ --- 912,916 ---- plus_constant (virtual_incoming_args_rtx, \ first_reg_offset * 4)), \ ! 8 - first_reg_offset, (8 - first_reg_offset) * UNITS_PER_WORD); \ PRETEND_SIZE = (8 - first_reg_offset) * UNITS_PER_WORD; \ } \ *************** *** 885,889 **** frame pointer register can often be eliminated in favor of the stack pointer register. Secondly, the argument pointer register can always be ! eliminated; it is replaced with either the stack or frame pointer. */ /* This is an array of structures. Each structure initializes one pair --- 997,1006 ---- frame pointer register can often be eliminated in favor of the stack pointer register. Secondly, the argument pointer register can always be ! eliminated; it is replaced with either the stack or frame pointer. ! ! In addition, we use the elimination mechanism to see if r30 is needed ! Initially we assume that it isn't. If it is, we spill it. This is done ! by making it an eliminable register. We replace it with itself so that ! if it isn't needed, then existing uses won't be modified. */ /* This is an array of structures. Each structure initializes one pair *************** *** 894,898 **** {{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ ! { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM} } /* Given FROM and TO register numbers, say whether this elimination is allowed. --- 1011,1016 ---- {{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ ! { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \ ! { 30, 30} } /* Given FROM and TO register numbers, say whether this elimination is allowed. *************** *** 900,908 **** For the RS/6000, if frame pointer elimination is being done, we would like ! to convert ap into fp, not sp. */ #define CAN_ELIMINATE(FROM, TO) \ ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM \ ? ! frame_pointer_needed \ : 1) --- 1018,1030 ---- For the RS/6000, if frame pointer elimination is being done, we would like ! to convert ap into fp, not sp. + We need r30 if -mmininal-toc was specified, and there are constant pool + references. */ + #define CAN_ELIMINATE(FROM, TO) \ ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM \ ? ! frame_pointer_needed \ + : (FROM) == 30 ? ! TARGET_MINIMAL_TOC || get_pool_size () == 0 \ : 1) *************** *** 932,935 **** --- 1054,1059 ---- (OFFSET) = 0; \ } \ + else if ((FROM) == 30) \ + (OFFSET) = 0; \ else \ abort (); \ *************** *** 1191,1197 **** #define SLOW_BYTE_ACCESS 1 ! /* Define if normal loads of shorter-than-word items from memory clears ! the rest of the bigs in the register. */ ! #define BYTE_LOADS_ZERO_EXTEND /* Define if loading short immediate values into registers sign extends. */ --- 1315,1327 ---- #define SLOW_BYTE_ACCESS 1 ! /* Define if operations between registers always perform the operation ! on the full register even if a narrower mode is specified. */ ! #define WORD_REGISTER_OPERATIONS ! ! /* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD ! will either zero-extend or sign-extend. The value of this macro should ! be the code that says which one of the two operations is implicitly ! done, NIL if none. */ ! #define LOAD_EXTEND_OP(MODE) ZERO_EXTEND /* Define if loading short immediate values into registers sign extends. */ *************** *** 1238,1245 **** #define NO_FUNCTION_CSE ! /* Define this if shift instructions ignore all but the low-order ! few bits. */ ! #define SHIFT_COUNT_TRUNCATED /* Use atexit for static constructors/destructors, instead of defining our own exit function. */ --- 1368,1379 ---- #define NO_FUNCTION_CSE ! /* Define this to be nonzero if shift instructions ignore all but the low-order ! few bits. ! ! The sle and sre instructions which allow SHIFT_COUNT_TRUNCATED ! have been dropped from the PowerPC architecture. */ + #define SHIFT_COUNT_TRUNCATED TARGET_POWER ? 1 : 0 + /* Use atexit for static constructors/destructors, instead of defining our own exit function. */ *************** *** 1411,1414 **** --- 1545,1558 ---- #define READONLY_DATA_SECTION read_only_data_section + /* If we are referencing a function that is static or is known to be + in this file, make the SYMBOL_REF special. We can use this to indicate + that we can branch to this function without emitting a no-op after the + call. */ + + #define ENCODE_SECTION_INFO(DECL) \ + if (TREE_CODE (DECL) == FUNCTION_DECL \ + && (TREE_ASM_WRITTEN (DECL) || ! TREE_PUBLIC (DECL))) \ + SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1; + /* Indicate that jump tables go in the text section. */ *************** *** 1456,1462 **** toc_section () \ { \ ! if (in_section != toc) \ ! fprintf (asm_out_file, ".toc\n"); \ \ in_section = toc; \ } --- 1600,1625 ---- toc_section () \ { \ ! if (TARGET_MINIMAL_TOC) \ ! { \ ! static int toc_initialized = 0; \ ! \ ! /* toc_section is always called at least once from ASM_FILE_START, \ ! so this is guaranteed to always be defined once and only once \ ! in each file. */ \ ! if (! toc_initialized) \ ! { \ ! fprintf (asm_out_file, ".toc\nLCTOC..0:\n"); \ ! fprintf (asm_out_file, "\t.tc toc_table[TC],toc_table[RW]\n"); \ ! toc_initialized = 1; \ ! } \ \ + if (in_section != toc) \ + fprintf (asm_out_file, ".csect toc_table[RW]\n"); \ + } \ + else \ + { \ + if (in_section != toc) \ + fprintf (asm_out_file, ".toc\n"); \ + } \ in_section = toc; \ } *************** *** 1493,1497 **** RS6000_OUTPUT_BASENAME (FILE, NAME); \ fprintf (FILE, ", TOC[tc0], 0\n"); \ ! fprintf (FILE, ".csect [PR]\n."); \ RS6000_OUTPUT_BASENAME (FILE, NAME); \ fprintf (FILE, ":\n"); \ --- 1656,1660 ---- RS6000_OUTPUT_BASENAME (FILE, NAME); \ fprintf (FILE, ", TOC[tc0], 0\n"); \ ! fprintf (FILE, ".csect .text[PR]\n."); \ RS6000_OUTPUT_BASENAME (FILE, NAME); \ fprintf (FILE, ":\n"); \ *************** *** 1513,1517 **** && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF) \ || GET_CODE (X) == LABEL_REF \ ! || (TARGET_FP_IN_TOC && GET_CODE (X) == CONST_DOUBLE \ && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \ && BITS_PER_WORD == HOST_BITS_PER_INT)) --- 1676,1681 ---- && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF) \ || GET_CODE (X) == LABEL_REF \ ! || (! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC) \ ! && GET_CODE (X) == CONST_DOUBLE \ && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \ && BITS_PER_WORD == HOST_BITS_PER_INT)) *************** *** 1632,1636 **** /* Output before instructions. */ ! #define TEXT_SECTION_ASM_OP ".csect [PR]" /* Output before writable data. */ --- 1796,1800 ---- /* Output before instructions. */ ! #define TEXT_SECTION_ASM_OP ".csect .text[PR]" /* Output before writable data. */ *************** *** 1681,1684 **** --- 1845,1852 ---- #define DBX_REGISTER_NUMBER(REGNO) (REGNO) + /* Text to write out after a CALL that may be replaced by glue code by + the loader. This depends on the AIX version. */ + #define RS6000_CALL_GLUE "cror 31,31,31" + /* 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. */ *************** *** 1764,1768 **** #define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \ ! fprintf (FILE, "\tstu %s,-4(r1)\n", reg_names[REGNO]); /* This is how to output an insn to pop a register from the stack. --- 1932,1936 ---- #define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \ ! asm_fprintf (FILE, "\{tstu|stwu} %s,-4(r1)\n", reg_names[REGNO]); /* This is how to output an insn to pop a register from the stack. *************** *** 1770,1774 **** #define ASM_OUTPUT_REG_POP(FILE,REGNO) \ ! fprintf (FILE, "\tl %s,0(r1)\n\tai r1,r1,4\n", reg_names[REGNO]) /* This is how to output an element of a case-vector that is absolute. --- 1938,1943 ---- #define ASM_OUTPUT_REG_POP(FILE,REGNO) \ ! asm_fprintf (FILE, "\t{l|lwz} %s,0(r1)\n\t{ai|addic} r1,r1,4\n", \ ! reg_names[REGNO]) /* This is how to output an element of a case-vector that is absolute. *************** *** 1843,1847 **** /* Define which CODE values are valid. */ ! #define PRINT_OPERAND_PUNCT_VALID_P(CODE) 0 /* Print a memory address as an operand to reference that memory location. */ --- 2012,2016 ---- /* Define which CODE values are valid. */ ! #define PRINT_OPERAND_PUNCT_VALID_P(CODE) ((CODE) == '.') /* Print a memory address as an operand to reference that memory location. */ *************** *** 1873,1879 **** {"mask_operand", {CONST_INT}}, \ {"call_operand", {SYMBOL_REF, REG}}, \ {"input_operand", {SUBREG, MEM, REG, CONST_INT}}, \ ! {"branch_comparison_operation", {EQ, NE, LE, LT, GE, \ ! LT, LEU, LTU, GEU, GTU}}, \ ! {"scc_comparison_operation", {EQ, NE, LE, LT, GE, \ ! LT, LEU, LTU, GEU, GTU}}, --- 2042,2051 ---- {"mask_operand", {CONST_INT}}, \ {"call_operand", {SYMBOL_REF, REG}}, \ + {"current_file_function_operand", {SYMBOL_REF}}, \ {"input_operand", {SUBREG, MEM, REG, CONST_INT}}, \ ! {"load_multiple_operation", {PARALLEL}}, \ ! {"store_multiple_operation", {PARALLEL}}, \ ! {"branch_comparison_operator", {EQ, NE, LE, LT, GE, \ ! GT, LEU, LTU, GEU, GTU}}, \ ! {"scc_comparison_operator", {EQ, NE, LE, LT, GE, \ ! GT, LEU, LTU, GEU, GTU}}, diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/rs6000/rs6000.md gcc-2.5.0/config/rs6000/rs6000.md *** gcc-2.4.5/config/rs6000/rs6000.md Fri Jun 11 21:46:27 1993 --- gcc-2.5.0/config/rs6000/rs6000.md Wed Oct 20 21:57:21 1993 *************** *** 23,47 **** ;; Define an insn type attribute. This is used in function unit delay ;; computations. ! (define_attr "type" "load,integer,fp,compare,delayed_compare,fpcompare,mtlr" (const_string "integer")) ! ;; Memory delivers its result in two cycles. ! (define_function_unit "memory" 1 0 (eq_attr "type" "load") 2 0) ! ! ;; We consider floating-point insns to deliver their result in two cycles ! ;; to try to intersperse integer and FP operations. ! (define_function_unit "fp" 1 0 (eq_attr "type" "fp,fpcompare") 2 0) ! ! ;; Most integer comparisons are ready in four cycles (a stall of three). ! (define_function_unit "compare" 1 0 (eq_attr "type" "compare") 4 0) ! ! ;; Some integer comparisons aren't ready for five cycles (a stall of four). ! (define_function_unit "compare" 1 0 (eq_attr "type" "delayed_compare") 5 0) ! ! ;; Floating-point comparisons take eight cycles. ! (define_function_unit "compare" 1 0 (eq_attr "type" "fpcompare") 8 0) ! ! ;; Branches on LR cannot be done until five cycles after LR is set. ! (define_function_unit "branch" 1 0 (eq_attr "type" "mtlr") 5 0) ;; Start with fixed-point load and store insns. Here we put only the more --- 23,211 ---- ;; Define an insn type attribute. This is used in function unit delay ;; computations. ! (define_attr "type" "integer,load,fpload,imul,idiv,branch,compare,delayed_compare,fpcompare,mtlr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt" (const_string "integer")) ! ;; Length (in bytes). ! (define_attr "length" "" ! (if_then_else (eq_attr "type" "branch") ! (if_then_else (and (ge (minus (pc) (match_dup 0)) ! (const_int -32768)) ! (lt (minus (pc) (match_dup 0)) ! (const_int 32767))) ! (const_int 8) ! (const_int 12)) ! (const_int 4))) ! ! ;; Processor type -- this attribute must exactly match the processor_type ! ;; enumeration in rs6000.h. ! ! (define_attr "cpu" "rios1,rios2,ppc601,ppc603,ppc604,ppc620" ! (const (symbol_ref "rs6000_cpu_attr"))) ! ! ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY ! ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST]) ! ! (define_function_unit "lsu" 1 0 ! (and (eq_attr "type" "load") ! (eq_attr "cpu" "rios2,ppc603,ppc604,ppc620")) ! 2 0) ! ! (define_function_unit "lsu" 1 0 ! (and (eq_attr "type" "fpload") ! (eq_attr "cpu" "rios2,ppc603,ppc604,ppc620")) ! 2 0) ! ! (define_function_unit "iu" 1 0 ! (and (eq_attr "type" "load") ! (eq_attr "cpu" "rios1")) ! 2 0) ! ! (define_function_unit "iu" 1 0 ! (and (eq_attr "type" "fpload") ! (eq_attr "cpu" "rios1")) ! 3 0) ! ! (define_function_unit "iu" 1 0 ! (and (eq_attr "type" "imul") ! (eq_attr "cpu" "rios1")) ! 3 0) ! ! (define_function_unit "iu" 1 0 ! (and (eq_attr "type" "imul") ! (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620")) ! 5 0) ! ! (define_function_unit "iu" 1 0 ! (and (eq_attr "type" "idiv") ! (eq_attr "cpu" "rios1")) ! 19 0) ! ! (define_function_unit "iu" 1 0 ! (and (eq_attr "type" "idiv") ! (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620")) ! 36 0) ! ! (define_function_unit "bpu" 1 0 ! (eq_attr "type" "compare") ! 4 0) ! ! (define_function_unit "bpu" 1 0 ! (eq_attr "type" "delayed_compare") ! 5 0) ! ! (define_function_unit "bpu" 1 0 ! (and (eq_attr "type" "fpcompare") ! (eq_attr "cpu" "rios1,rios2")) ! 8 0) ! ! (define_function_unit "bpu" 1 0 ! (and (eq_attr "type" "fpcompare") ! (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620")) ! 4 0) ! ! (define_function_unit "bpu" 1 0 ! (and (eq_attr "type" "mtlr") ! (eq_attr "cpu" "rios1,rios2")) ! 5 0) ! ! (define_function_unit "bpu" 1 0 ! (and (eq_attr "type" "mtlr") ! (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620")) ! 4 0) ! ! (define_function_unit "fpu" 1 0 ! (and (eq_attr "type" "fp") ! (eq_attr "cpu" "rios1")) ! 2 0) ! ! (define_function_unit "fpu" 1 0 ! (and (eq_attr "type" "fp") ! (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620")) ! 4 0) ! ! (define_function_unit "fpu" 1 0 ! (and (eq_attr "type" "dmul") ! (eq_attr "cpu" "rios1")) ! 2 0) ! ! (define_function_unit "fpu" 1 0 ! (and (eq_attr "type" "dmul") ! (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620")) ! 5 0) ! ! (define_function_unit "fpu" 1 0 ! (and (eq_attr "type" "sdiv") ! (eq_attr "cpu" "rios1")) ! 19 0) ! ! (define_function_unit "fpu" 1 0 ! (and (eq_attr "type" "sdiv") ! (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620")) ! 17 0) ! ! (define_function_unit "fpu" 1 0 ! (and (eq_attr "type" "ddiv") ! (eq_attr "cpu" "rios1")) ! 19 0) ! ! (define_function_unit "fpu" 1 0 ! (and (eq_attr "type" "ddiv") ! (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620")) ! 31 0) ! ! (define_function_unit "fpu" 1 0 ! (and (eq_attr "type" "ssqrt") ! (eq_attr "cpu" "ppc603,ppc604,ppc620")) ! 31 0) ! ! (define_function_unit "fpu" 1 0 ! (and (eq_attr "type" "dsqrt") ! (eq_attr "cpu" "ppc603,ppc604,ppc620")) ! 31 0) ! ! (define_function_unit "iu2" 2 0 ! (and (eq_attr "type" "integer") ! (eq_attr "cpu" "rios2")) ! 1 0 ! [(eq_attr "type" "imul,idiv")]) ! (define_function_unit "imuldiv" 1 0 ! (and (eq_attr "type" "imul") ! (eq_attr "cpu" "rios2")) ! 2 0 ! [(eq_attr "type" "integer")]) ! (define_function_unit "imuldiv" 1 0 ! (and (eq_attr "type" "idiv") ! (eq_attr "cpu" "rios2")) ! 13 0 ! [(eq_attr "type" "integer")]) ! (define_function_unit "fpu2" 2 0 ! (and (eq_attr "type" "fp") ! (eq_attr "cpu" "rios2")) ! 2 0) ! ! (define_function_unit "fpu2" 2 0 ! (and (eq_attr "type" "dmul") ! (eq_attr "cpu" "rios2")) ! 2 0) ! ! (define_function_unit "fpu2" 2 0 ! (and (eq_attr "type" "sdiv") ! (eq_attr "cpu" "rios2")) ! 17 0) ! ! (define_function_unit "fpu2" 2 0 ! (and (eq_attr "type" "ddiv") ! (eq_attr "cpu" "rios2")) ! 17 0) ! ! (define_function_unit "fpu2" 2 0 ! (and (eq_attr "type" "ssqrt") ! (eq_attr "cpu" "rios2")) ! 26 0) ! ! (define_function_unit "fpu2" 2 0 ! (and (eq_attr "type" "dsqrt") ! (eq_attr "cpu" "rios2")) ! 26 0) ;; Start with fixed-point load and store insns. Here we put only the more *************** *** 60,64 **** "@ lbz%U1%X1 %0,%1 ! rlinm %0,%1,0,24,31" [(set_attr "type" "load,*")]) --- 224,228 ---- "@ lbz%U1%X1 %0,%1 ! {rlinm|rlwinm} %0,%1,0,0xff" [(set_attr "type" "load,*")]) *************** *** 69,73 **** (clobber (match_scratch:SI 2 "=r"))] "" ! "andil. %2,%1,255" [(set_attr "type" "compare")]) --- 233,237 ---- (clobber (match_scratch:SI 2 "=r"))] "" ! "{andil.|andi.} %2,%1,0xff" [(set_attr "type" "compare")]) *************** *** 79,83 **** (zero_extend:SI (match_dup 1)))] "" ! "andil. %0,%1,255" [(set_attr "type" "compare")]) --- 243,247 ---- (zero_extend:SI (match_dup 1)))] "" ! "{andil.|andi.} %0,%1,0xff" [(set_attr "type" "compare")]) *************** *** 94,98 **** "@ lbz%U1%X1 %0,%1 ! rlinm %0,%1,0,24,31" [(set_attr "type" "load,*")]) --- 258,262 ---- "@ lbz%U1%X1 %0,%1 ! {rlinm|rlwinm} %0,%1,0,0xff" [(set_attr "type" "load,*")]) *************** *** 109,113 **** "@ lhz%U1%X1 %0,%1 ! rlinm %0,%1,0,16,31" [(set_attr "type" "load,*")]) --- 273,277 ---- "@ lhz%U1%X1 %0,%1 ! {rlinm|rlwinm} %0,%1,0,0xffff" [(set_attr "type" "load,*")]) *************** *** 118,122 **** (clobber (match_scratch:SI 2 "=r"))] "" ! "andil. %2,%1,65535" [(set_attr "type" "compare")]) --- 282,286 ---- (clobber (match_scratch:SI 2 "=r"))] "" ! "{andil.|andi.} %2,%1,0xffff" [(set_attr "type" "compare")]) *************** *** 128,132 **** (zero_extend:SI (match_dup 1)))] "" ! "andil. %0,%1,65535" [(set_attr "type" "compare")]) --- 292,296 ---- (zero_extend:SI (match_dup 1)))] "" ! "{andil.|andi.} %0,%1,0xffff" [(set_attr "type" "compare")]) *************** *** 143,147 **** "@ lha%U1%X1 %0,%1 ! exts %0,%1" [(set_attr "type" "load,*")]) --- 307,311 ---- "@ lha%U1%X1 %0,%1 ! {exts|extsh} %0,%1" [(set_attr "type" "load,*")]) *************** *** 152,156 **** (clobber (match_scratch:SI 2 "=r"))] "" ! "exts. %2,%1" [(set_attr "type" "compare")]) --- 316,320 ---- (clobber (match_scratch:SI 2 "=r"))] "" ! "{exts.|extsh.} %2,%1" [(set_attr "type" "compare")]) *************** *** 162,166 **** (sign_extend:SI (match_dup 1)))] "" ! "exts. %0,%1" [(set_attr "type" "compare")]) --- 326,330 ---- (sign_extend:SI (match_dup 1)))] "" ! "{exts.|extsh.} %0,%1" [(set_attr "type" "compare")]) *************** *** 172,177 **** "" "@ ! a%I2 %0,%1,%2 ! cau %0,%1,%u2") (define_insn "" --- 336,341 ---- "" "@ ! {a%I2|add%I2c} %0,%1,%2 ! {cau|addis} %0,%1,%u2") (define_insn "" *************** *** 182,186 **** (clobber (match_scratch:SI 3 "=r"))] "" ! "a%I2. %3,%1,%2" [(set_attr "type" "compare")]) --- 346,350 ---- (clobber (match_scratch:SI 3 "=r"))] "" ! "{a%I2.|add%I2c.} %3,%1,%2" [(set_attr "type" "compare")]) *************** *** 193,197 **** (plus:SI (match_dup 1) (match_dup 2)))] "" ! "a%I2. %0,%1,%2" [(set_attr "type" "compare")]) --- 357,361 ---- (plus:SI (match_dup 1) (match_dup 2)))] "" ! "{a%I2.|add%I2c.} %0,%1,%2" [(set_attr "type" "compare")]) *************** *** 219,236 **** }") ! (define_insn "one_cmplsi2" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")))] "" ! "sfi %0,%1,-1") (define_insn "" ! [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") ! (minus:SI (match_operand:SI 1 "reg_or_short_operand" "r,I") ! (match_operand:SI 2 "gpc_reg_operand" "r,r")))] "" ! "@ ! sf %0,%2,%1 ! sfi %0,%2,%1") (define_insn "" --- 383,429 ---- }") ! (define_expand "one_cmplsi2" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")))] "" ! "") (define_insn "" ! [(set (match_operand:SI 0 "gpc_reg_operand" "=r") ! (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")))] ! "TARGET_POWER" ! "{sfi|subfic} %0,%1,-1") ! ! (define_insn "" ! [(set (match_operand:SI 0 "gpc_reg_operand" "=r") ! (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")))] ! "! TARGET_POWER" ! "nor %0,%1,%1") ! ! (define_insn "" ! [(set (match_operand:CC 0 "cc_reg_operand" "=x") ! (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")) ! (const_int 0))) ! (clobber (match_scratch:SI 2 "=r"))] "" ! "nor. %2,%1,%1" ! [(set_attr "type" "compare")]) ! ! (define_insn "" ! [(set (match_operand:CC 2 "cc_reg_operand" "=-x") ! (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")) ! (const_int 0))) ! (set (match_operand:SI 0 "gpc_reg_operand" "=r") ! (not:SI (match_dup 1)))] ! "" ! "nor. %0,%2,%1" ! [(set_attr "type" "compare")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "gpc_reg_operand" "=r") ! (minus:SI (match_operand:SI 1 "reg_or_short_operand" "rI") ! (match_operand:SI 2 "gpc_reg_operand" "r")))] ! "" ! "{sf%I1|subf%I1c} %0,%2,%1") (define_insn "" *************** *** 241,245 **** (clobber (match_scratch:SI 3 "=r"))] "" ! "sf. %3,%2,%1" [(set_attr "type" "compare")]) --- 434,438 ---- (clobber (match_scratch:SI 3 "=r"))] "" ! "{sf.|subfc.} %3,%2,%1" [(set_attr "type" "compare")]) *************** *** 252,256 **** (minus:SI (match_dup 1) (match_dup 2)))] "" ! "sf. %0,%2,%1" [(set_attr "type" "compare")]) --- 445,449 ---- (minus:SI (match_dup 1) (match_dup 2)))] "" ! "{sf.|subfc.} %0,%2,%1" [(set_attr "type" "compare")]) *************** *** 283,287 **** (set (match_operand:SI 0 "gpc_reg_operand" "") (minus:SI (match_dup 2) (match_dup 3)))] ! "" " { operands[3] = gen_reg_rtx (SImode); }") --- 476,480 ---- (set (match_operand:SI 0 "gpc_reg_operand" "") (minus:SI (match_dup 2) (match_dup 3)))] ! "TARGET_POWER" " { operands[3] = gen_reg_rtx (SImode); }") *************** *** 292,296 **** (match_operand:SI 2 "reg_or_short_operand" ""))) (clobber (match_operand:SI 3 "gpc_reg_operand" ""))] ! "" [(set (match_dup 3) (if_then_else:SI (gt:SI (match_dup 1) (match_dup 2)) --- 485,489 ---- (match_operand:SI 2 "reg_or_short_operand" ""))) (clobber (match_operand:SI 3 "gpc_reg_operand" ""))] ! "TARGET_POWER" [(set (match_dup 3) (if_then_else:SI (gt:SI (match_dup 1) (match_dup 2)) *************** *** 308,312 **** (set (match_operand:SI 0 "gpc_reg_operand" "") (plus:SI (match_dup 3) (match_dup 1)))] ! "" " { operands[3] = gen_reg_rtx (SImode); }") --- 501,505 ---- (set (match_operand:SI 0 "gpc_reg_operand" "") (plus:SI (match_dup 3) (match_dup 1)))] ! "TARGET_POWER" " { operands[3] = gen_reg_rtx (SImode); }") *************** *** 317,321 **** (match_operand:SI 2 "reg_or_short_operand" ""))) (clobber (match_operand:SI 3 "gpc_reg_operand" ""))] ! "" [(set (match_dup 3) (if_then_else:SI (gt:SI (match_dup 1) (match_dup 2)) --- 510,514 ---- (match_operand:SI 2 "reg_or_short_operand" ""))) (clobber (match_operand:SI 3 "gpc_reg_operand" ""))] ! "TARGET_POWER" [(set (match_dup 3) (if_then_else:SI (gt:SI (match_dup 1) (match_dup 2)) *************** *** 335,339 **** (set (match_operand:SI 0 "gpc_reg_operand" "") (minus:SI (match_dup 2) (match_dup 3)))] ! "" " { operands[3] = gen_reg_rtx (SImode); operands[4] = gen_reg_rtx (SImode); }") --- 528,532 ---- (set (match_operand:SI 0 "gpc_reg_operand" "") (minus:SI (match_dup 2) (match_dup 3)))] ! "TARGET_POWER" " { operands[3] = gen_reg_rtx (SImode); operands[4] = gen_reg_rtx (SImode); }") *************** *** 349,353 **** (set (match_operand:SI 0 "gpc_reg_operand" "") (plus:SI (match_dup 3) (match_dup 1)))] ! "" " { operands[3] = gen_reg_rtx (SImode); operands[4] = gen_reg_rtx (SImode); }") --- 542,546 ---- (set (match_operand:SI 0 "gpc_reg_operand" "") (plus:SI (match_dup 3) (match_dup 1)))] ! "TARGET_POWER" " { operands[3] = gen_reg_rtx (SImode); operands[4] = gen_reg_rtx (SImode); }") *************** *** 359,363 **** (const_int 0) (minus:SI (match_dup 2) (match_dup 1))))] ! "" "doz%I2 %0,%1,%2") --- 552,556 ---- (const_int 0) (minus:SI (match_dup 2) (match_dup 1))))] ! "TARGET_POWER" "doz%I2 %0,%1,%2") *************** *** 371,375 **** (const_int 0))) (clobber (match_scratch:SI 3 "=r"))] ! "" "doz%I2. %3,%1,%2" [(set_attr "type" "delayed_compare")]) --- 564,568 ---- (const_int 0))) (clobber (match_scratch:SI 3 "=r"))] ! "TARGET_POWER" "doz%I2. %3,%1,%2" [(set_attr "type" "delayed_compare")]) *************** *** 387,391 **** (const_int 0) (minus:SI (match_dup 2) (match_dup 1))))] ! "" "doz%I2. %0,%1,%2" [(set_attr "type" "delayed_compare")]) --- 580,584 ---- (const_int 0) (minus:SI (match_dup 2) (match_dup 1))))] ! "TARGET_POWER" "doz%I2. %0,%1,%2" [(set_attr "type" "delayed_compare")]) *************** *** 396,400 **** [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))] ! "" "abs %0,%1") --- 589,593 ---- [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))] ! "TARGET_POWER" "abs %0,%1") *************** *** 402,406 **** [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r"))))] ! "" "nabs %0,%1") --- 595,599 ---- [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r"))))] ! "TARGET_POWER" "nabs %0,%1") *************** *** 434,440 **** (ffs:SI (match_operand:SI 1 "register_operand" "r")))] "" ! "neg %0,%1\;and %0,%0,%1\;cntlz %0,%0\;sfi %0,%0,32") ! (define_insn "mulsi3" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r") --- 627,648 ---- (ffs:SI (match_operand:SI 1 "register_operand" "r")))] "" ! "neg %0,%1\;and %0,%0,%1\;cntlz %0,%0\;{sfi|subfic} %0,%0,32" ! [(set_attr "length" "16")]) ! ! (define_expand "mulsi3" ! [(use (match_operand:SI 0 "gpc_reg_operand" "")) ! (use (match_operand:SI 1 "gpc_reg_operand" "")) ! (use (match_operand:SI 2 "reg_or_short_operand" ""))] ! "" ! " ! { ! if (TARGET_POWER) ! emit_insn (gen_mulsi3_power (operands[0], operands[1], operands[2])); ! else ! emit_insn (gen_mulsi3_powerpc (operands[0], operands[1], operands[2])); ! DONE; ! }") ! (define_insn "mulsi3_power" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r") *************** *** 441,448 **** (match_operand:SI 2 "reg_or_short_operand" "r,I"))) (clobber (match_scratch:SI 3 "=q,q"))] ! "" "@ ! muls %0,%1,%2 ! muli %0,%1,%2") (define_insn "" --- 649,667 ---- (match_operand:SI 2 "reg_or_short_operand" "r,I"))) (clobber (match_scratch:SI 3 "=q,q"))] ! "TARGET_POWER" ! "@ ! {muls|mullw} %0,%1,%2 ! {muli|mulli} %0,%1,%2" ! [(set_attr "type" "imul")]) ! ! (define_insn "mulsi3_powerpc" ! [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") ! (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r") ! (match_operand:SI 2 "reg_or_short_operand" "r,I")))] ! "TARGET_POWERPC" "@ ! mullw %0,%1,%2 ! mulli %0,%1,%2" ! [(set_attr "type" "imul")]) (define_insn "" *************** *** 453,458 **** (clobber (match_scratch:SI 3 "=r")) (clobber (match_scratch:SI 4 "=q"))] ! "" ! "muls. %3,%1,%2" [(set_attr "type" "delayed_compare")]) --- 672,687 ---- (clobber (match_scratch:SI 3 "=r")) (clobber (match_scratch:SI 4 "=q"))] ! "TARGET_POWER" ! "{muls.|mullw.} %3,%1,%2" ! [(set_attr "type" "delayed_compare")]) ! ! (define_insn "" ! [(set (match_operand:CC 0 "cc_reg_operand" "=x") ! (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "r") ! (match_operand:SI 2 "gpc_reg_operand" "r")) ! (const_int 0))) ! (clobber (match_scratch:SI 3 "=r"))] ! "TARGET_POWERPC" ! "mullw. %3,%1,%2" [(set_attr "type" "delayed_compare")]) *************** *** 465,470 **** (mult:SI (match_dup 1) (match_dup 2))) (clobber (match_scratch:SI 4 "=q"))] ! "" ! "muls. %0,%1,%2" [(set_attr "type" "delayed_compare")]) --- 694,710 ---- (mult:SI (match_dup 1) (match_dup 2))) (clobber (match_scratch:SI 4 "=q"))] ! "TARGET_POWER" ! "{muls.|mullw.} %0,%1,%2" ! [(set_attr "type" "delayed_compare")]) ! ! (define_insn "" ! [(set (match_operand:CC 3 "cc_reg_operand" "=x") ! (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "r") ! (match_operand:SI 2 "gpc_reg_operand" "r")) ! (const_int 0))) ! (set (match_operand:SI 0 "gpc_reg_operand" "=r") ! (mult:SI (match_dup 1) (match_dup 2)))] ! "TARGET_POWERPC" ! "mullw. %0,%1,%2" [(set_attr "type" "delayed_compare")]) *************** *** 479,487 **** (set (match_operand:SI 3 "gpc_reg_operand" "=q") (mod:SI (match_dup 1) (match_dup 2)))] ! "" ! "divs %0,%1,%2") ;; For powers of two we can do srai/aze for divide and then adjust for ! ;; modulus. If it isn't a power of two, FAIL so divmodsi4 will be used. (define_expand "divsi3" [(set (match_operand:SI 0 "gpc_reg_operand" "") --- 719,745 ---- (set (match_operand:SI 3 "gpc_reg_operand" "=q") (mod:SI (match_dup 1) (match_dup 2)))] ! "TARGET_POWER" ! "divs %0,%1,%2" ! [(set_attr "type" "idiv")]) ! ! (define_insn "" ! [(set (match_operand:SI 0 "gpc_reg_operand" "=r") ! (div:SI (match_operand:SI 1 "gpc_reg_operand" "r") ! (match_operand:SI 2 "gpc_reg_operand" "r")))] ! "TARGET_POWERPC" ! "divw %0, %1, %2" ! [(set_attr "type" "idiv")]) ! ! (define_insn "udivsi3" ! [(set (match_operand:SI 0 "gpc_reg_operand" "=r") ! (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "r") ! (match_operand:SI 2 "gpc_reg_operand" "r")))] ! "TARGET_POWERPC" ! "divwu %0, %1, %2" ! [(set_attr "type" "idiv")]) ;; For powers of two we can do srai/aze for divide and then adjust for ! ;; modulus. If it isn't a power of two, FAIL on POWER so divmodsi4 will be ! ;; used; for PowerPC, force operands into register and do a normal divide. (define_expand "divsi3" [(set (match_operand:SI 0 "gpc_reg_operand" "") *************** *** 491,497 **** " { ! if (GET_CODE (operands[2]) != CONST_INT ! || exact_log2 (INTVAL (operands[2])) < 0) FAIL; }") --- 749,761 ---- " { ! if (GET_CODE (operands[2]) == CONST_INT ! && exact_log2 (INTVAL (operands[2])) >= 0) ! ; ! ! else if (TARGET_POWER) FAIL; + + else if (TARGET_POWERPC) + operands[2] = force_reg (SImode, operands[2]); }") *************** *** 522,526 **** (match_operand:SI 2 "const_int_operand" "N")))] "exact_log2 (INTVAL (operands[2])) >= 0" ! "srai %0,%1,%p2\;aze %0,%0") (define_insn "" --- 786,791 ---- (match_operand:SI 2 "const_int_operand" "N")))] "exact_log2 (INTVAL (operands[2])) >= 0" ! "{srai|srawi} %0,%1,%p2\;{aze|addze} %0,%0" ! [(set_attr "length" "8")]) (define_insn "" *************** *** 530,535 **** (clobber (match_scratch:SI 3 "=r"))] "exact_log2 (INTVAL (operands[2])) >= 0" ! "srai %3,%1,%p2\;aze. %3,%3" ! [(set_attr "type" "compare")]) (define_insn "" --- 795,801 ---- (clobber (match_scratch:SI 3 "=r"))] "exact_log2 (INTVAL (operands[2])) >= 0" ! "{srai|srawi} %3,%1,%p2\;{aze.|addze.} %3,%3" ! [(set_attr "type" "compare") ! (set_attr "length" "8")]) (define_insn "" *************** *** 540,545 **** (div:SI (match_dup 1) (match_dup 2)))] "exact_log2 (INTVAL (operands[2])) >= 0" ! "srai %0,%1,%p2\;aze. %0,%0" ! [(set_attr "type" "compare")]) (define_insn "" --- 806,812 ---- (div:SI (match_dup 1) (match_dup 2)))] "exact_log2 (INTVAL (operands[2])) >= 0" ! "{srai|srawi} %0,%1,%p2\;{aze.|addze.} %0,%0" ! [(set_attr "type" "compare") ! (set_attr "length" "8")]) (define_insn "" *************** *** 558,563 **** (match_dup 3)))] ! "" ! "div %0,%1,%3") ;; To do unsigned divide we handle the cases of the divisor looking like a --- 825,831 ---- (match_dup 3)))] ! "TARGET_POWER" ! "div %0,%1,%3" ! [(set_attr "type" "idiv")]) ;; To do unsigned divide we handle the cases of the divisor looking like a *************** *** 578,582 **** (zero_extend:DI (match_dup 1))) (match_dup 2)))])] ! "" " { operands[4] = gen_reg_rtx (SImode); }") --- 846,850 ---- (zero_extend:DI (match_dup 1))) (match_dup 2)))])] ! "TARGET_POWER" " { operands[4] = gen_reg_rtx (SImode); }") *************** *** 594,598 **** (set (pc) (if_then_else (lt (match_dup 6) (const_int 0)) (label_ref (match_dup 4)) (pc)))] ! "" " { operands[5] = gen_reg_rtx (CCUNSmode); --- 862,866 ---- (set (pc) (if_then_else (lt (match_dup 6) (const_int 0)) (label_ref (match_dup 4)) (pc)))] ! "TARGET_POWER" " { operands[5] = gen_reg_rtx (CCUNSmode); *************** *** 606,610 **** (set (match_operand:SI 3 "gpc_reg_operand" "") (umod:SI (match_dup 1) (match_dup 2)))])] ! "" " { --- 874,878 ---- (set (match_operand:SI 3 "gpc_reg_operand" "") (umod:SI (match_dup 1) (match_dup 2)))])] ! "TARGET_POWER" " { *************** *** 637,643 **** "@ and %0,%1,%2 ! rlinm %0,%1,0,%m2,%M2 ! andil. %0,%1,%b2 ! andiu. %0,%1,%u2") (define_insn "" --- 905,911 ---- "@ and %0,%1,%2 ! {rlinm|rlwinm} %0,%1,0,%m2,%M2 ! {andil.|andi.} %0,%1,%b2 ! {andiu.|andis.} %0,%1,%u2") (define_insn "" *************** *** 650,656 **** "@ and. %3,%1,%2 ! andil. %3,%1,%b2 ! andiu. %3,%1,%u2 ! rlinm. %3,%1,0,%m2,%M2" [(set_attr "type" "compare,compare,compare,delayed_compare")]) --- 918,924 ---- "@ and. %3,%1,%2 ! {andil.|andi.} %3,%1,%b2 ! {andiu.|andis.} %3,%1,%u2 ! {rlinm.|rlwinm.} %3,%1,0,%m2,%M2" [(set_attr "type" "compare,compare,compare,delayed_compare")]) *************** *** 665,672 **** "@ and. %0,%1,%2 ! andil. %0,%1,%b2 ! andiu. %0,%1,%u2 ! rlinm. %0,%1,0,%m2,%M2" ! [(set_attr "type" "compare,compare,compare,delayed_compare")]) ;; Take a AND with a constant that cannot be done in a single insn and try to --- 933,940 ---- "@ and. %0,%1,%2 ! {andil.|andi.} %0,%1,%b2 ! {andiu.|andis.} %0,%1,%u2 ! {rlinm.|rlwinm.} %0,%1,0,%m2,%M2" ! [(set_attr "type" "compare,compare,compare,delayed_compare")]) ;; Take a AND with a constant that cannot be done in a single insn and try to *************** *** 717,722 **** "@ or %0,%1,%2 ! oril %0,%1,%b2 ! oriu %0,%1,%u2") (define_insn "" --- 985,990 ---- "@ or %0,%1,%2 ! {oril|ori} %0,%1,%b2 ! {oriu|oris} %0,%1,%u2") (define_insn "" *************** *** 765,770 **** "@ xor %0,%1,%2 ! xoril %0,%1,%b2 ! xoriu %0,%1,%u2") (define_insn "" --- 1033,1038 ---- "@ xor %0,%1,%2 ! {xoril|xori} %0,%1,%b2 ! {xoriu|xoris} %0,%1,%u2") (define_insn "" *************** *** 956,960 **** (and:SI (match_dup 2) (match_operand:SI 3 "gpc_reg_operand" "r"))))] ! "" "maskir %0,%3,%2") --- 1224,1228 ---- (and:SI (match_dup 2) (match_operand:SI 3 "gpc_reg_operand" "r"))))] ! "TARGET_POWER" "maskir %0,%3,%2") *************** *** 965,969 **** (and:SI (match_operand:SI 3 "gpc_reg_operand" "r") (match_dup 2))))] ! "" "maskir %0,%3,%2") --- 1233,1237 ---- (and:SI (match_operand:SI 3 "gpc_reg_operand" "r") (match_dup 2))))] ! "TARGET_POWER" "maskir %0,%3,%2") *************** *** 974,978 **** (and:SI (not:SI (match_dup 2)) (match_operand:SI 1 "gpc_reg_operand" "0"))))] ! "" "maskir %0,%3,%2") --- 1242,1246 ---- (and:SI (not:SI (match_dup 2)) (match_operand:SI 1 "gpc_reg_operand" "0"))))] ! "TARGET_POWER" "maskir %0,%3,%2") *************** *** 983,987 **** (and:SI (not:SI (match_dup 2)) (match_operand:SI 1 "gpc_reg_operand" "0"))))] ! "" "maskir %0,%3,%2") --- 1251,1255 ---- (and:SI (not:SI (match_dup 2)) (match_operand:SI 1 "gpc_reg_operand" "0"))))] ! "TARGET_POWER" "maskir %0,%3,%2") *************** *** 997,1001 **** (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1)) (and:SI (match_dup 2) (match_dup 3))))] ! "" "maskir. %0,%3,%2" [(set_attr "type" "compare")]) --- 1265,1269 ---- (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1)) (and:SI (match_dup 2) (match_dup 3))))] ! "TARGET_POWER" "maskir. %0,%3,%2" [(set_attr "type" "compare")]) *************** *** 1012,1016 **** (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1)) (and:SI (match_dup 3) (match_dup 2))))] ! "" "maskir. %0,%3,%2" [(set_attr "type" "compare")]) --- 1280,1284 ---- (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1)) (and:SI (match_dup 3) (match_dup 2))))] ! "TARGET_POWER" "maskir. %0,%3,%2" [(set_attr "type" "compare")]) *************** *** 1027,1031 **** (ior:SI (and:SI (match_dup 2) (match_dup 3)) (and:SI (not:SI (match_dup 2)) (match_dup 1))))] ! "" "maskir. %0,%3,%2" [(set_attr "type" "compare")]) --- 1295,1299 ---- (ior:SI (and:SI (match_dup 2) (match_dup 3)) (and:SI (not:SI (match_dup 2)) (match_dup 1))))] ! "TARGET_POWER" "maskir. %0,%3,%2" [(set_attr "type" "compare")]) *************** *** 1042,1046 **** (ior:SI (and:SI (match_dup 3) (match_dup 2)) (and:SI (not:SI (match_dup 2)) (match_dup 1))))] ! "" "maskir. %0,%3,%2" [(set_attr "type" "compare")]) --- 1310,1314 ---- (ior:SI (and:SI (match_dup 3) (match_dup 2)) (and:SI (not:SI (match_dup 2)) (match_dup 1))))] ! "TARGET_POWER" "maskir. %0,%3,%2" [(set_attr "type" "compare")]) *************** *** 1061,1065 **** operands[4] = gen_rtx (CONST_INT, VOIDmode, 32 - start - size); operands[1] = gen_rtx (CONST_INT, VOIDmode, start + size - 1); ! return \"rlimi %0,%3,%4,%h2,%h1\"; }") --- 1329,1333 ---- operands[4] = gen_rtx (CONST_INT, VOIDmode, 32 - start - size); operands[1] = gen_rtx (CONST_INT, VOIDmode, start + size - 1); ! return \"{rlimi|rlwimi} %0,%3,%4,%h2,%h1\"; }") *************** *** 1079,1083 **** else operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size); ! return \"rlinm %0,%1,%3,%s2,31\"; }") --- 1347,1351 ---- else operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size); ! return \"{rlinm|rlwinm} %0,%1,%3,%s2,31\"; }") *************** *** 1107,1113 **** - (1 << (16 - (start & 15) - size)))); if (start < 16) ! return \"andiu. %4,%1,%3\"; else ! return \"andil. %4,%1,%3\"; } --- 1375,1381 ---- - (1 << (16 - (start & 15) - size)))); if (start < 16) ! return \"{andiu.|andis.} %4,%1,%3\"; else ! return \"{andil.|andi.} %4,%1,%3\"; } *************** *** 1116,1120 **** else operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size); ! return \"rlinm. %4,%1,%3,%s2,31\"; }" [(set_attr "type" "compare")]) --- 1384,1388 ---- else operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size); ! return \"{rlinm.|rlwinm.} %4,%1,%3,%s2,31\"; }" [(set_attr "type" "compare")]) *************** *** 1137,1141 **** { operands[3] = gen_rtx (CONST_INT, VOIDmode, (1 << (32 - start)) - 1); ! return \"andil. %0,%1,%3\"; } --- 1405,1409 ---- { operands[3] = gen_rtx (CONST_INT, VOIDmode, (1 << (32 - start)) - 1); ! return \"{andil.|andi.} %0,%1,%3\"; } *************** *** 1144,1148 **** else operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size); ! return \"rlinm. %0,%1,%3,%s2,31\"; }" [(set_attr "type" "delayed_compare")]) --- 1412,1416 ---- else operands[3] = gen_rtx (CONST_INT, VOIDmode, start + size); ! return \"{rlinm.|rlwinm.} %0,%1,%3,%s2,31\"; }" [(set_attr "type" "delayed_compare")]) *************** *** 1153,1157 **** (match_operand:SI 2 "reg_or_cint_operand" "ri")))] "" ! "rl%I2nm %0,%1,%h2,0,31") (define_insn "" --- 1421,1425 ---- (match_operand:SI 2 "reg_or_cint_operand" "ri")))] "" ! "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffffffff") (define_insn "" *************** *** 1162,1166 **** (clobber (match_scratch:SI 3 "=r"))] "" ! "rl%I2nm. %3,%1,%h2,0,31" [(set_attr "type" "delayed_compare")]) --- 1430,1434 ---- (clobber (match_scratch:SI 3 "=r"))] "" ! "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffffffff" [(set_attr "type" "delayed_compare")]) *************** *** 1173,1177 **** (rotate:SI (match_dup 1) (match_dup 2)))] "" ! "rl%I2nm. %0,%1,%h2,0,31" [(set_attr "type" "delayed_compare")]) --- 1441,1445 ---- (rotate:SI (match_dup 1) (match_dup 2)))] "" ! "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffffffff" [(set_attr "type" "delayed_compare")]) *************** *** 1182,1186 **** (match_operand:SI 3 "mask_operand" "L")))] "" ! "rl%I2nm %0,%1,%h2,%m3,%M3") (define_insn "" --- 1450,1454 ---- (match_operand:SI 3 "mask_operand" "L")))] "" ! "{rl%I2nm|rlw%I2nm} %0,%1,%h2,%m3,%M3") (define_insn "" *************** *** 1193,1197 **** (clobber (match_scratch:SI 4 "=r"))] "" ! "rl%I2nm. %4,%1,%h2,%m3,%M3" [(set_attr "type" "delayed_compare")]) --- 1461,1465 ---- (clobber (match_scratch:SI 4 "=r"))] "" ! "{rl%I2nm.|rlw%I2nm.} %4,%1,%h2,%m3,%M3" [(set_attr "type" "delayed_compare")]) *************** *** 1206,1210 **** (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] "" ! "rl%I2nm. %0,%1,%h2,%m3,%M3" [(set_attr "type" "delayed_compare")]) --- 1474,1478 ---- (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] "" ! "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,%m3,%M3" [(set_attr "type" "delayed_compare")]) *************** *** 1216,1220 **** (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))] "" ! "rl%I2nm %0,%1,%h2,24,31") (define_insn "" --- 1484,1488 ---- (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))] "" ! "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xff") (define_insn "" *************** *** 1227,1231 **** (clobber (match_scratch:SI 3 "=r"))] "" ! "rl%I2nm. %3,%1,%h2,24,31" [(set_attr "type" "delayed_compare")]) --- 1495,1499 ---- (clobber (match_scratch:SI 3 "=r"))] "" ! "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xff" [(set_attr "type" "delayed_compare")]) *************** *** 1240,1244 **** (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))] "" ! "rl%I2nm. %0,%1,%h2,24,31" [(set_attr "type" "delayed_compare")]) --- 1508,1512 ---- (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))] "" ! "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xff" [(set_attr "type" "delayed_compare")]) *************** *** 1250,1254 **** (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))] "" ! "rl%I2nm %0,%1,%h2,16,31") (define_insn "" --- 1518,1522 ---- (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))] "" ! "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffff") (define_insn "" *************** *** 1261,1265 **** (clobber (match_scratch:SI 3 "=r"))] "" ! "rl%I2nm. %3,%1,%h2,16,31" [(set_attr "type" "delayed_compare")]) --- 1529,1533 ---- (clobber (match_scratch:SI 3 "=r"))] "" ! "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffff" [(set_attr "type" "delayed_compare")]) *************** *** 1274,1278 **** (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))] "" ! "rl%I2nm. %0,%1,%h2,16,31" [(set_attr "type" "delayed_compare")]) --- 1542,1546 ---- (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))] "" ! "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffff" [(set_attr "type" "delayed_compare")]) *************** *** 1280,1284 **** ;; SHIFT_COUNT_TRUNCATED. ! (define_insn "ashlsi3" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") --- 1548,1566 ---- ;; SHIFT_COUNT_TRUNCATED. ! (define_expand "ashlsi3" ! [(use (match_operand:SI 0 "gpc_reg_operand" "")) ! (use (match_operand:SI 1 "gpc_reg_operand" "")) ! (use (match_operand:SI 2 "reg_or_cint_operand" ""))] ! "" ! " ! { ! if (TARGET_POWER) ! emit_insn (gen_ashlsi3_power (operands[0], operands[1], operands[2])); ! else ! emit_insn (gen_ashlsi3_powerpc (operands[0], operands[1], operands[2])); ! DONE; ! }") ! ! (define_insn "ashlsi3_power" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") *************** *** 1285,1292 **** (match_operand:SI 2 "reg_or_cint_operand" "r,i"))) (clobber (match_scratch:SI 3 "=q,X"))] ! "" "@ sle %0,%1,%2 ! sli %0,%1,%h2") (define_insn "" --- 1567,1583 ---- (match_operand:SI 2 "reg_or_cint_operand" "r,i"))) (clobber (match_scratch:SI 3 "=q,X"))] ! "TARGET_POWER" "@ sle %0,%1,%2 ! {sli|slwi} %0,%1,%h2" ! [(set_attr "length" "8")]) ! ! (define_insn "ashlsi3_powerpc" ! [(set (match_operand:SI 0 "gpc_reg_operand" "=r") ! (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r") ! (match_operand:SI 2 "reg_or_cint_operand" "ri")))] ! "TARGET_POWERPC" ! "slw%I2 %0,%1,%2" ! [(set_attr "length" "8")]) (define_insn "" *************** *** 1297,1304 **** (clobber (match_scratch:SI 3 "=r,r")) (clobber (match_scratch:SI 4 "=q,X"))] ! "" "@ sle. %3,%1,%2 ! sli. %3,%1,%h2" [(set_attr "type" "delayed_compare")]) --- 1588,1604 ---- (clobber (match_scratch:SI 3 "=r,r")) (clobber (match_scratch:SI 4 "=q,X"))] ! "TARGET_POWER" "@ sle. %3,%1,%2 ! {sli.|slwi.} %3,%1,%h2" ! [(set_attr "type" "delayed_compare")]) ! (define_insn "" ! [(set (match_operand:CC 0 "cc_reg_operand" "=x") ! (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r") ! (match_operand:SI 2 "reg_or_cint_operand" "ri")) ! (const_int 0))) ! (clobber (match_scratch:SI 3 "=r"))] ! "TARGET_POWERPC" ! "slw%I2. %3,%1,%2" [(set_attr "type" "delayed_compare")]) *************** *** 1311,1318 **** (ashift:SI (match_dup 1) (match_dup 2))) (clobber (match_scratch:SI 4 "=q,X"))] ! "" "@ sle. %0,%1,%2 ! sli. %0,%1,%h2" [(set_attr "type" "delayed_compare")]) --- 1611,1628 ---- (ashift:SI (match_dup 1) (match_dup 2))) (clobber (match_scratch:SI 4 "=q,X"))] ! "TARGET_POWER" "@ sle. %0,%1,%2 ! {sli.|slwi.} %0,%1,%h2" ! [(set_attr "type" "delayed_compare")]) ! (define_insn "" ! [(set (match_operand:CC 3 "cc_reg_operand" "=x") ! (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r") ! (match_operand:SI 2 "reg_or_cint_operand" "ri")) ! (const_int 0))) ! (set (match_operand:SI 0 "gpc_reg_operand" "=r") ! (ashift:SI (match_dup 1) (match_dup 2)))] ! "TARGET_POWERPC" ! "slw%I2. %0,%1,%2" [(set_attr "type" "delayed_compare")]) *************** *** 1323,1327 **** (match_operand:SI 3 "mask_operand" "L")))] "includes_lshift_p (operands[2], operands[3])" ! "rlinm %0,%h1,%h2,%m3,%M3") (define_insn "" --- 1633,1637 ---- (match_operand:SI 3 "mask_operand" "L")))] "includes_lshift_p (operands[2], operands[3])" ! "{rlinm|rlwinm} %0,%h1,%h2,%m3,%M3") (define_insn "" *************** *** 1334,1338 **** (clobber (match_scratch:SI 4 "=r"))] "includes_lshift_p (operands[2], operands[3])" ! "rlinm. %4,%h1,%h2,%m3,%M3" [(set_attr "type" "delayed_compare")]) --- 1644,1648 ---- (clobber (match_scratch:SI 4 "=r"))] "includes_lshift_p (operands[2], operands[3])" ! "{rlinm.|rlwinm.} %4,%h1,%h2,%m3,%M3" [(set_attr "type" "delayed_compare")]) *************** *** 1347,1356 **** (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] "includes_lshift_p (operands[2], operands[3])" ! "rlinm. %0,%h1,%h2,%m3,%M3" [(set_attr "type" "delayed_compare")]) ! ;; The RS/6000 assembler mis-handles "sri x,x,0", so write that case as ;; "sli x,x,0". ! (define_insn "lshrsi3" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") --- 1657,1680 ---- (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] "includes_lshift_p (operands[2], operands[3])" ! "{rlinm.|rlwinm.} %0,%h1,%h2,%m3,%M3" [(set_attr "type" "delayed_compare")]) ! ;; The AIX assembler mis-handles "sri x,x,0", so write that case as ;; "sli x,x,0". ! (define_expand "lshrsi3" ! [(use (match_operand:SI 0 "gpc_reg_operand" "")) ! (use (match_operand:SI 1 "gpc_reg_operand" "")) ! (use (match_operand:SI 2 "reg_or_cint_operand" ""))] ! "" ! " ! { ! if (TARGET_POWER) ! emit_insn (gen_lshrsi3_power (operands[0], operands[1], operands[2])); ! else ! emit_insn (gen_lshrsi3_powerpc (operands[0], operands[1], operands[2])); ! DONE; ! }") ! ! (define_insn "lshrsi3_power" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") *************** *** 1357,1365 **** (match_operand:SI 2 "reg_or_cint_operand" "r,i"))) (clobber (match_scratch:SI 3 "=q,X"))] ! "" "@ sre %0,%1,%2 ! s%A2i %0,%1,%h2") (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,x") --- 1681,1696 ---- (match_operand:SI 2 "reg_or_cint_operand" "r,i"))) (clobber (match_scratch:SI 3 "=q,X"))] ! "TARGET_POWER" "@ sre %0,%1,%2 ! {s%A2i|s%A2wi} %0,%1,%h2") + (define_insn "lshrsi3_powerpc" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "reg_or_cint_operand" "ri")))] + "TARGET_POWERPC" + "srw%I2 %0,%1,%2") + (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,x") *************** *** 1369,1376 **** (clobber (match_scratch:SI 3 "=r,r")) (clobber (match_scratch:SI 4 "=q,X"))] ! "" "@ sre. %3,%1,%2 ! s%A2i. %3,%1,%h2" [(set_attr "type" "delayed_compare")]) --- 1700,1717 ---- (clobber (match_scratch:SI 3 "=r,r")) (clobber (match_scratch:SI 4 "=q,X"))] ! "TARGET_POWER" "@ sre. %3,%1,%2 ! {s%A2i.|s%A2wi.} %3,%1,%h2" ! [(set_attr "type" "delayed_compare")]) ! ! (define_insn "" ! [(set (match_operand:CC 0 "cc_reg_operand" "=x") ! (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") ! (match_operand:SI 2 "reg_or_cint_operand" "ri")) ! (const_int 0))) ! (clobber (match_scratch:SI 3 "=r"))] ! "TARGET_POWERPC" ! "srw%I2. %3,%1,%2" [(set_attr "type" "delayed_compare")]) *************** *** 1383,1390 **** (lshiftrt:SI (match_dup 1) (match_dup 2))) (clobber (match_scratch:SI 4 "=q,X"))] ! "" "@ sre. %0,%1,%2 ! s%A2i. %0,%1,%h2" [(set_attr "type" "delayed_compare")]) --- 1724,1742 ---- (lshiftrt:SI (match_dup 1) (match_dup 2))) (clobber (match_scratch:SI 4 "=q,X"))] ! "TARGET_POWER" "@ sre. %0,%1,%2 ! {s%A2i.|s%A2wi.} %0,%1,%h2" ! [(set_attr "type" "delayed_compare")]) ! ! (define_insn "" ! [(set (match_operand:CC 3 "cc_reg_operand" "=x") ! (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") ! (match_operand:SI 2 "reg_or_cint_operand" "ri")) ! (const_int 0))) ! (set (match_operand:SI 0 "gpc_reg_operand" "=r") ! (lshiftrt:SI (match_dup 1) (match_dup 2)))] ! "TARGET_POWERPC" ! "srw%I2. %0,%1,%2" [(set_attr "type" "delayed_compare")]) *************** *** 1395,1399 **** (match_operand:SI 3 "mask_operand" "L")))] "includes_rshift_p (operands[2], operands[3])" ! "rlinm %0,%1,%s2,%m3,%M3") (define_insn "" --- 1747,1751 ---- (match_operand:SI 3 "mask_operand" "L")))] "includes_rshift_p (operands[2], operands[3])" ! "{rlinm|rlwinm} %0,%1,%s2,%m3,%M3") (define_insn "" *************** *** 1406,1410 **** (clobber (match_scratch:SI 4 "=r"))] "includes_rshift_p (operands[2], operands[3])" ! "rlinm. %4,%1,%s2,%m3,%M3" [(set_attr "type" "delayed_compare")]) --- 1758,1762 ---- (clobber (match_scratch:SI 4 "=r"))] "includes_rshift_p (operands[2], operands[3])" ! "{rlinm.|rlwinm.} %4,%1,%s2,%m3,%M3" [(set_attr "type" "delayed_compare")]) *************** *** 1419,1423 **** (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] "includes_rshift_p (operands[2], operands[3])" ! "rlinm. %0,%1,%s2,%m3,%M3" [(set_attr "type" "delayed_compare")]) --- 1771,1775 ---- (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] "includes_rshift_p (operands[2], operands[3])" ! "{rlinm.|rlwinm.} %0,%1,%s2,%m3,%M3" [(set_attr "type" "delayed_compare")]) *************** *** 1429,1433 **** (match_operand:SI 2 "const_int_operand" "i")) 0)))] "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 255))" ! "rlinm %0,%1,%s2,24,31") (define_insn "" --- 1781,1785 ---- (match_operand:SI 2 "const_int_operand" "i")) 0)))] "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 255))" ! "{rlinm|rlwinm} %0,%1,%s2,0xff") (define_insn "" *************** *** 1441,1445 **** (clobber (match_scratch:SI 3 "=r"))] "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 255))" ! "rlinm. %3,%1,%s2,24,31" [(set_attr "type" "delayed_compare")]) --- 1793,1797 ---- (clobber (match_scratch:SI 3 "=r"))] "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 255))" ! "{rlinm.|rlwinm.} %3,%1,%s2,0xff" [(set_attr "type" "delayed_compare")]) *************** *** 1455,1459 **** (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))] "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 255))" ! "rlinm. %0,%1,%s2,24,31" [(set_attr "type" "delayed_compare")]) --- 1807,1811 ---- (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))] "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 255))" ! "{rlinm.|rlwinm.} %0,%1,%s2,0xff" [(set_attr "type" "delayed_compare")]) *************** *** 1465,1469 **** (match_operand:SI 2 "const_int_operand" "i")) 0)))] "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 65535))" ! "rlinm %0,%1,%s2,16,31") (define_insn "" --- 1817,1821 ---- (match_operand:SI 2 "const_int_operand" "i")) 0)))] "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 65535))" ! "{rlinm|rlwinm} %0,%1,%s2,0xffff") (define_insn "" *************** *** 1477,1481 **** (clobber (match_scratch:SI 3 "=r"))] "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 65535))" ! "rlinm. %3,%1,%s2,16,31" [(set_attr "type" "delayed_compare")]) --- 1829,1833 ---- (clobber (match_scratch:SI 3 "=r"))] "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 65535))" ! "{rlinm.|rlwinm.} %3,%1,%s2,0xffff" [(set_attr "type" "delayed_compare")]) *************** *** 1491,1495 **** (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))] "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 65535))" ! "rlinm. %0,%1,%s2,16,31" [(set_attr "type" "delayed_compare")]) --- 1843,1847 ---- (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))] "includes_rshift_p (operands[2], gen_rtx (CONST_INT, VOIDmode, 65535))" ! "{rlinm.|rlwinm.} %0,%1,%s2,0xffff" [(set_attr "type" "delayed_compare")]) *************** *** 1500,1504 **** (ashiftrt:SI (match_operand:SI 2 "gpc_reg_operand" "r") (const_int 31)))] ! "" "rrib %0,%1,%2") --- 1852,1856 ---- (ashiftrt:SI (match_operand:SI 2 "gpc_reg_operand" "r") (const_int 31)))] ! "TARGET_POWER" "rrib %0,%1,%2") *************** *** 1509,1513 **** (lshiftrt:SI (match_operand:SI 2 "gpc_reg_operand" "r") (const_int 31)))] ! "" "rrib %0,%1,%2") --- 1861,1865 ---- (lshiftrt:SI (match_operand:SI 2 "gpc_reg_operand" "r") (const_int 31)))] ! "TARGET_POWER" "rrib %0,%1,%2") *************** *** 1519,1526 **** (const_int 1) (const_int 0)))] ! "" "rrib %0,%1,%2") ! (define_insn "ashrsi3" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") --- 1871,1892 ---- (const_int 1) (const_int 0)))] ! "TARGET_POWER" "rrib %0,%1,%2") ! (define_expand "ashrsi3" ! [(set (match_operand:SI 0 "gpc_reg_operand" "") ! (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") ! (match_operand:SI 2 "reg_or_cint_operand" "")))] ! "" ! " ! { ! if (TARGET_POWER) ! emit_insn (gen_ashrsi3_power (operands[0], operands[1], operands[2])); ! else ! emit_insn (gen_ashrsi3_powerpc (operands[0], operands[1], operands[2])); ! DONE; ! }") ! ! (define_insn "ashrsi3_power" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") *************** *** 1527,1535 **** (match_operand:SI 2 "reg_or_cint_operand" "r,i"))) (clobber (match_scratch:SI 3 "=q,X"))] ! "" "@ srea %0,%1,%2 ! srai %0,%1,%h2") (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,x") --- 1893,1908 ---- (match_operand:SI 2 "reg_or_cint_operand" "r,i"))) (clobber (match_scratch:SI 3 "=q,X"))] ! "TARGET_POWER" "@ srea %0,%1,%2 ! {srai|srawi} %0,%1,%h2") + (define_insn "ashrsi3_powerpc" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "reg_or_cint_operand" "ri")))] + "TARGET_POWERPC" + "sraw%I2 %0,%1,%2") + (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,x") *************** *** 1539,1546 **** (clobber (match_scratch:SI 3 "=r,r")) (clobber (match_scratch:SI 4 "=q,X"))] ! "" "@ srea. %3,%1,%2 ! srai. %3,%1,%h2" [(set_attr "type" "delayed_compare")]) --- 1912,1929 ---- (clobber (match_scratch:SI 3 "=r,r")) (clobber (match_scratch:SI 4 "=q,X"))] ! "TARGET_POWER" "@ srea. %3,%1,%2 ! {srai.|srawi.} %3,%1,%h2" ! [(set_attr "type" "delayed_compare")]) ! ! (define_insn "" ! [(set (match_operand:CC 0 "cc_reg_operand" "=x") ! (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") ! (match_operand:SI 2 "reg_or_cint_operand" "ri")) ! (const_int 0))) ! (clobber (match_scratch:SI 3 "=r"))] ! "TARGET_POWERPC" ! "sraw%I2. %3,%1,%2" [(set_attr "type" "delayed_compare")]) *************** *** 1553,1557 **** (ashiftrt:SI (match_dup 1) (match_dup 2))) (clobber (match_scratch:SI 4 "=q,X"))] ! "" "@ srea. %0,%1,%2 --- 1936,1940 ---- (ashiftrt:SI (match_dup 1) (match_dup 2))) (clobber (match_scratch:SI 4 "=q,X"))] ! "TARGET_POWER" "@ srea. %0,%1,%2 *************** *** 1559,1563 **** --- 1942,1970 ---- [(set_attr "type" "delayed_compare")]) + (define_insn "" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "reg_or_cint_operand" "ri")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (ashiftrt:SI (match_dup 1) (match_dup 2)))] + "TARGET_POWERPC" + "sraw%I2. %0,%1,%2" + [(set_attr "type" "delayed_compare")]) + (define_expand "extendqisi2" + [(use (match_operand:SI 0 "gpc_reg_operand" "")) + (use (match_operand:QI 1 "gpc_reg_operand" ""))] + "" + " + { + if (TARGET_POWER) + emit_insn (gen_extendqisi2_power (operands[0], operands[1])); + else + emit_insn (gen_extendqisi2_powerpc (operands[0], operands[1])); + DONE; + }") + + (define_expand "extendqisi2_power" [(parallel [(set (match_dup 2) (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "") *************** *** 1568,1572 **** (const_int 24))) (clobber (scratch:SI))])] ! "" " { operands[1] = gen_lowpart (SImode, operands[1]); --- 1975,1991 ---- (const_int 24))) (clobber (scratch:SI))])] ! "TARGET_POWER" ! " ! { operands[1] = gen_lowpart (SImode, operands[1]); ! operands[2] = gen_reg_rtx (SImode); }") ! ! (define_expand "extendqisi2_powerpc" ! [(set (match_dup 2) ! (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "") ! (const_int 24))) ! (set (match_operand:SI 0 "gpc_reg_operand" "") ! (ashiftrt:SI (match_dup 2) ! (const_int 24)))] ! "TARGET_POWERPC" " { operands[1] = gen_lowpart (SImode, operands[1]); *************** *** 1574,1577 **** --- 1993,2009 ---- (define_expand "extendqihi2" + [(use (match_operand:HI 0 "gpc_reg_operand" "")) + (use (match_operand:QI 1 "gpc_reg_operand" ""))] + "" + " + { + if (TARGET_POWER) + emit_insn (gen_extendqihi2_power (operands[0], operands[1])); + else + emit_insn (gen_extendqihi2_powerpc (operands[0], operands[1])); + DONE; + }") + + (define_expand "extendqihi2_power" [(parallel [(set (match_dup 2) (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "") *************** *** 1582,1586 **** (const_int 24))) (clobber (scratch:SI))])] ! "" " { operands[0] = gen_lowpart (SImode, operands[0]); --- 2014,2031 ---- (const_int 24))) (clobber (scratch:SI))])] ! "TARGET_POWER" ! " ! { operands[0] = gen_lowpart (SImode, operands[0]); ! operands[1] = gen_lowpart (SImode, operands[1]); ! operands[2] = gen_reg_rtx (SImode); }") ! ! (define_expand "extendqihi2_powerpc" ! [(set (match_dup 2) ! (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "") ! (const_int 24))) ! (set (match_operand:HI 0 "gpc_reg_operand" "") ! (ashiftrt:SI (match_dup 2) ! (const_int 24)))] ! "TARGET_POWERPC" " { operands[0] = gen_lowpart (SImode, operands[0]); *************** *** 1590,1597 **** ;; Floating-point insns, excluding normal data motion. ;; ! ;; We pretend that we have both SFmode and DFmode insns, while, in fact, ! ;; all fp insns are actually done in double. The only conversions we will ! ;; do will be when storing to memory. In that case, we will use the "frsp" ! ;; instruction before storing. ;; ;; Note that when we store into a single-precision memory location, we need to --- 2035,2044 ---- ;; Floating-point insns, excluding normal data motion. ;; ! ;; PowerPC has a full set of single-precision floating point instructions. ! ;; ! ;; For the POWER architecture, we pretend that we have both SFmode and ! ;; DFmode insns, while, in fact, all fp insns are actually done in double. ! ;; The only conversions we will do will be when storing to memory. In that ! ;; case, we will use the "frsp" instruction before storing. ;; ;; Note that when we store into a single-precision memory location, we need to *************** *** 1619,1629 **** (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "f")))] "" ! "* ! { ! if (REGNO (operands[0]) == REGNO (operands[1])) ! return \"\"; ! else ! return \"fmr %0,%1\"; ! }" [(set_attr "type" "fp")]) --- 2066,2070 ---- (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "f")))] "" ! "frsp %0,%1" [(set_attr "type" "fp")]) *************** *** 1649,1682 **** [(set_attr "type" "fp")]) ! (define_insn "addsf3" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")))] "" ! "fa %0,%1,%2" [(set_attr "type" "fp")]) ! (define_insn "subsf3" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f") (match_operand:SF 2 "gpc_reg_operand" "f")))] "" ! "fs %0,%1,%2" [(set_attr "type" "fp")]) ! (define_insn "mulsf3" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")))] ! "" ! "fm %0,%1,%2" [(set_attr "type" "fp")]) ! (define_insn "divsf3" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (div:SF (match_operand:SF 1 "gpc_reg_operand" "f") (match_operand:SF 2 "gpc_reg_operand" "f")))] ! "" ! "fd %0,%1,%2" [(set_attr "type" "fp")]) --- 2090,2192 ---- [(set_attr "type" "fp")]) ! (define_expand "addsf3" ! [(set (match_operand:SF 0 "gpc_reg_operand" "") ! (plus:SF (match_operand:SF 1 "gpc_reg_operand" "") ! (match_operand:SF 2 "gpc_reg_operand" "")))] ! "" ! "") ! ! (define_insn "" ! [(set (match_operand:SF 0 "gpc_reg_operand" "=f") ! (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f") ! (match_operand:SF 2 "gpc_reg_operand" "f")))] ! "TARGET_POWER" ! "{fa|fadd} %0,%1,%2" ! [(set_attr "type" "fp")]) ! ! (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")))] + "TARGET_POWERPC" + "fadds %0,%1,%2" + [(set_attr "type" "fp")]) + + (define_expand "subsf3" + [(set (match_operand:SF 0 "gpc_reg_operand" "") + (minus:SF (match_operand:SF 1 "gpc_reg_operand" "") + (match_operand:SF 2 "gpc_reg_operand" "")))] "" ! "") ! ! (define_insn "" ! [(set (match_operand:SF 0 "gpc_reg_operand" "=f") ! (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f") ! (match_operand:SF 2 "gpc_reg_operand" "f")))] ! "TARGET_POWER" ! "{fs|fsub} %0,%1,%2" [(set_attr "type" "fp")]) ! (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f") (match_operand:SF 2 "gpc_reg_operand" "f")))] + "TARGET_POWERPC" + "fsubs %0,%1,%2" + [(set_attr "type" "fp")]) + + (define_expand "mulsf3" + [(set (match_operand:SF 0 "gpc_reg_operand" "") + (mult:SF (match_operand:SF 1 "gpc_reg_operand" "") + (match_operand:SF 2 "gpc_reg_operand" "")))] "" ! "") ! ! (define_insn "" ! [(set (match_operand:SF 0 "gpc_reg_operand" "=f") ! (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") ! (match_operand:SF 2 "gpc_reg_operand" "f")))] ! "TARGET_POWER" ! "{fm|fmul} %0,%1,%2" [(set_attr "type" "fp")]) ! (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")))] ! "TARGET_POWERPC" ! "fmuls %0,%1,%2" [(set_attr "type" "fp")]) ! (define_expand "divsf3" ! [(set (match_operand:SF 0 "gpc_reg_operand" "") ! (div:SF (match_operand:SF 1 "gpc_reg_operand" "") ! (match_operand:SF 2 "gpc_reg_operand" "")))] ! "" ! "") ! ! (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (div:SF (match_operand:SF 1 "gpc_reg_operand" "f") (match_operand:SF 2 "gpc_reg_operand" "f")))] ! "TARGET_POWER" ! "{fd|fdiv} %0,%1,%2" ! [(set_attr "type" "sdiv")]) ! ! (define_insn "" ! [(set (match_operand:SF 0 "gpc_reg_operand" "=f") ! (div:SF (match_operand:SF 1 "gpc_reg_operand" "f") ! (match_operand:SF 2 "gpc_reg_operand" "f")))] ! "TARGET_POWERPC" ! "fdivs %0,%1,%2" ! [(set_attr "type" "sdiv")]) ! ! (define_insn "" ! [(set (match_operand:SF 0 "gpc_reg_operand" "=f") ! (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") ! (match_operand:SF 2 "gpc_reg_operand" "f")) ! (match_operand:SF 3 "gpc_reg_operand" "f")))] ! "TARGET_POWER" ! "{fma|fmadd} %0,%1,%2,%3" [(set_attr "type" "fp")]) *************** *** 1686,1691 **** (match_operand:SF 2 "gpc_reg_operand" "f")) (match_operand:SF 3 "gpc_reg_operand" "f")))] ! "" ! "fma %0,%1,%2,%3" [(set_attr "type" "fp")]) --- 2196,2201 ---- (match_operand:SF 2 "gpc_reg_operand" "f")) (match_operand:SF 3 "gpc_reg_operand" "f")))] ! "TARGET_POWERPC" ! "fmadds %0,%1,%2,%3" [(set_attr "type" "fp")]) *************** *** 1695,1700 **** (match_operand:SF 2 "gpc_reg_operand" "f")) (match_operand:SF 3 "gpc_reg_operand" "f")))] ! "" ! "fms %0,%1,%2,%3" [(set_attr "type" "fp")]) --- 2205,2219 ---- (match_operand:SF 2 "gpc_reg_operand" "f")) (match_operand:SF 3 "gpc_reg_operand" "f")))] ! "TARGET_POWER" ! "{fms|fmsub} %0,%1,%2,%3" ! [(set_attr "type" "fp")]) ! ! (define_insn "" ! [(set (match_operand:SF 0 "gpc_reg_operand" "=f") ! (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") ! (match_operand:SF 2 "gpc_reg_operand" "f")) ! (match_operand:SF 3 "gpc_reg_operand" "f")))] ! "TARGET_POWERPC" ! "fmsubs %0,%1,%2,%3" [(set_attr "type" "fp")]) *************** *** 1704,1709 **** (match_operand:SF 2 "gpc_reg_operand" "f")) (match_operand:SF 3 "gpc_reg_operand" "f"))))] ! "" ! "fnma %0,%1,%2,%3" [(set_attr "type" "fp")]) --- 2223,2237 ---- (match_operand:SF 2 "gpc_reg_operand" "f")) (match_operand:SF 3 "gpc_reg_operand" "f"))))] ! "TARGET_POWER" ! "{fnma|fnmadd} %0,%1,%2,%3" ! [(set_attr "type" "fp")]) ! ! (define_insn "" ! [(set (match_operand:SF 0 "gpc_reg_operand" "=f") ! (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") ! (match_operand:SF 2 "gpc_reg_operand" "f")) ! (match_operand:SF 3 "gpc_reg_operand" "f"))))] ! "TARGET_POWERPC" ! "fnmadds %0,%1,%2,%3" [(set_attr "type" "fp")]) *************** *** 1713,1720 **** (match_operand:SF 2 "gpc_reg_operand" "f")) (match_operand:SF 3 "gpc_reg_operand" "f"))))] ! "" ! "fnms %0,%1,%2,%3" [(set_attr "type" "fp")]) (define_insn "negdf2" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") --- 2241,2277 ---- (match_operand:SF 2 "gpc_reg_operand" "f")) (match_operand:SF 3 "gpc_reg_operand" "f"))))] ! "TARGET_POWER" ! "{fnms|fnmsub} %0,%1,%2,%3" ! [(set_attr "type" "fp")]) ! ! (define_insn "" ! [(set (match_operand:SF 0 "gpc_reg_operand" "=f") ! (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") ! (match_operand:SF 2 "gpc_reg_operand" "f")) ! (match_operand:SF 3 "gpc_reg_operand" "f"))))] ! "TARGET_POWERPC" ! "fnmsubs %0,%1,%2,%3" [(set_attr "type" "fp")]) + (define_expand "sqrtsf2" + [(set (match_operand:SF 0 "gpc_reg_operand" "") + (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))] + "TARGET_POWERPCSQR || TARGET_POWER2" + "") + + (define_insn "" + [(set (match_operand:SF 0 "gpc_reg_operand" "=f") + (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))] + "TARGET_POWERPCSQR" + "fsqrts %0,%1" + [(set_attr "type" "ssqrt")]) + + (define_insn "" + [(set (match_operand:SF 0 "gpc_reg_operand" "=f") + (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))] + "TARGET_POWER2" + "fsqrt %0,%1" + [(set_attr "type" "dsqrt")]) + (define_insn "negdf2" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") *************** *** 1743,1747 **** (match_operand:DF 2 "gpc_reg_operand" "f")))] "" ! "fa %0,%1,%2" [(set_attr "type" "fp")]) --- 2300,2304 ---- (match_operand:DF 2 "gpc_reg_operand" "f")))] "" ! "{fa|fadd} %0,%1,%2" [(set_attr "type" "fp")]) *************** *** 1751,1755 **** (match_operand:DF 2 "gpc_reg_operand" "f")))] "" ! "fs %0,%1,%2" [(set_attr "type" "fp")]) --- 2308,2312 ---- (match_operand:DF 2 "gpc_reg_operand" "f")))] "" ! "{fs|fsub} %0,%1,%2" [(set_attr "type" "fp")]) *************** *** 1759,1764 **** (match_operand:DF 2 "gpc_reg_operand" "f")))] "" ! "fm %0,%1,%2" ! [(set_attr "type" "fp")]) (define_insn "divdf3" --- 2316,2321 ---- (match_operand:DF 2 "gpc_reg_operand" "f")))] "" ! "{fm|fmul} %0,%1,%2" ! [(set_attr "type" "dmul")]) (define_insn "divdf3" *************** *** 1767,1772 **** (match_operand:DF 2 "gpc_reg_operand" "f")))] "" ! "fd %0,%1,%2" ! [(set_attr "type" "fp")]) (define_insn "" --- 2324,2329 ---- (match_operand:DF 2 "gpc_reg_operand" "f")))] "" ! "{fd|fdiv} %0,%1,%2" ! [(set_attr "type" "ddiv")]) (define_insn "" *************** *** 1776,1781 **** (match_operand:DF 3 "gpc_reg_operand" "f")))] "" ! "fma %0,%1,%2,%3" ! [(set_attr "type" "fp")]) (define_insn "" --- 2333,2338 ---- (match_operand:DF 3 "gpc_reg_operand" "f")))] "" ! "{fma|fmadd} %0,%1,%2,%3" ! [(set_attr "type" "dmul")]) (define_insn "" *************** *** 1785,1790 **** (match_operand:DF 3 "gpc_reg_operand" "f")))] "" ! "fms %0,%1,%2,%3" ! [(set_attr "type" "fp")]) (define_insn "" --- 2342,2347 ---- (match_operand:DF 3 "gpc_reg_operand" "f")))] "" ! "{fms|fmsub} %0,%1,%2,%3" ! [(set_attr "type" "dmul")]) (define_insn "" *************** *** 1794,1799 **** (match_operand:DF 3 "gpc_reg_operand" "f"))))] "" ! "fnma %0,%1,%2,%3" ! [(set_attr "type" "fp")]) (define_insn "" --- 2351,2356 ---- (match_operand:DF 3 "gpc_reg_operand" "f"))))] "" ! "{fnma|fnmadd} %0,%1,%2,%3" ! [(set_attr "type" "dmul")]) (define_insn "" *************** *** 1803,1808 **** (match_operand:DF 3 "gpc_reg_operand" "f"))))] "" ! "fnms %0,%1,%2,%3" ! [(set_attr "type" "fp")]) ;; Conversions to and from floating-point. --- 2360,2372 ---- (match_operand:DF 3 "gpc_reg_operand" "f"))))] "" ! "{fnms|fnmsub} %0,%1,%2,%3" ! [(set_attr "type" "dmul")]) ! ! (define_insn "sqrtdf2" ! [(set (match_operand:DF 0 "gpc_reg_operand" "=f") ! (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "f")))] ! "TARGET_POWERPCSQR | TARGET_POWER2" ! "fsqrt %0,%1" ! [(set_attr "type" "dsqrt")]) ;; Conversions to and from floating-point. *************** *** 1978,1991 **** ;; Define the DImode operations that can be done in a small number ;; of instructions. ! (define_insn "adddi3" [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r") (match_operand:DI 2 "reg_or_short_operand" "r,I")))] ! "" "@ ! a %L0,%L1,%L2\;ae %0,%1,%2 ! ai %L0,%L1,%2\;a%G2e %0,%1") ! (define_insn "subdi3" [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I") --- 2542,2576 ---- ;; Define the DImode operations that can be done in a small number ;; of instructions. ! (define_expand "adddi3" ! [(set (match_operand:DI 0 "gpc_reg_operand" "") ! (plus:DI (match_operand:DI 1 "gpc_reg_operand" "") ! (match_operand:DI 2 "reg_or_short_operand" "")))] ! "" ! " ! { ! if (TARGET_POWERPC ! && short_cint_operand (operands[2], DImode)) ! FAIL; ! }") ! ! (define_insn "" [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r") (match_operand:DI 2 "reg_or_short_operand" "r,I")))] ! "TARGET_POWER" "@ ! {a|addc} %L0,%L1,%L2\;{ae|adde} %0,%1,%2 ! {ai|addic} %L0,%L1,%2\;{a%G2e|add%G2e} %0,%1" ! [(set_attr "length" "8")]) ! ! (define_insn "" ! [(set (match_operand:DI 0 "gpc_reg_operand" "=r") ! (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r") ! (match_operand:DI 2 "gpc_reg_operand" "r")))] ! "TARGET_POWERPC" ! "addc %L0,%L1,%L2\;adde %0,%1,%2" ! [(set_attr "length" "8")]) ! (define_expand "subdi3" [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I") *************** *** 1992,2005 **** (match_operand:DI 2 "gpc_reg_operand" "r,r")))] "" "@ ! sf %L0,%L2,%L1\;sfe %0,%2,%1 ! sfi %L0,%L2,%1\;sf%G1e %0,%2") ! (define_insn "negdi2" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))] "" ! "sfi %L0,%L1,0\;sfze %0,%1") (define_insn "mulsidi3" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") --- 2577,2625 ---- (match_operand:DI 2 "gpc_reg_operand" "r,r")))] "" + " + { + if (TARGET_POWERPC + && short_cint_operand (operands[1], DImode)) + FAIL; + }") + + (define_insn "" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I") + (match_operand:DI 2 "gpc_reg_operand" "r,r")))] + "TARGET_POWER" "@ ! {sf|subfc} %L0,%L2,%L1\;{sfe|subfe} %0,%2,%1 ! {sfi|subfic} %L0,%L2,%1\;{sf%G1e|subf%G1e} %0,%2" ! [(set_attr "length" "8")]) ! (define_insn "" ! [(set (match_operand:DI 0 "gpc_reg_operand" "=r") ! (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r") ! (match_operand:DI 2 "gpc_reg_operand" "r")))] ! "TARGET_POWERPC" ! "subfc %L0,%L2,%L1\;subfe %0,%2,%1" ! [(set_attr "length" "8")]) ! ! (define_expand "negdi2" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))] "" ! "") + (define_insn "" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))] + "TARGET_POWER" + "{sfi|subfic} %L0,%L1,0\;{sfze|subfze} %0,%1" + [(set_attr "length" "8")]) + + (define_insn "" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))] + "TARGET_POWERPC" + "subfic %L0,%L1,0\;subfze %0,%1" + [(set_attr "length" "8")]) + (define_insn "mulsidi3" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") *************** *** 2007,2012 **** (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r")))) (clobber (match_scratch:SI 3 "=q"))] ! "" ! "mul %0,%1,%2\;mfmq %L0") ;; If operands 0 and 2 are in the same register, we have a problem. But --- 2627,2633 ---- (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r")))) (clobber (match_scratch:SI 3 "=q"))] ! "TARGET_POWER" ! "mul %0,%1,%2\;mfmq %L0" ! [(set_attr "length" "8")]) ;; If operands 0 and 2 are in the same register, we have a problem. But *************** *** 2018,2027 **** (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r"))) (clobber (match_scratch:SI 3 "=X,q,q,q"))] ! "" "@ ! sli %0,%L1,%h2\;cal %L0,0(0) sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2 ! sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2") (define_insn "lshrdi3" --- 2639,2649 ---- (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r"))) (clobber (match_scratch:SI 3 "=X,q,q,q"))] ! "TARGET_POWER" "@ ! {sli|slwi} %0,%L1,%h2\;{cal %L0,0(0)|li %L0,0} sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2 sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2 ! sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2" ! [(set_attr "length" "8")]) (define_insn "lshrdi3" *************** *** 2030,2039 **** (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r"))) (clobber (match_scratch:SI 3 "=X,q,q,q"))] ! "" "@ ! cal %0,0(0)\;s%A2i %L0,%1,%h2 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2 ! sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2") ;; Shift by a variable amount is too complex to be worth open-coding. We --- 2652,2662 ---- (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r"))) (clobber (match_scratch:SI 3 "=X,q,q,q"))] ! "TARGET_POWER" "@ ! {cal %0,0(0)|li %0,0}\;{s%A2i|s%A2wi} %L0,%1,%h2 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2 sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2 ! sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2" ! [(set_attr "length" "8")]) ;; Shift by a variable amount is too complex to be worth open-coding. We *************** *** 2045,2049 **** (match_operand:SI 2 "general_operand" ""))) (clobber (match_scratch:SI 3 ""))])] ! "" " { if (GET_CODE (operands[2]) != CONST_INT) --- 2668,2672 ---- (match_operand:SI 2 "general_operand" ""))) (clobber (match_scratch:SI 3 ""))])] ! "TARGET_POWER" " { if (GET_CODE (operands[2]) != CONST_INT) *************** *** 2056,2063 **** (match_operand:SI 2 "const_int_operand" "M,i"))) (clobber (match_scratch:SI 3 "=X,q"))] ! "" "@ ! srai %0,%1,31\;srai %L0,%1,%h2 ! sraiq %0,%1,%h2\;srliq %L0,%L1,%h2") ;; Now define ways of moving data around. --- 2679,2687 ---- (match_operand:SI 2 "const_int_operand" "M,i"))) (clobber (match_scratch:SI 3 "=X,q"))] ! "TARGET_POWER" "@ ! {srai|srawi} %0,%1,31\;{srai|srawi} %L0,%1,%h2 ! sraiq %0,%1,%h2\;srliq %L0,%L1,%h2" ! [(set_attr "length" "8")]) ;; Now define ways of moving data around. *************** *** 2102,2113 **** [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,*c*q,*l,*h") (match_operand:SI 1 "input_operand" "r,m,r,I,J,*h,r,r,0"))] ! "gpc_reg_operand (operands[0], SImode) ! || gpc_reg_operand (operands[1], SImode)" "@ ! ai %0,%1,0 ! l%U1%X1 %0,%1 ! st%U0%X0 %1,%0 ! cal %0,%1(0) ! cau %0,0,%u1 mf%1 %0 mt%0 %1 --- 2726,2737 ---- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,*c*q,*l,*h") (match_operand:SI 1 "input_operand" "r,m,r,I,J,*h,r,r,0"))] ! "TARGET_POWER && (gpc_reg_operand (operands[0], SImode) ! || gpc_reg_operand (operands[1], SImode))" "@ ! {ai|addic} %0,%1,0 ! {l%U1%X1|lwz%U1%X1} %0,%1 ! {st%U0%X0|stw%U0%X0} %1,%0 ! {cal %0,%1(0)|li %0,%1} ! {cau %0,0,%u1|lis %0,%u1} mf%1 %0 mt%0 %1 *************** *** 2116,2119 **** --- 2740,2758 ---- [(set_attr "type" "*,load,*,*,*,*,*,mtlr,*")]) + (define_insn "" + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,*h") + (match_operand:SI 1 "input_operand" "r,m,r,I,J,*h,r"))] + "TARGET_POWERPC && (gpc_reg_operand (operands[0], SImode) + || gpc_reg_operand (operands[1], SImode))" + "@ + mr %0,%1 + lwz%U1%X1 %0,%1 + stw%U0%X0 %1,%0 + li %0,%1 + lis %0,%u1 + mf%1 %0 + mt%0 %1" + [(set_attr "type" "*,load,*,*,*,*,*")]) + ;; Split a load of a large constant into the appropriate two-insn ;; sequence. *************** *** 2142,2146 **** (set (match_operand:SI 0 "gpc_reg_operand" "=r") (match_dup 1))] "" ! "ai. %0,%1,0" [(set_attr "type" "compare")]) --- 2781,2785 ---- (set (match_operand:SI 0 "gpc_reg_operand" "=r") (match_dup 1))] "" ! "{ai.|addic.} %0,%1,0" [(set_attr "type" "compare")]) *************** *** 2167,2177 **** [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*h,*h") (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))] ! "gpc_reg_operand (operands[0], HImode) ! || gpc_reg_operand (operands[1], HImode)" "@ ! oril %0,%1,0 lhz%U1%X1 %0,%1 sth%U0%X0 %1,%0 ! cal %0,%w1(0) mf%1 %0 mt%0 %1 --- 2806,2816 ---- [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*h,*h") (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))] ! "TARGET_POWER && (gpc_reg_operand (operands[0], HImode) ! || gpc_reg_operand (operands[1], HImode))" "@ ! {oril|ori} %0,%1,0 lhz%U1%X1 %0,%1 sth%U0%X0 %1,%0 ! {cal %0,%w1(0)|li %0,%w1} mf%1 %0 mt%0 %1 *************** *** 2179,2182 **** --- 2818,2835 ---- [(set_attr "type" "*,load,*,*,*,*,*")]) + (define_insn "" + [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*h") + (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r"))] + "TARGET_POWERPC && (gpc_reg_operand (operands[0], HImode) + || gpc_reg_operand (operands[1], HImode))" + "@ + ori %0,%1,0 + lhz%U1%X1 %0,%1 + sth%U0%X0 %1,%0 + li %0,%w1 + mf%1 %0 + mt%0 %1" + [(set_attr "type" "*,load,*,*,*,*")]) + (define_expand "movqi" [(set (match_operand:QI 0 "general_operand" "") *************** *** 2201,2211 **** [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*h,*h") (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))] ! "gpc_reg_operand (operands[0], QImode) ! || gpc_reg_operand (operands[1], QImode)" "@ ! oril %0,%1,0 lbz%U1%X1 %0,%1 stb%U0%X0 %1,%0 ! cal %0,%1(0) mf%1 %0 mt%0 %1 --- 2854,2864 ---- [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*h,*h") (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))] ! "TARGET_POWER && (gpc_reg_operand (operands[0], QImode) ! || gpc_reg_operand (operands[1], QImode))" "@ ! {oril|ori} %0,%1,0 lbz%U1%X1 %0,%1 stb%U0%X0 %1,%0 ! {cal %0,%1(0)|li %0,%1} mf%1 %0 mt%0 %1 *************** *** 2212,2215 **** --- 2865,2882 ---- cror 0,0,0" [(set_attr "type" "*,load,*,*,*,*,*")]) + + (define_insn "" + [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*h") + (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r"))] + "TARGET_POWERPC && (gpc_reg_operand (operands[0], QImode) + || gpc_reg_operand (operands[1], QImode))" + "@ + mr %0,%1 + lbz%U1%X1 %0,%1 + stb%U0%X0 %1,%0 + li %0,%1 + mf%1 %0 + mt%0 %1" + [(set_attr "type" "*,load,*,*,*,*")]) ;; Here is how to move condition codes around. When we store CC data in *************** *** 2230,2240 **** mcrf %0,%1 mtcrf 128,%1 ! rlinm %1,%1,%F0,0,31\;mtcrf %R0,%1\;rlinm %1,%1,%f0,0,31 mfcr %0 ! mfcr %0\;rlinm %0,%0,%f1,0,3 ! ai %0,%1,0 ! l%U1%X1 %0,%1 ! st%U0%U1 %1,%0" ! [(set_attr "type" "*,*,*,compare,*,*,load,*")]) ;; For floating-point, we normally deal with the floating-point registers. --- 2897,2908 ---- mcrf %0,%1 mtcrf 128,%1 ! {rlinm|rlwinm} %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;{rlinm|rlwinm} %1,%1,%f0,0xffffffff mfcr %0 ! mfcr %0\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000 ! {ai %0,%1,0|mr %0,%1} ! {l%U1%X1|lwz%U1%X1} %0,%1 ! {st%U0%U1|stw%U0%U1} %1,%0" ! [(set_attr "type" "*,*,*,compare,*,*,load,*") ! (set_attr "length" "*,*,12,*,8,*,*,*")]) ;; For floating-point, we normally deal with the floating-point registers. *************** *** 2325,2337 **** }") - (define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=r,r") - (match_operand:SF 1 "mem_or_easy_const_operand" "G,m"))] - "REGNO (operands[0]) <= 31" - "@ - # - l%U1%X1 %0,%1" - [(set_attr "type" "*,load")]) - (define_split [(set (match_operand:SF 0 "gpc_reg_operand" "") --- 2993,2996 ---- *************** *** 2352,2356 **** lfs%U1%X1 %0,%1 frsp %1,%1\;stfs%U0%X0 %1,%0" ! [(set_attr "type" "fp,load,*")]) (define_expand "movdf" --- 3011,3016 ---- lfs%U1%X1 %0,%1 frsp %1,%1\;stfs%U0%X0 %1,%0" ! [(set_attr "type" "fp,fpload,*") ! (set_attr "length" "*,*,8")]) (define_expand "movdf" *************** *** 2360,2445 **** " { ! /* If we are called from reload, we might be getting a SUBREG of a hard ! reg. So expand it. */ ! if (GET_CODE (operands[0]) == SUBREG ! && GET_CODE (SUBREG_REG (operands[0])) == REG ! && REGNO (SUBREG_REG (operands[0])) < FIRST_PSEUDO_REGISTER) ! operands[0] = alter_subreg (operands[0]); ! if (GET_CODE (operands[1]) == SUBREG ! && GET_CODE (SUBREG_REG (operands[1])) == REG ! && REGNO (SUBREG_REG (operands[1])) < FIRST_PSEUDO_REGISTER) ! operands[1] = alter_subreg (operands[1]); ! ! if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 32) { ! rtx stack_slot; ! ! /* If this is a store to memory or another integer register do the ! move directly. Otherwise store to a temporary stack slot and ! load from there into a floating point register. */ ! ! if (GET_CODE (operands[0]) == MEM ! || (GET_CODE (operands[0]) == REG ! && (REGNO (operands[0]) < 32 ! || (reload_in_progress ! && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)))) ! { ! emit_move_insn (operand_subword (operands[0], 0, 0, DFmode), ! operand_subword (operands[1], 0, 0, DFmode)); ! emit_move_insn (operand_subword (operands[0], 1, 0, DFmode), ! operand_subword (operands[1], 1, 0, DFmode)); ! DONE; ! } ! ! stack_slot = gen_rtx (MEM, DFmode, plus_constant (stack_pointer_rtx, 8)); ! emit_move_insn (stack_slot, operands[1]); ! emit_move_insn (operands[0], stack_slot); DONE; } ! if (GET_CODE (operands[0]) == MEM) ! { ! if (GET_CODE (operands[1]) == MEM) ! { ! emit_move_insn (operand_subword (operands[0], 0, 0, DFmode), ! operand_subword (operands[1], 0, 0, DFmode)); ! emit_move_insn (operand_subword (operands[0], 1, 0, DFmode), ! operand_subword (operands[1], 1, 0, DFmode)); ! DONE; ! } ! ! operands[1] = force_reg (DFmode, operands[1]); ! } ! ! if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 32) ! { ! rtx stack_slot; ! ! if (GET_CODE (operands[1]) == MEM ! #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT && ! defined(REAL_IS_NOT_DOUBLE) ! || GET_CODE (operands[1]) == CONST_DOUBLE ! #endif ! || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 32) ! || (reload_in_progress && GET_CODE (operands[1]) == REG ! && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)) ! { ! emit_move_insn (operand_subword (operands[0], 0, 0, DFmode), ! operand_subword (operands[1], 0, 0, DFmode)); ! emit_move_insn (operand_subword (operands[0], 1, 0, DFmode), ! operand_subword (operands[1], 1, 0, DFmode)); ! DONE; ! } ! ! if (reload_in_progress) ! stack_slot = gen_rtx (MEM, DFmode, ! plus_constant (stack_pointer_rtx, 8)); ! else ! stack_slot = assign_stack_temp (DFmode, 8, 0); ! emit_move_insn (stack_slot, operands[1]); ! emit_move_insn (operands[0], stack_slot); ! DONE; ! } ! if (CONSTANT_P (operands[1])) { operands[1] = force_const_mem (DFmode, operands[1]); --- 3020,3036 ---- " { ! if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) { ! emit_move_insn (operand_subword (operands[0], 1, 1, DFmode), ! operand_subword_force (operands[1], 1, DFmode)); ! emit_move_insn (operand_subword (operands[0], 0, 1, DFmode), ! operand_subword_force (operands[1], 0, DFmode)); DONE; } ! if (GET_CODE (operands[0]) != REG) ! operands[1] = force_reg (DFmode, operands[1]); ! if (CONSTANT_P (operands[1]) && ! easy_fp_constant (operands[1], DFmode)) { operands[1] = force_const_mem (DFmode, operands[1]); *************** *** 2451,2463 **** }") - (define_insn "" - [(set (match_operand:DF 0 "gpc_reg_operand" "=r,r") - (match_operand:DF 1 "mem_or_easy_const_operand" "G,m"))] - "REGNO (operands[0]) <= 31" - "@ - # - l %0,%1\;l %L0,%L1" - [(set_attr "type" "*,load")]) - (define_split [(set (match_operand:DF 0 "gpc_reg_operand" "") --- 3042,3045 ---- *************** *** 2471,2485 **** operands[4] = operand_subword (operands[0], 1, 0, DFmode); operands[5] = operand_subword (operands[1], 1, 0, DFmode); }") ! (define_insn "" ! [(set (match_operand:DF 0 "fp_reg_or_mem_operand" "=f,f,m") ! (match_operand:DF 1 "fp_reg_or_mem_operand" "f,m,f"))] ! "gpc_reg_operand (operands[0], DFmode) ! || gpc_reg_operand (operands[1], DFmode)" ! "@ ! fmr %0,%1 ! lfd%U1%X1 %0,%1 ! stfd%U0%X0 %1,%0" ! [(set_attr "type" "fp,load,*")]) ;; Next come the multi-word integer load and store and the load and store --- 3053,3098 ---- operands[4] = operand_subword (operands[0], 1, 0, DFmode); operands[5] = operand_subword (operands[1], 1, 0, DFmode); }") ! (define_insn "" ! [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,r,o,r,f,f,m") ! (match_operand:DF 1 "input_operand" "r,o,r,G,f,m,f"))] ! "register_operand (operands[0], DFmode) ! || register_operand (operands[1], DFmode)" ! "* ! { ! switch (which_alternative) ! { ! case 0: ! /* We normally copy the low-numbered register first. However, if ! the first register operand 0 is the same as the second register of ! operand 1, we must copy in the opposite order. */ ! if (REGNO (operands[0]) == REGNO (operands[1]) + 1) ! return \"{oril %L0,%L1,0|mr %L0,%L1}\;{oril %0,%1,0|mr %0,%1}\"; ! else ! return \"{oril %0,%1,0|mr %0,%1}\;{oril %L0,%L1,0|mr %L0,%L1}\"; ! case 1: ! /* If the low-address word is used in the address, we must load it ! last. Otherwise, load it first. Note that we cannot have ! auto-increment in that case since the address register is known to be ! dead. */ ! if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, ! operands [1], 0)) ! return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\"; ! else ! return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\"; ! case 2: ! return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\"; ! case 3: ! return \"#\"; ! case 4: ! return \"fmr %0,%1\"; ! case 5: ! return \"lfd%U1%X1 %0,%1\"; ! case 6: ! return \"stfd%U0%X0 %1,%0\"; ! } ! }" ! [(set_attr "type" "*,load,*,*,fp,fpload,*") ! (set_attr "length" "8,8,8,8,*,*,*")]) ;; Next come the multi-word integer load and store and the load and store *************** *** 2519,2525 **** operand 1, we must copy in the opposite order. */ if (REGNO (operands[0]) == REGNO (operands[1]) + 1) ! return \"oril %L0,%L1,0\;oril %0,%1,0\"; else ! return \"oril %0,%1,0\;oril %L0,%L1,0\"; case 1: /* If the low-address word is used in the address, we must load it --- 3132,3138 ---- operand 1, we must copy in the opposite order. */ if (REGNO (operands[0]) == REGNO (operands[1]) + 1) ! return \"{oril %L0,%L1,0|mr %L0,%L1}\;{oril %0,%1,0|mr %0,%1}\"; else ! return \"{oril %0,%1,0|mr %0,%1}\;{oril %L0,%L1,0|mr %L0,%L1}\"; case 1: /* If the low-address word is used in the address, we must load it *************** *** 2529,2544 **** if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, operands [1], 0)) ! return \"l %L0,%L1\;l %0,%1\"; else ! return \"l%U1 %0,%1\;l %L0,%L1\"; case 2: ! return \"st%U0 %1,%0\;st %L1,%L0\"; } }" ! [(set_attr "type" "*,load,*")]) ;; TImode is similar, except that we usually want to compute the address into ;; a register and use lsi/stsi (the exception is during reload). MQ is also ! ;; clobbered in stsi, so we need a SCRATCH for it. (define_expand "movti" [(parallel [(set (match_operand:TI 0 "general_operand" "") --- 3142,3158 ---- if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, operands [1], 0)) ! return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\"; else ! return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\"; case 2: ! return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\"; } }" ! [(set_attr "type" "*,load,*") ! (set_attr "length" "8")]) ;; TImode is similar, except that we usually want to compute the address into ;; a register and use lsi/stsi (the exception is during reload). MQ is also ! ;; clobbered in stsi for POWER, so we need a SCRATCH for it. (define_expand "movti" [(parallel [(set (match_operand:TI 0 "general_operand" "") *************** *** 2545,2549 **** (match_operand:TI 1 "general_operand" "")) (clobber (scratch:SI))])] ! "" " { --- 3159,3163 ---- (match_operand:TI 1 "general_operand" "")) (clobber (scratch:SI))])] ! "TARGET_POWER" " { *************** *** 2573,2578 **** (match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m")) (clobber (match_scratch:SI 2 "=q,q#X,X,X,X"))] ! "gpc_reg_operand (operands[0], TImode) ! || gpc_reg_operand (operands[1], TImode)" "* { --- 3187,3192 ---- (match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m")) (clobber (match_scratch:SI 2 "=q,q#X,X,X,X"))] ! "TARGET_POWER && (gpc_reg_operand (operands[0], TImode) ! || gpc_reg_operand (operands[1], TImode))" "* { *************** *** 2580,2587 **** { case 0: ! return \"stsi %1,%P0,16\"; case 1: ! return \"st%U0 %1,%0\;st %L1,%L0\;st %Y1,%Y0\;st %Z1,%Z0\"; case 2: --- 3194,3201 ---- { case 0: ! return \"{stsi|stswi} %1,%P0,16\"; case 1: ! return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\"; case 2: *************** *** 2591,2597 **** if (REGNO (operands[0]) >= REGNO (operands[1]) + 1 && REGNO (operands[0]) <= REGNO (operands[1]) + 3) ! return \"oril %Z0,%Z1,0\;oril %Y0,%Y1,0\;oril %L0,%L1,0\;oril %0,%1,0\"; else ! return \"oril %0,%1,0\;oril %L0,%L1,0\;oril %Y0,%Y1,0\;oril %Z0,%Z1,0\"; case 3: /* If the address is not used in the output, we can use lsi. Otherwise, --- 3205,3211 ---- if (REGNO (operands[0]) >= REGNO (operands[1]) + 1 && REGNO (operands[0]) <= REGNO (operands[1]) + 3) ! return \"{oril %Z0,%Z1,0|mr %Z0,%Z1}\;{oril %Y0,%Y1,0|mr %Y0,%Y1}\;{oril %L0,%L1,0|mr %L0,%L1}\;{oril %0,%1,0|mr %0,%1}\"; else ! return \"{oril %0,%1,0|mr %0,%1}\;{oril %L0,%L1,0|mr %L0,%L1}\;{oril %Y0,%Y1,0|mr %Y0,%Y1}\;{oril %Z0,%Z1,0|mr %Z0,%Z1}\"; case 3: /* If the address is not used in the output, we can use lsi. Otherwise, *************** *** 2598,2602 **** fall through to generating four loads. */ if (! reg_overlap_mentioned_p (operands[0], operands[1])) ! return \"lsi %0,%P1,16\"; /* ... fall through ... */ case 4: --- 3212,3216 ---- fall through to generating four loads. */ if (! reg_overlap_mentioned_p (operands[0], operands[1])) ! return \"{lsi|lswi} %0,%P1,16\"; /* ... fall through ... */ case 4: *************** *** 2606,2621 **** if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, operands[1], 0)) ! return \"l %L0,%L1\;l %Y0,%Y1\;l %Z0,%Z1\;l %0,%1\"; else if (refers_to_regno_p (REGNO (operands[0]) + 1, REGNO (operands[0]) + 2, operands[1], 0)) ! return \"l %0,%1\;l %Y0,%Y1\;l %Z0,%Z1\;l %L0,%L1\"; else if (refers_to_regno_p (REGNO (operands[0]) + 2, REGNO (operands[0]) + 3, operands[1], 0)) ! return \"l %0,%1\;l %L0,%L1\;l %Z0,%Z1\;l %Y0,%Y1\"; else ! return \"l%U1 %0,%1\;l %L0,%L1\;l %Y0,%Y1\;l %Z0,%Z1\"; } }" ! [(set_attr "type" "*,load,load,*,*")]) (define_expand "load_multiple" --- 3220,3236 ---- if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, operands[1], 0)) ! return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\"; else if (refers_to_regno_p (REGNO (operands[0]) + 1, REGNO (operands[0]) + 2, operands[1], 0)) ! return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\"; else if (refers_to_regno_p (REGNO (operands[0]) + 2, REGNO (operands[0]) + 3, operands[1], 0)) ! return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\"; else ! return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\"; } }" ! [(set_attr "type" "*,load,load,*,*") ! (set_attr "length" "*,16,16,*,16")]) (define_expand "load_multiple" *************** *** 2623,2627 **** (match_operand:SI 1 "" "")) (use (match_operand:SI 2 "" ""))])] ! "" " { --- 3238,3242 ---- (match_operand:SI 1 "" "")) (use (match_operand:SI 2 "" ""))])] ! "TARGET_POWER" " { *************** *** 2658,2662 **** [(set (match_operand:SI 1 "gpc_reg_operand" "=r") (match_operand:SI 2 "indirect_operand" "Q"))])] ! "" "* { --- 3273,3277 ---- [(set (match_operand:SI 1 "gpc_reg_operand" "=r") (match_operand:SI 2 "indirect_operand" "Q"))])] ! "TARGET_POWER" "* { *************** *** 2664,2668 **** is assigned to one of the output registers. In that case, do the lsi, but then load the correct value. This is a bit of a mess, but is ! the best we can do. */ static char result[100]; char newload[40]; --- 3279,3284 ---- is assigned to one of the output registers. In that case, do the lsi, but then load the correct value. This is a bit of a mess, but is ! the best we can do. ! We set the length attribute to the maximum possible size (8 bytes). */ static char result[100]; char newload[40]; *************** *** 2669,2673 **** int i; ! strcpy (result, \"lsi %1,%P2,%N0\"); for (i = 0; i < XVECLEN (operands[0], 0); i++) if (refers_to_regno_p (REGNO (operands[1]) + i, --- 3285,3289 ---- int i; ! strcpy (result, \"{lsi|lswi} %1,%P2,%N0\"); for (i = 0; i < XVECLEN (operands[0], 0); i++) if (refers_to_regno_p (REGNO (operands[1]) + i, *************** *** 2674,2678 **** REGNO (operands[1]) + i + 1, operands[2], 0)) { ! sprintf (newload, \"\;l %d,%d(%d)\", REGNO (operands[1]) + i, i * 4, REGNO (XEXP (operands[2], 0))); --- 3290,3294 ---- REGNO (operands[1]) + i + 1, operands[2], 0)) { ! sprintf (newload, \"\;{l|lwz} %d,%d(%d)\", REGNO (operands[1]) + i, i * 4, REGNO (XEXP (operands[2], 0))); *************** *** 2682,2687 **** return result; }" ! [(set_attr "type" "load")]) (define_expand "store_multiple" [(match_par_dup 3 [(set (match_operand:SI 0 "" "") --- 3298,3305 ---- return result; }" ! [(set_attr "type" "load") ! (set_attr "length" "8")]) + (define_expand "store_multiple" [(match_par_dup 3 [(set (match_operand:SI 0 "" "") *************** *** 2689,2693 **** (clobber (scratch:SI)) (use (match_operand:SI 2 "" ""))])] ! "" " { --- 3307,3311 ---- (clobber (scratch:SI)) (use (match_operand:SI 2 "" ""))])] ! "TARGET_POWER" " { *************** *** 2731,2736 **** (match_operand:SI 2 "gpc_reg_operand" "r")) (clobber (match_scratch:SI 3 "=q"))])] ! "" ! "stsi %2,%P1,%O0") ;; Define insns that do load or store with update. Some of these we can --- 3349,3354 ---- (match_operand:SI 2 "gpc_reg_operand" "r")) (clobber (match_scratch:SI 3 "=q"))])] ! "TARGET_POWER" ! "{stsi|stswi} %2,%P1,%O0") ;; Define insns that do load or store with update. Some of these we can *************** *** 2751,2757 **** "" "@ ! lux %3,%0,%2 ! lu %3,%2(%0)" ! [(set_attr "type" "load,load")]) (define_insn "" --- 3369,3375 ---- "" "@ ! {lux|lwzux} %3,%0,%2 ! {lu|lwzu} %3,%2(%0)" ! [(set_attr "type" "load")]) (define_insn "" *************** *** 2763,2768 **** "" "@ ! stux %3,%0,%2 ! stu %3,%2(%0)") (define_insn "" --- 3381,3386 ---- "" "@ ! {stux|stwux} %3,%0,%2 ! {stu|stwu} %3,%2(%0)") (define_insn "" *************** *** 2776,2780 **** lhzux %3,%0,%2 lhzu %3,%2(%0)" ! [(set_attr "type" "load,load")]) (define_insn "" --- 3394,3398 ---- lhzux %3,%0,%2 lhzu %3,%2(%0)" ! [(set_attr "type" "load")]) (define_insn "" *************** *** 2789,2793 **** lhzux %3,%0,%2 lhzu %3,%2(%0)" ! [(set_attr "type" "load,load")]) (define_insn "" --- 3407,3411 ---- lhzux %3,%0,%2 lhzu %3,%2(%0)" ! [(set_attr "type" "load")]) (define_insn "" *************** *** 2802,2806 **** lhaux %3,%0,%2 lhau %3,%2(%0)" ! [(set_attr "type" "load,load")]) (define_insn "" --- 3420,3424 ---- lhaux %3,%0,%2 lhau %3,%2(%0)" ! [(set_attr "type" "load")]) (define_insn "" *************** *** 2813,2818 **** "@ sthux %3,%0,%2 ! sthu %3,%2(%0)" ! [(set_attr "type" "load,load")]) (define_insn "" --- 3431,3435 ---- "@ sthux %3,%0,%2 ! sthu %3,%2(%0)") (define_insn "" *************** *** 2826,2830 **** lbzux %3,%0,%2 lbzu %3,%2(%0)" ! [(set_attr "type" "load,load")]) (define_insn "" --- 3443,3447 ---- lbzux %3,%0,%2 lbzu %3,%2(%0)" ! [(set_attr "type" "load")]) (define_insn "" *************** *** 2839,2843 **** lbzux %3,%0,%2 lbzu %3,%2(%0)" ! [(set_attr "type" "load,load")]) (define_insn "" --- 3456,3460 ---- lbzux %3,%0,%2 lbzu %3,%2(%0)" ! [(set_attr "type" "load")]) (define_insn "" *************** *** 2862,2866 **** lfsux %3,%0,%2 lfsu %3,%2(%0)" ! [(set_attr "type" "load,load")]) (define_insn "" --- 3479,3483 ---- lfsux %3,%0,%2 lfsu %3,%2(%0)" ! [(set_attr "type" "fpload")]) (define_insn "" *************** *** 2885,2889 **** lfdux %3,%0,%2 lfdu %3,%2(%0)" ! [(set_attr "type" "load,load")]) (define_insn "" --- 3502,3506 ---- lfdux %3,%0,%2 lfdu %3,%2(%0)" ! [(set_attr "type" "fpload")]) (define_insn "" *************** *** 3041,3044 **** --- 3658,3673 ---- }") + ;; Call to function in current module. No TOC pointer reload needed. + + (define_insn "" + [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s")) + (match_operand 1 "" "g")) + (clobber (match_scratch:SI 2 "=l"))] + "" + "bl %z0") + + ;; Call to function which may be in another module. Restore the TOC + ;; pointer (r2) after the call. + (define_insn "" [(call (mem:SI (match_operand:SI 0 "call_operand" "l,s")) *************** *** 3047,3052 **** "" "@ ! brl\;l 2,20(1) ! bl %z0\;cror 15,15,15") (define_insn "" --- 3676,3690 ---- "" "@ ! {brl|blrl}\;{l|lwz} 2,20(1) ! bl %z0\;%." ! [(set_attr "length" "8")]) ! ! (define_insn "" ! [(set (match_operand 0 "" "=fg") ! (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s")) ! (match_operand 2 "" "g"))) ! (clobber (match_scratch:SI 3 "=l"))] ! "" ! "bl %z1") (define_insn "" *************** *** 3057,3062 **** "" "@ ! brl\;l 2,20(1) ! bl %z1\;cror 15,15,15") ;; Call subroutine returning any type. --- 3695,3701 ---- "" "@ ! {brl|blrl}\;{l|lwz} 2,20(1) ! bl %z1\;%." ! [(set_attr "length" "8")]) ;; Call subroutine returning any type. *************** *** 3547,3551 **** (const_int 0)]))] "" ! "%D1mfcr %0\;rlinm %0,%0,%J1,31,31") (define_insn "" --- 4186,4191 ---- (const_int 0)]))] "" ! "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1" ! [(set_attr "length" "12")]) (define_insn "" *************** *** 3558,3563 **** (match_op_dup 1 [(match_dup 2) (const_int 0)]))] "" ! "%D1mfcr %3\;rlinm. %3,%3,%J1,30,31" ! [(set_attr "type" "delayed_compare")]) (define_insn "" --- 4198,4204 ---- (match_op_dup 1 [(match_dup 2) (const_int 0)]))] "" ! "%D1mfcr %3\;{rlinm.|rlwinm.} %3,%3,%J1,1" ! [(set_attr "type" "delayed_compare") ! (set_attr "length" "12")]) (define_insn "" *************** *** 3582,3587 **** operands[5] = gen_rtx (CONST_INT, VOIDmode, put_bit); ! return \"%D1mfcr %0\;rlinm %0,%0,%4,%5,%5\"; ! }") (define_insn "" --- 4223,4229 ---- operands[5] = gen_rtx (CONST_INT, VOIDmode, put_bit); ! return \"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%4,%5,%5\"; ! }" ! [(set_attr "length" "12")]) (define_insn "" *************** *** 3611,3617 **** operands[6] = gen_rtx (CONST_INT, VOIDmode, put_bit); ! return \"%D1mfcr %4\;rlinm. %4,%4,%5,%6,%6\"; }" ! [(set_attr "type" "delayed_compare")]) ;; If we are comparing the result of two comparisons, this can be done --- 4253,4260 ---- operands[6] = gen_rtx (CONST_INT, VOIDmode, put_bit); ! return \"%D1mfcr %4\;{rlinm.|rlwinm.} %4,%4,%5,%6,%6\"; }" ! [(set_attr "type" "delayed_compare") ! (set_attr "length" "12")]) ;; If we are comparing the result of two comparisons, this can be done *************** *** 3644,3648 **** else return \"%C1%C3creqv %E0,%j1,%j3\"; ! }") ;; There is a 3 cycle delay between consecutive mfcr instructions --- 4287,4292 ---- else return \"%C1%C3creqv %E0,%j1,%j3\"; ! }" ! [(set_attr "length" "12")]) ;; There is a 3 cycle delay between consecutive mfcr instructions *************** *** 3659,3663 **** (const_int 0)]))] "REGNO (operands[2]) != REGNO (operands[5])" ! "%D1%D4mfcr %3\;rlinm %0,%3,%J1,31,31\;rlinm %3,%3,%J4,31,31") ;; There are some scc insns that can be done directly, without a compare. --- 4303,4308 ---- (const_int 0)]))] "REGNO (operands[2]) != REGNO (operands[5])" ! "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1" ! [(set_attr "length" "20")]) ;; There are some scc insns that can be done directly, without a compare. *************** *** 3682,3690 **** "" "@ ! xor %0,%1,%2\;sfi %3,%0,0\;ae %0,%3,%0 ! sfi %3,%1,0\;ae %0,%3,%1 ! xoril %0,%1,%b2\;sfi %3,%0,0\;ae %0,%3,%0 ! xoriu %0,%1,%u2\;sfi %3,%0,0\;ae %0,%3,%0 ! sfi %0,%1,%2\;sfi %3,%0,0\;ae %0,%3,%0") (define_insn "" --- 4327,4336 ---- "" "@ ! xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0 ! {sfi|subfic} %3,%1,0\;{ae|adde} %0,%3,%1 ! {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0 ! {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0 ! {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0" ! [(set_attr "length" "12,8,12,12,12")]) (define_insn "" *************** *** 3699,3709 **** "" "@ ! xor %0,%1,%2\;sfi %3,%0,0\;ae. %0,%3,%0 ! sfi %3,%1,0\;ae. %0,%3,%1 ! xoril %0,%1,%b2\;sfi %3,%0,0\;ae. %0,%3,%0 ! xoriu %0,%1,%u2\;sfi %3,%0,0\;ae. %0,%3,%0 ! sfi %0,%1,%2\;sfi %3,%0,0\;ae. %0,%3,%0" ! [(set_attr "type" "compare")]) (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r") --- 4345,4371 ---- "" "@ ! xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0 ! {sfi|subfic} %3,%1,0\;{ae.|adde.} %0,%3,%1 ! {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0 ! {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0 ! {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0" ! [(set_attr "type" "compare") ! (set_attr "length" "12,8,12,12,12")]) + ;; We have insns of the form shown by the first define_insn below. If + ;; there is something inside the comparison operation, we must split it. + (define_split + [(set (match_operand:SI 0 "gpc_reg_operand" "") + (plus:SI (match_operator 1 "comparison_operator" + [(match_operand:SI 2 "" "") + (match_operand:SI 3 + "reg_or_cint_operand" "")]) + (match_operand:SI 4 "gpc_reg_operand" ""))) + (clobber (match_operand:SI 5 "register_operand" ""))] + "! gpc_reg_operand (operands[2], SImode)" + [(set (match_dup 5) (match_dup 2)) + (set (match_dup 2) (plus:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)]) + (match_dup 4)))]) + (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r") *************** *** 3714,3722 **** "" "@ ! xor %4,%1,%2\;sfi %4,%4,0\;aze %0,%3 ! sfi %4,%1,0\;aze %0,%3 ! xoril %4,%1,%b2\;sfi %4,%4,0\;aze %0,%3 ! xoriu %4,%1,%u2\;sfi %4,%4,0\;aze %0,%3 ! sfi %4,%1,%2\;sfi %4,%4,0\;aze %0,%3") (define_insn "" --- 4376,4385 ---- "" "@ ! xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3 ! {sfi|subfic} %4,%1,0\;{aze|addze} %0,%3 ! {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3 ! {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3 ! {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|adddze} %0,%3" ! [(set_attr "length" "12,8,12,12,12")]) (define_insn "" *************** *** 3731,3740 **** "" "@ ! xor %4,%1,%2\;sfi %4,%4,0\;aze. %4,%3 ! sfi %4,%1,0\;aze. %0,%3 ! xoril %4,%1,%b2\;sfi %4,%4,0\;aze. %4,%3 ! xoriu %4,%1,%u2\;sfi %4,%4,0\;aze. %4,%3 ! sfi %4,%1,%2\;sfi %4,%4,0\;aze. %4,%3" ! [(set_attr "type" "compare")]) (define_insn "" --- 4394,4404 ---- "" "@ ! xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3 ! {sfi|subfic} %4,%1,0\;{aze.|addze.} %0,%3 ! {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3 ! {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3 ! {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3" ! [(set_attr "type" "compare") ! (set_attr "length" "12,8,12,12,12")]) (define_insn "" *************** *** 3751,3760 **** "" "@ ! xor %4,%1,%2\;sfi %4,%4,0\;aze. %0,%3 ! sfi %4,%1,0\;aze. %4,%3 ! xoril %4,%1,%b2\;sfi %4,%4,0\;aze. %0,%3 ! xoriu %4,%1,%u2\;sfi %4,%4,0\;aze. %0,%3 ! sfi %4,%1,%2\;sfi %4,%4,0\;aze. %0,%3" ! [(set_attr "type" "compare")]) (define_insn "" --- 4415,4425 ---- "" "@ ! xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3 ! {sfi|subfic} %4,%1,0\;{aze.|addze.} %4,%3 ! {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3 ! {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3 ! {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3" ! [(set_attr "type" "compare") ! (set_attr "length" "12,8,12,12,12")]) (define_insn "" *************** *** 3764,3772 **** "" "@ ! xor %0,%1,%2\;ai %0,%0,-1\;sfe %0,%0,%0 ! ai %0,%1,-1\;sfe %0,%0,%0 ! xoril %0,%1,%b2\;ai %0,%0,-1\;sfe %0,%0,%0 ! xoriu %0,%1,%u2\;ai %0,%0,-1\;sfe %0,%0,%0 ! sfi %0,%1,%2\;ai %0,%0,-1\;sfe %0,%0,%0") ;; This is what (plus (ne X (const_int 0)) Y) looks like. --- 4429,4438 ---- "" "@ ! xor %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0 ! {ai|addic} %0,%1,-1\;{sfe|subfe} %0,%0,%0 ! {xoril|xori} %0,%1,%b2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0 ! {xoriu|xoris} %0,%1,%u2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0 ! {sfi|subfic} %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0" ! [(set_attr "length" "12,8,12,12,12")]) ;; This is what (plus (ne X (const_int 0)) Y) looks like. *************** *** 3779,3783 **** (clobber (match_scratch:SI 3 "=&r"))] "" ! "ai %3,%1,-1\;aze %0,%2") (define_insn "" --- 4445,4450 ---- (clobber (match_scratch:SI 3 "=&r"))] "" ! "{ai|addic} %3,%1,-1\;{aze|addze} %0,%2" ! [(set_attr "length" "8")]) (define_insn "" *************** *** 3791,3796 **** (clobber (match_scratch:SI 3 "=&r"))] "" ! "ai %3,%1,-1\;aze. %3,%2" ! [(set_attr "type" "compare")]) (define_insn "" --- 4458,4464 ---- (clobber (match_scratch:SI 3 "=&r"))] "" ! "{ai|addic} %3,%1,-1\;{aze.|addze.} %3,%2" ! [(set_attr "type" "compare") ! (set_attr "length" "8")]) (define_insn "" *************** *** 3807,3812 **** (clobber (match_scratch:SI 3 "=&r"))] "" ! "ai %3,%1,-1\;aze. %0,%2" ! [(set_attr "type" "compare")]) (define_insn "" --- 4475,4481 ---- (clobber (match_scratch:SI 3 "=&r"))] "" ! "{ai|addic} %3,%1,-1\;{aze.|addze.} %0,%2" ! [(set_attr "type" "compare") ! (set_attr "length" "8")]) (define_insn "" *************** *** 3815,3822 **** (match_operand:SI 2 "reg_or_short_operand" "r,O"))) (clobber (match_scratch:SI 3 "=r,X"))] ! "" "@ ! doz %3,%2,%1\;sfi %0,%3,0\;ae %0,%0,%3 ! ai %0,%1,-1\;aze %0,%0\;sri %0,%0,31") (define_insn "" --- 4484,4492 ---- (match_operand:SI 2 "reg_or_short_operand" "r,O"))) (clobber (match_scratch:SI 3 "=r,X"))] ! "TARGET_POWER" "@ ! doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3 ! {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;sri %0,%0,31" ! [(set_attr "length" "12")]) (define_insn "" *************** *** 3829,3837 **** (le:SI (match_dup 1) (match_dup 2))) (clobber (match_scratch:SI 3 "=r,X"))] ! "" "@ ! doz %3,%2,%1\;sfi %0,%3,0\;ae. %0,%0,%3 ! ai %0,%1,-1\;aze %0,%0\;sri. %0,%0,31" ! [(set_attr "type" "delayed_compare,compare")]) (define_insn "" --- 4499,4508 ---- (le:SI (match_dup 1) (match_dup 2))) (clobber (match_scratch:SI 3 "=r,X"))] ! "TARGET_POWER" "@ ! doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3 ! {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;sri. %0,%0,31" ! [(set_attr "type" "delayed_compare,compare") ! (set_attr "length" "12")]) (define_insn "" *************** *** 3841,3848 **** (match_operand:SI 3 "gpc_reg_operand" "r,r"))) (clobber (match_scratch:SI 4 "=&r,&r"))] ! "" "@ ! doz %4,%2,%1\;sfi %4,%4,0\;aze %0,%3 ! srai %4,%1,31\;sf %4,%1,%4\;aze %0,%3") (define_insn "" --- 4512,4520 ---- (match_operand:SI 3 "gpc_reg_operand" "r,r"))) (clobber (match_scratch:SI 4 "=&r,&r"))] ! "TARGET_POWER" "@ ! doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3 ! {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze|addze} %0,%3" ! [(set_attr "length" "12")]) (define_insn "" *************** *** 3854,3862 **** (const_int 0))) (clobber (match_scratch:SI 4 "=&r,&r"))] ! "" "@ ! doz %4,%2,%1\;sfi %4,%4,0\;aze. %4,%3 ! srai %4,%1,31\;sf %4,%1,%4\;aze. %4,%3" ! [(set_attr "type" "compare")]) (define_insn "" --- 4526,4535 ---- (const_int 0))) (clobber (match_scratch:SI 4 "=&r,&r"))] ! "TARGET_POWER" "@ ! doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3 ! {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %4,%3" ! [(set_attr "type" "compare") ! (set_attr "length" "12")]) (define_insn "" *************** *** 3870,3878 **** (plus:SI (le:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (clobber (match_scratch:SI 4 "=&r,&r"))] ! "" "@ ! doz %4,%2,%1\;sfi %4,%4,0\;aze. %0,%3 ! srai %4,%1,31\;sf %4,%1,%4\;aze. %0,%3" ! [(set_attr "type" "compare")]) (define_insn "" --- 4543,4552 ---- (plus:SI (le:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (clobber (match_scratch:SI 4 "=&r,&r"))] ! "TARGET_POWER" "@ ! doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3 ! {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %0,%3" ! [(set_attr "type" "compare") ! (set_attr "length" "12")]) (define_insn "" *************** *** 3880,3887 **** (neg:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "reg_or_short_operand" "r,O"))))] ! "" "@ ! doz %0,%2,%1\;ai %0,%0,-1\;sfe %0,%0,%0 ! ai %0,%1,-1\;aze %0,%0\;srai %0,%0,31") (define_insn "" --- 4554,4562 ---- (neg:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "reg_or_short_operand" "r,O"))))] ! "TARGET_POWER" "@ ! doz %0,%2,%1\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0 ! {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{srai|srawi} %0,%0,31" ! [(set_attr "length" "12")]) (define_insn "" *************** *** 3890,3894 **** (match_operand:SI 2 "reg_or_short_operand" "rI")))] "" ! "sf%I2 %0,%1,%2\;cal %0,0(0)\;ae %0,%0,%0") (define_insn "" --- 4565,4570 ---- (match_operand:SI 2 "reg_or_short_operand" "rI")))] "" ! "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0" ! [(set_attr "length" "12")]) (define_insn "" *************** *** 3901,3906 **** (leu:SI (match_dup 1) (match_dup 2)))] "" ! "sf%I2 %0,%1,%2\;cal %0,0(0)\;ae. %0,%0,%0" ! [(set_attr "type" "compare")]) (define_insn "" --- 4577,4583 ---- (leu:SI (match_dup 1) (match_dup 2)))] "" ! "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0" ! [(set_attr "type" "compare") ! (set_attr "length" "12")]) (define_insn "" *************** *** 3911,3915 **** (clobber (match_scratch:SI 4 "=&r"))] "" ! "sf%I2 %4,%1,%2\;aze %0,%3") (define_insn "" --- 4588,4593 ---- (clobber (match_scratch:SI 4 "=&r"))] "" ! "{sf%I2|subf%I2c} %4,%1,%2\;{aze|addze} %0,%3" ! [(set_attr "length" "8")]) (define_insn "" *************** *** 3922,3927 **** (clobber (match_scratch:SI 4 "=&r"))] "" ! "sf%I2 %4,%1,%2\;aze. %4,%3" ! [(set_attr "type" "compare")]) (define_insn "" --- 4600,4606 ---- (clobber (match_scratch:SI 4 "=&r"))] "" ! "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %4,%3" ! [(set_attr "type" "compare") ! (set_attr "length" "8")]) (define_insn "" *************** *** 3936,3941 **** (clobber (match_scratch:SI 4 "=&r"))] "" ! "sf%I2 %4,%1,%2\;aze. %0,%3" ! [(set_attr "type" "compare")]) (define_insn "" --- 4615,4621 ---- (clobber (match_scratch:SI 4 "=&r"))] "" ! "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %0,%3" ! [(set_attr "type" "compare") ! (set_attr "length" "8")]) (define_insn "" *************** *** 3944,3948 **** (match_operand:SI 2 "reg_or_short_operand" "rI"))))] "" ! "sf%I2 %0,%1,%2\;sfe %0,%0,%0\;nand %0,%0,%0") (define_insn "" --- 4624,4629 ---- (match_operand:SI 2 "reg_or_short_operand" "rI"))))] "" ! "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0" ! [(set_attr "length" "12")]) (define_insn "" *************** *** 3954,3958 **** (clobber (match_scratch:SI 4 "=&r"))] "" ! "sf%I2 %4,%1,%2\;sfe %4,%4,%4\;andc %0,%3,%4") (define_insn "" --- 4635,4640 ---- (clobber (match_scratch:SI 4 "=&r"))] "" ! "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4" ! [(set_attr "length" "12")]) (define_insn "" *************** *** 3966,3971 **** (clobber (match_scratch:SI 4 "=&r"))] "" ! "sf%I2 %4,%1,%2\;sfe %4,%4,%4\;andc. %4,%3,%4" ! [(set_attr "type" "compare")]) (define_insn "" --- 4648,4654 ---- (clobber (match_scratch:SI 4 "=&r"))] "" ! "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4" ! [(set_attr "type" "compare") ! (set_attr "length" "12")]) (define_insn "" *************** *** 3981,3986 **** (clobber (match_scratch:SI 4 "=&r"))] "" ! "sf%I2 %4,%1,%2\;sfe %4,%4,%4\;andc. %0,%3,%4" ! [(set_attr "type" "compare")]) (define_insn "" --- 4664,4670 ---- (clobber (match_scratch:SI 4 "=&r"))] "" ! "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4" ! [(set_attr "type" "compare") ! (set_attr "length" "12")]) (define_insn "" *************** *** 3988,3993 **** (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_short_operand" "rI")))] ! "" ! "doz%I2 %0,%1,%2\;nabs %0,%0\;sri %0,%0,31") (define_insn "" --- 4672,4678 ---- (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_short_operand" "rI")))] ! "TARGET_POWER" ! "doz%I2 %0,%1,%2\;nabs %0,%0\;sri %0,%0,31" ! [(set_attr "length" "12")]) (define_insn "" *************** *** 3999,4005 **** (set (match_operand:SI 0 "gpc_reg_operand" "=r") (lt:SI (match_dup 1) (match_dup 2)))] ! "" "doz%I2 %0,%1,%2\;nabs %0,%0\;sri. %0,%0,31" ! [(set_attr "type" "delayed_compare")]) (define_insn "" --- 4684,4691 ---- (set (match_operand:SI 0 "gpc_reg_operand" "=r") (lt:SI (match_dup 1) (match_dup 2)))] ! "TARGET_POWER" "doz%I2 %0,%1,%2\;nabs %0,%0\;sri. %0,%0,31" ! [(set_attr "type" "delayed_compare") ! (set_attr "length" "12")]) (define_insn "" *************** *** 4009,4014 **** (match_operand:SI 3 "gpc_reg_operand" "r"))) (clobber (match_scratch:SI 4 "=&r"))] ! "" ! "doz%I2 %4,%1,%2\;ai %4,%4,-1\;aze %0,%3") (define_insn "" --- 4695,4701 ---- (match_operand:SI 3 "gpc_reg_operand" "r"))) (clobber (match_scratch:SI 4 "=&r"))] ! "TARGET_POWER" ! "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3" ! [(set_attr "length" "12")]) (define_insn "" *************** *** 4020,4026 **** (const_int 0))) (clobber (match_scratch:SI 4 "=&r"))] ! "" ! "doz%I2 %4,%1,%2\;ai %4,%4,-1\;aze. %4,%3" ! [(set_attr "type" "compare")]) (define_insn "" --- 4707,4714 ---- (const_int 0))) (clobber (match_scratch:SI 4 "=&r"))] ! "TARGET_POWER" ! "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3" ! [(set_attr "type" "compare") ! (set_attr "length" "12")]) (define_insn "" *************** *** 4034,4040 **** (plus:SI (lt:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (clobber (match_scratch:SI 4 "=&r"))] ! "" ! "doz%I2 %4,%1,%2\;ai %4,%4,-1\;aze. %0,%3" ! [(set_attr "type" "compare")]) (define_insn "" --- 4722,4729 ---- (plus:SI (lt:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (clobber (match_scratch:SI 4 "=&r"))] ! "TARGET_POWER" ! "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3" ! [(set_attr "type" "compare") ! (set_attr "length" "12")]) (define_insn "" *************** *** 4042,4047 **** (neg:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_short_operand" "rI"))))] ! "" ! "doz%I2 %0,%1,%2\;nabs %0,%0\;srai %0,%0,31") (define_insn "" --- 4731,4737 ---- (neg:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_short_operand" "rI"))))] ! "TARGET_POWER" ! "doz%I2 %0,%1,%2\;nabs %0,%0\;{srai|srawi} %0,%0,31" ! [(set_attr "length" "12")]) (define_insn "" *************** *** 4051,4056 **** "" "@ ! sf %0,%2,%1\;sfe %0,%0,%0\;neg %0,%0 ! ai %0,%1,%n2\;sfe %0,%0,%0\;neg %0,%0") (define_insn "" --- 4741,4747 ---- "" "@ ! {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg %0,%0 ! {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg %0,%0" ! [(set_attr "length" "12")]) (define_insn "" *************** *** 4064,4070 **** "" "@ ! sf %0,%2,%1\;sfe %0,%0,%0\;neg. %0,%0 ! ai %0,%1,%n2\;sfe %0,%0,%0\;neg. %0,%0" ! [(set_attr "type" "compare")]) (define_insn "" --- 4755,4762 ---- "" "@ ! {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg. %0,%0 ! {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0" ! [(set_attr "type" "compare") ! (set_attr "length" "12")]) (define_insn "" *************** *** 4076,4117 **** "" "@ ! sf %4,%2,%1\;sfe %4,%4,%4\;sf%I3 %0,%4,%3 ! sf %4,%2,%1\;sfe %4,%4,%4\;sf%I3 %0,%4,%3 ! ai %4,%1,%n2\;sfe %4,%4,%4\;sf%I3 %0,%4,%3 ! ai %4,%1,%n2\;sfe %4,%4,%4\;sf%I3 %0,%4,%3") (define_insn "" ! [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x") (compare:CC ! (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") ! (match_operand:SI 2 "reg_or_neg_short_operand" "r,r,P,P")) ! (match_operand:SI 3 "reg_or_short_operand" "r,I,r,I")) (const_int 0))) ! (clobber (match_scratch:SI 4 "=&r,r,&r,r"))] "" "@ ! sf %4,%2,%1\;sfe %4,%4,%4\;sf%I3. %4,%4,%3 ! sf %4,%2,%1\;sfe %4,%4,%4\;sf%I3. %4,%4,%3 ! ai %4,%1,%n2\;sfe %4,%4,%4\;sf%I3. %4,%4,%3 ! ai %4,%1,%n2\;sfe %4,%4,%4\;sf%I3. %4,%4,%3" ! [(set_attr "type" "compare")]) (define_insn "" ! [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,x,x") (compare:CC ! (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") ! (match_operand:SI 2 "reg_or_neg_short_operand" "r,r,P,P")) ! (match_operand:SI 3 "reg_or_short_operand" "r,I,r,I")) (const_int 0))) ! (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) ! (clobber (match_scratch:SI 4 "=&r,r,&r,r"))] "" "@ ! sf %4,%2,%1\;sfe %4,%4,%4\;sf%I3. %0,%4,%3 ! sf %4,%2,%1\;sfe %4,%4,%4\;sf%I3. %0,%4,%3 ! ai %4,%1,%n2\;sfe %4,%4,%4\;sf%I3. %0,%4,%3 ! ai %4,%1,%n2\;sfe %4,%4,%4\;sf%I3. %0,%4,%3" ! [(set_attr "type" "compare")]) (define_insn "" --- 4768,4808 ---- "" "@ ! {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3 ! {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3 ! {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3 ! {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3" ! [(set_attr "length" "12")]) (define_insn "" ! [(set (match_operand:CC 0 "cc_reg_operand" "=x,x") (compare:CC ! (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") ! (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")) ! (match_operand:SI 3 "gpc_reg_operand" "r,r")) (const_int 0))) ! (clobber (match_scratch:SI 4 "=&r,&r"))] "" "@ ! {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3 ! {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3" ! [(set_attr "type" "compare") ! (set_attr "length" "12")]) (define_insn "" ! [(set (match_operand:CC 5 "cc_reg_operand" "=x,x") (compare:CC ! (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") ! (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")) ! (match_operand:SI 3 "gpc_reg_operand" "r,r")) (const_int 0))) ! (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) ! (clobber (match_scratch:SI 4 "=&r,&r"))] "" "@ ! {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3 ! {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3" ! [(set_attr "type" "compare") ! (set_attr "length" "12")]) (define_insn "" *************** *** 4121,4126 **** "" "@ ! sf %0,%2,%1\;sfe %0,%0,%0 ! ai %0,%1,%n2\;sfe %0,%0,%0") (define_insn "" --- 4812,4818 ---- "" "@ ! {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0 ! {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0" ! [(set_attr "length" "8")]) (define_insn "" *************** *** 4129,4134 **** (match_operand:SI 2 "reg_or_short_operand" "rI"))) (clobber (match_scratch:SI 3 "=r"))] ! "" ! "doz%I2 %3,%1,%2\;sfi %0,%3,0\;ae %0,%0,%3") (define_insn "" --- 4821,4827 ---- (match_operand:SI 2 "reg_or_short_operand" "rI"))) (clobber (match_scratch:SI 3 "=r"))] ! "TARGET_POWER" ! "doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3" ! [(set_attr "length" "12")]) (define_insn "" *************** *** 4141,4147 **** (ge:SI (match_dup 1) (match_dup 2))) (clobber (match_scratch:SI 3 "=r"))] ! "" ! "doz%I2 %3,%1,%2\;sfi %0,%3,0\;ae. %0,%0,%3" ! [(set_attr "type" "compare")]) (define_insn "" --- 4834,4841 ---- (ge:SI (match_dup 1) (match_dup 2))) (clobber (match_scratch:SI 3 "=r"))] ! "TARGET_POWER" ! "doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3" ! [(set_attr "type" "compare") ! (set_attr "length" "12")]) (define_insn "" *************** *** 4151,4156 **** (match_operand:SI 3 "gpc_reg_operand" "r"))) (clobber (match_scratch:SI 4 "=&r"))] ! "" ! "doz%I2 %4,%1,%2\;sfi %4,%4,0\;aze %0,%3") (define_insn "" --- 4845,4851 ---- (match_operand:SI 3 "gpc_reg_operand" "r"))) (clobber (match_scratch:SI 4 "=&r"))] ! "TARGET_POWER" ! "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3" ! [(set_attr "length" "12")]) (define_insn "" *************** *** 4162,4168 **** (const_int 0))) (clobber (match_scratch:SI 4 "=&r"))] ! "" ! "doz%I2 %4,%1,%2\;sfi %4,%4,0\;aze. %4,%3" ! [(set_attr "type" "compare")]) (define_insn "" --- 4857,4864 ---- (const_int 0))) (clobber (match_scratch:SI 4 "=&r"))] ! "TARGET_POWER" ! "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3" ! [(set_attr "type" "compare") ! (set_attr "length" "12")]) (define_insn "" *************** *** 4176,4182 **** (plus:SI (ge:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (clobber (match_scratch:SI 4 "=&r"))] ! "" ! "doz%I2 %4,%1,%2\;sfi %4,%4,0\;aze. %0,%3" ! [(set_attr "type" "compare")]) (define_insn "" --- 4872,4879 ---- (plus:SI (ge:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (clobber (match_scratch:SI 4 "=&r"))] ! "TARGET_POWER" ! "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3" ! [(set_attr "type" "compare") ! (set_attr "length" "12")]) (define_insn "" *************** *** 4184,4189 **** (neg:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_short_operand" "rI"))))] ! "" ! "doz%I2 %0,%1,%2\;ai %0,%0,-1\;sfe %0,%0,%0") ;; This is (and (neg (ge X (const_int 0))) Y). --- 4881,4887 ---- (neg:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_short_operand" "rI"))))] ! "TARGET_POWER" ! "doz%I2 %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0" ! [(set_attr "length" "12")]) ;; This is (and (neg (ge X (const_int 0))) Y). *************** *** 4197,4201 **** (clobber (match_scratch:SI 3 "=&r"))] "" ! "srai %3,%1,31\;andc %0,%2,%3") (define_insn "" --- 4895,4900 ---- (clobber (match_scratch:SI 3 "=&r"))] "" ! "{srai|srawi} %3,%1,31\;andc %0,%2,%3" ! [(set_attr "length" "8")]) (define_insn "" *************** *** 4210,4215 **** (clobber (match_scratch:SI 3 "=&r"))] "" ! "srai %3,%1,31\;andc. %3,%2,%3" ! [(set_attr "type" "compare")]) (define_insn "" --- 4909,4915 ---- (clobber (match_scratch:SI 3 "=&r"))] "" ! "{srai|srawi} %3,%1,31\;andc. %3,%2,%3" ! [(set_attr "type" "compare") ! (set_attr "length" "8")]) (define_insn "" *************** *** 4228,4233 **** (clobber (match_scratch:SI 3 "=&r"))] "" ! "srai %3,%1,31\;andc. %0,%2,%3" ! [(set_attr "type" "compare")]) (define_insn "" --- 4928,4934 ---- (clobber (match_scratch:SI 3 "=&r"))] "" ! "{srai|srawi} %3,%1,31\;andc. %0,%2,%3" ! [(set_attr "type" "compare") ! (set_attr "length" "8")]) (define_insn "" *************** *** 4237,4242 **** "" "@ ! sf %0,%2,%1\;cal %0,0(0)\;ae %0,%0,%0 ! ai %0,%1,%n2\;cal %0,0(0)\;ae %0,%0,%0") (define_insn "" --- 4938,4944 ---- "" "@ ! {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0 ! {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0" ! [(set_attr "length" "12")]) (define_insn "" *************** *** 4250,4256 **** "" "@ ! sf %0,%2,%1\;cal %0,0(0)\;ae. %0,%0,%0 ! ai %0,%1,%n2\;cal %0,0(0)\;ae. %0,%0,%0" ! [(set_attr "type" "compare")]) (define_insn "" --- 4952,4959 ---- "" "@ ! {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0 ! {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0" ! [(set_attr "type" "compare") ! (set_attr "length" "12")]) (define_insn "" *************** *** 4262,4267 **** "" "@ ! sf %4,%2,%1\;aze %0,%3 ! ai %4,%1,%n2\;aze %0,%3") (define_insn "" --- 4965,4971 ---- "" "@ ! {sf|subfc} %4,%2,%1\;{aze|addze} %0,%3 ! {ai|addic} %4,%1,%n2\;{aze|addze} %0,%3" ! [(set_attr "length" "8")]) (define_insn "" *************** *** 4275,4281 **** "" "@ ! sf %4,%2,%1\;aze. %4,%3 ! ai %4,%1,%n2\;aze. %4,%3" ! [(set_attr "type" "compare")]) (define_insn "" --- 4979,4986 ---- "" "@ ! {sf|subfc} %4,%2,%1\;{aze.|addze.} %4,%3 ! {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3" ! [(set_attr "type" "compare") ! (set_attr "length" "8")]) (define_insn "" *************** *** 4291,4297 **** "" "@ ! sf %4,%2,%1\;aze. %0,%3 ! ai %4,%1,%n2\;aze. %4,%3" ! [(set_attr "type" "compare")]) (define_insn "" --- 4996,5003 ---- "" "@ ! {sf|subfc} %4,%2,%1\;{aze.|addze.} %0,%3 ! {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3" ! [(set_attr "type" "compare") ! (set_attr "length" "8")]) (define_insn "" *************** *** 4301,4306 **** "" "@ ! sf %0,%2,%1\;sfe %0,%0,%0\;nand %0,%0,%0 ! sfi %0,%1,-1\;a%I2 %0,%0,%2\;sfe %0,%0,%0") (define_insn "" --- 5007,5013 ---- "" "@ ! {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0 ! {sfi|subfic} %0,%1,-1\;a%I2 %0,%0,%2\;{sfe|subfe} %0,%0,%0" ! [(set_attr "length" "12")]) (define_insn "" *************** *** 4313,4318 **** "" "@ ! sf %4,%2,%1\;sfe %4,%4,%4\;andc %0,%3,%4 ! ai %4,%1,%n2\;sfe %4,%4,%4\;andc %0,%3,%4") (define_insn "" --- 5020,5026 ---- "" "@ ! {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4 ! {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4" ! [(set_attr "length" "12")]) (define_insn "" *************** *** 4327,4333 **** "" "@ ! sf %4,%2,%1\;sfe %4,%4,%4\;andc. %4,%3,%4 ! ai %4,%1,%n2\;sfe %4,%4,%4\;andc. %4,%3,%4" ! [(set_attr "type" "compare")]) (define_insn "" --- 5035,5042 ---- "" "@ ! {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4 ! {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4" ! [(set_attr "type" "compare") ! (set_attr "length" "12")]) (define_insn "" *************** *** 4344,4350 **** "" "@ ! sf %4,%2,%1\;sfe %4,%4,%4\;andc. %0,%3,%4 ! ai %4,%1,%n2\;sfe %4,%4,%4\;andc. %0,%3,%4" ! [(set_attr "type" "compare")]) (define_insn "" --- 5053,5060 ---- "" "@ ! {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4 ! {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4" ! [(set_attr "type" "compare") ! (set_attr "length" "12")]) (define_insn "" *************** *** 4353,4357 **** (const_int 0)))] "" ! "sfi %0,%1,0\;ame %0,%0\;sri %0,%0,31") (define_insn "" --- 5063,5068 ---- (const_int 0)))] "" ! "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri|srwi} %0,%0,31" ! [(set_attr "length" "12")]) (define_insn "" *************** *** 4364,4369 **** (gt:SI (match_dup 1) (const_int 0)))] "" ! "sfi %0,%1,0\;ame %0,%0\;sri. %0,%0,31" ! [(set_attr "type" "delayed_compare")]) (define_insn "" --- 5075,5081 ---- (gt:SI (match_dup 1) (const_int 0)))] "" ! "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri.|srwi.} %0,%0,31" ! [(set_attr "type" "delayed_compare") ! (set_attr "length" "12")]) (define_insn "" *************** *** 4371,4376 **** (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_short_operand" "r")))] ! "" ! "doz %0,%2,%1\;nabs %0,%0\;sri %0,%0,31") (define_insn "" --- 5083,5089 ---- (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_short_operand" "r")))] ! "TARGET_POWER" ! "doz %0,%2,%1\;nabs %0,%0\;{sri|srwi} %0,%0,31" ! [(set_attr "length" "12")]) (define_insn "" *************** *** 4382,4388 **** (set (match_operand:SI 0 "gpc_reg_operand" "=r") (gt:SI (match_dup 1) (match_dup 2)))] ! "" ! "doz %0,%2,%1\;nabs %0,%0\;sri. %0,%0,31" ! [(set_attr "type" "delayed_compare")]) (define_insn "" --- 5095,5102 ---- (set (match_operand:SI 0 "gpc_reg_operand" "=r") (gt:SI (match_dup 1) (match_dup 2)))] ! "TARGET_POWER" ! "doz %0,%2,%1\;nabs %0,%0\;{sri.|srwi.} %0,%0,31" ! [(set_attr "type" "delayed_compare") ! (set_attr "length" "12")]) (define_insn "" *************** *** 4393,4397 **** (clobber (match_scratch:SI 3 "=&r"))] "" ! "a %3,%1,%1\;sfe %3,%1,%3\;aze %0,%2") (define_insn "" --- 5107,5112 ---- (clobber (match_scratch:SI 3 "=&r"))] "" ! "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze|addze} %0,%2" ! [(set_attr "length" "12")]) (define_insn "" *************** *** 4404,4409 **** (clobber (match_scratch:SI 3 "=&r"))] "" ! "a %3,%1,%1\;sfe %3,%1,%3\;aze. %0,%2" ! [(set_attr "type" "compare")]) (define_insn "" --- 5119,5125 ---- (clobber (match_scratch:SI 3 "=&r"))] "" ! "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %0,%2" ! [(set_attr "type" "compare") ! (set_attr "length" "12")]) (define_insn "" *************** *** 4418,4423 **** (clobber (match_scratch:SI 3 "=&r"))] "" ! "a %3,%1,%1\;sfe %3,%1,%3\;aze. %3,%2" ! [(set_attr "type" "compare")]) (define_insn "" --- 5134,5140 ---- (clobber (match_scratch:SI 3 "=&r"))] "" ! "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %3,%2" ! [(set_attr "type" "compare") ! (set_attr "length" "12")]) (define_insn "" *************** *** 4427,4432 **** (match_operand:SI 3 "gpc_reg_operand" "r"))) (clobber (match_scratch:SI 4 "=&r"))] ! "" ! "doz %4,%2,%1\;ai %4,%4,-1\;aze %0,%3") (define_insn "" --- 5144,5150 ---- (match_operand:SI 3 "gpc_reg_operand" "r"))) (clobber (match_scratch:SI 4 "=&r"))] ! "TARGET_POWER" ! "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze|addze} %0,%3" ! [(set_attr "length" "12")]) (define_insn "" *************** *** 4438,4444 **** (const_int 0))) (clobber (match_scratch:SI 4 "=&r"))] ! "" ! "doz %4,%2,%1\;ai %4,%4,-1\;aze. %4,%3" ! [(set_attr "type" "compare")]) (define_insn "" --- 5156,5163 ---- (const_int 0))) (clobber (match_scratch:SI 4 "=&r"))] ! "TARGET_POWER" ! "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3" ! [(set_attr "type" "compare") ! (set_attr "length" "12")]) (define_insn "" *************** *** 4452,4458 **** (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (clobber (match_scratch:SI 4 "=&r"))] ! "" ! "doz %4,%2,%1\;ai %4,%4,-1\;aze. %0,%3" ! [(set_attr "type" "compare")]) (define_insn "" --- 5171,5178 ---- (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (clobber (match_scratch:SI 4 "=&r"))] ! "TARGET_POWER" ! "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3" ! [(set_attr "type" "compare") ! (set_attr "length" "12")]) (define_insn "" *************** *** 4461,4465 **** (const_int 0))))] "" ! "sfi %0,%1,0\;ame %0,%0\;srai %0,%0,31") (define_insn "" --- 5181,5186 ---- (const_int 0))))] "" ! "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{srai|srawi} %0,%0,31" ! [(set_attr "length" "12")]) (define_insn "" *************** *** 4467,4472 **** (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_short_operand" "r"))))] ! "" ! "doz %0,%2,%1\;nabs %0,%0\;srai %0,%0,31") (define_insn "" --- 5188,5194 ---- (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_short_operand" "r"))))] ! "TARGET_POWER" ! "doz %0,%2,%1\;nabs %0,%0\;{srai|srawi} %0,%0,31" ! [(set_attr "length" "12")]) (define_insn "" *************** *** 4475,4479 **** (match_operand:SI 2 "reg_or_short_operand" "rI")))] "" ! "sf%I2 %0,%1,%2\;sfe %0,%0,%0\;neg %0,%0") (define_insn "" --- 5197,5202 ---- (match_operand:SI 2 "reg_or_short_operand" "rI")))] "" ! "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg %0,%0" ! [(set_attr "length" "12")]) (define_insn "" *************** *** 4486,4491 **** (gtu:SI (match_dup 1) (match_dup 2)))] "" ! "sf%I2 %0,%1,%2\;sfe %0,%0,%0\;neg. %0,%0" ! [(set_attr "type" "compare")]) (define_insn "" --- 5209,5215 ---- (gtu:SI (match_dup 1) (match_dup 2)))] "" ! "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0" ! [(set_attr "type" "compare") ! (set_attr "length" "12")]) (define_insn "" *************** *** 4497,4535 **** "" "@ ! ai %4,%1,%k2\;aze %0,%3 ! sf%I2 %4,%1,%2\;sfe %4,%4,%4\;sf%I3 %0,%4,%3 ! sf%I2 %4,%1,%2\;sfe %4,%4,%4\;sf%I3 %0,%4,%3") (define_insn "" ! [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x") (compare:CC ! (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r") ! (match_operand:SI 2 "reg_or_short_operand" "I,r,rI")) ! (match_operand:SI 3 "reg_or_short_operand" "r,r,I")) (const_int 0))) ! (clobber (match_scratch:SI 4 "=&r,&r,&r"))] "" "@ ! ai %4,%1,%k2\;aze. %0,%3 ! sf%I2 %4,%1,%2\;sfe %4,%4,%4\;sf%I3. %0,%4,%3 ! sf%I2 %4,%1,%2\;sfe %4,%4,%4\;sf%I3. %0,%4,%3" ! [(set_attr "type" "compare")]) (define_insn "" ! [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,x") (compare:CC ! (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r") ! (match_operand:SI 2 "reg_or_short_operand" "I,r,rI")) ! (match_operand:SI 3 "reg_or_short_operand" "r,r,I")) (const_int 0))) ! (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r") (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) ! (clobber (match_scratch:SI 4 "=&r,&r,&r"))] "" "@ ! ai %4,%1,%k2\;aze. %0,%3 ! sf%I2 %4,%1,%2\;sfe %4,%4,%4\;sf%I3. %0,%4,%3 ! sf%I2 %4,%1,%2\;sfe %4,%4,%4\;sf%I3. %0,%4,%3" ! [(set_attr "type" "compare")]) (define_insn "" --- 5221,5260 ---- "" "@ ! {ai|addic} %4,%1,%k2\;{aze|addze} %0,%3 ! {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3 ! {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3" ! [(set_attr "length" "8,12,12")]) (define_insn "" ! [(set (match_operand:CC 0 "cc_reg_operand" "=x,x") (compare:CC ! (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") ! (match_operand:SI 2 "reg_or_short_operand" "I,r")) ! (match_operand:SI 3 "gpc_reg_operand" "r,r")) (const_int 0))) ! (clobber (match_scratch:SI 4 "=&r,&r"))] "" "@ ! {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3 ! {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3" ! [(set_attr "type" "compare") ! (set_attr "length" "8,12")]) (define_insn "" ! [(set (match_operand:CC 5 "cc_reg_operand" "=x,x") (compare:CC ! (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") ! (match_operand:SI 2 "reg_or_short_operand" "I,r")) ! (match_operand:SI 3 "gpc_reg_operand" "r,r")) (const_int 0))) ! (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) ! (clobber (match_scratch:SI 4 "=&r,&r"))] "" "@ ! {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3 ! {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3" ! [(set_attr "type" "compare") ! (set_attr "length" "8,12")]) (define_insn "" *************** *** 4538,4542 **** (match_operand:SI 2 "reg_or_short_operand" "rI"))))] "" ! "sf%I2 %0,%1,%2\;sfe %0,%0,%0") ;; Define both directions of branch and return. If we need a reload --- 5263,5268 ---- (match_operand:SI 2 "reg_or_short_operand" "rI"))))] "" ! "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0" ! [(set_attr "length" "8")]) ;; Define both directions of branch and return. If we need a reload *************** *** 4553,4558 **** (pc)))] "" ! "%C1bc %t1,%j1,%0") (define_insn "" [(set (pc) --- 5279,5292 ---- (pc)))] "" ! "* ! { ! if (get_attr_length (insn) == 8) ! return \"%C1bc %t1,%j1,%l0\"; ! else ! return \"%C1bc %T1,%j1,$+8\;b %l0\"; ! }" ! [(set_attr "type" "branch")]) + (define_insn "" [(set (pc) *************** *** 4564,4568 **** (pc)))] "direct_return ()" ! "%C0bcr %t0,%j0") (define_insn "" --- 5298,5303 ---- (pc)))] "direct_return ()" ! "{%C0bcr|%C0bclr} %t0,%j0" ! [(set_attr "length" "8")]) (define_insn "" *************** *** 4575,4579 **** (label_ref (match_operand 0 "" ""))))] "" ! "%C1bc %T1,%j1,%0") (define_insn "" --- 5310,5321 ---- (label_ref (match_operand 0 "" ""))))] "" ! "* ! { ! if (get_attr_length (insn) == 8) ! return \"%C1bc %T1,%j1,%l0\"; ! else ! return \"%C1bc %t1,%j1,$+8\;b %l0\"; ! }" ! [(set_attr "type" "branch")]) (define_insn "" *************** *** 4586,4590 **** (return)))] "direct_return ()" ! "%C0bcr %T0,%j0") ;; Unconditional branch and return. --- 5328,5333 ---- (return)))] "direct_return ()" ! "{%C0bcr|%C0bclr} %T0,%j0" ! [(set_attr "length" "8")]) ;; Unconditional branch and return. *************** *** 4599,4603 **** [(return)] "direct_return ()" ! "br") (define_insn "indirect_jump" --- 5342,5346 ---- [(return)] "direct_return ()" ! "{br|blr}") (define_insn "indirect_jump" *************** *** 4606,4610 **** "@ bctr ! br") ;; Table jump for switch statements: --- 5349,5353 ---- "@ bctr ! {br|blr}") ;; Table jump for switch statements: *************** *** 4629,4633 **** "@ bctr ! br") (define_insn "nop" --- 5372,5376 ---- "@ bctr ! {br|blr}") (define_insn "nop" *************** *** 4634,4638 **** [(const_int 0)] "" ! "cror 0,0,0") ;; Define the subtract-one-and-jump insns, starting with the template --- 5377,5381 ---- [(const_int 0)] "" ! "{cror 0,0,0|nop}") ;; Define the subtract-one-and-jump insns, starting with the template *************** *** 4662,4669 **** (clobber (match_scratch:SI 4 "=X,X,r"))] "" ! "@ ! bdn %l2 ! # ! #") ;; Similar, but we can use GE since we have a REG_NONNEG. --- 5405,5418 ---- (clobber (match_scratch:SI 4 "=X,X,r"))] "" ! "* ! { ! if (which_alternative == 1) ! return \"#\"; ! else if (get_attr_length (insn) == 8) ! return \"{bdn|bdnz} %l2\"; ! else ! return \"bdz $+8\;b %l2\"; ! }" ! [(set_attr "type" "branch")]) ;; Similar, but we can use GE since we have a REG_NONNEG. *************** *** 4679,4686 **** (clobber (match_scratch:SI 4 "=X,X,r"))] "find_reg_note (insn, REG_NONNEG, 0)" ! "@ ! bdn %l2 ! # ! #") (define_insn "" --- 5428,5441 ---- (clobber (match_scratch:SI 4 "=X,X,r"))] "find_reg_note (insn, REG_NONNEG, 0)" ! "* ! { ! if (which_alternative == 1) ! return \"#\"; ! else if (get_attr_length (insn) == 8) ! return \"{bdn|bdnz} %l2\"; ! else ! return \"bdz $+8\;b %l2\"; ! }" ! [(set_attr "type" "branch")]) (define_insn "" *************** *** 4695,4702 **** (clobber (match_scratch:SI 4 "=X,X,r"))] "" ! "@ ! bdz %l2 ! # ! #") (define_split --- 5450,5463 ---- (clobber (match_scratch:SI 4 "=X,X,r"))] "" ! "* ! { ! if (which_alternative == 1) ! return \"#\"; ! else if (get_attr_length (insn) == 8) ! return \"bdz %l2\"; ! else ! return \"{bdn|bdnz} $+8\;b %l2\"; ! }" ! [(set_attr "type" "branch")]) (define_split diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/rs6000/x-aix31 gcc-2.5.0/config/rs6000/x-aix31 *** gcc-2.4.5/config/rs6000/x-aix31 --- gcc-2.5.0/config/rs6000/x-aix31 Mon Jul 5 17:45:05 1993 *************** *** 0 **** --- 1,11 ---- + # configuration for IBM rs6000 running aix + INSTALL=/usr/ucb/install -c + + # Show we need to use the C version of ALLOCA + ALLOCA=alloca.o + + # For some reason, we need -lm for cc1. + # We need -lld for collect2 (actually this only matters + # for a native compiler, but this is as good a place as any + # to define the symbol). + CLIB=-lm -lld diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/rs6000/x-rs6000 gcc-2.5.0/config/rs6000/x-rs6000 *** gcc-2.4.5/config/rs6000/x-rs6000 Fri Jul 3 16:55:30 1992 --- gcc-2.5.0/config/rs6000/x-rs6000 Mon Jul 5 17:49:07 1993 *************** *** 5,11 **** ALLOCA=alloca.o - # For some reason, we need -lm for cc1. # We need -lld for collect2 (actually this only matters # for a native compiler, but this is as good a place as any # to define the symbol). ! CLIB=-lm -lld --- 5,10 ---- ALLOCA=alloca.o # We need -lld for collect2 (actually this only matters # for a native compiler, but this is as good a place as any # to define the symbol). ! CLIB=-lld diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/rs6000/xm-rs6000.h gcc-2.5.0/config/rs6000/xm-rs6000.h *** gcc-2.4.5/config/rs6000/xm-rs6000.h Thu Dec 31 08:50:12 1992 --- gcc-2.5.0/config/rs6000/xm-rs6000.h Sat Jun 26 11:30:34 1993 *************** *** 1,4 **** /* Configuration for GNU C-compiler for IBM RS/6000. ! Copyright (C) 1990 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@nyu.edu). --- 1,4 ---- /* Configuration for GNU C-compiler for IBM RS/6000. ! Copyright (C) 1990, 1993 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@nyu.edu). *************** *** 42,54 **** #define FATAL_EXIT_CODE 3 ! /* If compiled with GNU C, use the built-in alloca. */ ! #ifdef __GNUC__ ! #define alloca __builtin_alloca ! #else ! #define USE_C_ALLOCA ! #endif ! ! /* If not compiled with GNU C, use only int bitfields. */ #ifndef __GNUC__ #define ONLY_INT_FIELDS #endif --- 42,48 ---- #define FATAL_EXIT_CODE 3 ! /* If not compiled with GNU C, use the C alloca and use only int bitfields. */ #ifndef __GNUC__ + #define USE_C_ALLOCA #define ONLY_INT_FIELDS #endif diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/sh/sh.c gcc-2.5.0/config/sh/sh.c *** gcc-2.4.5/config/sh/sh.c Mon May 10 11:58:36 1993 --- gcc-2.5.0/config/sh/sh.c Mon Jun 28 20:11:33 1993 *************** *** 40,48 **** static int add_constant (); ! static int dump_constants (); int current_function_anonymous_args; extern int current_function_pretend_args_size; /* Global variables for machine-dependent things. */ --- 40,53 ---- static int add_constant (); ! int dump_constants (); int current_function_anonymous_args; extern int current_function_pretend_args_size; + extern char *version_string; + extern int flag_traditional; + + enum attr_cpu sh_cpu; /* target cpu */ + /* Global variables for machine-dependent things. */ *************** *** 81,84 **** --- 86,91 ---- + + /* Local label counter, used for constants in the pool and inside pattern branches. */ *************** *** 93,244 **** static int dumpnext; - /* Functions for generating procedure prologue and epilogue code */ - - /* Adjust the stack and return the number of bytes taken to do it */ ! static int ! output_stack_adjust (file, direction, size) ! FILE *file; ! int direction; ! int size; { ! int code_size; ! ! if (size > 127) ! { ! fprintf (file, "\tmov.l LK%d,r13\n", ! add_constant (GEN_INT (size * direction), SImode)); ! ! fprintf (file, "\tadd r13,r15\n"); ! code_size += 4; ! } ! else if (size) ! { ! fprintf (file, "\tadd #%d,r15\n", direction * size); ! code_size += 2; ! } ! return code_size; } ! /* Generate code to push the regs specified in the mask, and return ! the number of bytes the insns take. */ ! ! static int ! push_regs (f, mask) ! FILE *f; ! int mask; { ! int i; ! int size = 0; ! ! for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) ! { ! if (mask & (1 << i)) ! { ! fprintf (f, "\tmov.l r%d,@-r15\n", i); ! size += 2; ! } ! } ! return size; } ! /* Working out the right code to use for an epilogue can get quite ! hairy, since there are only certain insns which can go in the delay ! slot, and there may or may not be a delay insn provided already. ! ! We generate a canonical list of the instructions to use to perform ! the exit, massage that and output from that list */ ! ! ! /* The structure of a canonical element. */ ! typedef struct { ! enum epi_type { ! STACK_ADJUST, /* add i to stack pointer */ ! POP, /* pop into register i */ ! RTS, /* rts instruction */ ! DELAY, /* delay slot instruction */ ! NOP, /* a nop */ ! DELETED, ! } type; ! int i; ! } ! epilogue_insn; ! static epilogue_insn epilogue_vec[20]; ! static int epilogue_vec_len; ! static void ! set_epilogue_insn (type, l) ! enum epi_type type; ! int l; ! { ! epilogue_vec[epilogue_vec_len].type = type; ! epilogue_vec[epilogue_vec_len].i = l; ! epilogue_vec_len++; } - /* Delete an insn from the epilogue list. */ - - static void - delete_epilogue_insn (n) - int n; - { - int j; - for (j = n; j < epilogue_vec_len; j++) - epilogue_vec[j] = epilogue_vec[j + 1]; - - epilogue_vec_len--; - } ! /* Run through the epilogue list and optimize it. */ static void ! optimize_epilogue_vec () { int i; ! ! /* Turn two adds in a row into one add and kill empty adds */ ! for (i = 0; i < epilogue_vec_len - 1; i++) ! { ! if (epilogue_vec[i].type == STACK_ADJUST ! && epilogue_vec[i + 1].type == STACK_ADJUST) ! { ! epilogue_vec[i].i += epilogue_vec[i + 1].i; ! delete_epilogue_insn (i + 1); ! } ! if (epilogue_vec[i].type == STACK_ADJUST ! && epilogue_vec[i].i == 0) ! delete_epilogue_insn (i); ! } ! ! /* If the instruction after the RTS is a nop, see if it can be ! changed */ ! ! for (i = 1; i < epilogue_vec_len - 1; i++) ! { ! if (epilogue_vec[i].type == RTS ! && epilogue_vec[i + 1].type == NOP) ! { ! epilogue_vec[i + 1] = epilogue_vec[i - 1]; ! delete_epilogue_insn (i - 1); ! } ! } ! /* Delete all the instructions after the rts's delay slot */ ! for (i = 0; i < epilogue_vec_len; i++) { ! if (epilogue_vec[i].type == RTS) { ! int j; ! ! for (j = i + 2; j < epilogue_vec_len; j++) ! epilogue_vec[j].type = DELETED; ! return; } } --- 100,162 ---- static int dumpnext; ! void ! push (rn) { ! emit_insn (gen_push (gen_rtx (REG, SImode, rn))); } ! void ! pop (rn) { ! emit_insn (gen_pop (gen_rtx (REG, SImode, rn))); } ! /* Adjust the stack and return the number of bytes taken to do it */ ! static void ! output_stack_adjust (direction, size) ! int direction; ! int size; { ! if (size) { ! rtx val = GEN_INT (size); ! rtx insn; ! if (size > 120) ! { ! rtx nval = gen_rtx (REG, SImode, 13); ! emit_insn (gen_movsi (nval, val)); ! val = nval; ! } ! if (direction > 0) ! insn = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, val); ! else ! insn = gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, val); ! emit_insn (insn); ! } } ! /* Generate code to push the regs specified in the mask, and return ! the number of bytes the insns take. */ static void ! push_regs (mask) ! int mask; { int i; ! int size = 0; ! for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) { ! if (mask & (1 << i)) { ! push (i); } } *************** *** 245,287 **** } - /* Dump out the insns in epilogue vector. */ - - static void - output_epilogue_vec () - { - int i; - - for (i = 0; i < epilogue_vec_len; i++) - { - switch (epilogue_vec[i].type) - { - case STACK_ADJUST: - fprintf (asm_out_file, "\tadd #%d,r15\n", epilogue_vec[i].i); - break; - - case NOP: - fprintf (asm_out_file, "\tor r0,r0\n"); - break; - - case DELAY: - final_scan_insn (XEXP (current_function_epilogue_delay_list, 0), - asm_out_file, 1, 0, 1); - break; ! case DELETED: ! fprintf (asm_out_file, "\t!delete_epilogue_insnd\n"); ! break; ! case RTS: ! fprintf (asm_out_file, "\trts\n"); ! break; ! case POP: ! fprintf (asm_out_file, "\tmov.l @r15+,r%d\n", ! epilogue_vec[i].i); ! break; ! } ! } ! epilogue_vec_len = 0; } --- 163,180 ---- } ! /* ! Print an instruction which would have gone into a delay slot ! after an instructiuon, but couldn't because the instruction expanded ! into a sequence where putting the slot insn at the end wouldn't work. ! */ ! void ! print_slot (insn) ! rtx insn; ! { ! final_scan_insn (XVECEXP (insn, 0, 1), asm_out_file, optimize, 0, 1); ! INSN_DELETED_P (XVECEXP (insn, 0, 1)) = 1; } *************** *** 311,470 **** return live_regs_mask; } ! ! /* Generate a procedure prologue. */ ! ! void ! output_prologue (f, frame_size) ! FILE *f; ! int frame_size; ! { ! int live_regs_mask; ! int d; ! ! pc = 0; ! ! /* This only happens when an arg has been split, part in ! registers, part in memory. Allocate the stack space so there is ! somewhere to put the value */ ! ! output_stack_adjust (f, -1, current_function_pretend_args_size); ! ! live_regs_mask = calc_live_regs (&d); ! ! extra_push = 0; ! ! if (current_function_anonymous_args) ! { ! /* Push arg regs as if they'd been provided by caller in stack */ ! int i; ! for (i = 0; i < NPARM_REGS; i++) ! { ! int rn = NPARM_REGS + FIRST_PARM_REG - i - 1; ! if (i > NPARM_REGS - current_function_args_info) ! break; ! fprintf (f, "\tmov.l r%d,@-r15\n", rn); ! extra_push += 4; ! pc += 2; ! } ! } ! ! if (frame_pointer_needed) ! { ! /* Don't need to push the fp with the rest of the registers. */ ! live_regs_mask &= ~(1 << FRAME_POINTER_REGNUM); ! pc += push_regs (f, live_regs_mask); ! if (regs_ever_live[PR_REG]) ! { ! ! fprintf (f, "\tsts.l pr,@-r15\n"); ! pc += 2; ! } ! ! fprintf (f, "\tmov.l r14,@-r15\n"); ! fprintf (f, "\tmov r15,r14\n"); ! pc += 4; ! pc += output_stack_adjust (f, -1, frame_size); ! } ! else ! { ! pc += push_regs (f, live_regs_mask); ! ! if (regs_ever_live[PR_REG]) ! { ! ! fprintf (f, "\tsts.l pr,@-r15\n"); ! pc += 2; ! } ! pc += output_stack_adjust (f, -1, frame_size); ! } ! } - /* Generate a procedure epilogue. */ ! void ! output_epilogue (f, frame_size) ! FILE *f; ! int frame_size; { ! int live_regs_mask = 0; ! int d; ! int i; ! rtx delay_insn; ! ! live_regs_mask = calc_live_regs (&d); ! ! ! /* See if the delay insn is really ok for the slot. */ ! if (current_function_epilogue_delay_list) { ! delay_insn = PATTERN (XEXP (current_function_epilogue_delay_list, 0)); ! ! if (GET_CODE (delay_insn) == SET ! && SET_DEST (delay_insn) == stack_pointer_rtx) ! { ! /* Can not use this instruction in the delay slot because ! it changes the stack pointer, so emit it now. */ ! final_scan_insn (XEXP (current_function_epilogue_delay_list, 0), ! asm_out_file, 1, 0, 1); ! current_function_epilogue_delay_list = 0; ! } ! } ! ! ! /* Reclaim the room for the automatics. */ ! ! output_stack_adjust (f, 1, frame_size); ! ! /* Make the frame pointer. */ ! ! if (frame_pointer_needed) ! { ! fprintf (f, "\tmov r14,r15\n"); ! fprintf (f, "\tmov.l @r15+,r14\n"); ! live_regs_mask &= ~(1 << FRAME_POINTER_REGNUM); ! } ! ! /* Get the PR register if it was clobbered in the function. */ ! ! if (regs_ever_live[PR_REG]) ! fprintf (f, "\tlds.l @r15+,pr\n"); ! ! /* Pop all the registers */ ! for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) ! { ! int j = (FIRST_PSEUDO_REGISTER - 1) - i; ! if (live_regs_mask & (1 << j)) ! { ! set_epilogue_insn (POP, j); ! } ! } ! ! /* Need to adjust the stack by some amount of bytes since we've pushed ! some of the args which normally come in registers */ ! ! set_epilogue_insn (STACK_ADJUST, extra_push); ! ! /* Need to adjust the stack by some amount of bytes if there ! an arg has been split part register and part stack */ ! ! set_epilogue_insn (STACK_ADJUST, current_function_pretend_args_size); ! ! set_epilogue_insn (RTS, 0); ! ! /* Got here without dumping a register pop into the delay slot */ ! if (current_function_epilogue_delay_list) ! { ! set_epilogue_insn (DELAY, 0); ! } ! set_epilogue_insn (NOP, 0); ! ! optimize_epilogue_vec (); ! ! output_epilogue_vec (); ! ! dump_constants (0); ! current_function_anonymous_args = 0; } ! /* Print the operand address in x to the stream */ --- 204,218 ---- return live_regs_mask; } ! ! static int ! need_slot (insn) ! rtx insn; { ! return (insn && !INSN_ANNULLED_BRANCH_P (XVECEXP (insn, 0, 0))); } ! /* Print the operand address in x to the stream */ *************** *** 479,483 **** fprintf (stream, "@%s", reg_names[REGNO (x)]); break; - case PLUS: { --- 227,230 ---- *************** *** 502,511 **** case REG: ! fprintf (stream, "@(%s,%s)", ! reg_names[REGNO (base)], ! reg_names[REGNO (index)]); break; default: abort (); } --- 249,260 ---- case REG: ! fprintf (stream, "@(r0,%s)", ! reg_names[MAX (REGNO (base), REGNO (index))]); ! break; default: + debug_rtx (x); + abort (); } *************** *** 530,540 **** according to modifier code. ! '*' print a local label ! '^' increment the local label number ! '!' dump the constant table ! '#' output a nop if there is nothing to put in the delay slot ! 'R' print the next register or memory location along, ie the lsw in ! a double word value ! 'I' put something into the constant pool and print its label */ void --- 279,292 ---- according to modifier code. ! '.' print a .s if insn needs delay slot ! '*' print a local label ! '^' increment the local label number ! '!' dump the constant table ! '#' output a nop if there is nothing to put in the delay slot ! 'R' print the next register or memory location along, ie the lsw in ! a double word value ! 'O' print a constant without the # ! 'M' print a constant as its negative ! 'I' put something into the constant pool and print its label */ void *************** *** 546,549 **** --- 298,307 ---- switch (code) { + + + case '.': + if (need_slot (final_sequence)) + fprintf (stream, ".s"); + break; case '*': fprintf (stream, "LF%d", lf); *************** *** 563,566 **** --- 321,327 ---- } break; + case 'O': + fprintf (asm_out_file, "%d", INTVAL (x)); + break; case 'I': *************** *** 568,571 **** --- 329,336 ---- break; + case 'M': + fprintf (asm_out_file, "#%d", -INTVAL (x)); + break; + case 'R': /* Next location along in memory or register*/ *************** *** 600,607 **** } } - ! /* Define the offset between two registers, one to be eliminated, and the other its replacement, at the start of a routine. */ --- 365,372 ---- } } ! ! /* Define the offset between two registers, one to be eliminated, and the other its replacement, at the start of a routine. */ *************** *** 611,615 **** int regs_saved; int d = calc_live_regs (®s_saved); ! int total_saved_regs_space = (regs_saved + regs_ever_live[PR_REG]) * 4; int total_auto_space = get_frame_size (); --- 376,380 ---- int regs_saved; int d = calc_live_regs (®s_saved); ! int total_saved_regs_space = (regs_saved) * 4; int total_auto_space = get_frame_size (); *************** *** 631,650 **** } - delay_slots_for_epilogue () - { - /* We need to find something to fill the epilogue if there won't be - any instructions to make the stack or pop registers which can be - moved into the slot */ - - int d; - calc_live_regs (&d); - return !(get_frame_size () + d); - } - /* Prepare operands for a move define_expand; specifically, one of the ! operands must be in a register */ ! void prepare_move_operands (operands, mode) rtx operands[]; --- 396,405 ---- } /* Prepare operands for a move define_expand; specifically, one of the ! operands must be in a register. Take this chance to remove ! addressing modes which can't be coped with very well. */ ! int prepare_move_operands (operands, mode) rtx operands[]; *************** *** 654,658 **** if ((!register_operand (operands[0], mode) && !register_operand (operands[1], mode)) ! || GET_CODE(operands[1]) == PLUS) { /* copy the source to a register */ --- 409,413 ---- if ((!register_operand (operands[0], mode) && !register_operand (operands[1], mode)) ! || GET_CODE (operands[1]) == PLUS) { /* copy the source to a register */ *************** *** 659,662 **** --- 414,439 ---- operands[1] = copy_to_mode_reg (mode, operands[1]); } + + /* If we've got a negative index, break it down */ + + if (GET_CODE (operands[0]) == MEM && !reload_in_progress) + { + + rtx inside = XEXP (operands[0], 0); + if (GET_CODE (inside) == PLUS) + { + rtx inside1 = XEXP (inside, 1); + if (GET_CODE (inside1) == CONST_INT + && INTVAL (inside1) < 0) + { + /* Catch this now and break it into bits, it will only cause + problems later */ + + rtx sub = copy_to_mode_reg (SImode, inside); + XEXP (operands[0], 0) = sub; + } + } + } + return 0; } *************** *** 667,675 **** prepare_scc_operands (code) { ! if (GET_CODE(sh_compare_op0) != REG ! || REGNO(sh_compare_op0) != T_REG) { /* First need a compare insn */ ! emit_insn (gen_rtx (SET, SImode, gen_rtx (REG, SImode, T_REG), gen_rtx (code, SImode, sh_compare_op0, --- 444,452 ---- prepare_scc_operands (code) { ! if (GET_CODE (sh_compare_op0) != REG ! || REGNO (sh_compare_op0) != T_REG) { /* First need a compare insn */ ! emit_insn (gen_rtx (SET, SImode, gen_rtx (REG, SImode, T_REG), gen_rtx (code, SImode, sh_compare_op0, *************** *** 676,687 **** sh_compare_op1))); } ! return gen_rtx(REG, SImode, T_REG); } /* Functions to output assembly */ ! /* Return a sequence of instructions to perform DI move, taking into ! account overlapping source and dest registers */ char * output_movedouble (operands, mode) --- 453,468 ---- sh_compare_op1))); } ! return gen_rtx (REG, SImode, T_REG); } + /* Functions to output assembly */ ! /* Return a sequence of instructions to perform DI or DF move. ! ! Since the SH cannot move a DI or DF in one instruction, we have ! to take care when we see overlapping source and dest registers. + */ char * output_movedouble (operands, mode) *************** *** 689,710 **** enum machine_mode mode; { ! if (register_operand (operands[0], mode) ! && register_operand (operands[1], mode)) { ! if (REGNO (operands[1]) == MACH_REG) return "sts mach,%0\n\tsts macl,%R0"; - if (REGNO (operands[1]) > REGNO (operands[0])) - { - return "mov %1,%0\n\tmov %R1,%R0"; - } - else - { - return "mov %R1,%R0\n\tmov %1,%0"; - } - } ! if (GET_CODE (operands[1]) == CONST_INT) { ! if (INTVAL (operands[1]) < 0) return "mov #-1,%0\n\tmov %1,%R0"; else --- 470,497 ---- enum machine_mode mode; { ! rtx dst = operands[0]; ! rtx src = operands[1]; ! int lowfirst; ! ! if (register_operand (dst, mode) ! && register_operand (src, mode)) { ! if (REGNO (src) == MACH_REG) return "sts mach,%0\n\tsts macl,%R0"; ! /* ! when mov.d r1,r2 do r2->r3 then r1->r2 ! when mov.d r1,r0 do r1->r0 then r2->r1 ! */ ! ! if (REGNO (src) + 1 == REGNO (dst)) ! return "mov %1,%0\n\tmov %R1,%R0 ! cr"; ! else ! return "mov %R1,%R0\n\tmov %1,%0 "; ! ! } ! else if (GET_CODE (src) == CONST_INT) { ! if (INTVAL (src) < 0) return "mov #-1,%0\n\tmov %1,%R0"; else *************** *** 712,722 **** } ! if (GET_CODE (operands[1]) == MEM) { ! int idxreg = -1; ! rtx inside = XEXP (operands[1], 0); if (GET_CODE (inside) == REG) ! idxreg = REGNO (inside); else if (GET_CODE (inside) == PLUS) { --- 499,513 ---- } ! else if (GET_CODE (src) == MEM) { ! int ptrreg1 = -1; ! int ptrreg2 = -1; ! int dreg = REGNO (dst); ! rtx inside = XEXP (src, 0); if (GET_CODE (inside) == REG) ! { ! ptrreg1 = REGNO (inside); ! } else if (GET_CODE (inside) == PLUS) { *************** *** 724,732 **** rtx rhs = XEXP (inside, 1); if (GET_CODE (lhs) == REG) ! idxreg = REGNO (lhs); ! else if (GET_CODE (rhs) == REG) ! idxreg = REGNO (rhs); ! else ! abort (); } else --- 515,521 ---- rtx rhs = XEXP (inside, 1); if (GET_CODE (lhs) == REG) ! ptrreg1 = REGNO (lhs); ! if (GET_CODE (rhs) == REG) ! ptrreg2 = REGNO (rhs); } else *************** *** 733,746 **** abort (); ! if (REGNO (operands[0]) != idxreg) { ! /* The dest register is mentioned in the addressing mode, ! so print them the other way around */ ! return "mov.l %1,%0\n\tmov.l %R1,%R0 ! one way"; } - return "mov.l %R1,%R0\n\tmov.l %1,%0 ! other way"; } ! return "mov.l %R1,%R0\n\tmov.l %1,%0"; } --- 522,573 ---- abort (); ! ! if ((ptrreg1 >= 0 && ptrreg2 >= 0) ! && (dreg == ptrreg1 ! || dreg == ptrreg2 ! || dreg + 1 == ptrreg1 ! || dreg + 1 == ptrreg2)) ! { ! /* This move clobbers both index registers, ! calculate the sum in one register. */ ! fprintf (asm_out_file, " add %s,%s ! special fix\n", ! reg_names[ptrreg2], reg_names[ptrreg1]); ! ! if (dreg == ptrreg1) ! { ! /* Copy into dreg+1 first. */ ! fprintf (asm_out_file, " mov.l @(4,%s),%s\n", ! reg_names[ptrreg1], ! reg_names[dreg + 1]); ! ! fprintf (asm_out_file, " mov.l @(%s),%s\n", ! reg_names[ptrreg1], ! reg_names[dreg]); ! } ! else ! { ! /* Copy into dreg first. */ ! fprintf (asm_out_file, " mov.l @(%s),%s\n", ! reg_names[ptrreg1], ! reg_names[dreg]); ! ! fprintf (asm_out_file, " mov.l @(4,%s),%s\n", ! reg_names[ptrreg1], ! reg_names[dreg + 1]); ! ! } ! warning ("generated complex amode"); ! return ""; ! } ! ! /* Work out the safe way to copy */ ! if (dreg == ptrreg1) { ! /* Copy into the second half first */ ! return "mov.l %R1,%R0\n\tmov.l %1,%0 ! cr"; } } ! return "mov.l %1,%0\n\tmov.l %R1,%R0"; } *************** *** 748,757 **** char * ! output_shift (string, reg, k) char *string; rtx reg; rtx k; { int s = INTVAL (k); while (s) { --- 575,605 ---- char * ! output_shift (string, reg, k, code) char *string; rtx reg; rtx k; + int code; + { int s = INTVAL (k); + + if (code == ASHIFT && s == 31) + { + /* Shift left by 31 moving into the t bit, clearing and rotating the other way */ + + fprintf (asm_out_file, "\trotr r%d\n", REGNO (reg)); + fprintf (asm_out_file, "\tmov #0,r%d\n", REGNO (reg)); + fprintf (asm_out_file, "\trotcr r%d\n", REGNO (reg)); + s = 0; + } + + if (code == LSHIFTRT && s == 31) + { + fprintf (asm_out_file, "\trotl r%d\n", REGNO (reg)); + fprintf (asm_out_file, "\tmov #0,r%d\n", REGNO (reg)); + fprintf (asm_out_file, "\trotcl r%d\n", REGNO (reg)); + s = 0; + } + while (s) { *************** *** 786,799 **** /* Return the text of the branch instruction which matches its length ! attribute. */ char * output_branch (logic, insn) int logic; ! rtx *insn; { extern rtx recog_operand[]; int label = lf++; ! switch (get_attr_length (insn)) { --- 634,654 ---- /* Return the text of the branch instruction which matches its length ! attribute. + This gets tricky if we have an insn in the delay slot of a branch + and the branch needs more than 1 insn to complete.*/ + + + char * output_branch (logic, insn) int logic; ! rtx insn; { extern rtx recog_operand[]; int label = lf++; ! int rn = -1; ! int need_save; ! switch (get_attr_length (insn)) { *************** *** 800,812 **** case 2: /* Simple branch in range -200..+200 bytes */ ! return logic ? "bt %l0" : "bf %l0"; case 6: /* Branch in range -4000..+4000 bytes */ ! fprintf (asm_out_file, "\tb%c\tLF%d\n", logic ? 'f' : 't', label); ! output_asm_insn ("bra %l0 ! 12 bit cond ", recog_operand); ! fprintf (asm_out_file, "\tor r0,r0\n"); ! label = dump_constants (label); ! fprintf (asm_out_file, "LF%d:\n", label); return ""; --- 655,687 ---- case 2: /* Simple branch in range -200..+200 bytes */ ! return logic ? "bt%. %l0" : "bf%. %l0"; case 6: /* Branch in range -4000..+4000 bytes */ ! { ! rtx oldop = recog_operand[0]; ! ! ! if (need_slot (final_sequence)) ! { ! fprintf (asm_out_file, "\tb%c.s\tLF%d\n", logic ? 'f' : 't', ! label); ! ! print_slot (final_sequence); ! } ! ! else ! { ! fprintf (asm_out_file, "\tb%c\tLF%d\n", logic ? 'f' : 't', ! label); ! } ! recog_operand[0] = oldop; ! ! output_asm_insn ("bra %l0 ! 12 bit cond ", recog_operand); ! fprintf (asm_out_file, "\tor r0,r0\n"); ! label = dump_constants (label); ! fprintf (asm_out_file, "LF%d:\n", label); ! } ! return ""; *************** *** 813,834 **** case 8: /* Branches a long way away */ ! ! fprintf (asm_out_file, "\tb%c\tLF%d\n", logic ? 'f' : 't', label); ! output_asm_insn ("mov.l %I0,r13", recog_operand); ! fprintf (asm_out_file, "\tjmp @r13 ! 32 cond \n"); ! fprintf (asm_out_file, "\tor r0,r0\n"); ! fprintf (asm_out_file, "LF%d:\n", label); ! return ""; } return "bad"; - } /* Predicates used by the templates */ /* Nonzero if OP is a normal arithmetic register. */ int ! arith_reg_operand(op, mode) rtx op; enum machine_mode mode; --- 688,802 ---- case 8: /* Branches a long way away */ ! { ! ! rtx oldop = recog_operand[0]; ! ! if (need_slot (final_sequence)) ! { ! fprintf (asm_out_file, "\tb%c.s\tLF%d\n", logic ? 'f' : 't', label); ! print_slot (final_sequence); ! ! } ! else ! { ! fprintf (asm_out_file, "\tb%c\tLF%d\n", logic ? 'f' : 't', label); ! } ! ! recog_operand[0] = oldop; ! ! /* We use r13 as a scratch */ ! need_save = 0; ! rn = 13; ! ! if (need_save) ! fprintf (asm_out_file, "\tpush r%d\n", rn); ! fprintf (asm_out_file, "\tmov.l LK%d,r%d\n", add_constant (oldop, SImode), rn); ! fprintf (asm_out_file, "\tjmp @r%d ! 32 cond \n", rn); ! if (need_save) ! fprintf (asm_out_file, "\tpop r%d\n", rn); ! else ! fprintf (asm_out_file, "\tor r0,r0\n"); ! fprintf (asm_out_file, "LF%d:\n", label); ! return ""; ! } } return "bad"; } + /* Predicates used by the templates */ + /* Non zero if op is an immediate ok for a byte index */ + + int + byte_index_operand (op, mode) + rtx op; + enum machine_mode mode; + { + return (GET_CODE (op) == CONST_INT + && INTVAL (op) >= 0 && INTVAL (op) <= 15); + } + + /* Non zero if OP is a pop operand */ + + int + pop_operand (op, mode) + rtx op; + enum machine_mode mode; + { + if (GET_CODE (op) != MEM) + return 0; + + if (GET_MODE (op) != mode) + return 0; + + op = XEXP (op, 0); + + if (GET_CODE (op) != POST_INC) + return 0; + + return XEXP (op, 0) == stack_pointer_rtx; + } + + /* Non zero if OP is an immediate which can be made from two insns. */ + + int + painful_immediate_operand (op, mode) + rtx op; + enum machine_mode mode; + { + if (GET_CODE (op) == CONST_INT) + { + int i = INTVAL (op); + + if (i > 127 && i < 255) + return 1; /* two adds */ + } + return 0; + } + + + /* Non zero if OP can be source of a simple move operation. */ + + int + general_movsrc_operand (op, mode) + rtx op; + enum machine_mode mode; + { + if (GET_CODE (op) == REG + || GET_CODE (op) == SUBREG + || (GET_CODE (op) == CONST_INT && + CONST_OK_FOR_I (INTVAL (op))) + || GET_CODE (op) == MEM) + return general_operand (op, mode); + return 0; + } + + + /* Nonzero if OP is a normal arithmetic register. */ int ! arith_reg_operand (op, mode) rtx op; enum machine_mode mode; *************** *** 843,847 **** } ! /* Nonzero if OP is a valid source operand for an arithmetic insn. */ --- 811,815 ---- } ! /* Nonzero if OP is a valid source operand for an arithmetic insn. */ *************** *** 898,902 **** default: if (TARGET_FASTCODE) ! return INTVAL(p) >= 0; } } --- 866,870 ---- default: if (TARGET_FASTCODE) ! return INTVAL (p) >= 0; } } *************** *** 1026,1031 **** return pool_vector[i].number; } - pool_vector[pool_size].value = x; pool_vector[pool_size].mode = mode; --- 994,999 ---- return pool_vector[i].number; } + pool_vector[pool_size].value = x; pool_vector[pool_size].mode = mode; *************** *** 1079,1083 **** int target_insn_range; int current_pc; ! int table_size; void --- 1047,1054 ---- int target_insn_range; int current_pc; ! int pool_bytes; ! ! int last_uid; ! int last_pc; void *************** *** 1087,1139 **** { int uid = INSN_UID (insn); current_pc += insn_lengths[uid]; ! if (has_constant_table (insn)) { ! if (current_pc >= target_insn_range) { ! /* This instruction is further away from the referencing ! instruction than it can reach, so we'll stop accumulating ! from that one and start fresh. */ ! target_pc = current_pc; ! target_insn_range = current_pc + MAYBE_DUMP_LEVEL; } ! else { ! /* This instruction is within the reach of the target, ! remove the constant table from the target by adjusting ! downwards, and increase the size of this one to ! compensate. */ ! /* Add the stuff from this insn to what will go in the ! growing table. */ ! table_size += get_attr_constantsize (insn); ! /* The target shinks to its smallest natural size */ ! insn_lengths[target_insn_uid] = target_insn_smallest_size; ! /* The current insn grows to be its larger size plust the ! table size. */ ! insn_lengths[uid] = get_attr_largestsize (insn) + table_size; ! } ! /* Current insn becomes the target. */ ! target_insn_uid = uid; ! target_insn_smallest_size = get_attr_smallestsize (insn); } - } - /* Dump out the pending constant pool. - If label provided then insert an branch in the middle of the table - */ ! static int dump_constants (label) { --- 1058,1124 ---- { int uid = INSN_UID (insn); + rtx body = PATTERN (insn); current_pc += insn_lengths[uid]; ! ! if (GET_CODE (body) == SEQUENCE) { ! int i; ! ! for (i = 0; i < XVECLEN (body, 0); i++) { ! adjust_insn_length (XVECEXP (body, 0, i), insn_lengths); } ! } ! else ! { ! if (has_constant_table (insn)) { ! if (current_pc >= target_insn_range) ! { ! /* This instruction is further away from the referencing ! instruction than it can reach, so we'll stop accumulating ! from that one and start fresh. */ ! target_pc = current_pc; ! target_insn_range = current_pc + MAYBE_DUMP_LEVEL; ! } ! else ! { ! /* This instruction is within the reach of the target, ! remove the constant table from the target by adjusting ! downwards, and increase the size of this one to ! compensate. */ ! /* Add the stuff from this insn to what will go in the ! growing table. */ ! pool_bytes += get_attr_constantsize (insn); ! /* The target shinks to its smallest natural size */ ! insn_lengths[target_insn_uid] = target_insn_smallest_size; ! /* The current insn grows to be its larger size plust the ! table size. */ ! insn_lengths[uid] = get_attr_largestsize (insn) + pool_bytes; ! } ! /* Current insn becomes the target. */ ! target_insn_uid = uid; ! target_insn_smallest_size = get_attr_smallestsize (insn); + } } } ! /* Dump out the pending constant pool. ! If label provided then insert an branch in the middle of the table ! */ ! ! int dump_constants (label) { *************** *** 1141,1183 **** int rlabel = label; int size = 0; ! ! for (i = 0; i < pool_size; i++) { - pool_node *p = pool_vector + i; fprintf (asm_out_file, "\n\t! constants - waited %d\n", pc - first_pc); fprintf (asm_out_file, "\t.align\t2\n"); ! fprintf (asm_out_file, "LK%d:", p->number); ! size += GET_MODE_SIZE (p->mode); ! ! switch (GET_MODE_CLASS (p->mode)) ! { ! case MODE_INT: ! case MODE_PARTIAL_INT: ! assemble_integer (p->value, GET_MODE_SIZE (p->mode), 1); ! break; ! case MODE_FLOAT: ! { ! union real_extract u; ! bcopy (&CONST_DOUBLE_LOW (p->value), &u, sizeof u); ! assemble_real (u.d, p->mode); ! } ! } ! ! /* After 200 bytes of table, stick in another branch */ ! if (label && size > 200) ! { ! rlabel = lf ++; ! fprintf (asm_out_file,"LF%d:\tbra LF%d\n", label, rlabel); ! fprintf (asm_out_file,"\tor r0,r0\n"); ! label = 0; } - - fprintf (asm_out_file, "\n"); } pool_size = 0; current_pc = 0; target_insn_range = 0; return rlabel; ! } --- 1126,1176 ---- int rlabel = label; int size = 0; ! ! if (pool_size) { fprintf (asm_out_file, "\n\t! constants - waited %d\n", pc - first_pc); fprintf (asm_out_file, "\t.align\t2\n"); ! ! for (i = 0; i < pool_size; i++) ! { ! pool_node *p = pool_vector + i; ! ! fprintf (asm_out_file, "LK%d:", p->number); ! size += GET_MODE_SIZE (p->mode); ! ! switch (GET_MODE_CLASS (p->mode)) ! { ! case MODE_INT: ! case MODE_PARTIAL_INT: ! assemble_integer (p->value, GET_MODE_SIZE (p->mode), 1); ! break; ! case MODE_FLOAT: ! { ! union real_extract u; ! bcopy (&CONST_DOUBLE_LOW (p->value), &u, sizeof u); ! assemble_real (u.d, p->mode); ! } ! } ! ! /* After 200 bytes of table, stick in another branch */ ! if (label && size > 200) ! { ! rlabel = lf++; ! fprintf (asm_out_file, "LF%d:\tbra LF%d\n", label, rlabel); ! fprintf (asm_out_file, "\tor r0,r0\n"); ! label = 0; ! } ! } } + pool_size = 0; current_pc = 0; + pc = 0; + pool_bytes = 0; + target_insn_range = 0; return rlabel; ! } *************** *** 1197,1201 **** add_constant (operands[1], mode), rn); ! if (GET_MODE_SIZE(mode) > 4) { fprintf (asm_out_file, --- 1190,1194 ---- add_constant (operands[1], mode), rn); ! if (GET_MODE_SIZE (mode) > 4) { fprintf (asm_out_file, *************** *** 1204,1211 **** rn + 1); ! } ! /* If this instruction is as small as it can be, there can be no constant table attached to it. */ ! if (get_attr_length (insn) != get_attr_smallestsize (insn)) { /* This needs a constant table */ --- 1197,1214 ---- rn + 1); ! } ! ! /* This may have been the last move in the function, so nothing ! took its constant table, we may be able to move it past the end ! of the function (after the rts) if we are careful */ ! ! if (target_insn_uid == INSN_UID (insn) ! && current_pc < target_insn_range) ! return ""; ! ! ! /* If this instruction is as small as it can be, there can be no constant table attached to it. */ ! if (get_attr_length (insn) != get_attr_smallestsize (insn)) { /* This needs a constant table */ *************** *** 1223,1227 **** /* Dump out interesting debug info */ ! void final_prescan_insn (insn, opvec, noperands) rtx insn; --- 1226,1230 ---- /* Dump out interesting debug info */ ! rtx final_prescan_insn (insn, opvec, noperands) rtx insn; *************** *** 1246,1261 **** } - - pc += get_attr_length (insn); if (pool_size && pc - first_pc > MUST_DUMP_LEVEL) { ! /* For some reason we have not dumped out a constant table, and ! we have emitted a lot of code. This can happen if the think ! which wants the table is a long conditional branch (which has no ! room for a constant table), and there has not been a move ! constant anywhere. */ int label = lf++; ! fprintf (asm_out_file, "\t!forced constant table\n"); fprintf (asm_out_file, "\tbra LF%d\n", label); fprintf (asm_out_file, "\tor r0,r0 ! wasted slot\n"); --- 1249,1263 ---- } + pc += get_attr_length (insn); if (pool_size && pc - first_pc > MUST_DUMP_LEVEL) { ! /* For some reason we have not dumped out a constant table, and ! we have emitted a lot of code. This can happen if the think ! which wants the table is a long conditional branch (which has no ! room for a constant table), and there has not been a move ! constant anywhere. */ int label = lf++; ! fprintf (asm_out_file, "\t!forced constant table\n"); fprintf (asm_out_file, "\tbra LF%d\n", label); fprintf (asm_out_file, "\tor r0,r0 ! wasted slot\n"); *************** *** 1264,1269 **** fprintf (asm_out_file, "\t!constant table end\n"); } ! } --- 1266,1637 ---- fprintf (asm_out_file, "\t!constant table end\n"); } ! } ! ! ! ! /* Block move stuff stolen from m88k*/ ! ! /* Emit code to perform a block move. Choose the best method. ! ! OPERANDS[0] is the destination. ! OPERANDS[1] is the source. ! OPERANDS[2] is the size. ! OPERANDS[3] is the alignment safe to use. */ ! ! /* Emit code to perform a block move with an offset sequence of ld/st ! instructions (..., ld 0, st 1, ld 1, st 0, ...). SIZE and ALIGN are ! known constants. DEST and SRC are registers. OFFSET is the known ! starting point for the output pattern. */ ! ! static enum machine_mode mode_from_align[] = ! {VOIDmode, QImode, HImode, VOIDmode, SImode, ! VOIDmode, VOIDmode, VOIDmode, DImode}; ! static void ! ! block_move_sequence (dest, dest_mem, src, src_mem, size, align, offset) ! rtx dest, dest_mem; ! rtx src, src_mem; ! int size; ! int align; ! int offset; ! { ! rtx temp[2]; ! enum machine_mode mode[2]; ! int amount[2]; ! int active[2]; ! int phase = 0; ! int next; ! int offset_ld = offset; ! int offset_st = offset; ! ! active[0] = active[1] = FALSE; ! ! /* Establish parameters for the first load and for the second load if ! it is known to be the same mode as the first. */ ! amount[0] = amount[1] = align; ! ! ! mode[0] = mode_from_align[align]; ! ! temp[0] = gen_reg_rtx (mode[0]); ! if (size >= 2 * align) ! { ! mode[1] = mode[0]; ! temp[1] = gen_reg_rtx (mode[1]); ! } ! ! do ! { ! rtx srcp, dstp; ! next = phase; ! phase = !phase; ! ! if (size > 0) ! { ! /* Change modes as the sequence tails off. */ ! if (size < amount[next]) ! { ! amount[next] = (size >= 4 ? 4 : (size >= 2 ? 2 : 1)); ! mode[next] = mode_from_align[amount[next]]; ! temp[next] = gen_reg_rtx (mode[next]); ! } ! size -= amount[next]; ! srcp = gen_rtx (MEM, ! MEM_IN_STRUCT_P (src_mem) ? mode[next] : BLKmode, ! gen_rtx (PLUS, Pmode, src, ! gen_rtx (CONST_INT, SImode, offset_ld))); ! RTX_UNCHANGING_P (srcp) = RTX_UNCHANGING_P (src_mem); ! MEM_VOLATILE_P (srcp) = MEM_VOLATILE_P (src_mem); ! MEM_IN_STRUCT_P (srcp) = 1; ! emit_insn (gen_rtx (SET, VOIDmode, temp[next], srcp)); ! offset_ld += amount[next]; ! active[next] = TRUE; ! } ! ! if (active[phase]) ! { ! active[phase] = FALSE; ! dstp = gen_rtx (MEM, ! MEM_IN_STRUCT_P (dest_mem) ? mode[phase] : BLKmode, ! gen_rtx (PLUS, Pmode, dest, ! gen_rtx (CONST_INT, SImode, offset_st))); ! RTX_UNCHANGING_P (dstp) = RTX_UNCHANGING_P (dest_mem); ! MEM_VOLATILE_P (dstp) = MEM_VOLATILE_P (dest_mem); ! MEM_IN_STRUCT_P (dstp) = 1; ! emit_insn (gen_rtx (SET, VOIDmode, dstp, temp[phase])); ! offset_st += amount[phase]; ! } ! } ! while (active[next]); ! } ! ! void ! expand_block_move (dest_mem, src_mem, operands) ! rtx dest_mem; ! rtx src_mem; ! rtx *operands; ! { ! int align = INTVAL (operands[3]); ! int constp = (GET_CODE (operands[2]) == CONST_INT); ! int bytes = (constp ? INTVAL (operands[2]) : 0); ! ! #if 0 ! if (constp && bytes <= 0) ! return; ! ! if (align > 4) ! align = 4; ! ! if (constp && bytes <= 3 * align) ! block_move_sequence (operands[0], dest_mem, operands[1], src_mem, ! bytes, align, 0); ! ! #if 0 ! else if (constp && bytes <= best_from_align[target][align]) ! block_move_no_loop (operands[0], dest_mem, operands[1], src_mem, ! bytes, align); ! ! else if (constp && align == 4 && TARGET_88100) ! block_move_loop (operands[0], dest_mem, operands[1], src_mem, ! bytes, align); ! #endif ! else ! #endif ! { ! emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "memcpy"), 0, ! VOIDmode, 3, ! operands[0], Pmode, ! operands[1], Pmode, ! operands[2], SImode); ! } ! } ! ! ! override_options () ! { ! sh_cpu = CPU_SH0; ! if (TARGET_SH1) ! sh_cpu = CPU_SH1; ! if (TARGET_SH2) ! sh_cpu = CPU_SH2; ! if (TARGET_SH3) ! sh_cpu = CPU_SH3; ! } ! ! ! /* Stuff taken from m88k.c */ ! ! /* Output to FILE the start of the assembler file. */ ! ! struct option ! { ! char *string; ! int *variable; ! int on_value; ! }; ! ! static int ! output_option (file, sep, type, name, indent, pos, max) ! FILE *file; ! char *sep; ! char *type; ! char *name; ! char *indent; ! int pos; ! int max; ! { ! if (strlen (sep) + strlen (type) + strlen (name) + pos > max) ! { ! fprintf (file, indent); ! return fprintf (file, "%s%s", type, name); ! } ! return pos + fprintf (file, "%s%s%s", sep, type, name); ! } ! ! static struct ! { ! char *name; ! int value; ! } ! ! m_options[] = TARGET_SWITCHES; ! ! static void ! output_options (file, f_options, f_len, W_options, W_len, ! pos, max, sep, indent, term) ! FILE *file; ! struct option *f_options; ! struct option *W_options; ! int f_len, W_len; ! int pos; ! int max; ! char *sep; ! char *indent; ! char *term; ! { ! register int j; ! ! ! if (optimize) ! pos = output_option (file, sep, "-O", "", indent, pos, max); ! if (write_symbols != NO_DEBUG) ! pos = output_option (file, sep, "-g", "", indent, pos, max); ! if (flag_traditional) ! pos = output_option (file, sep, "-traditional", "", indent, pos, max); ! if (profile_flag) ! pos = output_option (file, sep, "-p", "", indent, pos, max); ! if (profile_block_flag) ! pos = output_option (file, sep, "-a", "", indent, pos, max); ! ! for (j = 0; j < f_len; j++) ! if (*f_options[j].variable == f_options[j].on_value) ! pos = output_option (file, sep, "-f", f_options[j].string, ! indent, pos, max); ! ! for (j = 0; j < W_len; j++) ! if (*W_options[j].variable == W_options[j].on_value) ! pos = output_option (file, sep, "-W", W_options[j].string, ! indent, pos, max); ! ! for (j = 0; j < sizeof m_options / sizeof m_options[0]; j++) ! if (m_options[j].name[0] != '\0' ! && m_options[j].value > 0 ! && ((m_options[j].value & target_flags) ! == m_options[j].value)) ! pos = output_option (file, sep, "-m", m_options[j].name, ! indent, pos, max); ! ! ! fprintf (file, term); ! } ! ! void ! output_file_start (file, f_options, f_len, W_options, W_len) ! FILE *file; ! struct option *f_options; ! struct option *W_options; ! int f_len, W_len; ! { ! register int pos; ! ! output_file_directive (file, main_input_filename); ! ! /* Switch to the data section so that the coffsem symbol and the ! gcc2_compiled. symbol aren't in the text section. */ ! data_section (); ! ! ! pos = fprintf (file, "\n! Hitachi SH cc1 (%s) arguments:", version_string); ! output_options (file, f_options, f_len, W_options, W_len, ! pos, 75, " ", "\n! ", "\n\n"); ! } ! ! ! /* Code to generate prologue and epilogue sequences */ ! ! void ! sh_expand_prologue () ! { ! int live_regs_mask; ! int d; ! ! live_regs_mask = calc_live_regs (&d); ! ! output_stack_adjust (-1, current_function_pretend_args_size); ! ! if (current_function_anonymous_args) ! { ! /* Push arg regs as if they'd been provided by caller in stack */ ! int i; ! for (i = 0; i < NPARM_REGS; i++) ! { ! int rn = NPARM_REGS + FIRST_PARM_REG - i - 1; ! if (i > NPARM_REGS - current_function_args_info) ! break; ! push (rn); ! ! extra_push += 4; ! } ! } ! ! if (frame_pointer_needed) ! { ! push_regs (live_regs_mask); ! emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx)); ! } ! else ! { ! push_regs (live_regs_mask); ! } ! ! output_stack_adjust (-1, get_frame_size ()); ! } ! ! void ! sh_expand_epilogue () ! { ! int live_regs_mask; ! int d; ! int i; ! ! live_regs_mask = calc_live_regs (&d); ! ! if (frame_pointer_needed) ! { ! emit_insn (gen_movsi (stack_pointer_rtx, frame_pointer_rtx)); ! } ! else ! { ! output_stack_adjust (1, get_frame_size ()); ! } ! ! ! /* Pop all the registers */ ! for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) ! { ! int j = (FIRST_PSEUDO_REGISTER - 1) - i; ! if (live_regs_mask & (1 << j)) ! { ! pop (j); ! } ! } ! output_stack_adjust (1, extra_push + ! current_function_pretend_args_size); ! ! extra_push = 0; ! ! current_function_anonymous_args = 0; } + /* Return the cost of a shift */ + + int + shiftcosts (RTX) + rtx RTX; + { + /* If shift by a non constant, then this will be expensive. */ + if (GET_CODE (XEXP (RTX, 1)) != CONST_INT) + return 20; + + /* otherwise, it will be very cheap if by one of the constants + we can cope with. */ + if (CONST_OK_FOR_K (INTVAL (XEXP (RTX, 1)))) + return 1; + + /* otherwise it will be several insns. */ + return 4; + } + + /* Return the cost of a multiply */ + int + multcosts (RTX) + rtx RTX; + { + /* If we we're aiming at small code, then just count the number of + insns in a multiply call sequence, otherwise, count all the insnsn + inside the call. */ + if (TARGET_SMALLCODE) + return 3; + return 30; + } diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/sh/sh.h gcc-2.5.0/config/sh/sh.h *** gcc-2.4.5/config/sh/sh.h Tue May 4 11:21:38 1993 --- gcc-2.5.0/config/sh/sh.h Sat Oct 2 04:23:23 1993 *************** *** 33,37 **** #define SDB_DELIM ";" ! #define CPP_PREDEFINES "-D__sh__" --- 33,37 ---- #define SDB_DELIM ";" ! #define CPP_PREDEFINES "-D__sh__ -Acpu(sh) -Amachine(sh)" *************** *** 50,54 **** #define ISIZE_BIT 1 #define FAST_BIT 2 ! #define MULSI3_BIT 4 #define MAC_BIT 8 #define RTL_BIT 16 --- 50,54 ---- #define ISIZE_BIT 1 #define FAST_BIT 2 ! #define MAC_BIT 8 #define RTL_BIT 16 *************** *** 55,65 **** #define DT_BIT 32 #define DALIGN_BIT 64 ! /* Nonzero if we should generate code using muls.l insn */ ! #define TARGET_HAS_MULSI3 (target_flags & MULSI3_BIT) /* Nonzero if we should generate faster code rather than smaller code */ #define TARGET_FASTCODE (target_flags & FAST_BIT) /* Nonzero if we should dump out instruction size info */ #define TARGET_DUMPISIZE (target_flags & ISIZE_BIT) --- 55,84 ---- #define DT_BIT 32 #define DALIGN_BIT 64 + #define SH0_BIT 128 + #define SH1_BIT 256 + #define SH2_BIT 512 + #define SH3_BIT 1024 + #define C_BIT 2048 + #define R_BIT (1<<12) + #define SPACE_BIT (1<<13) + + /* Nonzero if we should generate code using type 0 insns */ + #define TARGET_SH0 (target_flags & SH0_BIT) + + /* Nonzero if we should generate code using type 1 insns */ + #define TARGET_SH1 (target_flags & SH1_BIT) ! /* Nonzero if we should generate code using type 2 insns */ ! #define TARGET_SH2 (target_flags & SH2_BIT) + /* Nonzero if we should generate code using type 3 insns */ + #define TARGET_SH3 (target_flags & SH3_BIT) + /* Nonzero if we should generate faster code rather than smaller code */ #define TARGET_FASTCODE (target_flags & FAST_BIT) + /* Nonzero if we should generate faster code rather than smaller code */ + #define TARGET_SMALLCODE (target_flags & SPACE_BIT) + /* Nonzero if we should dump out instruction size info */ #define TARGET_DUMPISIZE (target_flags & ISIZE_BIT) *************** *** 71,76 **** #define TARGET_DUMP_RTL (target_flags & RTL_BIT) ! /* Nonzero if the target has a decrement and test instruction .*/ ! #define TARGET_HAS_DT (target_flags & DT_BIT) /* Nonzero to align doubles on 64 bit boundaries */ --- 90,95 ---- #define TARGET_DUMP_RTL (target_flags & RTL_BIT) ! /* Nonzero if we should dump the rtl somewher else. */ ! #define TARGET_DUMP_R (target_flags & R_BIT) /* Nonzero to align doubles on 64 bit boundaries */ *************** *** 77,87 **** #define TARGET_ALIGN_DOUBLE (target_flags & DALIGN_BIT) #define TARGET_SWITCHES \ { {"isize", ( ISIZE_BIT) },\ ! {"space", (-FAST_BIT) },\ ! {"hasmulsi", ( MULSI3_BIT) },\ ! {"hasdt", ( DT_BIT) },\ {"ac", ( MAC_BIT) },\ {"dalign", ( DALIGN_BIT) },\ {"", TARGET_DEFAULT} \ } --- 96,115 ---- #define TARGET_ALIGN_DOUBLE (target_flags & DALIGN_BIT) + + /* Nonzero if Combine dumping wanted */ + #define TARGET_CDUMP (target_flags & C_BIT) + #define TARGET_SWITCHES \ { {"isize", ( ISIZE_BIT) },\ ! {"space", ( SPACE_BIT) },\ ! {"0", ( SH0_BIT) },\ ! {"1", ( SH1_BIT) },\ ! {"2", ( SH2_BIT) },\ ! {"3", ( SH3_BIT) },\ {"ac", ( MAC_BIT) },\ {"dalign", ( DALIGN_BIT) },\ + {"c", ( C_BIT) },\ + {"r", ( RTL_BIT) },\ + {"R", ( R_BIT) },\ {"", TARGET_DEFAULT} \ } *************** *** 89,95 **** --- 117,129 ---- #define TARGET_DEFAULT FAST_BIT + #define OVERRIDE_OPTIONS override_options(); + /* Target machine storage Layout. */ + /* Define to use software floating point emulator for REAL_ARITHMETIC and + decimal <-> binary conversion. */ + #define REAL_ARITHMETIC + /* Define this if most significant bit is lowest numbered in instructions that operate on numbered bit-fields. */ *************** *** 164,169 **** r0-r3 scratch r4-r7 args in and out ! r8-r11 call saved ! r12 r13 assembler temp r14 frame pointer --- 198,202 ---- r0-r3 scratch r4-r7 args in and out ! r8-r12 call saved r13 assembler temp r14 frame pointer *************** *** 196,204 **** /* 1 for registers that have pervasive standard uses and are not available for the register allocator. */ ! /* r0 r1 r2 r3 r4 r5 r6 r7 r8 ! r9 r10 r11 r12 r13 r14 r15 ap pr t gbr mh ml */ #define FIXED_REGISTERS \ ! { 0, 0, 0, 0, 0, 0, 0, 0, 0, \ ! 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1} /* 1 for registers not available across function calls. --- 229,235 ---- /* 1 for registers that have pervasive standard uses and are not available for the register allocator. */ ! /* r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 ap pr t gbr mh ml */ #define FIXED_REGISTERS \ ! { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1} /* 1 for registers not available across function calls. *************** *** 209,217 **** Aside from that, you can include as many other registers as you like. */ ! /* r0 r1 r2 r3 r4 r5 r6 r7 r8 ! r9 r10 r11 r12 r13 r14 r15 ap pr t gbr mh ml */ #define CALL_USED_REGISTERS \ ! { 1, 1, 1, 1, 1, 1, 1, 1, 0, \ ! 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1} /* Return number of consecutive hard regs needed starting at reg REGNO --- 240,246 ---- Aside from that, you can include as many other registers as you like. */ ! /* r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 ap pr t gbr mh ml */ #define CALL_USED_REGISTERS \ ! { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1} /* Return number of consecutive hard regs needed starting at reg REGNO *************** *** 253,257 **** Zero means the frame pointer need not be set up (and parms may be accessed via the stack pointer) in functions that seem suitable. */ ! #define FRAME_POINTER_REQUIRED 0 /* Definitions for register eliminations. --- 282,288 ---- Zero means the frame pointer need not be set up (and parms may be accessed via the stack pointer) in functions that seem suitable. */ ! ! ! #define FRAME_POINTER_REQUIRED (get_frame_size() > 1000) /* Definitions for register eliminations. *************** *** 289,299 **** #define STATIC_CHAIN_REGNUM 13 ! /* If the structure value address is not passed in a register, define ! this as an expression returning an RTX for the place ! where the address is passed. If it returns 0, the address is ! passed as an "invisible" first argument. */ ! #define STRUCT_VALUE 0 /* Define the classes of registers for register constraints in the --- 320,328 ---- #define STATIC_CHAIN_REGNUM 13 ! /* The register in which a struct value address is passed */ ! #define STRUCT_VALUE_REGNUM 3 + /* Define the classes of registers for register constraints in the *************** *** 373,377 **** /* The order in which register should be allocated. */ #define REG_ALLOC_ORDER \ ! { 1,2,3,0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21} /* The class value for index registers, and the one for base regs. */ --- 402,406 ---- /* The order in which register should be allocated. */ #define REG_ALLOC_ORDER \ ! { 1,2,3,7,4,5,6,0,8,9,10,11,12,13,14,15,16,17,18,19,20,21} /* The class value for index registers, and the one for base regs. */ *************** *** 393,397 **** Return 1 if VALUE is in the range specified by C. I: arithmetic operand -127..128, as used in add, sub, etc ! L: logical operand 0..255, as used in add, or, etc. M: constant 1 K: shift operand 1,2,8 or 16 */ --- 422,426 ---- Return 1 if VALUE is in the range specified by C. I: arithmetic operand -127..128, as used in add, sub, etc ! L: logical operand 0..255, as used in and, or, etc. M: constant 1 K: shift operand 1,2,8 or 16 */ *************** *** 398,403 **** ! #define CONST_OK_FOR_I(VALUE) ((VALUE)>= -128 && (VALUE) <= 127) ! #define CONST_OK_FOR_L(VALUE) ((VALUE)>= 0 && (VALUE) <= 255) #define CONST_OK_FOR_M(VALUE) ((VALUE)==1) #define CONST_OK_FOR_K(VALUE) ((VALUE)==1||(VALUE)==2||(VALUE)==8||(VALUE)==16) --- 427,432 ---- ! #define CONST_OK_FOR_I(VALUE) (((int)(VALUE))>= -128 && ((int)(VALUE)) <= 127) ! #define CONST_OK_FOR_L(VALUE) (((int)(VALUE))>= 0 && ((int)(VALUE)) <= 255) #define CONST_OK_FOR_M(VALUE) ((VALUE)==1) #define CONST_OK_FOR_K(VALUE) ((VALUE)==1||(VALUE)==2||(VALUE)==8||(VALUE)==16) *************** *** 423,427 **** in some cases it is preferable to use a more restrictive class. */ ! #define PREFERRED_RELOAD_CLASS(X, CLASS) (CLASS) /* Return the register class of a scratch register needed to copy IN into --- 452,456 ---- in some cases it is preferable to use a more restrictive class. */ ! #define PREFERRED_RELOAD_CLASS(X, CLASS) CLASS /* Return the register class of a scratch register needed to copy IN into *************** *** 606,622 **** - /* Generate assembly output for the start of a function. */ - - #define FUNCTION_PROLOGUE(STREAM, SIZE) \ - output_prologue ((STREAM), (SIZE)) - /* Call the function profiler with a given profile label. */ ! #define FUNCTION_PROFILER(STREAM,LABELNO) \ ! { \ ! fprintf(STREAM, "\tsts.l pr,@-r15\n"); \ ! fprintf(STREAM, "\tjsr\tmcount\n"); \ ! fprintf(STREAM, "\tor r0,r0\n"); \ ! fprintf(STREAM, "\t.long\tLP%d\n", (LABELNO)); \ } --- 635,645 ---- /* Call the function profiler with a given profile label. */ ! #define FUNCTION_PROFILER(STREAM,LABELNO) \ ! { \ ! fprintf(STREAM, " trapa #5\n"); \ ! fprintf(STREAM, " .align 2\n"); \ ! fprintf(STREAM, " .long LP%d\n", (LABELNO)); \ } *************** *** 629,643 **** #define EXIT_IGNORE_STACK 0 ! /* Generate the assembly code for function exit. */ #define FUNCTION_EPILOGUE(STREAM, SIZE) \ ! output_epilogue ((STREAM), (SIZE)) - #define ELIGIBLE_FOR_EPILOGUE_DELAY(INSN,N) \ - (get_attr_in_delay_slot(INSN) == IN_DELAY_SLOT_YES) - - #define DELAY_SLOTS_FOR_EPILOGUE \ - delay_slots_for_epilogue(); - /* Output assembler code for a block containing the constant parts of a trampoline, leaving space for the variable parts. --- 652,661 ---- #define EXIT_IGNORE_STACK 0 ! /* Generate the assembly code for function exit ! Just dump out any accumulated constant table.*/ #define FUNCTION_EPILOGUE(STREAM, SIZE) \ ! dump_constants(0); /* Output assembler code for a block containing the constant parts of a trampoline, leaving space for the variable parts. *************** *** 704,708 **** address. */ ! #define MAX_REGS_PER_ADDRESS 1 /* Recognize any constant value that is a valid address. */ --- 722,726 ---- address. */ ! #define MAX_REGS_PER_ADDRESS 4 /* Recognize any constant value that is a valid address. */ *************** *** 710,720 **** #define CONSTANT_ADDRESS_P(X) \ (GET_CODE (X) == LABEL_REF) - #if 0 - - || GET_CODE (X) == SYMBOL_REF \ - || GET_CODE (X) == CONST_INT \ - || GET_CODE (X) == CONST) - - #endif /* Nonzero if the constant value X is a legitimate general operand. --- 728,731 ---- *************** *** 721,728 **** It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. ! On the SH, allow any thing but a double */ ! #define LEGITIMATE_CONSTANT_P(X) \ ! (GET_CODE (X) != CONST_DOUBLE || GET_MODE (X) == VOIDmode) /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx --- 732,738 ---- It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. ! On the SH, allow anything but a double */ ! #define LEGITIMATE_CONSTANT_P(X) (GET_CODE(X) != CONST_DOUBLE) /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx *************** *** 734,741 **** #ifndef REG_OK_STRICT /* 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) \ ! (REGNO(X) <= 16 || REGNO(X) >= FIRST_PSEUDO_REGISTER) /* Nonzero if X is a hard reg that can be used as an index --- 744,752 ---- #ifndef REG_OK_STRICT + /* 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) \ ! (REGNO (X) <= 16 || REGNO (X) >= FIRST_PSEUDO_REGISTER) /* Nonzero if X is a hard reg that can be used as an index *************** *** 742,755 **** or if it is a pseudo reg. */ #define REG_OK_FOR_INDEX_P(X) \ ! (REGNO(X)==0||REGNO(X)>=FIRST_PSEUDO_REGISTER) ! #define REG_OK_FOR_PRE_POST_P(X) (REGNO(X) <= 16) #else /* 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)) /* 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)) #define REG_OK_FOR_PRE_POST_P(X) \ ! (REGNO (X) <= 16 || (unsigned) reg_renumber[REGNO (X)] <=16) #endif --- 753,773 ---- or if it is a pseudo reg. */ #define REG_OK_FOR_INDEX_P(X) \ ! (REGNO (X) == 0 || REGNO (X) >= FIRST_PSEUDO_REGISTER) ! ! #define REG_OK_FOR_PRE_POST_P(X) \ ! (REGNO (X) <= 16) ! #else /* 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)) ! /* 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)) ! #define REG_OK_FOR_PRE_POST_P(X) \ ! (REGNO (X) <= 16 || (unsigned) reg_renumber[REGNO (X)] <=16) #endif *************** *** 760,763 **** --- 778,782 ---- The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS. */ + #define BASE_REGISTER_RTX_P(X) \ (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) *************** *** 778,784 **** */ ! /* A legitimate index for a QI or HI is 0, SI and above can be any ! number 0..64 */ #define GO_IF_LEGITIMATE_INDEX(MODE, REGNO, OP, LABEL) \ do { \ --- 797,807 ---- */ ! /* The SH allows a displacement in a QI or HI amode, but only when the ! other operand is R0. GCC doesn't handle this very well, so we forgo ! all of that. + A legitimate index for a QI or HI is 0, SI and above can be any + number 0..63 */ + #define GO_IF_LEGITIMATE_INDEX(MODE, REGNO, OP, LABEL) \ do { \ *************** *** 785,789 **** if (GET_CODE (OP) == CONST_INT) \ { \ ! if (GET_MODE_SIZE (MODE) < 4 && INTVAL(OP) == 0)\ goto LABEL; \ if (GET_MODE_SIZE (MODE) >=4 \ --- 808,814 ---- if (GET_CODE (OP) == CONST_INT) \ { \ ! if (0&&GET_MODE_SIZE (MODE) == 2 && ((unsigned)INTVAL(OP)) <=30)\ ! goto LABEL; \ ! if (0&&GET_MODE_SIZE (MODE) == 1 && ((unsigned)INTVAL(OP)) <=15)\ goto LABEL; \ if (GET_MODE_SIZE (MODE) >=4 \ *************** *** 794,823 **** ! ! #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \ ! { \ ! if (BASE_REGISTER_RTX_P (X)) \ ! goto LABEL; \ ! else if ((GET_CODE (X) == POST_INC || GET_CODE (X) == PRE_DEC) \ ! && GET_CODE (XEXP (X, 0)) == REG \ ! && REG_OK_FOR_PRE_POST_P (XEXP (X, 0))) \ ! goto LABEL; \ ! else if (GET_CODE (X) == PLUS) \ ! { \ ! rtx xop0 = XEXP(X,0); \ ! rtx xop1 = XEXP(X,1); \ ! if (BASE_REGISTER_RTX_P (xop0)) \ ! GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop0), xop1, LABEL); \ ! else if (BASE_REGISTER_RTX_P (xop1)) \ ! GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop1), xop0, LABEL); \ ! } \ ! else if ((GET_CODE (X) == PRE_INC || GET_CODE (X) == POST_DEC) \ ! && GET_CODE (XEXP (X, 0)) == REG \ ! && REG_OK_FOR_PRE_POST_P (XEXP (X, 0))) \ ! goto LABEL; \ ! } ! ! ! /* 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. --- 819,853 ---- ! #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \ ! { \ ! if (BASE_REGISTER_RTX_P (X)) \ ! goto LABEL; \ ! else if ((GET_CODE (X) == POST_INC || GET_CODE (X) == PRE_DEC) \ ! && GET_CODE (XEXP (X, 0)) == REG \ ! && REG_OK_FOR_PRE_POST_P (XEXP (X, 0))) \ ! goto LABEL; \ ! else if (GET_CODE (X) == PLUS || GET_CODE(X) == LO_SUM) \ ! { \ ! rtx xop0 = XEXP(X,0); \ ! rtx xop1 = XEXP(X,1); \ ! if (GET_MODE_SIZE(MODE) >= 4 && BASE_REGISTER_RTX_P (xop0)) \ ! GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop0), xop1, LABEL); \ ! if (GET_MODE_SIZE(MODE) >= 4 && BASE_REGISTER_RTX_P (xop1)) \ ! GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop1), xop0, LABEL); \ ! if (GET_MODE_SIZE(MODE)<=4) { \ ! if(BASE_REGISTER_RTX_P(xop1) && \ ! INDEX_REGISTER_RTX_P(xop0)) goto LABEL; \ ! if(INDEX_REGISTER_RTX_P(xop1) && \ ! BASE_REGISTER_RTX_P(xop0)) goto LABEL; \ ! } \ ! } \ ! else if ((GET_CODE (X) == PRE_INC || GET_CODE (X) == POST_DEC) \ ! && GET_CODE (XEXP (X, 0)) == REG \ ! && REG_OK_FOR_PRE_POST_P (XEXP (X, 0))) \ ! goto LABEL; \ ! } ! ! ! /* 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. *************** *** 873,879 **** #define MOVE_MAX 4 ! /* Define if normal loads of shorter-than-word items from sign extends ! the rest of the bigs in the register. */ ! #define BYTE_LOADS_SIGN_EXTEND 1 /* Define this if zero-extension is slow (more than one real instruction). --- 903,915 ---- #define MOVE_MAX 4 ! /* Define if operations between registers always perform the operation ! on the full register even if a narrower mode is specified. */ ! #define WORD_REGISTER_OPERATIONS ! ! /* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD ! will either zero-extend or sign-extend. The value of this macro should ! be the code that says which one of the two operations is implicitly ! done, NIL if none. */ ! #define LOAD_EXTEND_OP(MODE) SIGN_EXTEND /* Define this if zero-extension is slow (more than one real instruction). *************** *** 927,935 **** return 1; \ else \ ! return 5; \ case CONST: \ case LABEL_REF: \ case SYMBOL_REF: \ ! return 6; \ case CONST_DOUBLE: \ return 10; --- 963,971 ---- return 1; \ else \ ! return 8; \ case CONST: \ case LABEL_REF: \ case SYMBOL_REF: \ ! return 5; \ case CONST_DOUBLE: \ return 10; *************** *** 937,941 **** #define RTX_COSTS(X, CODE, OUTER_CODE) \ case MULT: \ ! return COSTS_N_INSNS (TARGET_HAS_MULSI3 ? 2 : 20); \ case DIV: \ case UDIV: \ --- 973,981 ---- #define RTX_COSTS(X, CODE, OUTER_CODE) \ case MULT: \ ! return COSTS_N_INSNS (multcosts (X)); \ ! case ASHIFT: \ ! case ASHIFTRT: \ ! case LSHIFT: \ ! return COSTS_N_INSNS (shiftcosts (X)) ; \ case DIV: \ case UDIV: \ *************** *** 955,959 **** #define REGISTER_MOVE_COST(SRCCLASS, DSTCLASS) \ ! ((DSTCLASS ==T_REGS) ? 10 : 2) /* Assembler output control */ --- 995,999 ---- #define REGISTER_MOVE_COST(SRCCLASS, DSTCLASS) \ ! ((DSTCLASS == T_REGS) ? 10 : 1) /* Assembler output control */ *************** *** 960,967 **** /* The text to go at the start of the assembler file */ ! #define ASM_FILE_START(STREAM) \ ! fprintf (STREAM,"! GCC for the Hitachi Super-H\n"); \ ! output_file_directive (STREAM, main_input_filename); #define ASM_APP_ON "" #define ASM_APP_OFF "" --- 1000,1011 ---- /* The text to go at the start of the assembler file */ ! #define ASM_FILE_START(STREAM) \ ! output_file_start (STREAM, f_options, sizeof f_options / sizeof f_options[0], \ ! W_options, sizeof W_options / sizeof W_options[0]); + + #define ASM_FILE_END(STREAM) \ + dump_constants(0); + #define ASM_APP_ON "" #define ASM_APP_OFF "" *************** *** 972,978 **** /* Switch to the text or data segment. */ ! #define TEXT_SECTION_ASM_OP ".text" ! #define DATA_SECTION_ASM_OP ".data" /* The assembler's names for the registers. RFP need not always be used as the Real framepointer; it can also be used as a normal general register. --- 1016,1091 ---- /* Switch to the text or data segment. */ ! #define TEXT_SECTION_ASM_OP "\t.text" ! #define DATA_SECTION_ASM_OP "\t.data" ! #define CTORS_SECTION_ASM_OP "\t.section\t.ctors\n" ! #define DTORS_SECTION_ASM_OP "\t.section\t.dtors\n" ! ! #define EXTRA_SECTIONS in_ctors, in_dtors ! #define EXTRA_SECTION_FUNCTIONS \ ! void \ ! ctors_section() \ ! { \ ! if (in_section != in_ctors) \ ! { \ ! fprintf (asm_out_file, "%s\n", CTORS_SECTION_ASM_OP); \ ! in_section = in_ctors; \ ! } \ ! } \ ! void \ ! dtors_section() \ ! { \ ! if (in_section != in_dtors) \ ! { \ ! fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP); \ ! in_section = in_dtors; \ ! } \ ! } ! ! #define ASM_OUTPUT_SECTION(file, nam) \ ! do { fprintf (file, "\t.section\t%s\n", nam); } while(0) ! ! #define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \ ! do { ctors_section(); fprintf(FILE,"\t.long\t_%s\n", NAME); } while (0) ! ! #define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \ ! do { dtors_section(); fprintf(FILE,"\t.long\t_%s\n", NAME); } while (0) ! ! ! #undef DO_GLOBAL_CTORS_BODY ! #define DO_GLOBAL_CTORS_BODY \ ! { \ ! typedef (*pfunc)(); \ ! extern pfunc __ctors[]; \ ! extern pfunc __ctors_end[]; \ ! pfunc *p; \ ! for (p = __ctors; p < __ctors_end; p++) \ ! { \ ! (*p)(); \ ! } \ ! } ! ! #undef DO_GLOBAL_DTORS_BODY ! #define DO_GLOBAL_DTORS_BODY \ ! { \ ! typedef (*pfunc)(); \ ! extern pfunc __dtors[]; \ ! extern pfunc __dtors_end[]; \ ! pfunc *p; \ ! for (p = __dtors; p < __dtors_end; p++) \ ! { \ ! (*p)(); \ ! } \ ! } ! ! ! ! #define ASM_OUTPUT_REG_PUSH(file, v) \ ! fprintf (file, "\tmov.l r%s,-@r15\n", v); + #define ASM_OUTPUT_REG_POP(file, v) \ + fprintf (file, "\tmov.l @r15+,r%s\n", v); + + + /* The assembler's names for the registers. RFP need not always be used as the Real framepointer; it can also be used as a normal general register. *************** *** 1049,1068 **** /* This is how to output an assembler line defining a `double' */ ! #define ASM_OUTPUT_DOUBLE(FILE,VALUE) \ ! { \ ! long t[2]; \ ! REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t); \ ! fprintf (FILE, "\t.long\t0x%lx\n\t.long\t0x%lx\n", \ ! t[0], t[1]); \ ! } \ /* This is how to output an assembler line defining a `float' constant. */ - #define ASM_OUTPUT_FLOAT(FILE,VALUE) \ - { \ - long t; \ - REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \ - fprintf (FILE, "\t.long\t0x%lx\n", t); \ - } \ #define ASM_OUTPUT_INT(STREAM, EXP) \ --- 1162,1179 ---- /* This is how to output an assembler line defining a `double' */ ! #define ASM_OUTPUT_DOUBLE(FILE,VALUE) \ ! do { char dstr[30]; \ ! REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", dstr); \ ! fprintf (FILE, "\t.double %s\n", dstr); \ ! } while (0) ! /* This is how to output an assembler line defining a `float' constant. */ + #define ASM_OUTPUT_FLOAT(FILE,VALUE) \ + do { char dstr[30]; \ + REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", dstr); \ + fprintf (FILE, "\t.float %s\n", dstr); \ + } while (0) #define ASM_OUTPUT_INT(STREAM, EXP) \ *************** *** 1124,1128 **** we're optimising. Otherwise it's of no use anyway. */ #define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \ ! final_prescan_insn (INSN, OPVEC, NOPERANDS) /* Print operand X (an rtx) in assembler syntax to file FILE. --- 1235,1239 ---- we're optimising. Otherwise it's of no use anyway. */ #define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \ ! final_prescan_insn (INSN, OPVEC, NOPERANDS) /* Print operand X (an rtx) in assembler syntax to file FILE. *************** *** 1137,1141 **** #define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \ ! ((CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^' || (CHAR) == '!') --- 1248,1252 ---- #define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \ ! ((CHAR)=='.' || (CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^' || (CHAR) == '!') *************** *** 1148,1153 **** extern struct rtx_def *prepare_scc_operands(); - /* Declare functions defined in sh.c and used in templates. */ --- 1259,1264 ---- extern struct rtx_def *prepare_scc_operands(); + extern enum attr_cpu sh_cpu; /* target cpu */ /* Declare functions defined in sh.c and used in templates. */ *************** *** 1160,1161 **** --- 1271,1277 ---- #define ADJUST_INSN_LENGTH(insn, length) \ adjust_insn_length (insn, insn_lengths) + + + + + diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/sh/sh.md gcc-2.5.0/config/sh/sh.md *** gcc-2.4.5/config/sh/sh.md Mon May 10 11:59:23 1993 --- gcc-2.5.0/config/sh/sh.md Mon Jun 28 20:11:35 1993 *************** *** 27,31 **** ;; ------------------------------------------------------------------------- ! (define_attr "type" "cbranch,ctable,jump,arith,other" (const_string "other")) --- 27,36 ---- ;; ------------------------------------------------------------------------- ! ; Target CPU. ! ! (define_attr "cpu" "sh0,sh1,sh2,sh3" ! (const (symbol_ref "sh_cpu"))) ! ! (define_attr "type" "cbranch,ctable,jump,arith,other,load,store,move,smpy,dmpy,return,pload" (const_string "other")) *************** *** 63,72 **** (const_int 6)) ] (const_int 2))) (define_attr "needs_delay_slot" "yes,no" ! (cond [(eq_attr "type" "jump") (const_string "yes")] (const_string "no"))) (define_attr "dump" "yes,no,must" (const_string "no")) (define_attr "constneed" "yes,no" (const_string "no")) --- 68,89 ---- (const_int 6)) ] (const_int 2))) + + ;; (define_function_unit {name} {num-units} {n-users} {test} + ;; {ready-delay} {issue-delay} [{conflict-list}]) + (define_function_unit "memory" 1 1 (eq_attr "type" "load") 1 0) + (define_function_unit "mpy" 1 1 (eq_attr "type" "smpy") 3 0) + (define_function_unit "mpy" 1 1 (eq_attr "type" "dmpy") 5 0) (define_attr "needs_delay_slot" "yes,no" ! (cond [(eq_attr "type" "jump") (const_string "yes") ! (eq_attr "type" "return") (const_string "yes")] (const_string "no"))) + (define_delay + (eq_attr "needs_delay_slot" "yes") + [(eq_attr "in_delay_slot" "yes") (nil) (nil)]) + + (define_attr "dump" "yes,no,must" (const_string "no")) (define_attr "constneed" "yes,no" (const_string "no")) *************** *** 78,81 **** --- 95,100 ---- (cond [(eq_attr "type" "cbranch") (const_string "no") (eq_attr "type" "jump") (const_string "no") + (eq_attr "type" "pload") (const_string "no") + (eq_attr "type" "return") (const_string "no") (eq_attr "length" "2") (const_string "yes") (eq_attr "length" "4,6,8,10,12") (const_string "no") *************** *** 83,90 **** - (define_delay (eq_attr "needs_delay_slot" "yes") - [(eq_attr "in_delay_slot" "yes") (nil) (nil)]) - - ;; ------------------------------------------------------------------------- --- 102,105 ---- *************** *** 138,142 **** (define_insn "cmplesi_t" [(set (reg:SI 18) (le (match_operand:SI 0 "arith_reg_operand" "r") ! (match_operand:SI 1 "arith_reg_operand" "r")))] "" "cmp/ge %0,%1") --- 153,157 ---- (define_insn "cmplesi_t" [(set (reg:SI 18) (le (match_operand:SI 0 "arith_reg_operand" "r") ! (match_operand:SI 1 "arith_reg_operand" "r")))] "" "cmp/ge %0,%1") *************** *** 234,242 **** (define_insn "subsi3" ! [(set (match_operand:SI 0 "arith_reg_operand" "=r") ! (minus:SI (match_operand:SI 1 "arith_reg_operand" "0") ! (match_operand:SI 2 "arith_reg_operand" "r")))] "" ! "sub %2,%0" [(set_attr "type" "arith")]) --- 249,259 ---- (define_insn "subsi3" ! [(set (match_operand:SI 0 "arith_reg_operand" "=r,r") ! (minus:SI (match_operand:SI 1 "arith_reg_operand" "0,0") ! (match_operand:SI 2 "arith_operand" "r,I")))] "" ! "@ ! sub %2,%0 ! add %M2,%0" [(set_attr "type" "arith")]) *************** *** 254,258 **** (match_operand:HI 2 "arith_reg_operand" "r"))))] "" ! "mulu %2,%1") (define_insn "" --- 271,276 ---- (match_operand:HI 2 "arith_reg_operand" "r"))))] "" ! "mulu %2,%1" ! [(set_attr "type" "smpy")]) (define_insn "" *************** *** 263,267 **** (match_operand:HI 2 "arith_reg_operand" "r"))))] "" ! "muls %2,%1") (define_expand "mulhisi3" --- 281,286 ---- (match_operand:HI 2 "arith_reg_operand" "r"))))] "" ! "muls %2,%1" ! [(set_attr "type" "smpy")]) (define_expand "mulhisi3" *************** *** 287,345 **** "") - (define_insn "" - [(set (reg:SI 21) - (mult:SI (match_operand:SI 1 "arith_reg_operand" "r") - (match_operand:SI 2 "arith_reg_operand" "r")))] - "TARGET_HAS_MULSI3" - "muls.l %2,%1") - - (define_expand "mulsi3" - [(set (reg:SI 21) - (mult:SI (match_operand:SI 1 "arith_reg_operand" "r") - (match_operand:SI 2 "arith_reg_operand" "r"))) - (set (match_operand:SI 0 "arith_reg_operand" "=r") - (reg:SI 20))] - "TARGET_HAS_MULSI3" - "") - - (define_insn "" - [(set (reg:DI 20) - (mult:DI (sign_extend:DI - (match_operand:SI 1 "arith_reg_operand" "r")) - (sign_extend:DI - (match_operand:SI 2 "arith_reg_operand" "r"))))] - "TARGET_HAS_MULSI3" - "dmuls.l %2,%1") - - (define_expand "mulsidi3" - [(set (reg:DI 20) - (mult:DI (sign_extend:DI - (match_operand:SI 1 "arith_reg_operand" "r")) - (sign_extend:DI - (match_operand:SI 2 "arith_reg_operand" "r")))) - (set (match_operand:DI 0 "arith_reg_operand" "=r") - (reg:DI 20))] - "TARGET_HAS_MULSI3" - "") - - (define_insn "" - [(set (reg:DI 20) - (mult:DI (zero_extend:DI - (match_operand:SI 1 "arith_reg_operand" "r")) - (zero_extend:DI - (match_operand:SI 2 "arith_reg_operand" "r"))))] - "TARGET_HAS_MULSI3" - "dmulu.l %2,%1") - - (define_expand "umulsidi3" - [(set (reg:DI 20) - (mult:DI (zero_extend:DI - (match_operand:SI 1 "arith_reg_operand" "r")) - (zero_extend:DI - (match_operand:SI 2 "arith_reg_operand" "r")))) - (set (match_operand:DI 0 "arith_reg_operand" "=r") - (reg:DI 20))] - "TARGET_HAS_MULSI3" - "") ;; ------------------------------------------------------------------------- --- 306,309 ---- *************** *** 375,384 **** ;; ------------------------------------------------------------------------- (define_insn "ashlsi3_k" [(set (match_operand:SI 0 "arith_reg_operand" "=r,r") (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0") ! (match_operand:SI 2 "immediate_operand" "L,n")))] "" ! "*return output_shift(\"shll\", operands[0], operands[2]);" [(set_attr "length" "2,12") (set_attr "in_delay_slot" "yes,no") --- 339,381 ---- ;; ------------------------------------------------------------------------- + (define_insn "rotlsi3_k" + [(set (match_operand:SI 0 "arith_reg_operand" "=r") + (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0") + (const_int 1))) + (clobber (reg:SI 18))] + "" + "rotl %0") + + (define_expand "rotlsi3" + [(parallel[(set (match_operand:SI 0 "arith_reg_operand" "") + (rotate:SI (match_operand:SI 1 "arith_reg_operand" "") + (match_operand:SI 2 "immediate_operand" ""))) + (clobber (reg:SI 18))])] + "" + "{ if (GET_CODE(operands[2]) != CONST_INT || INTVAL(operands[2]) != 1) FAIL;}") + + (define_insn "rotrsi3_k" + [(set (match_operand:SI 0 "arith_reg_operand" "=r") + (rotatert:SI (match_operand:SI 1 "arith_reg_operand" "0") + (const_int 1))) + (clobber (reg:SI 18))] + "" + "rotr %0") + + (define_expand "rotrsi3" + [(parallel[(set (match_operand:SI 0 "arith_reg_operand" "") + (rotatert:SI (match_operand:SI 1 "arith_reg_operand" "") + (match_operand:SI 2 "immediate_operand" ""))) + (clobber (reg:SI 18))])] + "" + "{ if (GET_CODE(operands[2]) != CONST_INT || INTVAL(operands[2]) != 1) FAIL;}") + (define_insn "ashlsi3_k" [(set (match_operand:SI 0 "arith_reg_operand" "=r,r") (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0") ! (match_operand:SI 2 "immediate_operand" "K,n"))) ! (clobber (reg:SI 18))] "" ! "*return output_shift(\"shll\", operands[0], operands[2], ASHIFT);" [(set_attr "length" "2,12") (set_attr "in_delay_slot" "yes,no") *************** *** 386,394 **** (define_expand "ashlsi3" ! [(set (match_operand:SI 0 "arith_reg_operand" "") ! (ashift:SI (match_operand:SI 1 "arith_reg_operand" "") ! (match_operand:SI 2 "immediate_operand" "")))] "" ! "if (!ok_shift_value(operands[2])) FAIL;") (define_insn "ashrsi3_k" --- 383,392 ---- (define_expand "ashlsi3" ! [(parallel[(set (match_operand:SI 0 "arith_reg_operand" "") ! (ashift:SI (match_operand:SI 1 "arith_reg_operand" "") ! (match_operand:SI 2 "immediate_operand" ""))) ! (clobber (reg:SI 18))])] "" ! "if (!ok_shift_value(operands[2], ASHIFT)) FAIL;") (define_insn "ashrsi3_k" *************** *** 395,399 **** [(set (match_operand:SI 0 "arith_reg_operand" "=r") (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0") ! (const_int 1)))] "" "shar %0" --- 393,398 ---- [(set (match_operand:SI 0 "arith_reg_operand" "=r") (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0") ! (const_int 1))) ! (clobber (reg:SI 18))] "" "shar %0" *************** *** 401,407 **** (define_expand "ashrsi3" ! [(set (match_operand:SI 0 "arith_reg_operand" "=r") ! (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r") ! (match_operand:SI 2 "nonmemory_operand" "M")))] "" " --- 400,407 ---- (define_expand "ashrsi3" ! [(parallel[(set (match_operand:SI 0 "arith_reg_operand" "=r") ! (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r") ! (match_operand:SI 2 "nonmemory_operand" "M"))) ! (clobber (reg:SI 18))])] "" " *************** *** 413,429 **** (define_insn "lshrsi3_k" ! [(set (match_operand:SI 0 "arith_reg_operand" "=r") ! (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0") ! (match_operand:SI 2 "immediate_operand" "L")))] "" ! "* return output_shift (\"shlr\", operands[0], operands[2]);" ! [(set_attr "length" "12") ! (set_attr "in_delay_slot" "no") (set_attr "type" "arith")]) (define_expand "lshrsi3" ! [(set (match_operand:SI 0 "arith_reg_operand" "") ! (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "") ! (match_operand:SI 2 "nonmemory_operand" "")))] "" "if (!ok_shift_value (operands[2])) FAIL; ") --- 413,431 ---- (define_insn "lshrsi3_k" ! [(set (match_operand:SI 0 "arith_reg_operand" "=r,r") ! (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0,0") ! (match_operand:SI 2 "immediate_operand" "K,n"))) ! (clobber (reg:SI 18))] "" ! "* return output_shift (\"shlr\", operands[0], operands[2], LSHIFTRT);" ! [(set_attr "length" "2,12") ! (set_attr "in_delay_slot" "yes,no") (set_attr "type" "arith")]) (define_expand "lshrsi3" ! [(parallel[(set (match_operand:SI 0 "arith_reg_operand" "") ! (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "") ! (match_operand:SI 2 "nonmemory_operand" ""))) ! (clobber (reg:SI 18))])] "" "if (!ok_shift_value (operands[2])) FAIL; ") *************** *** 450,456 **** (define_insn "lshrdi3_k" [(set (match_operand:DI 0 "arith_reg_operand" "=r") ! (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0") ! (match_operand:DI 2 "immediate_operand" "I"))) ! (clobber (reg:SI 18))] "" "shlr %0\;rotcr %R0" --- 452,458 ---- (define_insn "lshrdi3_k" [(set (match_operand:DI 0 "arith_reg_operand" "=r") ! (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0") ! (match_operand:DI 2 "immediate_operand" "I"))) ! (clobber (reg:SI 18))] "" "shlr %0\;rotcr %R0" *************** *** 575,597 **** (define_insn "" ! [(set (match_operand:SI 0 "push_operand" "=<") ! (match_operand:SI 1 "arith_reg_operand" "r"))] ! "" ! "mov.l %1,%0") ! (define_insn "movsi_pcrel" ! [(set (match_operand:SI 0 "arith_reg_operand" "=r") ! (match_operand:SI 1 "hard_immediate_operand" "i"))] "" ! "* return output_movepcrel (insn, operands, SImode);" ! [(set_attr "length" "2") ! (set_attr "in_delay_slot" "no") ! (set_attr "constneed" "yes") ! (set_attr "smallestsize" "2") ! (set_attr "largestsize" "8")]) ! (define_insn "movsi_i" ! [(set (match_operand:SI 0 "general_operand" "=r,r,r,m,l,r,r,r,t") ! (match_operand:SI 1 "general_operand" "r,I,m,r,r,l,t,x,r"))] "" "@ --- 577,629 ---- (define_insn "" ! [(set (match_operand:SI 0 "push_operand" "=<,<") ! (match_operand:SI 1 "arith_reg_operand" "r,l"))] ! "" ! "@ ! mov.l %1,%0 ! sts.l pr,%0" ! [(set_attr "type" "store")]) ! (define_insn "" ! [(set (match_operand:SI 0 "arith_reg_operand" "=r,l") ! (match_operand:SI 1 "pop_operand" "=>,>"))] "" ! "@ ! mov.l %1,%0 ! lds.l %1,pr" ! [(set_attr "type" "load,pload")]) ! ! (define_insn "push" ! [(set (mem:SI (pre_dec:SI (reg:SI 15))) ! (match_operand:SI 0 "register_operand" "r,l"))] ! "" ! "@ ! mov.l %0,@-r15 ! sts.l pr,@-r15") ! ! (define_insn "pop" ! [(set (match_operand:SI 0 "register_operand" "=r,l") ! (mem:SI (post_inc:SI (reg:SI 15))))] ! "" ! "@ ! mov.l @r15+,%0 ! lds.l @r15+,pr" ! [(set_attr "type" "load,pload")]) ! ! ; some constants are easier to generate with alu operations ! ; rather than loading from memory ! ! (define_split ! [(set (match_operand:SI 0 "register_operand" "=r") ! (match_operand:SI 1 "painful_immediate_operand" "i"))] ! "" ! [(set (match_dup 0) (const_int 127)) ! (set (match_dup 0) (plus:SI (match_dup 0) ! (match_dup 2)))] ! "operands[2] = GEN_INT (INTVAL(operands[1]) - 127);" ) ! (define_insn "movsi_i" ! [(set (match_operand:SI 0 "general_operand" "=r,r,r,m,l,r,r,r,t,x") ! (match_operand:SI 1 "general_movsrc_operand" "r,I,m,r,r,l,t,x,r,r"))] "" "@ *************** *** 600,609 **** mov.l %1,%0 mov.l %1,%0 ! mov %1,%0 ! mov %1,%0 movt %0 sts %1,%0 ! tst %1,%1\;bt T%*\;bra F%*\;sett\;T%*:clrt\;F%*:%^" ! [(set_attr "length" "2,2,2,2,2,2,2,2,10")]) (define_expand "movsi" --- 632,655 ---- mov.l %1,%0 mov.l %1,%0 ! lds %1,%0 ! sts %1,%0 movt %0 sts %1,%0 ! tst %1,%1\;bt T%*\;bra F%*\;sett\;T%*:clrt\;F%*:%^ ! lds %1,%0" ! [(set_attr "length" "2,2,2,2,2,2,2,2,10,2") ! (set_attr "type" "move,move,load,pload,move,move,move,move,move,move")]) ! ! (define_insn "movsi_pcrel" ! [(set (match_operand:SI 0 "arith_reg_operand" "=r") ! (match_operand:SI 1 "hard_immediate_operand" "i"))] ! "" ! "* return output_movepcrel (insn, operands, SImode);" ! [(set_attr "length" "2") ! (set_attr "in_delay_slot" "no") ! (set_attr "constneed" "yes") ! (set_attr "smallestsize" "2") ! (set_attr "largestsize" "8") ! (set_attr "type" "load")]) (define_expand "movsi" *************** *** 611,619 **** (match_operand:SI 1 "general_operand" ""))] "" ! "{ prepare_move_operands(operands, SImode); } ") (define_insn "movqi_i" ! [(set (match_operand:QI 0 "general_operand" "=r,r,z,m,r,m,r,r") ! (match_operand:QI 1 "general_operand" "r,n,m,z,m,r,x,t"))] "" "@ --- 657,665 ---- (match_operand:SI 1 "general_operand" ""))] "" ! "{ if(prepare_move_operands(operands, SImode)) DONE; } ") (define_insn "movqi_i" ! [(set (match_operand:QI 0 "general_operand" "=r,r,r,m,r,m,r,r") ! (match_operand:QI 1 "general_operand" "r,n,m,r,m,r,x,t"))] "" "@ *************** *** 620,627 **** mov %1,%0 mov %1,%0 ! mov.b %1,%0 !4 ! mov.b %1,%0 !5 ! mov.b %1,%0 !6 ! mov.b %1,%0 ! 7 sts %1,%0 movt %0") --- 666,673 ---- mov %1,%0 mov %1,%0 ! mov.b %1,%0 ! mov.b %1,%0 ! mov.b %1,%0 ! mov.b %1,%0 sts %1,%0 movt %0") *************** *** 642,646 **** (set_attr "constneed" "yes") (set_attr "smallestsize" "2") ! (set_attr "largestsize" "8")]) (define_insn "movhi_i" --- 688,693 ---- (set_attr "constneed" "yes") (set_attr "smallestsize" "2") ! (set_attr "largestsize" "8") ! (set_attr "type" "load")]) (define_insn "movhi_i" *************** *** 655,659 **** mov.w %1,%0 sts %1,%0 ! movt %0") (define_expand "movhi" --- 702,707 ---- mov.w %1,%0 sts %1,%0 ! movt %0" ! [(set_attr "type" "move,load,store,load,store,move,move")]) (define_expand "movhi" *************** *** 668,672 **** "" "mov.l %R1,%0\;mov.l %1,%0" ! [(set_attr "length" "4")]) (define_insn "movdi_pcrel" --- 716,721 ---- "" "mov.l %R1,%0\;mov.l %1,%0" ! [(set_attr "length" "4") ! (set_attr "type" "store")]) (define_insn "movdi_pcrel" *************** *** 680,684 **** (set_attr "smallestsize" "4") (set_attr "constantsize" "8") ! (set_attr "largestsize" "18")]) (define_insn "movdi_k" --- 729,734 ---- (set_attr "smallestsize" "4") (set_attr "constantsize" "8") ! (set_attr "largestsize" "18") ! (set_attr "type" "load")]) (define_insn "movdi_k" *************** *** 687,691 **** "" "* return output_movedouble(operands, DImode);" ! [(set_attr "length" "4")]) (define_expand "movdi" --- 737,743 ---- "" "* return output_movedouble(operands, DImode);" ! [(set_attr "length" "4") ! (set_attr "type" "move,load,store,move,load,store,load")]) ! (define_expand "movdi" *************** *** 700,704 **** "" "mov.l %R1,%0\;mov.l %1,%0" ! [(set_attr "length" "4")]) (define_insn "movdf_pcrel" --- 752,757 ---- "" "mov.l %R1,%0\;mov.l %1,%0" ! [(set_attr "length" "4") ! (set_attr "type" "store")]) (define_insn "movdf_pcrel" *************** *** 712,716 **** (set_attr "smallestsize" "4") (set_attr "constantsize" "8") ! (set_attr "largestsize" "18")]) (define_insn "movdf_k" --- 765,770 ---- (set_attr "smallestsize" "4") (set_attr "constantsize" "8") ! (set_attr "largestsize" "18") ! (set_attr "type" "load")]) (define_insn "movdf_k" *************** *** 719,723 **** "" "* return output_movedouble(operands, DFmode);" ! [(set_attr "length" "4")]) (define_expand "movdf" --- 773,778 ---- "" "* return output_movedouble(operands, DFmode);" ! [(set_attr "length" "4") ! (set_attr "type" "move,load,store")]) (define_expand "movdf" *************** *** 731,735 **** (match_operand:SF 1 "arith_reg_operand" "r"))] "" ! "mov.l %1,%0") (define_insn "movsf_pcrel" --- 786,791 ---- (match_operand:SF 1 "arith_reg_operand" "r"))] "" ! "mov.l %1,%0" ! [(set_attr "type" "store")]) (define_insn "movsf_pcrel" *************** *** 742,746 **** (set_attr "constneed" "yes") (set_attr "smallestsize" "2") ! (set_attr "largestsize" "8")]) (define_insn "movsf_i" --- 798,803 ---- (set_attr "constneed" "yes") (set_attr "smallestsize" "2") ! (set_attr "largestsize" "8") ! (set_attr "type" "load")]) (define_insn "movsf_i" *************** *** 753,760 **** mov.l %1,%0 mov.l %1,%0 ! mov %1,%0 ! mov %1,%0 mov %1,%0 ! mov %1,%0") (define_expand "movsf" --- 810,818 ---- mov.l %1,%0 mov.l %1,%0 ! lds %1,%0 ! sts %1,%0 mov %1,%0 ! mov %1,%0" ! [(set_attr "type" "move,move,load,store,move,move,move,move")]) (define_expand "movsf" *************** *** 1038,1042 **** (match_operand:SI 0 "arith_reg_operand" "r"))] "" ! "jmp @%0" [(set_attr "needs_delay_slot" "yes") (set_attr "in_delay_slot" "no") --- 1096,1100 ---- (match_operand:SI 0 "arith_reg_operand" "r"))] "" ! "jmp @%0%#" [(set_attr "needs_delay_slot" "yes") (set_attr "in_delay_slot" "no") *************** *** 1065,1068 **** --- 1123,1151 ---- (set_attr "type" "jump") (set_attr "dump" "no")]) + + (define_insn "return" + [(return)] + "reload_completed" + "rts %#" + [(set_attr "type" "return") + (set_attr "needs_delay_slot" "yes") + (set_attr "dump" "yes")]) + + (define_expand "prologue" + [(const_int 0)] + "" + "sh_expand_prologue (); DONE;") + + (define_expand "epilogue" + [(return)] + "" + "sh_expand_epilogue ();") + + (define_insn "blockage" + [(unspec_volatile [(const_int 0)] 0)] + "" + "" + [(set_attr "length" "0")]) + ;; ------------------------------------------------------------------------ *************** *** 1137,1140 **** --- 1220,1226 ---- "operands[1] = prepare_scc_operands (EQ);") + ; these patterns give better code then gcc invents if + ; left to its own devices + (define_insn "anddi3" [(set (match_operand:DI 0 "arith_reg_operand" "=r") *************** *** 1175,1235 **** " { ! rtx src_ptr = copy_to_mode_reg(Pmode,XEXP(operands[1], 0)); ! rtx dst_ptr = copy_to_mode_reg(Pmode,XEXP(operands[0], 0)); ! int maxsize = GET_CODE (operands[2]) == CONST_INT ! ? MAX (INTVAL (operands[2]), INTVAL (operands[3])) : 1; ! enum machine_mode mode = ! (maxsize >= 4) ? SImode : ! (maxsize >= 2) ? HImode : ! QImode; ! ! rtx tmpreg = gen_reg_rtx(mode); ! rtx increment = GEN_INT(GET_MODE_SIZE(mode)); ! rtx length = operands[2]; ! rtx label = gen_label_rtx(); ! rtx end_src_ptr = gen_reg_rtx(Pmode); ! ! /* If done first rtl emmiting stage we can't generate a loop */ ! /* if (!rtx_equal_function_value_matters) ! FAIL;*/ ! ! if (GET_CODE (length) != CONST_INT) ! length = convert_to_mode (Pmode, length, 1); ! ! if (!arith_operand (length, SImode)) ! length = force_reg (SImode, length); ! ! emit_insn(gen_rtx(SET, ! VOIDmode, ! end_src_ptr, ! gen_rtx(PLUS, Pmode, src_ptr, length))); ! ! ! emit_label(label); ! emit_move_insn(tmpreg, gen_rtx(MEM, mode, src_ptr)); ! ! ! emit_insn(gen_rtx(SET, ! VOIDmode, ! src_ptr, ! gen_rtx(PLUS, Pmode, src_ptr, increment))); ! ! emit_move_insn(gen_rtx(MEM, mode, dst_ptr), tmpreg); ! ! emit_insn(gen_rtx(SET, ! VOIDmode, ! dst_ptr, ! gen_rtx(PLUS, Pmode, dst_ptr, increment))); ! ! sh_compare_op0 = src_ptr; ! sh_compare_op1 = end_src_ptr; ! ! emit_insn(gen_cmpeqsi_t(src_ptr, end_src_ptr)); ! emit_jump_insn(gen_bne(label)); ! emit_insn(gen_rtx(SET, VOIDmode, dst_ptr, dst_ptr)); ! ! DONE; ! } ! ") --- 1261,1271 ---- " { ! rtx dest_mem = operands[0]; ! rtx src_mem = operands[1]; ! operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0)); ! operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); ! expand_block_move (dest_mem, src_mem, operands); ! DONE; ! }") *************** *** 1262,1265 **** --- 1298,1338 ---- "REGNO(operands[1]) != REGNO(operands[0])" "mov.l @%1+,%0") + + (define_peephole + [(set (match_operand:QI 0 "register_operand" "=r") + (match_operand:QI 1 "general_operand" "g")) + (set (match_operand:SI 2 "register_operand" "=r") + (sign_extend:SI (match_dup 0)))] + "REGNO(operands[0]) == REGNO(operands[2])" + "mov.b %1,%0") + + (define_peephole + [(set (match_operand:QI 0 "register_operand" "=r") + (match_operand:QI 1 "general_operand" "g")) + (set (match_operand:SI 2 "register_operand" "=r") + (sign_extend:SI (match_dup 0)))] + "REGNO(operands[0]) != REGNO(operands[2]) + && dead_or_set_p (insn, operands[0])" + "mov.b %1,%2") + + ; notice when a mov.b could be done with a displacement + + (define_peephole + [(set (match_operand:SI 0 "register_operand" "=r") + (plus:SI (match_dup 0) + (match_operand:SI 1 "byte_index_operand" "i"))) + (set (mem:QI (match_dup 0)) (reg:QI 0))] + "dead_or_set_p(insn, operands[0])" + "mov.b r0,@(%O1,%0)") + + (define_peephole + [(set (match_operand:SI 0 "register_operand" "=r") + (plus:SI (match_dup 0) + (match_operand:SI 1 "byte_index_operand" "i"))) + (set (reg:QI 0) (mem:QI (match_dup 0)))] + "dead_or_set_p(insn, operands[0])" + "mov.b @(%O1,%0),r0") + + diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/sh/t-sh gcc-2.5.0/config/sh/t-sh *** gcc-2.4.5/config/sh/t-sh Tue May 4 11:22:51 1993 --- gcc-2.5.0/config/sh/t-sh Thu Sep 9 16:02:49 1993 *************** *** 1,15 **** LIBGCC1 = libgcc1.null ! T_CFLAGS = -DDONT_HAVE_STDIO -DDONT_HAVE_SETJMP -Dinhibit_libc ! LIBGCC2_CFLAGS=-g -fno-omit-frame-pointer -O2 $(GCC_CFLAGS) ! ! # These are really part of libgcc1, but this will cause them to be ! # built correctly, so... [taken from t-ose68k] ! LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c ! dp-bit.c: $(srcdir)/config/fp-bit.c ! cat $(srcdir)/config/fp-bit.c >> dp-bit.c ! ! fp-bit.c: $(srcdir)/config/fp-bit.c ! echo '#define FLOAT' > fp-bit.c ! cat $(srcdir)/config/fp-bit.c >> fp-bit.c --- 1,6 ---- LIBGCC1 = libgcc1.null ! CROSS_LIBGCC1 = libgcc1.null ! T_CFLAGS = -DDONT_HAVE_STDIO -DDONT_HAVE_SETJMP -Dinhibit_libc ! LIBGCC2_CFLAGS=-g -O5 $(GCC_CFLAGS) diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/sparc/bsd.h gcc-2.5.0/config/sparc/bsd.h *** gcc-2.4.5/config/sparc/bsd.h --- gcc-2.5.0/config/sparc/bsd.h Tue Sep 28 18:35:12 1993 *************** *** 0 **** --- 1,7 ---- + #include "sparc/sparc.h" + + #undef LIB_SPEC + #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}" + + #undef STARTFILE_SPEC + #define STARTFILE_SPEC "%{pg:gcrt0.o%s}%{!pg:%{p:gcrt0.o%s}%{!p:crt0.o%s}}" diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/sparc/lite.h gcc-2.5.0/config/sparc/lite.h *** gcc-2.4.5/config/sparc/lite.h Mon May 3 20:27:06 1993 --- gcc-2.5.0/config/sparc/lite.h Sat Oct 2 04:23:26 1993 *************** *** 1,3 **** ! /* Definitions of target machine for GNU compiler, for SPARClite. Copyright (C) 1993 Free Software Foundation, Inc. Contributed by Jim Wilson (wilson@cygnus.com). --- 1,3 ---- ! /* Definitions of target machine for GNU compiler, for SPARClite w/o FPU. Copyright (C) 1993 Free Software Foundation, Inc. Contributed by Jim Wilson (wilson@cygnus.com). *************** *** 22,26 **** #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dsparc -Dsparclite" #undef TARGET_VERSION --- 22,26 ---- #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dsparc -Dsparclite -Acpu(sparc) -Amachine(sparc)" #undef TARGET_VERSION diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/sparc/lynx.h gcc-2.5.0/config/sparc/lynx.h *** gcc-2.4.5/config/sparc/lynx.h --- gcc-2.5.0/config/sparc/lynx.h Sat Oct 2 04:23:29 1993 *************** *** 0 **** --- 1,30 ---- + /* Definitions for SPARC running LynxOS. + Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + #include "sparc/sparc.h" + #include "lynx.h" + + /* ??? Must redefine to get sparclite and v8 defines. Can this be done + differently? */ + #undef CPP_SPEC + #define CPP_SPEC "%{mthreads:-D_MULTITHREADED} %{msparclite:-D__sparclite__} %{mv8:-D__sparc_v8__} %{mposix:-D_POSIX_SOURCE} %{msystem-v:-lynx-sysv}" + + /* Names to predefine in the preprocessor for this target machine. */ + #undef CPP_PREDEFINES + #define CPP_PREDEFINES "-Dunix -Dsparc -DLynx -DIBITS32 -Asystem(unix) -Asystem(lynx) -Acpu(sparc) -Amachine(sparc)" diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/sparc/pbd.h gcc-2.5.0/config/sparc/pbd.h *** gcc-2.4.5/config/sparc/pbd.h Fri Feb 26 19:48:14 1993 --- gcc-2.5.0/config/sparc/pbd.h Sat Oct 2 04:23:33 1993 *************** *** 27,31 **** #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dsparc -DUnicomPBD -Dunix -D__GCC_NEW_VARARGS__" /* We want DBX format for use with gdb under COFF. */ --- 27,31 ---- #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dsparc -DUnicomPBD -Dunix -D__GCC_NEW_VARARGS__ -Asystem(unix) -Acpu(sparc) -Amachine(sparc)" /* We want DBX format for use with gdb under COFF. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/sparc/sol2.h gcc-2.5.0/config/sparc/sol2.h *** gcc-2.4.5/config/sparc/sol2.h Tue May 25 23:43:42 1993 --- gcc-2.5.0/config/sparc/sol2.h Sat Oct 2 04:23:38 1993 *************** *** 25,29 **** #undef CPP_PREDEFINES #define CPP_PREDEFINES \ ! "-Dsun -Dsparc -Dunix -D__svr4__ -Asystem(unix) -Acpu(sparc) -Amachine(sparc)\ -D__GCC_NEW_VARARGS__" --- 25,30 ---- #undef CPP_PREDEFINES #define CPP_PREDEFINES \ ! "-Dsun -Dsparc -Dunix -D__svr4__ \ ! -Asystem(unix) -Asystem(svr4) -Acpu(sparc) -Amachine(sparc)\ -D__GCC_NEW_VARARGS__" *************** *** 30,34 **** #undef CPP_SPEC #define CPP_SPEC "\ ! %{compat-bsd:-iwithprefix ucbinclude -idirafter /usr/ucbinclude}\ %{msparclite:-D__sparclite__} %{mv8:-D__sparc_v8__}" --- 31,35 ---- #undef CPP_SPEC #define CPP_SPEC "\ ! %{compat-bsd:-iwithprefixbefore ucbinclude -I/usr/ucbinclude}\ %{msparclite:-D__sparclite__} %{mv8:-D__sparc_v8__}" diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/sparc/sparc.c gcc-2.5.0/config/sparc/sparc.c *** gcc-2.4.5/config/sparc/sparc.c Tue Jun 8 14:50:09 1993 --- gcc-2.5.0/config/sparc/sparc.c Wed Oct 6 00:05:00 1993 *************** *** 63,66 **** --- 63,67 ---- 56, 57, 58, 59, 60, 61, 62, 63}; + #if 0 /* not used anymore */ char leaf_reg_backmap[] = { 0, 1, 2, 3, 4, 5, 6, 7, *************** *** 74,77 **** --- 75,79 ---- 56, 57, 58, 59, 60, 61, 62, 63}; #endif + #endif /* Global variables set by FUNCTION_PROLOGUE. */ *************** *** 78,83 **** /* Size of frame. Need to know this to emit return insns from leaf procedures. */ ! int apparent_fsize; ! int actual_fsize; /* Name of where we pretend to think the frame pointer points. --- 80,85 ---- /* Size of frame. Need to know this to emit return insns from leaf procedures. */ ! static int apparent_fsize; ! static int actual_fsize; /* Name of where we pretend to think the frame pointer points. *************** *** 97,107 **** if (op == const0_rtx || register_operand (op, mode)) return 1; ! if (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0 && CONST_DOUBLE_LOW (op) == 0) return 1; return 0; } /* Nonzero if OP can appear as the dest of a RESTORE insn. */ int --- 99,124 ---- if (op == const0_rtx || register_operand (op, mode)) return 1; ! if (GET_MODE (op) == DImode && GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0 && CONST_DOUBLE_LOW (op) == 0) return 1; + if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT + && GET_CODE (op) == CONST_DOUBLE + && fp_zero_operand (op)) + return 1; return 0; } + /* Nonzero if OP is a floating point value with value 0.0. */ + int + fp_zero_operand (op) + rtx op; + { + REAL_VALUE_TYPE r; + + REAL_VALUE_FROM_CONST_DOUBLE (r, op); + return REAL_VALUES_EQUAL (r, dconst0); + } + /* Nonzero if OP can appear as the dest of a RESTORE insn. */ int *************** *** 257,300 **** return 0; } - - /* The rtx for the global offset table which is a special form - that *is* a position independent symbolic constant. */ - rtx pic_pc_rtx; - - /* Ensure that we are not using patterns that are not OK with PIC. */ - - int - check_pic (i) - int i; - { - switch (flag_pic) - { - case 1: - if (GET_CODE (recog_operand[i]) == SYMBOL_REF - || (GET_CODE (recog_operand[i]) == CONST - && ! rtx_equal_p (pic_pc_rtx, recog_operand[i]))) - abort (); - case 2: - default: - return 1; - } - } - - /* Return true if X is an address which needs a temporary register when - reloaded while generating PIC code. */ - - int - pic_address_needs_scratch (x) - rtx x; - { - /* An address which is a symbolic plus a non SMALL_INT needs a temp reg. */ - if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS - && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF - && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT - && ! SMALL_INT (XEXP (XEXP (x, 0), 1))) - return 1; - - return 0; - } int --- 274,277 ---- *************** *** 433,436 **** --- 410,426 ---- } + /* Return true if OP is a register, or is a CONST_INT that can fit in a 5 + bit unsigned immediate field. This is an acceptable SImode operand for + the count field of shift instructions. */ + + int + shift_operand (op, mode) + rtx op; + enum machine_mode mode; + { + return (register_operand (op, mode) + || (GET_CODE (op) == CONST_INT && (unsigned) (INTVAL (op)) < 32)); + } + /* Return truth value of whether OP is a integer which fits the range constraining immediate operands in most three-address insns, *************** *** 445,448 **** --- 435,468 ---- } + /* Recognize operand values for the umul instruction. That instruction sign + extends immediate values just like all other sparc instructions, but + interprets the extended result as an unsigned number. */ + + int + uns_small_int (op, mode) + rtx op; + enum machine_mode mode; + { + #if HOST_BITS_PER_WIDE_INT > 32 + /* All allowed constants will fit a CONST_INT. */ + return (GET_CODE (op) == CONST_INT + && ((INTVAL (op) >= 0 && INTVAL (op) < 0x1000) + || (INTVAL (op) >= 0xFFFFF000 && INTVAL (op) < 0x100000000L))); + #else + return ((GET_CODE (op) == CONST_INT && (unsigned) INTVAL (op) < 0x1000) + || (GET_CODE (op) == CONST_DOUBLE + && CONST_DOUBLE_HIGH (op) == 0 + && (unsigned) CONST_DOUBLE_LOW (op) - 0xFFFFF000 < 0x1000)); + #endif + } + + int + uns_arith_operand (op, mode) + rtx op; + enum machine_mode mode; + { + return register_operand (op, mode) || uns_small_int (op, mode); + } + /* Return truth value of statement that OP is a call-clobbered register. */ int *************** *** 594,609 **** } /* Legitimize PIC addresses. If the address is already position-independent, we return ORIG. Newly generated position-independent addresses go into a reg. This is REG if non zero, otherwise we allocate register(s) as ! necessary. If this is called during reload, and we need a second temp ! register, then we use SCRATCH, which is provided via the ! SECONDARY_INPUT_RELOAD_CLASS mechanism. */ rtx ! legitimize_pic_address (orig, mode, reg, scratch) rtx orig; enum machine_mode mode; ! rtx reg, scratch; { if (GET_CODE (orig) == SYMBOL_REF) --- 614,667 ---- } + /* The rtx for the global offset table which is a special form + that *is* a position independent symbolic constant. */ + static rtx pic_pc_rtx; + + /* Ensure that we are not using patterns that are not OK with PIC. */ + + int + check_pic (i) + int i; + { + switch (flag_pic) + { + case 1: + if (GET_CODE (recog_operand[i]) == SYMBOL_REF + || (GET_CODE (recog_operand[i]) == CONST + && ! rtx_equal_p (pic_pc_rtx, recog_operand[i]))) + abort (); + case 2: + default: + return 1; + } + } + + /* Return true if X is an address which needs a temporary register when + reloaded while generating PIC code. */ + + int + pic_address_needs_scratch (x) + rtx x; + { + /* An address which is a symbolic plus a non SMALL_INT needs a temp reg. */ + if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS + && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF + && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT + && ! SMALL_INT (XEXP (XEXP (x, 0), 1))) + return 1; + + return 0; + } + /* Legitimize PIC addresses. If the address is already position-independent, we return ORIG. Newly generated position-independent addresses go into a reg. This is REG if non zero, otherwise we allocate register(s) as ! necessary. */ rtx ! legitimize_pic_address (orig, mode, reg) rtx orig; enum machine_mode mode; ! rtx reg; { if (GET_CODE (orig) == SYMBOL_REF) *************** *** 677,684 **** if (GET_CODE (XEXP (orig, 0)) == PLUS) { ! base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, ! reg, 0); offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode, ! base == reg ? 0 : reg, 0); } else --- 735,741 ---- if (GET_CODE (XEXP (orig, 0)) == PLUS) { ! base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg); offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode, ! base == reg ? 0 : reg); } else *************** *** 691,705 **** else if (! reload_in_progress && ! reload_completed) offset = force_reg (Pmode, offset); - /* We can't create any new registers during reload, so use the - SCRATCH reg provided by the reload_insi pattern. */ - else if (scratch) - { - emit_move_insn (scratch, offset); - offset = scratch; - } else ! /* If we reach here, then the SECONDARY_INPUT_RELOAD_CLASS ! macro needs to be adjusted so that a scratch reg is provided ! for this address. */ abort (); } --- 748,753 ---- else if (! reload_in_progress && ! reload_completed) offset = force_reg (Pmode, offset); else ! /* If we reach here, then something is seriously wrong. */ abort (); } *************** *** 824,837 **** Return 1 if we have written out everything that needs to be done to do the move. Otherwise, return 0 and the caller will emit the move ! normally. - SCRATCH_REG if non zero can be used as a scratch register for the move - operation. It is provided by a SECONDARY_RELOAD_* macro if needed. */ - int ! emit_move_sequence (operands, mode, scratch_reg) rtx *operands; enum machine_mode mode; - rtx scratch_reg; { register rtx operand0 = operands[0]; --- 872,881 ---- Return 1 if we have written out everything that needs to be done to do the move. Otherwise, return 0 and the caller will emit the move ! normally. */ int ! emit_move_sequence (operands, mode) rtx *operands; enum machine_mode mode; { register rtx operand0 = operands[0]; *************** *** 838,841 **** --- 882,889 ---- register rtx operand1 = operands[1]; + if (CONSTANT_P (operand1) && flag_pic + && pic_address_needs_scratch (operand1)) + operands[1] = operand1 = legitimize_pic_address (operand1, mode, 0); + /* Handle most common case first: storing into a register. */ if (register_operand (operand0, mode)) *************** *** 878,883 **** rtx temp_reg = reload_in_progress ? operand0 : 0; ! operands[1] = legitimize_pic_address (operand1, mode, temp_reg, ! scratch_reg); } else if (GET_CODE (operand1) == CONST_INT --- 926,930 ---- rtx temp_reg = reload_in_progress ? operand0 : 0; ! operands[1] = legitimize_pic_address (operand1, mode, temp_reg); } else if (GET_CODE (operand1) == CONST_INT *************** *** 947,953 **** else if (GET_CODE (operands[1]) == CONST_DOUBLE) { ! int i; ! union real_extract u; ! union float_extract { float f; int i; } v; /* Must be SFmode, otherwise this doesn't make sense. */ --- 994,999 ---- else if (GET_CODE (operands[1]) == CONST_DOUBLE) { ! REAL_VALUE_TYPE r; ! long i; /* Must be SFmode, otherwise this doesn't make sense. */ *************** *** 955,962 **** abort (); ! bcopy (&CONST_DOUBLE_LOW (operands[1]), &u, sizeof u); ! v.f = REAL_VALUE_TRUNCATE (SFmode, u.d); ! i = v.i; ! operands[1] = gen_rtx (CONST_INT, VOIDmode, i); --- 1001,1006 ---- abort (); ! REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); ! REAL_VALUE_TO_TARGET_SINGLE (r, i); operands[1] = gen_rtx (CONST_INT, VOIDmode, i); *************** *** 1062,1065 **** --- 1106,1111 ---- rtx addreg0 = 0; rtx addreg1 = 0; + int highest_first = 0; + int no_addreg1_decrement = 0; /* First classify both operands. */ *************** *** 1157,1171 **** && reg_overlap_mentioned_p (op0, op1)) { ! /* ??? This fails if the address is a double register address, each ! of which is clobbered by operand 0. */ ! /* 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. */ --- 1203,1240 ---- && reg_overlap_mentioned_p (op0, op1)) { ! /* If both halves of dest are used in the src memory address, ! add the two regs and put them in the low reg (op0). ! Then it works to load latehalf first. */ ! if (reg_mentioned_p (op0, XEXP (op1, 0)) ! && reg_mentioned_p (latehalf[0], XEXP (op1, 0))) ! { ! rtx xops[2]; ! xops[0] = latehalf[0]; ! xops[1] = op0; ! output_asm_insn ("add %1,%0,%1", xops); ! operands[1] = gen_rtx (MEM, DImode, op0); ! latehalf[1] = adj_offsettable_operand (operands[1], 4); ! addreg1 = 0; ! highest_first = 1; ! } ! /* Only one register in the dest is used in the src memory address, ! and this is the first register of the dest, so we want to do ! the late half first here also. */ ! else if (! reg_mentioned_p (latehalf[0], XEXP (op1, 0))) ! highest_first = 1; ! /* Only one register in the dest is used in the src memory address, ! and this is the second register of the dest, so we want to do ! the late half last. If addreg1 is set, and addreg1 is the same ! register as latehalf, then we must suppress the trailing decrement, ! because it would clobber the value just loaded. */ ! else if (addreg1 && reg_mentioned_p (addreg1, latehalf[0])) ! no_addreg1_decrement = 1; } ! /* Normal case: do the two words, low-numbered first. ! Overlap case (highest_first set): do high-numbered word first. */ ! if (! highest_first) ! output_asm_insn (singlemove_string (operands), operands); /* Make any unoffsettable addresses point at high-numbered word. */ *************** *** 1181,1187 **** if (addreg0) output_asm_insn ("add %0,-0x4,%0", &addreg0); ! if (addreg1) output_asm_insn ("add %0,-0x4,%0", &addreg1); return ""; } --- 1250,1259 ---- if (addreg0) output_asm_insn ("add %0,-0x4,%0", &addreg0); ! if (addreg1 && ! no_addreg1_decrement) output_asm_insn ("add %0,-0x4,%0", &addreg1); + if (highest_first) + output_asm_insn (singlemove_string (operands), operands); + return ""; } *************** *** 1283,1295 **** else if (optype1 == CNSTOP) { ! /* This case isn't implemented yet, because there is no internal ! representation for quad-word constants, and there is no split_quad ! function. */ ! #if 0 ! split_quad (op1, &wordpart[0][1], &wordpart[1][1], ! &wordpart[2][1], &wordpart[3][1]); ! #else ! abort (); ! #endif } else --- 1355,1372 ---- else if (optype1 == CNSTOP) { ! REAL_VALUE_TYPE r; ! long l[4]; ! ! /* This only works for TFmode floating point constants. */ ! if (GET_CODE (op1) != CONST_DOUBLE || GET_MODE (op1) != TFmode) ! abort (); ! ! REAL_VALUE_FROM_CONST_DOUBLE (r, op1); ! REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l); ! ! wordpart[0][1] = GEN_INT (l[0]); ! wordpart[1][1] = GEN_INT (l[1]); ! wordpart[2][1] = GEN_INT (l[2]); ! wordpart[3][1] = GEN_INT (l[3]); } else *************** *** 1482,1485 **** --- 1559,1564 ---- } + #if 0 /* not currently used */ + void output_sized_memop (opname, mode, signedp) *************** *** 1516,1519 **** --- 1595,1599 ---- abort (); } + #endif /* not currently used */ #if 0 *************** *** 2890,2893 **** --- 2970,2981 ---- case INTEGER_TYPE: + /* If this is a range type, consider it to be the underlying + type. */ + if (TREE_TYPE (type) != 0) + { + type = TREE_TYPE (type); + break; + } + /* Carefully distinguish all the standard types of C, without messing up if the language is not C. *************** *** 2973,2979 **** case BOOLEAN_TYPE: /* GNU Fortran BOOLEAN type. */ case FILE_TYPE: /* GNU Pascal FILE type. */ ! case STRING_TYPE: /* GNU Fortran STRING type. */ case LANG_TYPE: /* ? */ ! abort (); default: --- 3061,3068 ---- case BOOLEAN_TYPE: /* GNU Fortran BOOLEAN type. */ case FILE_TYPE: /* GNU Pascal FILE type. */ ! case STRING_TYPE: /* GNU Fortran STRING type. */ ! case SET_TYPE: /* GNU Pascal SET type. */ case LANG_TYPE: /* ? */ ! return qualifiers; default: *************** *** 3225,3229 **** || (regno == FRAME_POINTER_REGNUM && frame_pointer_needed)) { ! if ((regno & 0x1) == 0 && ((mask & (1L << regno+1)) != 0)) { if (gp_offset % 8 != 0) --- 3314,3318 ---- || (regno == FRAME_POINTER_REGNUM && frame_pointer_needed)) { ! if ((regno & 0x1) == 0 && ((mask & (1L << (regno+1))) != 0)) { if (gp_offset % 8 != 0) diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/sparc/sparc.h gcc-2.5.0/config/sparc/sparc.h *** gcc-2.4.5/config/sparc/sparc.h Tue Jun 8 14:47:11 1993 --- gcc-2.5.0/config/sparc/sparc.h Wed Oct 20 18:21:25 1993 *************** *** 35,39 **** /* Define macros to distinguish architectures. */ ! #define CPP_SPEC "%{msparclite:-D__sparclite__} %{mv8:-D__sparc_v8__}" /* Prevent error on `-sun4' and `-target sun4' options. */ --- 35,40 ---- /* Define macros to distinguish architectures. */ ! #define CPP_SPEC "%{msparclite:-D__sparclite__} %{mf930:-D__sparclite__} \ ! %{mf934:-D__sparclite__} %{mv8:-D__sparc_v8__}" /* Prevent error on `-sun4' and `-target sun4' options. */ *************** *** 43,57 **** #define CC1_SPEC "%{sun4:} %{target:}" - #if 0 - /* ??? This fails because REAL_VALUE_TYPE is `double' making it impossible to - represent and output `long double' constants. This causes problems during - a bootstrap with enquire/float.h, and hence must be disabled for now. - To fix, we need to implement code for TFmode just like the existing XFmode - support in real.[ch]. */ - /* Sparc ABI says that long double is 4 words. */ - - #define LONG_DOUBLE_TYPE_SIZE 128 - #endif - #define PTRDIFF_TYPE "int" /* In 2.4 it should work to delete this. --- 44,47 ---- *************** *** 75,80 **** #define OVERRIDE_OPTIONS \ ! do { if (profile_flag || profile_block_flag) \ ! flag_omit_frame_pointer = 0, flag_pic = 0; } while (0) /* These compiler options take an argument. We ignore -target for now. */ --- 65,76 ---- #define OVERRIDE_OPTIONS \ ! { \ ! if (profile_flag || profile_block_flag) \ ! flag_omit_frame_pointer = 0, flag_pic = 0; \ ! SUBTARGET_OVERRIDE_OPTIONS \ ! } ! ! /* This is meant to be redefined in the host dependent files */ ! #define SUBTARGET_OVERRIDE_OPTIONS /* These compiler options take an argument. We ignore -target for now. */ *************** *** 91,95 **** wrong varargs file when it is compiled with a different version of gcc. */ ! #define CPP_PREDEFINES "-Dsparc -Dsun -Dunix -D__GCC_NEW_VARARGS__" /* Print subsidiary information on the compiler version in use. */ --- 87,93 ---- wrong varargs file when it is compiled with a different version of gcc. */ ! #define CPP_PREDEFINES \ ! "-Dsparc -Dsun -Dunix -D__GCC_NEW_VARARGS__ \ ! -Asystem(unix) -Asystem(bsd) -Acpu(sparc) -Amachine(sparc)" /* Print subsidiary information on the compiler version in use. */ *************** *** 120,124 **** #define TARGET_V8 (target_flags & 64) ! /* Nonzero means that we should generate code for a sparclite. */ #define TARGET_SPARCLITE (target_flags & 128) --- 118,124 ---- #define TARGET_V8 (target_flags & 64) ! /* Nonzero means that we should generate code for a sparclite. ! This enables the sparclite specific instructions, but does not affect ! whether FPU instructions are emitted. */ #define TARGET_SPARCLITE (target_flags & 128) *************** *** 145,148 **** --- 145,153 ---- An empty string NAME is used to identify the default VALUE. */ + /* The Fujitsu MB86930 is the original sparclite chip, with no fpu. + The Fujitsu MB86934 is the recent sparclite chip, with an fup. + We use -mf930 and -mf934 options to choose which. + ??? These should perhaps be -mcpu= options. */ + #define TARGET_SWITCHES \ { {"fpu", 1}, \ *************** *** 157,163 **** {"no-v8", -64}, \ {"sparclite", 128}, \ - {"sparclite", -1}, \ {"no-sparclite", -128}, \ - {"no-sparclite", 1}, \ /* {"frw", 256}, */ \ /* {"no-frw", -256}, */ \ --- 162,166 ---- *************** *** 164,173 **** --- 167,191 ---- /* {"frw-compat", 256+512}, */ \ /* {"no-frw-compat", -(256+512)}, */ \ + {"f930", 128}, \ + {"f930", -1}, \ + {"f934", 128}, \ + SUBTARGET_SWITCHES \ { "", TARGET_DEFAULT}} #define TARGET_DEFAULT 3 + + /* This is meant to be redefined in the host dependent files */ + #define SUBTARGET_SWITCHES /* target machine storage layout */ + /* Define for support of TFmode long double and REAL_ARITHMETIC. + Sparc ABI says that long double is 4 words. */ + #define LONG_DOUBLE_TYPE_SIZE 128 + + /* Define for cross-compilation to a sparc target with no TFmode from a host + with a different float format (e.g. VAX). */ + #define REAL_ARITHMETIC + /* Define this if most significant bit is lowest numbered in instructions that operate on numbered bit-fields. */ *************** *** 513,517 **** We put %f0/%f1 last among the float registers, so as to make it more ! likely that a pseduo-register which dies in the float return register will get allocated to the float return register, thus saving a move instruction at the end of the function. */ --- 531,535 ---- We put %f0/%f1 last among the float registers, so as to make it more ! likely that a pseudo-register which dies in the float return register will get allocated to the float return register, thus saving a move instruction at the end of the function. */ *************** *** 590,595 **** #define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \ ! ((C) == 'G' ? CONST_DOUBLE_HIGH (VALUE) == 0 \ ! && CONST_DOUBLE_LOW (VALUE) == 0 \ : (C) == 'H' ? arith_double_operand (VALUE, DImode) \ : 0) --- 608,612 ---- #define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \ ! ((C) == 'G' ? fp_zero_operand (VALUE) \ : (C) == 'H' ? arith_double_operand (VALUE, DImode) \ : 0) *************** *** 620,625 **** #define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, IN) \ ! (flag_pic && pic_address_needs_scratch (IN) ? GENERAL_REGS \ ! : ((CLASS) == FP_REGS && ((MODE) == HImode || (MODE) == QImode)\ && (GET_CODE (IN) == MEM \ || ((GET_CODE (IN) == REG || GET_CODE (IN) == SUBREG) \ --- 637,641 ---- #define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, IN) \ ! (((CLASS) == FP_REGS && ((MODE) == HImode || (MODE) == QImode)\ && (GET_CODE (IN) == MEM \ || ((GET_CODE (IN) == REG || GET_CODE (IN) == SUBREG) \ *************** *** 640,644 **** /* Return the stack location to use for secondary memory needed reloads. */ #define SECONDARY_MEMORY_NEEDED_RTX(MODE) \ ! gen_rtx (MEM, MODE, gen_rtx (PLUS, Pmode, frame_pointer_rtx, GEN_INT (-8))) /* Return the maximum number of consecutive registers --- 656,661 ---- /* Return the stack location to use for secondary memory needed reloads. */ #define SECONDARY_MEMORY_NEEDED_RTX(MODE) \ ! gen_rtx (MEM, MODE, gen_rtx (PLUS, Pmode, frame_pointer_rtx, \ ! GEN_INT (STARTING_FRAME_OFFSET))) /* Return the maximum number of consecutive registers *************** *** 668,672 **** 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, --- 685,690 ---- first local allocated. Otherwise, it is the offset to the BEGINNING of the first local allocated. */ ! /* This is 16 to allow space for one TFmode floating point value. */ ! #define STARTING_FRAME_OFFSET (-16) /* If we generate an insn to push BYTES bytes, *************** *** 880,887 **** } while (0) - /* Two views of the size of the current frame. */ - extern int actual_fsize; - extern int apparent_fsize; - /* This macro generates the assembly code for function entry. FILE is a stdio stream to output the code to. --- 898,901 ---- *************** *** 972,976 **** (TARGET_FRW ? sparc_frw_eligible_for_epilogue_delay (trial, slots_filled) \ : eligible_for_epilogue_delay (trial, slots_filled)) ! /* Output assembler code for a block containing the constant parts of a trampoline, leaving space for the variable parts. */ --- 986,990 ---- (TARGET_FRW ? sparc_frw_eligible_for_epilogue_delay (trial, slots_filled) \ : eligible_for_epilogue_delay (trial, slots_filled)) ! /* Output assembler code for a block containing the constant parts of a trampoline, leaving space for the variable parts. */ *************** *** 1002,1006 **** (to load in opcodes), 4 iors (to merge address and opcodes), and 4 writes (to store insns). This is a bit excessive. Perhaps a different ! mechanism would be better here. */ #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ --- 1016,1023 ---- (to load in opcodes), 4 iors (to merge address and opcodes), and 4 writes (to store insns). This is a bit excessive. Perhaps a different ! mechanism would be better here. ! ! Emit 3 FLUSH instructions (UNSPEC_VOLATILE 2) to synchonize the data ! and instruction caches. */ #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ *************** *** 1033,1038 **** emit_insn (gen_iorsi3 (low_cxt, low_cxt, tem)); \ emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 16)), low_cxt);\ } ! /* Generate necessary RTL for __builtin_saveregs(). ARGLIST is the argument list; see expr.c. */ --- 1050,1064 ---- emit_insn (gen_iorsi3 (low_cxt, low_cxt, tem)); \ emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 16)), low_cxt);\ + emit_insn (gen_rtx (UNSPEC_VOLATILE, VOIDmode, \ + gen_rtvec (1, plus_constant (TRAMP, 0)), \ + 2)); \ + emit_insn (gen_rtx (UNSPEC_VOLATILE, VOIDmode, \ + gen_rtvec (1, plus_constant (TRAMP, 8)), \ + 2)); \ + emit_insn (gen_rtx (UNSPEC_VOLATILE, VOIDmode, \ + gen_rtvec (1, plus_constant (TRAMP, 16)), \ + 2)); \ } ! /* Generate necessary RTL for __builtin_saveregs(). ARGLIST is the argument list; see expr.c. */ *************** *** 1106,1115 **** #define MAX_REGS_PER_ADDRESS 2 ! /* Recognize any constant value that is a valid address. */ #define CONSTANT_ADDRESS_P(X) \ (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ ! || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \ ! || GET_CODE (X) == HIGH) /* Nonzero if the constant value X is a legitimate general operand. --- 1132,1149 ---- #define MAX_REGS_PER_ADDRESS 2 ! /* Recognize any constant value that is a valid address. ! When PIC, we do not accept an address that would require a scratch reg ! to load into a register. */ #define CONSTANT_ADDRESS_P(X) \ (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ ! || GET_CODE (X) == CONST_INT || GET_CODE (X) == HIGH \ ! || (GET_CODE (X) == CONST \ ! && ! (flag_pic && pic_address_needs_scratch (X)))) ! ! /* Define this, so that when PIC, reload won't try to reload invalid ! addresses which require two reload registers. */ ! ! #define LEGITIMATE_PIC_OPERAND_P(X) (! pic_address_needs_scratch (X)) /* Nonzero if the constant value X is a legitimate general operand. *************** *** 1158,1163 **** || (reload_in_progress && GET_CODE (OP) == REG \ && REGNO (OP) >= FIRST_PSEUDO_REGISTER)) \ - : (C) == 'S' \ - ? (CONSTANT_P (OP) || memory_address_p (Pmode, OP)) \ : (C) == 'T' \ ? (mem_aligned_8 (OP)) \ --- 1192,1195 ---- *************** *** 1179,1190 **** && reg_renumber[REGNO (OP)] < 0) \ : GET_CODE (OP) == MEM) \ - : (C) == 'S' \ - ? (CONSTANT_P (OP) \ - || (GET_CODE (OP) == REG && reg_renumber[REGNO (OP)] > 0) \ - || strict_memory_address_p (Pmode, OP)) \ : (C) == 'T' \ ! ? mem_aligned_8 (OP) && strict_memory_address_p (Pmode, OP) \ : (C) == 'U' \ ! ? register_ok_for_ldd (OP) : 0) #endif --- 1211,1221 ---- && reg_renumber[REGNO (OP)] < 0) \ : GET_CODE (OP) == MEM) \ : (C) == 'T' \ ! ? mem_aligned_8 (OP) && strict_memory_address_p (Pmode, XEXP (OP, 0)) \ : (C) == 'U' \ ! ? (GET_CODE (OP) == REG \ ! && (REGNO (OP) < FIRST_PSEUDO_REGISTER \ ! || reg_renumber[REGNO (OP)] > 0) \ ! && register_ok_for_ldd (OP)) : 0) #endif *************** *** 1228,1232 **** && GET_CODE (op1) != REG \ && GET_CODE (op1) != LO_SUM \ ! && GET_CODE (op1) != MEM) \ goto ADDR; \ } \ --- 1259,1265 ---- && GET_CODE (op1) != REG \ && GET_CODE (op1) != LO_SUM \ ! && GET_CODE (op1) != MEM \ ! && (GET_CODE (op1) != CONST_INT \ ! || SMALL_INT (op1))) \ goto ADDR; \ } \ *************** *** 1287,1291 **** if (sparc_x != (X) && memory_address_p (MODE, X)) \ goto WIN; \ ! if (flag_pic) (X) = legitimize_pic_address (X, MODE, 0, 0); \ else if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 1))) \ (X) = gen_rtx (PLUS, Pmode, XEXP (X, 0), \ --- 1320,1324 ---- if (sparc_x != (X) && memory_address_p (MODE, X)) \ goto WIN; \ ! if (flag_pic) (X) = legitimize_pic_address (X, MODE, 0); \ else if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 1))) \ (X) = gen_rtx (PLUS, Pmode, XEXP (X, 0), \ *************** *** 1339,1345 **** #endif /* 0 */ ! /* Define if normal loads of shorter-than-word items from memory clears ! the rest of the bigs in the register. */ ! #define BYTE_LOADS_ZERO_EXTEND /* Nonzero if access to memory by bytes is slow and undesirable. --- 1372,1384 ---- #endif /* 0 */ ! /* Define if operations between registers always perform the operation ! on the full register even if a narrower mode is specified. */ ! #define WORD_REGISTER_OPERATIONS ! ! /* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD ! will either zero-extend or sign-extend. The value of this macro should ! be the code that says which one of the two operations is implicitly ! done, NIL if none. */ ! #define LOAD_EXTEND_OP(MODE) ZERO_EXTEND /* Nonzero if access to memory by bytes is slow and undesirable. *************** *** 1357,1364 **** #define PROMOTE_PROTOTYPES ! /* 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 --- 1396,1402 ---- #define PROMOTE_PROTOTYPES ! /* Define this to be nonzero if shift instructions ignore all but the low-order ! few bits. */ ! #define SHIFT_COUNT_TRUNCATED 1 /* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits *************** *** 1393,1402 **** return the mode to be used for the comparison. For floating-point, CCFP[E]mode is used. CC_NOOVmode should be used when the first operand is a ! PLUS, MINUS, or NEG. CCmode should be used when no special processing is ! needed. */ #define SELECT_CC_MODE(OP,X,Y) \ (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \ ! ? ((OP == EQ || OP == NE) ? CCFPmode : CCFPEmode) \ ! : ((GET_CODE (X) == PLUS || GET_CODE (X) == MINUS || GET_CODE (X) == NEG) \ ? CC_NOOVmode : CCmode)) --- 1431,1441 ---- return the mode to be used for the comparison. For floating-point, CCFP[E]mode is used. CC_NOOVmode should be used when the first operand is a ! PLUS, MINUS, NEG, or ASHIFT. CCmode should be used when no special ! processing is needed. */ #define SELECT_CC_MODE(OP,X,Y) \ (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \ ! ? ((OP == EQ || OP == NE) ? CCFPmode : CCFPEmode) \ ! : ((GET_CODE (X) == PLUS || GET_CODE (X) == MINUS \ ! || GET_CODE (X) == NEG || GET_CODE (X) == ASHIFT) \ ? CC_NOOVmode : CCmode)) *************** *** 1602,1621 **** /* This is how to output an assembler line defining a `double' constant. */ - /* Assemblers (both gas 1.35 and as in 4.0.3) - seem to treat -0.0 as if it were 0.0. - They reject 99e9999, but accept inf. */ #define ASM_OUTPUT_DOUBLE(FILE,VALUE) \ { \ ! if (REAL_VALUE_ISINF (VALUE) \ ! || REAL_VALUE_ISNAN (VALUE) \ ! || REAL_VALUE_MINUS_ZERO (VALUE)) \ ! { \ ! long t[2]; \ ! REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t); \ ! fprintf (FILE, "\t%s\t0x%lx\n\t%s\t0x%lx\n", \ ! ASM_LONG, t[0], ASM_LONG, t[1]); \ ! } \ ! else \ ! fprintf (FILE, "\t.double 0r%.17g\n", VALUE); \ } --- 1641,1650 ---- /* This is how to output an assembler line defining a `double' constant. */ #define ASM_OUTPUT_DOUBLE(FILE,VALUE) \ { \ ! long t[2]; \ ! REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t); \ ! fprintf (FILE, "\t%s\t0x%lx\n\t%s\t0x%lx\n", \ ! ASM_LONG, t[0], ASM_LONG, t[1]); \ } *************** *** 1624,1638 **** #define ASM_OUTPUT_FLOAT(FILE,VALUE) \ { \ ! if (REAL_VALUE_ISINF (VALUE) \ ! || REAL_VALUE_ISNAN (VALUE) \ ! || REAL_VALUE_MINUS_ZERO (VALUE)) \ ! { \ ! long t; \ ! REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \ ! fprintf (FILE, "\t%s\t0x%lx\n", ASM_LONG, t); \ ! } \ ! else \ ! fprintf (FILE, "\t.single 0r%.9g\n", VALUE); \ ! } /* This is how to output an assembler line defining a `long double' --- 1653,1660 ---- #define ASM_OUTPUT_FLOAT(FILE,VALUE) \ { \ ! long t; \ ! REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \ ! fprintf (FILE, "\t%s\t0x%lx\n", ASM_LONG, t); \ ! } \ /* This is how to output an assembler line defining a `long double' diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/sparc/sparc.md gcc-2.5.0/config/sparc/sparc.md *** gcc-2.4.5/config/sparc/sparc.md Mon May 3 19:40:28 1993 --- gcc-2.5.0/config/sparc/sparc.md Wed Oct 20 18:21:35 1993 *************** *** 773,799 **** ;; Move instructions ! (define_expand "movsi" ! [(set (match_operand:SI 0 "general_operand" "") ! (match_operand:SI 1 "general_operand" ""))] "" " { ! if (emit_move_sequence (operands, SImode, NULL_RTX)) DONE; }") ! (define_expand "reload_insi" ! [(set (match_operand:SI 0 "register_operand" "=r") ! (match_operand:SI 1 "general_operand" "")) ! (clobber (match_operand:SI 2 "register_operand" "=&r"))] "" " { ! if (emit_move_sequence (operands, SImode, operands[2])) DONE; ! /* We don't want the clobber emitted, so handle this ourselves. */ ! emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); ! DONE; }") --- 773,866 ---- ;; Move instructions ! (define_expand "movqi" ! [(set (match_operand:QI 0 "general_operand" "") ! (match_operand:QI 1 "general_operand" ""))] "" " { ! if (emit_move_sequence (operands, QImode)) DONE; }") ! (define_insn "" ! [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q") ! (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))] ! "register_operand (operands[0], QImode) ! || register_operand (operands[1], QImode) ! || operands[1] == const0_rtx" ! "@ ! mov %1,%0 ! sethi %%hi(%a1),%0 ! ldub %1,%0 ! stb %r1,%0" ! [(set_attr "type" "move,move,load,store") ! (set_attr "length" "*,1,*,1")]) ! ! (define_insn "" ! [(set (match_operand:QI 0 "register_operand" "=r") ! (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r") ! (match_operand 2 "immediate_operand" "in")) 0))] ! "" ! "or %1,%%lo(%a2),%0" ! [(set_attr "length" "1")]) ! ! (define_insn "" ! [(set (mem:QI (match_operand:SI 0 "symbolic_operand" "")) ! (match_operand:QI 1 "reg_or_0_operand" "rJ")) ! (clobber (match_scratch:SI 2 "=&r"))] ! "" ! "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]" ! [(set_attr "type" "store") ! (set_attr "length" "2")]) ! ! (define_expand "movhi" ! [(set (match_operand:HI 0 "general_operand" "") ! (match_operand:HI 1 "general_operand" ""))] "" " { ! if (emit_move_sequence (operands, HImode)) DONE; + }") ! (define_insn "" ! [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q") ! (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))] ! "register_operand (operands[0], HImode) ! || register_operand (operands[1], HImode) ! || operands[1] == const0_rtx" ! "@ ! mov %1,%0 ! sethi %%hi(%a1),%0 ! lduh %1,%0 ! sth %r1,%0" ! [(set_attr "type" "move,move,load,store") ! (set_attr "length" "*,1,*,1")]) ! ! (define_insn "" ! [(set (match_operand:HI 0 "register_operand" "=r") ! (lo_sum:HI (match_operand:HI 1 "register_operand" "r") ! (match_operand 2 "immediate_operand" "in")))] ! "" ! "or %1,%%lo(%a2),%0" ! [(set_attr "length" "1")]) ! ! (define_insn "" ! [(set (mem:HI (match_operand:SI 0 "symbolic_operand" "")) ! (match_operand:HI 1 "reg_or_0_operand" "rJ")) ! (clobber (match_scratch:SI 2 "=&r"))] ! "" ! "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]" ! [(set_attr "type" "store") ! (set_attr "length" "2")]) ! ! (define_expand "movsi" ! [(set (match_operand:SI 0 "general_operand" "") ! (match_operand:SI 1 "general_operand" ""))] ! "" ! " ! { ! if (emit_move_sequence (operands, SImode)) ! DONE; }") *************** *** 899,919 **** (set_attr "length" "1")]) - (define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (lo_sum:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:DI 2 "immediate_operand" "in")))] - "" - "* - { - /* Don't output a 64 bit constant, since we can't trust the assembler to - handle it correctly. */ - if (GET_CODE (operands[2]) == CONST_DOUBLE) - operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2])); - return \"or %R1,%%lo(%a2),%R0\"; - }" - ;; Need to set length for this arith insn because operand2 - ;; is not an "arith_operand". - [(set_attr "length" "1")]) - ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't ;; confuse them with real addresses. --- 966,969 ---- *************** *** 928,931 **** --- 978,983 ---- [(set_attr "length" "1")]) + ;; ??? Can the next two be moved above the PIC stuff? + (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") *************** *** 947,957 **** (set_attr "length" "2")]) ! (define_expand "movhi" ! [(set (match_operand:HI 0 "general_operand" "") ! (match_operand:HI 1 "general_operand" ""))] "" " { ! if (emit_move_sequence (operands, HImode, NULL_RTX)) DONE; }") --- 999,1009 ---- (set_attr "length" "2")]) ! (define_expand "movdi" ! [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "") ! (match_operand:DI 1 "general_operand" ""))] "" " { ! if (emit_move_sequence (operands, DImode)) DONE; }") *************** *** 958,1031 **** (define_insn "" ! [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q") ! (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))] ! "register_operand (operands[0], HImode) ! || register_operand (operands[1], HImode) || operands[1] == const0_rtx" ! "@ ! mov %1,%0 ! sethi %%hi(%a1),%0 ! lduh %1,%0 ! sth %r1,%0" ! [(set_attr "type" "move,move,load,store") ! (set_attr "length" "*,1,*,1")]) ! ! (define_insn "" ! [(set (match_operand:HI 0 "register_operand" "=r") ! (lo_sum:HI (match_operand:HI 1 "register_operand" "r") ! (match_operand 2 "immediate_operand" "in")))] ! "" ! "or %1,%%lo(%a2),%0" ! [(set_attr "length" "1")]) ! ! (define_insn "" ! [(set (mem:HI (match_operand:SI 0 "symbolic_operand" "")) ! (match_operand:HI 1 "reg_or_0_operand" "rJ")) ! (clobber (match_scratch:SI 2 "=&r"))] ! "" ! "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]" ! [(set_attr "type" "store") ! (set_attr "length" "2")]) ! ! (define_expand "movqi" ! [(set (match_operand:QI 0 "general_operand" "") ! (match_operand:QI 1 "general_operand" ""))] ! "" ! " { ! if (emit_move_sequence (operands, QImode, NULL_RTX)) ! DONE; ! }") ! ! (define_insn "" ! [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q") ! (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))] ! "register_operand (operands[0], QImode) ! || register_operand (operands[1], QImode) ! || operands[1] == const0_rtx" ! "@ ! mov %1,%0 ! sethi %%hi(%a1),%0 ! ldub %1,%0 ! stb %r1,%0" ! [(set_attr "type" "move,move,load,store") ! (set_attr "length" "*,1,*,1")]) (define_insn "" ! [(set (match_operand:QI 0 "register_operand" "=r") ! (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r") ! (match_operand 2 "immediate_operand" "in")) 0))] "" ! "or %1,%%lo(%a2),%0" [(set_attr "length" "1")]) ! (define_insn "" ! [(set (mem:QI (match_operand:SI 0 "symbolic_operand" "")) ! (match_operand:QI 1 "reg_or_0_operand" "rJ")) ! (clobber (match_scratch:SI 2 "=&r"))] ! "" ! "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]" ! [(set_attr "type" "store") ! (set_attr "length" "2")]) ;; ??? We get better code without it. See output_block_move in sparc.c. --- 1010,1047 ---- (define_insn "" ! [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,Q,r,r,?f,?f,?Q") ! (match_operand:DI 1 "general_operand" "r,r,Q,i,f,Q,f"))] ! "register_operand (operands[0], DImode) ! || register_operand (operands[1], DImode) || operands[1] == const0_rtx" ! "* { ! if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) ! return output_fp_move_double (operands); ! return output_move_double (operands); ! }" ! [(set_attr "type" "move,store,load,multi,fp,fpload,fpstore") ! (set_attr "length" "2,3,3,3,2,3,3")]) (define_insn "" ! [(set (match_operand:DI 0 "register_operand" "=r") ! (lo_sum:DI (match_operand:DI 1 "register_operand" "0") ! (match_operand:DI 2 "immediate_operand" "in")))] "" ! "* ! { ! /* Don't output a 64 bit constant, since we can't trust the assembler to ! handle it correctly. */ ! if (GET_CODE (operands[2]) == CONST_DOUBLE) ! operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2])); ! return \"or %R1,%%lo(%a2),%R0\"; ! }" ! ;; Need to set length for this arith insn because operand2 ! ;; is not an "arith_operand". [(set_attr "length" "1")]) ! ;; ??? There's no symbolic (set (mem:DI ...) ...). ! ! ;; Block move insns. ;; ??? We get better code without it. See output_block_move in sparc.c. *************** *** 1078,1087 **** ;; Floating point move insns ! ;; This pattern forces (set (reg:TF ...) (const_double ...)) ;; to be reloaded by putting the constant into memory. ! ;; It must come before the more general movtf pattern. (define_insn "" ! [(set (match_operand:TF 0 "general_operand" "=?r,f,o") ! (match_operand:TF 1 "" "?E,m,G"))] "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE" "* --- 1094,1103 ---- ;; Floating point move insns ! ;; This pattern forces (set (reg:SF ...) (const_double ...)) ;; to be reloaded by putting the constant into memory. ! ;; It must come before the more general movsf pattern. (define_insn "" ! [(set (match_operand:SF 0 "general_operand" "=?r,f,m") ! (match_operand:SF 1 "" "?E,m,G"))] "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE" "* *************** *** 1090,1113 **** { case 0: ! return output_move_quad (operands); case 1: ! return output_fp_move_quad (operands); case 2: ! operands[1] = adj_offsettable_operand (operands[0], 4); ! operands[2] = adj_offsettable_operand (operands[0], 8); ! operands[3] = adj_offsettable_operand (operands[0], 12); ! return \"st %%g0,%0\;st %%g0,%1\;st %%g0,%2\;st %%g0,%3\"; } }" [(set_attr "type" "load,fpload,store") ! (set_attr "length" "5,5,5")]) ! (define_expand "movtf" ! [(set (match_operand:TF 0 "general_operand" "") ! (match_operand:TF 1 "general_operand" ""))] "" " { ! if (emit_move_sequence (operands, TFmode, NULL_RTX)) DONE; }") --- 1106,1126 ---- { case 0: ! return singlemove_string (operands); case 1: ! return \"ld %1,%0\"; case 2: ! return \"st %%g0,%0\"; } }" [(set_attr "type" "load,fpload,store") ! (set_attr "length" "2,1,1")]) ! (define_expand "movsf" ! [(set (match_operand:SF 0 "general_operand" "") ! (match_operand:SF 1 "general_operand" ""))] "" " { ! if (emit_move_sequence (operands, SFmode)) DONE; }") *************** *** 1114,1130 **** (define_insn "" ! [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=f,r,Q,Q,f,&r") ! (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "f,r,f,r,Q,Q"))] "TARGET_FPU ! && (register_operand (operands[0], TFmode) ! || register_operand (operands[1], TFmode))" ! "* ! { ! if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) ! return output_fp_move_quad (operands); ! return output_move_quad (operands); ! }" ! [(set_attr "type" "fp,move,fpstore,store,fpload,load") ! (set_attr "length" "4,4,5,5,5,5")]) ;; Exactly the same as above, except that all `f' cases are deleted. --- 1127,1143 ---- (define_insn "" ! [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,f,r,Q,Q") ! (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,Q,Q,f,r"))] "TARGET_FPU ! && (register_operand (operands[0], SFmode) ! || register_operand (operands[1], SFmode))" ! "@ ! fmovs %1,%0 ! mov %1,%0 ! ld %1,%0 ! ld %1,%0 ! st %r1,%0 ! st %r1,%0" ! [(set_attr "type" "fp,move,fpload,load,fpstore,store")]) ;; Exactly the same as above, except that all `f' cases are deleted. *************** *** 1133,1166 **** (define_insn "" ! [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r") ! (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "r,r,Q"))] "! TARGET_FPU ! && (register_operand (operands[0], TFmode) ! || register_operand (operands[1], TFmode))" ! "* ! { ! if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) ! return output_fp_move_quad (operands); ! return output_move_quad (operands); ! }" ! [(set_attr "type" "move,store,load") ! (set_attr "length" "4,5,5")]) (define_insn "" ! [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i")) ! (match_operand:TF 1 "reg_or_0_operand" "rf,G")) ! (clobber (match_scratch:SI 2 "=&r,&r"))] "" ! "* ! { ! output_asm_insn (\"sethi %%hi(%a0),%2\", operands); ! if (which_alternative == 0) ! return \"std %1,[%2+%%lo(%a0)]\;std %S1,[%2+%%lo(%a0+8)]\"; ! else ! return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\; st %%g0,[%2+%%lo(%a0+8)]\;st %%g0,[%2+%%lo(%a0+12)]\"; ! }" [(set_attr "type" "store") ! (set_attr "length" "5")]) ! ;; This pattern forces (set (reg:DF ...) (const_double ...)) ;; to be reloaded by putting the constant into memory. --- 1146,1169 ---- (define_insn "" ! [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=r,r,Q") ! (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "r,Q,r"))] "! TARGET_FPU ! && (register_operand (operands[0], SFmode) ! || register_operand (operands[1], SFmode))" ! "@ ! mov %1,%0 ! ld %1,%0 ! st %r1,%0" ! [(set_attr "type" "move,load,store")]) (define_insn "" ! [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i")) ! (match_operand:SF 1 "reg_or_0_operand" "rfG")) ! (clobber (match_scratch:SI 2 "=&r"))] "" ! "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]" [(set_attr "type" "store") ! (set_attr "length" "2")]) ! ;; This pattern forces (set (reg:DF ...) (const_double ...)) ;; to be reloaded by putting the constant into memory. *************** *** 1193,1197 **** " { ! if (emit_move_sequence (operands, DFmode, NULL_RTX)) DONE; }") --- 1196,1200 ---- " { ! if (emit_move_sequence (operands, DFmode)) DONE; }") *************** *** 1198,1202 **** (define_insn "" ! [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,f,r,Q,Q,f,&r") (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,f,r,f,r,Q,Q"))] "TARGET_FPU --- 1201,1205 ---- (define_insn "" ! [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,f,r,Q,Q,f,r") (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,f,r,f,r,Q,Q"))] "TARGET_FPU *************** *** 1253,1292 **** [(set_attr "type" "store") (set_attr "length" "3")]) - - ;; Double-word move insns. - - (define_expand "movdi" - [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "") - (match_operand:DI 1 "general_operand" ""))] - "" - " - { - if (emit_move_sequence (operands, DImode, NULL_RTX)) - DONE; - }") - - (define_insn "" - [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r,&r,?f,?f,?Q") - (match_operand:DI 1 "general_operand" "r,r,Q,i,f,Q,f"))] - "register_operand (operands[0], DImode) - || register_operand (operands[1], DImode) - || operands[1] == const0_rtx" - "* - { - if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) - return output_fp_move_double (operands); - return output_move_double (operands); - }" - [(set_attr "type" "move,store,load,multi,fp,fpload,fpstore") - (set_attr "length" "2,3,3,3,2,3,3")]) - - ;; Floating-point move insns. ! ;; This pattern forces (set (reg:SF ...) (const_double ...)) ;; to be reloaded by putting the constant into memory. ! ;; It must come before the more general movsf pattern. (define_insn "" ! [(set (match_operand:SF 0 "general_operand" "=?r,f,m") ! (match_operand:SF 1 "" "?E,m,G"))] "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE" "* --- 1256,1266 ---- [(set_attr "type" "store") (set_attr "length" "3")]) ! ;; This pattern forces (set (reg:TF ...) (const_double ...)) ;; to be reloaded by putting the constant into memory. ! ;; It must come before the more general movtf pattern. (define_insn "" ! [(set (match_operand:TF 0 "general_operand" "=?r,f,o") ! (match_operand:TF 1 "" "?E,m,G"))] "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE" "* *************** *** 1295,1315 **** { case 0: ! return singlemove_string (operands); case 1: ! return \"ld %1,%0\"; case 2: ! return \"st %%g0,%0\"; } }" [(set_attr "type" "load,fpload,store") ! (set_attr "length" "2,1,1")]) ! (define_expand "movsf" ! [(set (match_operand:SF 0 "general_operand" "") ! (match_operand:SF 1 "general_operand" ""))] "" " { ! if (emit_move_sequence (operands, SFmode, NULL_RTX)) DONE; }") --- 1269,1292 ---- { case 0: ! return output_move_quad (operands); case 1: ! return output_fp_move_quad (operands); case 2: ! operands[1] = adj_offsettable_operand (operands[0], 4); ! operands[2] = adj_offsettable_operand (operands[0], 8); ! operands[3] = adj_offsettable_operand (operands[0], 12); ! return \"st %%g0,%0\;st %%g0,%1\;st %%g0,%2\;st %%g0,%3\"; } }" [(set_attr "type" "load,fpload,store") ! (set_attr "length" "5,5,5")]) ! (define_expand "movtf" ! [(set (match_operand:TF 0 "general_operand" "") ! (match_operand:TF 1 "general_operand" ""))] "" " { ! if (emit_move_sequence (operands, TFmode)) DONE; }") *************** *** 1316,1332 **** (define_insn "" ! [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,f,r,Q,Q") ! (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,Q,Q,f,r"))] "TARGET_FPU ! && (register_operand (operands[0], SFmode) ! || register_operand (operands[1], SFmode))" ! "@ ! fmovs %1,%0 ! mov %1,%0 ! ld %1,%0 ! ld %1,%0 ! st %r1,%0 ! st %r1,%0" ! [(set_attr "type" "fp,move,fpload,load,fpstore,store")]) ;; Exactly the same as above, except that all `f' cases are deleted. --- 1293,1309 ---- (define_insn "" ! [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=f,r,Q,Q,f,&r") ! (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "f,r,f,r,Q,Q"))] "TARGET_FPU ! && (register_operand (operands[0], TFmode) ! || register_operand (operands[1], TFmode))" ! "* ! { ! if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) ! return output_fp_move_quad (operands); ! return output_move_quad (operands); ! }" ! [(set_attr "type" "fp,move,fpstore,store,fpload,load") ! (set_attr "length" "4,4,5,5,5,5")]) ;; Exactly the same as above, except that all `f' cases are deleted. *************** *** 1335,1357 **** (define_insn "" ! [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=r,r,Q") ! (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "r,Q,r"))] "! TARGET_FPU ! && (register_operand (operands[0], SFmode) ! || register_operand (operands[1], SFmode))" ! "@ ! mov %1,%0 ! ld %1,%0 ! st %r1,%0" ! [(set_attr "type" "move,load,store")]) (define_insn "" ! [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i")) ! (match_operand:SF 1 "reg_or_0_operand" "rfG")) ! (clobber (match_scratch:SI 2 "=&r"))] "" ! "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]" [(set_attr "type" "store") ! (set_attr "length" "2")]) ;;- zero extension instructions --- 1312,1344 ---- (define_insn "" ! [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r") ! (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "r,r,Q"))] "! TARGET_FPU ! && (register_operand (operands[0], TFmode) ! || register_operand (operands[1], TFmode))" ! "* ! { ! if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) ! return output_fp_move_quad (operands); ! return output_move_quad (operands); ! }" ! [(set_attr "type" "move,store,load") ! (set_attr "length" "4,5,5")]) (define_insn "" ! [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i")) ! (match_operand:TF 1 "reg_or_0_operand" "rf,G")) ! (clobber (match_scratch:SI 2 "=&r,&r"))] "" ! "* ! { ! output_asm_insn (\"sethi %%hi(%a0),%2\", operands); ! if (which_alternative == 0) ! return \"std %1,[%2+%%lo(%a0)]\;std %S1,[%2+%%lo(%a0+8)]\"; ! else ! return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\; st %%g0,[%2+%%lo(%a0+8)]\;st %%g0,[%2+%%lo(%a0+12)]\"; ! }" [(set_attr "type" "store") ! (set_attr "length" "5")]) ;;- zero extension instructions *************** *** 1369,1377 **** rtx temp = gen_reg_rtx (SImode); rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16); if (GET_CODE (operand1) == SUBREG) ! operand1 = XEXP (operand1, 0); ! emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0), shift_16)); emit_insn (gen_lshrsi3 (operand0, temp, shift_16)); --- 1356,1369 ---- rtx temp = gen_reg_rtx (SImode); rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16); + int op1_subword = 0; if (GET_CODE (operand1) == SUBREG) ! { ! op1_subword = SUBREG_WORD (operand1); ! operand1 = XEXP (operand1, 0); ! } ! emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, ! op1_subword), shift_16)); emit_insn (gen_lshrsi3 (operand0, temp, shift_16)); *************** *** 1470,1478 **** rtx temp = gen_reg_rtx (SImode); rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16); if (GET_CODE (operand1) == SUBREG) ! operand1 = XEXP (operand1, 0); ! emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0), shift_16)); emit_insn (gen_ashrsi3 (operand0, temp, shift_16)); --- 1462,1475 ---- rtx temp = gen_reg_rtx (SImode); rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16); + int op1_subword = 0; if (GET_CODE (operand1) == SUBREG) ! { ! op1_subword = SUBREG_WORD (operand1); ! operand1 = XEXP (operand1, 0); ! } ! emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, ! op1_subword), shift_16)); emit_insn (gen_ashrsi3 (operand0, temp, shift_16)); *************** *** 1495,1507 **** rtx temp = gen_reg_rtx (SImode); rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24); if (GET_CODE (operand1) == SUBREG) ! operand1 = XEXP (operand1, 0); if (GET_CODE (operand0) == SUBREG) ! operand0 = XEXP (operand0, 0); ! emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0), shift_24)); if (GET_MODE (operand0) != SImode) ! operand0 = gen_rtx (SUBREG, SImode, operand0, 0); emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); DONE; --- 1492,1513 ---- rtx temp = gen_reg_rtx (SImode); rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24); + int op1_subword = 0; + int op0_subword = 0; if (GET_CODE (operand1) == SUBREG) ! { ! op1_subword = SUBREG_WORD (operand1); ! operand1 = XEXP (operand1, 0); ! } if (GET_CODE (operand0) == SUBREG) ! { ! op0_subword = SUBREG_WORD (operand0); ! operand0 = XEXP (operand0, 0); ! } ! emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, ! op1_subword), shift_24)); if (GET_MODE (operand0) != SImode) ! operand0 = gen_rtx (SUBREG, SImode, operand0, op0_subword); emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); DONE; *************** *** 1523,1530 **** rtx temp = gen_reg_rtx (SImode); rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24); if (GET_CODE (operand1) == SUBREG) ! operand1 = XEXP (operand1, 0); ! emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0), shift_24)); emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); --- 1529,1542 ---- rtx temp = gen_reg_rtx (SImode); rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24); + int op1_subword = 0; if (GET_CODE (operand1) == SUBREG) ! { ! op1_subword = SUBREG_WORD (operand1); ! operand1 = XEXP (operand1, 0); ! } ! ! emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, ! op1_subword), shift_24)); emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); *************** *** 1829,1833 **** [(set (match_operand:DI 0 "register_operand" "") (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) ! (zero_extend:DI (match_operand:SI 2 "arith_operand" ""))))] "TARGET_V8 || TARGET_SPARCLITE" " --- 1841,1845 ---- [(set (match_operand:DI 0 "register_operand" "") (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) ! (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))] "TARGET_V8 || TARGET_SPARCLITE" " *************** *** 1853,1857 **** [(set (match_operand:DI 0 "register_operand" "=r") (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) ! (match_operand:SI 2 "small_int" "I")))] "TARGET_V8 || TARGET_SPARCLITE" "umul %1,%2,%R0\;rd %%y,%0" --- 1865,1869 ---- [(set (match_operand:DI 0 "register_operand" "=r") (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) ! (match_operand:SI 2 "uns_small_int" "")))] "TARGET_V8 || TARGET_SPARCLITE" "umul %1,%2,%R0\;rd %%y,%0" *************** *** 1904,1909 **** "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0" [(set_attr "length" "5")]) ! ! ;;- and instructions ;; We define DImode `and` so with DImode `not` we can get ;; DImode `andn`. Other combinations are possible. --- 1916,1921 ---- "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0" [(set_attr "length" "5")]) ! ! ;;- Boolean instructions ;; We define DImode `and` so with DImode `not` we can get ;; DImode `andn`. Other combinations are possible. *************** *** 2511,2590 **** ;;- arithmetic shift instructions - ;; We can trivially handle shifting the constant 1 by 64 bits. - ;; For other shifts we use the library routine. - ;; ??? Questionable, we can do better than this can't we? - (define_expand "ashldi3" - [(parallel [(set (match_operand:DI 0 "register_operand" "") - (ashift:DI (match_operand:DI 1 "const_double_operand" "") - (match_operand:SI 2 "register_operand" ""))) - (clobber (reg:SI 0))])] - "" - " - { - if (GET_CODE (operands[1]) == CONST_DOUBLE - && CONST_DOUBLE_HIGH (operands[1]) == 0 - && CONST_DOUBLE_LOW (operands[1]) == 1) - operands[1] = const1_rtx; - else if (operands[1] != const1_rtx) - FAIL; - }") - - ;; ??? Questionable, we can do better than this can't we? - (define_insn "" - [(set (match_operand:DI 0 "register_operand" "=&r") - (ashift:DI (const_int 1) - (match_operand:SI 1 "register_operand" "r"))) - (clobber (reg:SI 0))] - "" - "subcc %1,32,%%g0\;addx %%g0,0,%R0\;xor %R0,1,%0\;sll %R0,%1,%R0\;sll %0,%1,%0" - [(set_attr "type" "multi") - (set_attr "length" "5")]) - (define_insn "ashlsi3" [(set (match_operand:SI 0 "register_operand" "=r") (ashift:SI (match_operand:SI 1 "register_operand" "r") ! (match_operand:SI 2 "arith_operand" "rI")))] "" "sll %1,%2,%0") - (define_expand "lshldi3" - [(parallel [(set (match_operand:DI 0 "register_operand" "") - (lshift:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "const_int_operand" ""))) - (clobber (match_scratch:SI 3 ""))])] - "" - " - { - if (GET_CODE (operands[2]) != CONST_INT) - FAIL; - }") - (define_insn "" ! [(set (match_operand:DI 0 "register_operand" "=r") ! (lshift:DI (match_operand:DI 1 "register_operand" "r") ! (match_operand:DI 2 "const_int_operand" "I"))) ! (clobber (match_scratch:SI 3 "=r"))] ! "INTVAL (operands[2]) < 32" ! "* ! { ! operands[4] = GEN_INT (32 - INTVAL (operands[2])); ! return \"srl %R1,%4,%3\;sll %R1,%2,%R0\;sll %1,%2,%0\;or %3,%0,%0\"; ! }" ! [(set_attr "type" "multi") ! (set_attr "length" "4")]) (define_insn "" ! [(set (match_operand:DI 0 "register_operand" "=r") ! (lshift:DI (match_operand:DI 1 "register_operand" "r") ! (match_operand:DI 2 "const_int_operand" "I"))) ! (clobber (match_scratch:SI 3 "=X"))] ! "INTVAL (operands[2]) >= 32" ! "* ! { ! operands[4] = GEN_INT (INTVAL (operands[2]) - 32); ! return \"sll %R1,%4,%0\;mov %%g0,%R0\"; ! }" ! [(set_attr "type" "multi") ! (set_attr "length" "2")]) (define_insn "ashrsi3" --- 2523,2551 ---- ;;- 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 "shift_operand" "rI")))] "" "sll %1,%2,%0") (define_insn "" ! [(set (reg:CC_NOOV 0) ! (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r") ! (const_int 1)) ! (const_int 0)))] ! "" ! "addcc %0,%0,%%g0" ! [(set_attr "type" "compare")]) (define_insn "" ! [(set (reg:CC_NOOV 0) ! (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r") ! (const_int 1)) ! (const_int 0))) ! (set (match_operand:SI 0 "register_operand" "=r") ! (ashift:SI (match_dup 1) (const_int 1)))] ! "" ! "addcc %1,%1,%0") (define_insn "ashrsi3" *************** *** 2591,2595 **** [(set (match_operand:SI 0 "register_operand" "=r") (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") ! (match_operand:SI 2 "arith_operand" "rI")))] "" "sra %1,%2,%0") --- 2552,2556 ---- [(set (match_operand:SI 0 "register_operand" "=r") (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") ! (match_operand:SI 2 "shift_operand" "rI")))] "" "sra %1,%2,%0") *************** *** 2598,2644 **** [(set (match_operand:SI 0 "register_operand" "=r") (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") ! (match_operand:SI 2 "arith_operand" "rI")))] "" "srl %1,%2,%0") - - (define_expand "lshrdi3" - [(parallel [(set (match_operand:DI 0 "register_operand" "") - (lshiftrt:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "const_int_operand" ""))) - (clobber (match_scratch:SI 3 ""))])] - "" - " - { - if (GET_CODE (operands[2]) != CONST_INT) - FAIL; - }") - - (define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") - (match_operand:DI 2 "const_int_operand" "I"))) - (clobber (match_scratch:SI 3 "=r"))] - "INTVAL (operands[2]) < 32" - "* - { - operands[4] = GEN_INT (32 - INTVAL (operands[2])); - return \"sll %1,%4,%3\;srl %1,%2,%0\;srl %R1,%2,%R0\;or %3,%R0,%R0\"; - }" - [(set_attr "type" "multi") - (set_attr "length" "4")]) - - (define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") - (match_operand:DI 2 "const_int_operand" "I"))) - (clobber (match_scratch:SI 3 "=X"))] - "INTVAL (operands[2]) >= 32" - "* - { - operands[4] = GEN_INT (INTVAL (operands[2]) - 32); - return \"srl %1,%4,%R0\;mov %%g0,%0\"; - }" - [(set_attr "type" "multi") - (set_attr "length" "2")]) ;; Unconditional and other jump instructions --- 2559,2565 ---- [(set (match_operand:SI 0 "register_operand" "=r") (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") ! (match_operand:SI 2 "shift_operand" "rI")))] "" "srl %1,%2,%0") ;; Unconditional and other jump instructions *************** *** 2776,2781 **** }") (define_insn "" ! [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r")) (match_operand 1 "" "")) (clobber (reg:SI 15))] --- 2697,2717 ---- }") + ;; We can't use the same pattern for these two insns, because then registers + ;; in the address may not be properly reloaded. + + (define_insn "" + [(call (mem:SI (match_operand:SI 0 "address_operand" "p")) + (match_operand 1 "" "")) + (clobber (reg:SI 15))] + ;;- Do not use operand 1 for most machines. + "" + "* + { + return \"call %a0,%1%#\"; + }" + [(set_attr "type" "call")]) + (define_insn "" ! [(call (mem:SI (match_operand:SI 0 "immediate_operand" "i")) (match_operand 1 "" "")) (clobber (reg:SI 15))] *************** *** 2790,2794 **** ;; This is a call that wants a structure value. (define_insn "" ! [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r")) (match_operand 1 "" "")) (match_operand 2 "immediate_operand" "") --- 2726,2744 ---- ;; This is a call that wants a structure value. (define_insn "" ! [(call (mem:SI (match_operand:SI 0 "address_operand" "p")) ! (match_operand 1 "" "")) ! (match_operand 2 "immediate_operand" "") ! (clobber (reg:SI 15))] ! ;;- Do not use operand 1 for most machines. ! "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0" ! "* ! { ! return \"call %a0,%1\;nop\;unimp %2\"; ! }" ! [(set_attr "type" "call_no_delay_slot")]) ! ! ;; This is a call that wants a structure value. ! (define_insn "" ! [(call (mem:SI (match_operand:SI 0 "immediate_operand" "i")) (match_operand 1 "" "")) (match_operand 2 "immediate_operand" "") *************** *** 2836,2840 **** (define_insn "" [(set (match_operand 0 "" "=rf") ! (call (mem:SI (match_operand:SI 1 "call_operand_address" "rS")) (match_operand 2 "" ""))) (clobber (reg:SI 15))] --- 2786,2803 ---- (define_insn "" [(set (match_operand 0 "" "=rf") ! (call (mem:SI (match_operand:SI 1 "address_operand" "p")) ! (match_operand 2 "" ""))) ! (clobber (reg:SI 15))] ! ;;- Do not use operand 2 for most machines. ! "" ! "* ! { ! return \"call %a1,%2%#\"; ! }" ! [(set_attr "type" "call")]) ! ! (define_insn "" ! [(set (match_operand 0 "" "=rf") ! (call (mem:SI (match_operand:SI 1 "immediate_operand" "i")) (match_operand 2 "" ""))) (clobber (reg:SI 15))] *************** *** 2863,2867 **** (define_insn "" ! [(call (mem:SI (match_operand:SI 0 "call_operand_address" "rS")) (const_int 0)) (match_operand:DI 1 "memory_operand" "o") --- 2826,2847 ---- (define_insn "" ! [(call (mem:SI (match_operand:SI 0 "address_operand" "p")) ! (const_int 0)) ! (match_operand:DI 1 "memory_operand" "o") ! (match_operand 2 "" "") ! (clobber (reg:SI 15))] ! "" ! "* ! { ! operands[2] = adj_offsettable_operand (operands[1], 8); ! return \"call %a0,0\;nop\;nop\;std %%o0,%1\;st %%f0,%2\"; ! }" ! [(set_attr "type" "multi")]) ! ! ;; Make a call followed by two nops in case the function being called ! ;; returns a structure value and expects to skip an unimp instruction. ! ! (define_insn "" ! [(call (mem:SI (match_operand:SI 0 "immediate_operand" "i")) (const_int 0)) (match_operand:DI 1 "memory_operand" "o") *************** *** 2992,2995 **** --- 2972,2983 ---- [(set_attr "type" "misc") (set_attr "length" "2")]) + + ;; Special pattern for the FLUSH instruction. + + (define_insn "flush" + [(unspec_volatile [(match_operand 0 "" "")] 2)] + "" + "iflush %a0" + [(set_attr "type" "misc")]) ;; find first set. *************** *** 3035,3039 **** { operands[1] = legitimize_pic_address (operands[1], GET_MODE (operands[0]), ! operands[3], 0); }") --- 3023,3027 ---- { operands[1] = legitimize_pic_address (operands[1], GET_MODE (operands[0]), ! operands[3]); }") *************** *** 3048,3052 **** { operands[2] = legitimize_pic_address (operands[2], GET_MODE (operands[1]), ! operands[0], 0); }") --- 3036,3040 ---- { operands[2] = legitimize_pic_address (operands[2], GET_MODE (operands[1]), ! operands[0]); }") *************** *** 3064,3068 **** { operands[3] = legitimize_pic_address (operands[3], GET_MODE (operands[2]), ! operands[0], 0); }") --- 3052,3056 ---- { operands[3] = legitimize_pic_address (operands[3], GET_MODE (operands[2]), ! operands[0]); }") *************** *** 3088,3092 **** " { ! operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0], 0); }") --- 3076,3080 ---- " { ! operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0]); }") *************** *** 3477,3481 **** (define_peephole [(parallel [(set (match_operand 0 "" "") ! (call (mem:SI (match_operand:SI 1 "call_operand_address" "S,r")) (match_operand 2 "" ""))) (clobber (reg:SI 15))]) --- 3465,3469 ---- (define_peephole [(parallel [(set (match_operand 0 "" "") ! (call (mem:SI (match_operand:SI 1 "call_operand_address" "pi")) (match_operand 2 "" ""))) (clobber (reg:SI 15))]) *************** *** 3488,3492 **** (define_peephole ! [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r")) (match_operand 1 "" "")) (clobber (reg:SI 15))]) --- 3476,3480 ---- (define_peephole ! [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "pi")) (match_operand 1 "" "")) (clobber (reg:SI 15))]) diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/sparc/sysv4.h gcc-2.5.0/config/sparc/sysv4.h *** gcc-2.4.5/config/sparc/sysv4.h Mon Apr 26 07:52:24 1993 --- gcc-2.5.0/config/sparc/sysv4.h Sat Oct 2 04:23:48 1993 *************** *** 53,57 **** #define CPP_PREDEFINES \ ! "-Dsparc -Dunix -D__svr4__ -Asystem(unix) -Acpu(sparc) -Amachine(sparc) \ -D__GCC_NEW_VARARGS__" --- 53,58 ---- #define CPP_PREDEFINES \ ! "-Dsparc -Dunix -D__svr4__ \ ! -Asystem(unix) -Asystem(svr4) -Acpu(sparc) -Amachine(sparc) \ -D__GCC_NEW_VARARGS__" diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/sparc/t-sol2 gcc-2.5.0/config/sparc/t-sol2 *** gcc-2.4.5/config/sparc/t-sol2 Tue Feb 2 15:16:45 1993 --- gcc-2.5.0/config/sparc/t-sol2 Thu Sep 9 16:02:43 1993 *************** *** 7,10 **** --- 7,11 ---- LIBGCC1 = libgcc1.null + CROSS_LIBGCC1 = libgcc1.null # gmon build rule: diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/sparc/xm-sparc.h gcc-2.5.0/config/sparc/xm-sparc.h *** gcc-2.4.5/config/sparc/xm-sparc.h Thu Jun 11 00:44:16 1992 --- gcc-2.5.0/config/sparc/xm-sparc.h Sat Jun 26 11:28:48 1993 *************** *** 1,4 **** /* Configuration for GNU C-compiler for Sun Sparc. ! Copyright (C) 1988 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com). --- 1,4 ---- /* Configuration for GNU C-compiler for Sun Sparc. ! Copyright (C) 1988, 1993 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com). *************** *** 46,55 **** #ifndef __GNUC__ #include "alloca.h" - #endif - - /* If compiled with GNU C, use the built-in alloca. */ - #ifdef __GNUC__ - /* Use an arg in this macro because that's what some other - system does--let's avoid conflict. */ - #define alloca(x) __builtin_alloca(x) #endif --- 46,48 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/sparc/xm-sysv4.h gcc-2.5.0/config/sparc/xm-sysv4.h *** gcc-2.4.5/config/sparc/xm-sysv4.h Thu Jul 23 02:09:05 1992 --- gcc-2.5.0/config/sparc/xm-sysv4.h Sat Jun 26 11:28:15 1993 *************** *** 1,4 **** /* Configuration for GNU C-compiler for Sun Sparc running System V.4. ! Copyright (C) 1992 Free Software Foundation, Inc. Contributed by Ron Guilmette (rfg@ncd.com). --- 1,4 ---- /* Configuration for GNU C-compiler for Sun Sparc running System V.4. ! Copyright (C) 1992, 1993 Free Software Foundation, Inc. Contributed by Ron Guilmette (rfg@ncd.com). *************** *** 42,52 **** #define SUCCESS_EXIT_CODE 0 #define FATAL_EXIT_CODE 33 - - /* If compiled with GNU C, use the built-in alloca. */ - #ifdef __GNUC__ - /* Use an arg in this macro because that's what some other - system does--let's avoid conflict. */ - #define alloca(x) __builtin_alloca(x) - #endif #include "xm-svr4.h" --- 42,45 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/spur/spur.h gcc-2.5.0/config/spur/spur.h *** gcc-2.4.5/config/spur/spur.h Wed Mar 31 15:01:30 1993 --- gcc-2.5.0/config/spur/spur.h Sat Oct 2 04:23:54 1993 *************** *** 25,29 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dspur" /* Link with libg.a when debugging, for dbx's sake. */ --- 25,29 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dspur -Acpu(spur) -Amachine(spur)" /* Link with libg.a when debugging, for dbx's sake. */ *************** *** 415,419 **** #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME) \ ! ((CUM) = ((FNTYPE) != 0 && aggregate_value_p ((FNTYPE)))) /* Update the data in CUM to advance over an argument --- 415,419 ---- #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME) \ ! ((CUM) = ((FNTYPE) != 0 && aggregate_value_p (TREE_TYPE ((FNTYPE))))) /* Update the data in CUM to advance over an argument diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/spur/xm-spur.h gcc-2.5.0/config/spur/xm-spur.h *** gcc-2.4.5/config/spur/xm-spur.h Sat Dec 26 17:26:03 1992 --- gcc-2.5.0/config/spur/xm-spur.h Sat Jun 26 11:27:18 1993 *************** *** 1,4 **** /* Configuration for GNU C-compiler for Berkeley SPUR processor. ! Copyright (C) 1988 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,4 ---- /* Configuration for GNU C-compiler for Berkeley SPUR processor. ! Copyright (C) 1988, 1993 Free Software Foundation, Inc. This file is part of GNU CC. *************** *** 37,43 **** #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 --- 37,38 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/svr4.h gcc-2.5.0/config/svr4.h *** gcc-2.4.5/config/svr4.h Tue Apr 27 10:55:56 1993 --- gcc-2.5.0/config/svr4.h Wed Oct 20 15:41:28 1993 *************** *** 441,445 **** #define READONLY_DATA_SECTION() const_section () ! extern void text_section(); #define CONST_SECTION_FUNCTION \ --- 441,445 ---- #define READONLY_DATA_SECTION() const_section () ! extern void text_section (); #define CONST_SECTION_FUNCTION \ *************** *** 588,599 **** fprintf (FILE, TYPE_OPERAND_FMT, "object"); \ putc ('\n', FILE); \ ! if (!flag_inhibit_size_directive) \ { \ fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ assemble_name (FILE, NAME); \ ! fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (decl))); \ } \ ASM_OUTPUT_LABEL(FILE, NAME); \ } while (0) /* This is how to declare the size of a function. */ --- 588,621 ---- fprintf (FILE, TYPE_OPERAND_FMT, "object"); \ putc ('\n', FILE); \ ! size_directive_output = 0; \ ! if (!flag_inhibit_size_directive && DECL_SIZE (DECL)) \ { \ + size_directive_output = 1; \ fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ assemble_name (FILE, NAME); \ ! fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \ } \ ASM_OUTPUT_LABEL(FILE, NAME); \ } while (0) + + /* Output the size directive for a decl in rest_of_decl_compilation + in the case where we did not do so before the initializer. + Once we find the error_mark_node, we know that the value of + size_directive_output was set + by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */ + + #define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \ + do { \ + char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \ + if (!flag_inhibit_size_directive && DECL_SIZE (DECL) \ + && ! AT_END && TOP_LEVEL \ + && DECL_INITIAL (DECL) == error_mark_node \ + && !size_directive_output) \ + { \ + fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ + assemble_name (FILE, name); \ + fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \ + } \ + } while (0) /* This is how to declare the size of a function. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/t-libc-ok gcc-2.5.0/config/t-libc-ok *** gcc-2.4.5/config/t-libc-ok Mon Jul 27 23:07:12 1992 --- gcc-2.5.0/config/t-libc-ok Thu Sep 9 16:02:50 1993 *************** *** 1 **** --- 1,2 ---- LIBGCC1=libgcc1.null + CROSS_LIBGCC1=libgcc1.null diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/tahoe/harris.h gcc-2.5.0/config/tahoe/harris.h *** gcc-2.4.5/config/tahoe/harris.h Tue Jan 5 23:31:20 1993 --- gcc-2.5.0/config/tahoe/harris.h Sat Oct 2 04:23:57 1993 *************** *** 22,26 **** #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dtahoe -Dunix -Dhcx" #undef DBX_DEBUGGING_INFO --- 22,26 ---- #undef CPP_PREDEFINES ! #define CPP_PREDEFINES "-Dtahoe -Dunix -Dhcx -Asystem(unix) -Acpu(tahoe) -Amachine(tahoe)" #undef DBX_DEBUGGING_INFO diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/tahoe/tahoe.h gcc-2.5.0/config/tahoe/tahoe.h *** gcc-2.4.5/config/tahoe/tahoe.h Wed Mar 31 15:01:35 1993 --- gcc-2.5.0/config/tahoe/tahoe.h Mon Oct 11 07:36:53 1993 *************** *** 45,49 **** #else /* we want "tahoe" and "unix" defined for all future compilations */ ! #define CPP_PREDEFINES "-Dtahoe -Dunix" /* have cc1 print that this is the tahoe version */ #define TARGET_VERSION printf (" (tahoe)"); --- 45,49 ---- #else /* we want "tahoe" and "unix" defined for all future compilations */ ! #define CPP_PREDEFINES "-Dtahoe -Dunix -Asystem(unix) -Acpu(tahoe) -Amachine(tahoe)" /* have cc1 print that this is the tahoe version */ #define TARGET_VERSION printf (" (tahoe)"); *************** *** 622,626 **** /* 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 */ --- 622,626 ---- /* so don't bother zero extending or sign extending them */ ! #define SHIFT_COUNT_TRUNCATED 1 /* we don't need to officially convert from one fixed type to another */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/tahoe/xm-tahoe.h gcc-2.5.0/config/tahoe/xm-tahoe.h *** gcc-2.4.5/config/tahoe/xm-tahoe.h Sat Dec 26 17:26:20 1992 --- gcc-2.5.0/config/tahoe/xm-tahoe.h Sat Jun 26 11:26:49 1993 *************** *** 1,4 **** /* Configuration for GNU C-compiler for Tahoe. ! Copyright (C) 1987 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,4 ---- /* Configuration for GNU C-compiler for Tahoe. ! Copyright (C) 1987, 1993 Free Software Foundation, Inc. This file is part of GNU CC. *************** *** 57,63 **** #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 --- 57,58 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/vax/ultrix.h gcc-2.5.0/config/vax/ultrix.h *** gcc-2.4.5/config/vax/ultrix.h Thu Jan 7 18:03:02 1993 --- gcc-2.5.0/config/vax/ultrix.h Sat Oct 2 04:24:06 1993 *************** *** 2,6 **** #undef CPP_PREDEFINES ! #define CPP_PREDEFINES " -Dvax -Dunix -Dultrix -Dbsd4_2 -D__vax -D__unix -D__ultrix -D__bsd4_2" /* By default, allow $ to be part of an identifier. */ --- 2,6 ---- #undef CPP_PREDEFINES ! #define CPP_PREDEFINES " -Dvax -Dunix -Dultrix -Dbsd4_2 -D__vax -D__unix -D__ultrix -D__bsd4_2 -Asystem(unix) -Asystem(bsd) -Acpu(vax) -Amachine(vax)" /* By default, allow $ to be part of an identifier. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/vax/vax.h gcc-2.5.0/config/vax/vax.h *** gcc-2.4.5/config/vax/vax.h Sun Jun 6 16:31:31 1993 --- gcc-2.5.0/config/vax/vax.h Sat Oct 2 04:24:12 1993 *************** *** 21,25 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dvax -Dunix" /* If using g-format floating point, alter math.h. */ --- 21,25 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dvax -Dunix -Asystem(unix) -Asystem(bsd) -Acpu(vax) -Amachine(vax)" /* If using g-format floating point, alter math.h. */ *************** *** 542,545 **** --- 542,547 ---- #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ { \ + emit_insn (gen_rtx (ASM_INPUT, VOIDmode, \ + "movpsl -(sp)\n\tpushal 1(pc)\n\trei")); \ emit_move_insn (gen_rtx (MEM, HImode, TRAMP), \ gen_rtx (MEM, HImode, FNADDR)); \ *************** *** 676,680 **** #define GO_IF_NONINDEXED_ADDRESS(X, ADDR) \ { register rtx xfoob = (X); \ ! if (GET_CODE (xfoob) == REG) goto ADDR; \ if (CONSTANT_ADDRESS_P (xfoob)) goto ADDR; \ if (INDIRECTABLE_ADDRESS_P (xfoob)) goto ADDR; \ --- 678,689 ---- #define GO_IF_NONINDEXED_ADDRESS(X, ADDR) \ { register rtx xfoob = (X); \ ! if (GET_CODE (xfoob) == REG) \ ! { \ ! extern rtx *reg_equiv_mem; \ ! if (! reload_in_progress \ ! || reg_equiv_mem[REGNO (xfoob)] == 0 \ ! || INDIRECTABLE_ADDRESS_P (reg_equiv_mem[REGNO (xfoob)])) \ ! goto ADDR; \ ! } \ if (CONSTANT_ADDRESS_P (xfoob)) goto ADDR; \ if (INDIRECTABLE_ADDRESS_P (xfoob)) goto ADDR; \ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/vax/vaxv.h gcc-2.5.0/config/vax/vaxv.h *** gcc-2.4.5/config/vax/vaxv.h Wed Mar 31 15:35:55 1993 --- gcc-2.5.0/config/vax/vaxv.h Sat Oct 2 04:24:15 1993 *************** *** 24,27 **** --- 24,30 ---- #define SCCS_DIRECTIVE + #undef CPP_PREDEFINES + #define CPP_PREDEFINES "-Dvax -Dunix -Asystem(unix) -Asystem(svr3) -Acpu(vax) -Amachine(vax)" + /* Output #ident as a .ident. */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/vax/vms.h gcc-2.5.0/config/vax/vms.h *** gcc-2.4.5/config/vax/vms.h Sat Jun 19 18:34:59 1993 --- gcc-2.5.0/config/vax/vms.h Sat Oct 2 04:24:19 1993 *************** *** 38,42 **** /* Predefine this in CPP because VMS limits the size of command options and GNU CPP is not used on VMS except with GNU C. */ ! #define CPP_PREDEFINES "-Dvax -Dvms -DVMS -D__GNUC__=2" /* These match the definitions used in VAXCRTL, the VMS C run-time library */ --- 38,42 ---- /* Predefine this in CPP because VMS limits the size of command options and GNU CPP is not used on VMS except with GNU C. */ ! #define CPP_PREDEFINES "-Dvax -Dvms -DVMS -D__GNUC__=2 -Asystem(vms) -Acpu(vax) -Amachine(vax)" /* These match the definitions used in VAXCRTL, the VMS C run-time library */ diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/vax/xm-vax.h gcc-2.5.0/config/vax/xm-vax.h *** gcc-2.4.5/config/vax/xm-vax.h Thu Jun 11 01:00:06 1992 --- gcc-2.5.0/config/vax/xm-vax.h Sat Jun 26 11:26:18 1993 *************** *** 1,4 **** /* Configuration for GNU C-compiler for Vax. ! Copyright (C) 1987 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,4 ---- /* Configuration for GNU C-compiler for Vax. ! Copyright (C) 1987, 1993 Free Software Foundation, Inc. This file is part of GNU CC. *************** *** 39,47 **** #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 /* isinf isn't there, but finite is. */ --- 39,42 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/vax/xm-vms.h gcc-2.5.0/config/vax/xm-vms.h *** gcc-2.4.5/config/vax/xm-vms.h Sun Mar 21 13:56:06 1993 --- gcc-2.5.0/config/vax/xm-vms.h Sun Oct 10 01:27:03 1993 *************** *** 65,73 **** #endif - /* If compiled with GNU C, use the built-in alloca */ - #ifdef __GNUC__ - #define alloca __builtin_alloca - #endif - #define GCC_INCLUDE_DIR "///not used with VMS///" /* nonsense string for now */ --- 65,68 ---- *************** *** 146,152 **** --- 141,149 ---- /* rename all too-long external symbol names to avoid warnings */ + #define bc_check_for_full_enumeration_handling bc_check_for_full_enum_handling #define check_for_full_enumeration_handling check_for_full_enum_handling #define current_function_contains_functions curfunc_contains_functions #define current_function_epilogue_delay_list curfunc_epilogue_delay_list + #define current_function_has_nonlocal_goto curfunc_has_nonlocal_goto #define current_function_has_nonlocal_label curfunc_has_nonlocal_label #define current_function_internal_arg_pointer curfunc_internal_arg_pointer *************** *** 160,163 **** --- 157,161 ---- #define flag_schedule_insns_after_reload flag_sched_insns_after_reload #define maybe_building_objc_message_expr maybe_building_objc_msg_expr + #define output_deferred_addressed_constants output_deferred_addr_constants #define reg_overlap_mentioned_for_reload_p reg_overlap_mtnd_for_reload_p #define reposition_prologue_and_epilogue_notes repos_prolog_and_epilog_notes diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/we32k/we32k.c gcc-2.5.0/config/we32k/we32k.c *** gcc-2.4.5/config/we32k/we32k.c Mon Jul 27 23:05:59 1992 --- gcc-2.5.0/config/we32k/we32k.c Sat Jun 26 03:04:42 1993 *************** *** 26,32 **** ! void output_move_double(operands) ! rtx *operands; ! { rtx lsw_operands[2]; rtx lsw_sreg = NULL; --- 26,33 ---- ! void ! output_move_double (operands) ! rtx *operands; ! { rtx lsw_operands[2]; rtx lsw_sreg = NULL; *************** *** 33,133 **** rtx msw_dreg = NULL; ! if (GET_CODE (operands[0]) == REG) { ! lsw_operands[0] = gen_rtx(REG, SImode, REGNO (operands[0]) + 1); ! msw_dreg = operands[0]; } else ! if (GET_CODE (operands[0]) == MEM && offsettable_memref_p (operands[0])) ! lsw_operands[0] = adj_offsettable_operand(operands[0], 4); ! else ! abort(); ! ! if (GET_CODE (operands[1]) == REG) { ! lsw_operands[1] = gen_rtx(REG, SImode, REGNO (operands[1]) + 1); ! lsw_sreg = lsw_operands[1]; } ! else ! if (GET_CODE (operands[1]) == MEM && offsettable_memref_p (operands[1])) { ! lsw_operands[1] = adj_offsettable_operand(operands[1], 4); lsw_sreg = operands[1]; ! for ( ; ; ) { ! if (REG_P (lsw_sreg)) ! break; ! if (CONSTANT_ADDRESS_P (lsw_sreg)) { ! lsw_sreg = NULL; ! break; ! } ! if (GET_CODE (lsw_sreg) == MEM) { ! lsw_sreg = XEXP (lsw_sreg, 0); ! continue; ! } ! if (GET_CODE (lsw_sreg) == PLUS) ! if (CONSTANT_ADDRESS_P (XEXP (lsw_sreg, 1))) { ! lsw_sreg = XEXP (lsw_sreg, 0); ! continue; ! } ! else ! if (CONSTANT_ADDRESS_P (XEXP (lsw_sreg, 0))) { ! lsw_sreg = XEXP (lsw_sreg, 1); ! continue; ! } ! abort(); ! } ! } ! else ! if (GET_CODE (operands[1]) == CONST_DOUBLE) ! { ! lsw_operands[1] = gen_rtx(CONST_INT, SImode, ! CONST_DOUBLE_HIGH(operands[1])); ! operands[1] = gen_rtx(CONST_INT, SImode, ! CONST_DOUBLE_LOW(operands[1])); ! } ! else ! if (GET_CODE (operands[1]) == CONST_INT) ! { ! lsw_operands[1] = operands[1]; ! operands[1] = const0_rtx; ! } ! else ! abort(); ! ! if ( !msw_dreg || !lsw_sreg || REGNO (msw_dreg) != REGNO (lsw_sreg)) { ! output_asm_insn("movw %1, %0", operands); ! output_asm_insn("movw %1, %0", lsw_operands); ! } ! else { ! output_asm_insn("movw %1, %0", lsw_operands); ! output_asm_insn("movw %1, %0", operands); ! } ! } ! ! void output_push_double(operands) ! rtx *operands; ! { rtx lsw_operands[1]; if (GET_CODE (operands[0]) == REG) ! lsw_operands[0] = gen_rtx(REG, SImode, REGNO (operands[0]) + 1); else ! if (GET_CODE (operands[0]) == MEM && offsettable_memref_p (operands[0])) ! lsw_operands[0] = adj_offsettable_operand(operands[0], 4); ! else ! if (GET_CODE (operands[0]) == CONST_DOUBLE) ! { ! lsw_operands[0] = gen_rtx(CONST_INT, SImode, ! CONST_DOUBLE_HIGH(operands[0])); ! operands[0] = gen_rtx(CONST_INT, SImode, ! CONST_DOUBLE_LOW(operands[0])); ! } ! else ! if (GET_CODE (operands[0]) == CONST_INT) ! { ! lsw_operands[0] = operands[0]; ! operands[0] = const0_rtx; ! } ! else ! abort(); ! ! output_asm_insn("pushw %0", operands); ! output_asm_insn("pushw %0", lsw_operands); ! } --- 34,139 ---- rtx msw_dreg = NULL; ! if (GET_CODE (operands[0]) == REG) ! { ! lsw_operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); ! msw_dreg = operands[0]; } + else if (GET_CODE (operands[0]) == MEM && offsettable_memref_p (operands[0])) + lsw_operands[0] = adj_offsettable_operand (operands[0], 4); else ! abort (); ! ! if (GET_CODE (operands[1]) == REG) ! { ! lsw_operands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); ! lsw_sreg = lsw_operands[1]; } ! else if (GET_CODE (operands[1]) == MEM && offsettable_memref_p (operands[1])) ! { ! lsw_operands[1] = adj_offsettable_operand (operands[1], 4); lsw_sreg = operands[1]; ! for ( ; ; ) ! { ! if (REG_P (lsw_sreg)) ! break; ! if (CONSTANT_ADDRESS_P (lsw_sreg)) ! { ! lsw_sreg = NULL; ! break; ! } ! if (GET_CODE (lsw_sreg) == MEM) ! { ! lsw_sreg = XEXP (lsw_sreg, 0); ! continue; ! } ! if (GET_CODE (lsw_sreg) == PLUS) ! { ! if (CONSTANT_ADDRESS_P (XEXP (lsw_sreg, 1))) ! { ! lsw_sreg = XEXP (lsw_sreg, 0); ! continue; ! } ! else if (CONSTANT_ADDRESS_P (XEXP (lsw_sreg, 0))) ! { ! lsw_sreg = XEXP (lsw_sreg, 1); ! continue; ! } ! } ! abort (); ! } ! } ! else if (GET_CODE (operands[1]) == CONST_DOUBLE) ! { ! lsw_operands[1] = gen_rtx (CONST_INT, SImode, ! CONST_DOUBLE_HIGH (operands[1])); ! operands[1] = gen_rtx (CONST_INT, SImode, ! CONST_DOUBLE_LOW (operands[1])); ! } ! else if (GET_CODE (operands[1]) == CONST_INT) ! { ! lsw_operands[1] = operands[1]; ! operands[1] = const0_rtx; ! } ! else ! abort (); ! ! if (!msw_dreg || !lsw_sreg || REGNO (msw_dreg) != REGNO (lsw_sreg)) ! { ! output_asm_insn ("movw %1, %0", operands); ! output_asm_insn ("movw %1, %0", lsw_operands); ! } ! else ! { ! output_asm_insn ("movw %1, %0", lsw_operands); ! output_asm_insn ("movw %1, %0", operands); ! } ! } ! ! void ! output_push_double (operands) ! rtx *operands; ! { rtx lsw_operands[1]; if (GET_CODE (operands[0]) == REG) ! lsw_operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); ! else if (GET_CODE (operands[0]) == MEM && offsettable_memref_p (operands[0])) ! lsw_operands[0] = adj_offsettable_operand (operands[0], 4); ! else if (GET_CODE (operands[0]) == CONST_DOUBLE) ! { ! lsw_operands[0] = gen_rtx (CONST_INT, SImode, ! CONST_DOUBLE_HIGH (operands[0])); ! operands[0] = gen_rtx (CONST_INT, SImode, ! CONST_DOUBLE_LOW (operands[0])); ! } ! else if (GET_CODE (operands[0]) == CONST_INT) ! { ! lsw_operands[0] = operands[0]; ! operands[0] = const0_rtx; ! } else ! abort (); ! ! output_asm_insn ("pushw %0", operands); ! output_asm_insn ("pushw %0", lsw_operands); ! } diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/we32k/we32k.h gcc-2.5.0/config/we32k/we32k.h *** gcc-2.4.5/config/we32k/we32k.h Thu May 6 22:54:20 1993 --- gcc-2.5.0/config/we32k/we32k.h Mon Oct 11 07:36:58 1993 *************** *** 22,26 **** /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dwe32000 -Du3b -Dunix" /* Print subsidiary information on the compiler version in use. */ --- 22,26 ---- /* Names to predefine in the preprocessor for this target machine. */ ! #define CPP_PREDEFINES "-Dwe32000 -Du3b -Dunix -Asystem(unix) -Acpu(we32000) -Amachine(we32000)" /* Print subsidiary information on the compiler version in use. */ *************** *** 648,655 **** #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 --- 648,654 ---- #define SLOW_BYTE_ACCESS 0 ! /* Define this to be nonzero if shift instructions ignore all but the low-order ! few bits. */ ! #define SHIFT_COUNT_TRUNCATED 1 /* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/we32k/xm-we32k.h gcc-2.5.0/config/we32k/xm-we32k.h *** gcc-2.4.5/config/we32k/xm-we32k.h Tue Feb 16 01:46:18 1993 --- gcc-2.5.0/config/we32k/xm-we32k.h Sat Jun 26 11:25:40 1993 *************** *** 1,5 **** /* Configuration for GNU C-compiler for AT&T we32000 Family. Contributed by John Wehle (john@feith1.uucp) ! Copyright (C) 1991-1992 Free Software Foundation, Inc. This file is part of GNU CC. --- 1,5 ---- /* Configuration for GNU C-compiler for AT&T we32000 Family. Contributed by John Wehle (john@feith1.uucp) ! Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. This file is part of GNU CC. *************** *** 36,44 **** #define SUCCESS_EXIT_CODE 0 #define FATAL_EXIT_CODE 33 - - /* If compiled with GNU C, use the built-in alloca */ - #ifdef __GNUC__ - #define alloca(x) __builtin_alloca(x) - #endif /* target machine dependencies. --- 36,39 ---- diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/x-lynx gcc-2.5.0/config/x-lynx *** gcc-2.4.5/config/x-lynx --- gcc-2.5.0/config/x-lynx Tue Aug 31 17:14:43 1993 *************** *** 0 **** --- 1,7 ---- + # /bin/cc is hopelessly broken, so we must use /bin/gcc instead. + CC = $(OLDCC) + OLDCC = /bin/gcc + + # ??? This takes far too long to run, several hours, so let's not do it for + # now. + STMP_FIXPROTO = diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config/xm-lynx.h gcc-2.5.0/config/xm-lynx.h *** gcc-2.4.5/config/xm-lynx.h --- gcc-2.5.0/config/xm-lynx.h Tue Aug 31 17:16:55 1993 *************** *** 0 **** --- 1,42 ---- + /* Configuration for GNU C-compiler for Lynx. + Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 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 + #define HOST_BITS_PER_LONGLONG 64 + + /* Arguments to use with `exit'. */ + #define SUCCESS_EXIT_CODE 0 + #define FATAL_EXIT_CODE 33 + + /* Lynx has no vfork system call. */ + #define vfork fork + + /* target machine dependencies. + tm.h is a symbolic link to the actual target specific file. */ + + #include "tm.h" + diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config.guess gcc-2.5.0/config.guess *** gcc-2.4.5/config.guess --- gcc-2.5.0/config.guess Thu Oct 21 22:35:06 1993 *************** *** 0 **** --- 1,230 ---- + #!/bin/sh + # This script attempts to guess a canonical system name. + # Copyright (C) 1992, 1993 Free Software Foundation, Inc. + # + # This file is free software; you can redistribute it and/or modify it + # under the terms of the GNU General Public License as published by + # the Free Software Foundation; either version 2 of the License, or + # (at your option) any later version. + # + # This program 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 this program; if not, write to the Free Software + # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + + # + # This script attempts to guess a canonical system name similar to + # config.sub. If it succeeds, it prints the system name on stdout, and + # exits with 0. Otherwise, it prints an error message on stderr, and + # exits with 1. + # + # The plan is that this can be called by configure scripts if you + # don't specify an explicit system type (host/target name). + # + # Only a few systems have been added to this list; please add others + # (but try to keep the structure clean). + # + + UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown + UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown + UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown + UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + + # Note: order is significant - the case branches are not exclusive. + + case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + alpha:OSF1:1.*:*) + # 1.2 uses "1.2" for uname -r. + echo alpha-dec-osf${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:V1.*:*) + # 1.3 uses "V1.3" for uname -r. + echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^V//'` + exit 0 ;; + sun4*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + echo sparc-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + mips:*:5*:RISCos) + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + *:IRIX:*:*) + echo mips-sgi-irix${UNAME_RELEASE} + exit 0 ;; + i[34]86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + *:AIX:2:3) + echo rs6000-ibm-aix3.2 + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/31?:HP-UX:*:*) + echo m68000-hp-hpux + exit 0 ;; + 9000/[34]??:HP-UX:*:*) + echo m68k-hp-hpux + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/7??:HP-UX:*:* | 9000/8?7:HP-UX:*:* ) + echo hppa1.1-hp-hpux + exit 0 ;; + 9000/8??:HP-UX:*:*) + echo hppa1.0-hp-hpux + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?7:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + C1*:ConvexOS:*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:*) + echo c2-convex-bsd + exit 0 ;; + CRAY*X-MP:UNICOS:*:*) + echo xmp-cray-unicos + exit 0 ;; + CRAY*Y-MP:UNICOS:*:*) + echo ymp-cray-unicos + exit 0 ;; + CRAY-2:UNICOS:*:*) + echo cray2-cray-unicos + exit 0 ;; + hp3[0-9][05]:NetBSD:*:*) + echo m68k-hp-netbsd${UNAME_RELEASE} + exit 0 ;; + i[34]86:NetBSD:*:*) + echo ${UNAME_MACHINE}-unknown-netbsd${UNAME_RELEASE} + exit 0 ;; + i[34]86:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux + exit 0 ;; + i[34]86:UNIX_SV:4.*:*) + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} + else + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + i[34]86:*:3.2:*) + if /bin/uname -X 2>/dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + echo ${UNAME_MACHINE}-unknown-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-unknown-sysv3.2 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M680[234]0:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 33??:*:4.0:*) + uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + esac + + #echo '(No uname command or uname output not recognized.)' 1>&2 + #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + + cat >dummy.c <&2 + + exit 1 diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/config.sub gcc-2.5.0/config.sub *** gcc-2.4.5/config.sub Tue Jun 1 00:09:04 1993 --- gcc-2.5.0/config.sub Mon Oct 18 23:25:53 1993 *************** *** 1,5 **** #!/bin/sh # Configuration validation subroutine script, version 1.1. ! # Copyright (C) 1991, 1992 Free Software Foundation, Inc. # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software --- 1,5 ---- #!/bin/sh # Configuration validation subroutine script, version 1.1. ! # Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software *************** *** 72,75 **** --- 72,83 ---- basic_machine=$1 ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. *************** *** 90,93 **** --- 98,104 ---- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` ;; + -lynx) + os=-lynxos + ;; esac *************** *** 94,102 **** # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in ! # Recognize the basic CPU types with without company name. # Some are omitted here because they have special meanings below. tahoe | i[34]86 | i860 | m68k | m68000 | m88k | ns32k | arm | pyramid \ | tron | a29k | 580 | i960 | h8300 | hppa1.0 | hppa1.1 \ ! | alpha | we32k | ns16k | clipper | sparclite | i370 | sh) basic_machine=$basic_machine-unknown ;; --- 105,114 ---- # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in ! # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. tahoe | i[34]86 | i860 | m68k | m68000 | m88k | ns32k | arm | pyramid \ | tron | a29k | 580 | i960 | h8300 | hppa1.0 | hppa1.1 \ ! | alpha | we32k | ns16k | clipper | sparclite | i370 | sh \ ! | powerpc) basic_machine=$basic_machine-unknown ;; *************** *** 106,110 **** exit 1 ;; ! # Recognize the basic CPU types with with company name. vax-* | tahoe-* | i[34]86-* | i860-* | m68k-* | m68000-* | m88k-* \ | sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \ --- 118,122 ---- exit 1 ;; ! # Recognize the basic CPU types with company name. vax-* | tahoe-* | i[34]86-* | i860-* | m68k-* | m68000-* | m88k-* \ | sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \ *************** *** 113,117 **** | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \ | pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \ ! | sh-*) ;; # Recognize the various machine names and aliases which stand --- 125,129 ---- | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \ | pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \ ! | sh-* | powerpc-*) ;; # Recognize the various machine names and aliases which stand *************** *** 361,367 **** os=-sysv3 ;; ! dpx2) basic_machine=m68k-bull ! os=-sysv ;; ebmon29k) --- 373,383 ---- os=-sysv3 ;; ! dpx2* | dpx2*-bull) basic_machine=m68k-bull ! os=-sysv3 ! ;; ! sps7) ! basic_machine=m68k-bull ! os=-sysv2 ;; ebmon29k) *************** *** 484,488 **** # Decode manufacturer-specific aliases for certain operating systems. ! if [ "$os" ] then case $os in --- 500,504 ---- # Decode manufacturer-specific aliases for certain operating systems. ! if [ x"$os" != x"" ] then case $os in *************** *** 491,498 **** os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative must end in a *, to match a version number. ! -bsd* | -sysv* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]* | -hpux* \ | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ --- 507,518 ---- os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; + -solaris) + os=-solaris2 + ;; # First accept the basic system types. # The portable systems comes first. # Each alternative must end in a *, to match a version number. ! # -sysv* is not here because it comes later, after sysvr4. ! -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]* | -hpux* \ | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ *************** *** 500,504 **** | -nindy* | -vxworks* | -ebmon* | -hms* | -mvs* | -clix* \ | -riscos* | -linux* | -uniplus* | -iris* | -rtu* | -xenix* \ ! | -386bsd*) ;; -sunos5*) --- 520,524 ---- | -nindy* | -vxworks* | -ebmon* | -hms* | -mvs* | -clix* \ | -riscos* | -linux* | -uniplus* | -iris* | -rtu* | -xenix* \ ! | -386bsd* | -netbsd* | -riscix* | -lynxos*) ;; -sunos5*) *************** *** 538,541 **** --- 558,567 ---- os=-sysv3 ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; -xenix) os=-xenix *************** *** 563,566 **** --- 589,595 ---- case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; *-dec | vax-*) os=-ultrix4.2 *************** *** 647,652 **** --- 676,687 ---- *-unknown) case $os in + -riscix*) + vendor=acorn + ;; -sunos*) vendor=sun + ;; + -lynxos*) + vendor=lynx ;; -aix*) diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/configure gcc-2.5.0/configure *** gcc-2.4.5/configure Fri Jun 18 14:21:08 1993 --- gcc-2.5.0/configure Thu Oct 21 14:38:34 1993 *************** *** 1,5 **** #!/bin/sh # Configuration script for GNU CC ! # Copyright (C) 1988, 1990, 1991, 1992 Free Software Foundation, Inc. #This file is part of GNU CC. --- 1,5 ---- #!/bin/sh # Configuration script for GNU CC ! # Copyright (C) 1988, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. #This file is part of GNU CC. *************** *** 34,37 **** --- 34,38 ---- # --with-gnu-as arrange to work with GAS. # --with-stabs arrange to use stabs instead of host debug format. + # --with-elf arrange to use elf instead of host debug format. # --nfp assume system has no FPU. # *************** *** 180,184 **** --- 181,192 ---- stabs=yes ;; + -with-elf | -with-el | -with-se \ + | --with-elf | --with-el | --with-e \ + | -elf | -el | -e \ + |--elf | --el | --e) + elf=yes + ;; -with-* | --with-*) ;; #ignored + -enable-* | --enable-*) ;; #ignored -x | --x) ;; # ignored -*) *************** *** 229,244 **** if [ x$target = x ] then ! echo "No target specified." 1>&2 ! ! echo "\ Usage: `basename $progname` [--host=HOST] [--build=BUILD] [--prefix=DIR] [--local-pref=DIR] [--exec-pref=DIR] ! [--with-gnu-as] [--with-gnu-ld] [--with-stabs] [--nfp] TARGET" 1>&2 echo "Where HOST, TARGET and BUILD are three-part configuration names " 1>&2 ! if [ -r config.status ] ! then ! tail +2 config.status 1>&2 fi - exit 1 fi --- 237,257 ---- if [ x$target = x ] then ! # This way of testing the result of a command substitution is ! # defined by Posix.2 (section 3.9.1) as well as traditional shells. ! if target=`${srcdir}/config.guess` ; then ! echo "Configuring for a ${target} host." 1>&2 ! else ! echo 'Config.guess failed to determine the host type. You need to specify one.' 1>&2 ! echo "\ Usage: `basename $progname` [--host=HOST] [--build=BUILD] [--prefix=DIR] [--local-pref=DIR] [--exec-pref=DIR] ! [--with-gnu-as] [--with-gnu-ld] [--with-stabs] [--with-elf] [--nfp] TARGET" 1>&2 echo "Where HOST, TARGET and BUILD are three-part configuration names " 1>&2 ! if [ -r config.status ] ! then ! tail +2 config.status 1>&2 ! fi ! exit 1 fi fi *************** *** 278,281 **** --- 291,295 ---- tmake_file= header_files= + extra_passes= # Set this to force installation and use of collect2. use_collect2= *************** *** 288,291 **** --- 302,308 ---- # Set this to control how the header file directory is installed. install_headers_dir=install-headers-tar + # Set this to a non-empty list of args to pass to cpp if the target + # wants its .md file passed through cpp. + cpp_md_flags= case $machine in *************** *** 326,329 **** --- 343,352 ---- # tahoe-*-bsd*) # tahoe running BSD # ;; + i370-*-mvs*) + cpu_type=i370 + tm_file=i370/mvs.h + xm_file=i370/xm-mvs.h + out_file=i370/mvs370.c + ;; i[34]86-*-osfrose*) # 386 using OSF/rose # The following line (and similar below) is not redundant since this can *************** *** 330,344 **** # be used for i486 or i386. cpu_type=i386 ! tm_file=i386/osfrose.h ! xmake_file=i386/x-osfrose ! tmake_file=i386/t-osfrose ! use_collect2=yes ! ;; ! i[34]86-*-osfelf*) # 386 using OSF/1 with Elf objects ! cpu_type=i386 ! tm_file=i386/osfelf.h xmake_file=i386/x-osfrose tmake_file=i386/t-osfrose - use_collect2=no ;; i[34]86-sequent-bsd*) # 80386 from Sequent --- 353,366 ---- # be used for i486 or i386. cpu_type=i386 ! if [ x$elf = xyes ] ! then ! tm_file=i386/osfelf.h ! use_collect2= ! else ! tm_file=i386/osfrose.h ! use_collect2=yes ! fi xmake_file=i386/x-osfrose tmake_file=i386/t-osfrose ;; i[34]86-sequent-bsd*) # 80386 from Sequent *************** *** 458,462 **** xm_file=i386/xm-linux.h xmake_file=i386/x-linux ! tm_file=i386/linux.h fixincludes=Makefile.in #On Linux, the headers are ok already. broken_install=yes --- 480,489 ---- xm_file=i386/xm-linux.h xmake_file=i386/x-linux ! if [ x$elf = xyes ] ! then ! tm_file=i386/linuxelf.h ! else ! tm_file=i386/linux.h ! fi fixincludes=Makefile.in #On Linux, the headers are ok already. broken_install=yes *************** *** 476,479 **** --- 503,513 ---- xmake_file=x-svr4 ;; + i[34]86-sequent-sysv*) # Sequent 80386's running system V + cpu_type=i386 + xm_file=i386/xm-sysv3.h + xmake_file=i386/x-sysv3 + tm_file=i386/seq-sysv3.h + tmake_file=t-svr3 + ;; i[34]86-*-sysv*) # Intel 80386's running system V cpu_type=i386 *************** *** 504,507 **** --- 538,553 ---- broken_install=yes ;; + i[34]86-*-lynxos) + cpu_type=i386 + tm_file=i386/lynx.h + xm_file=xm-lynx.h + xmake_file=x-lynx + # ??? Due to bugs in /bin/sh, it is too much trouble to get + # the fixincludes script to run correctly, so just don't do it. + # There are only a very few very minor things that need fixing + # anyways. Also, a number of headers files do not have final + # newlines, which causes them to be incorrectly editted by sed. + fixincludes=Makefile.in + ;; i860-*-mach*) xm_file=i860/xm-i860.h *************** *** 551,554 **** --- 597,603 ---- use_collect2=yes ;; + sparc-*-bsd*) + tm_file=sparc/bsd.h + ;; sparc-*-sysv4*) xm_file=sparc/xm-sysv4.h *************** *** 565,568 **** --- 614,628 ---- broken_install=yes ;; + sparc-*-lynxos) + tm_file=sparc/lynx.h + xm_file=xm-lynx.h + xmake_file=x-lynx + # ??? Due to bugs in /bin/sh, it is too much trouble to get + # the fixincludes script to run correctly, so just don't do it. + # There are only a very few very minor things that need fixing + # anyways. Also, a number of headers files do not have final + # newlines, which causes them to be incorrectly editted by sed. + fixincludes=Makefile.in + ;; sparclite-*-*) cpu_type=sparc *************** *** 586,593 **** if [ x$gas = xyes ] then ! tm_file=m68k/dpx2g.h else - echo dpx2 supported only with GAS 1>&2 - exit 1 tm_file=m68k/dpx2.h fi --- 646,656 ---- if [ x$gas = xyes ] then ! if [ x$stabs = xyes ] ! then ! tm_file=m68k/dpx2cdbx.h ! else ! tm_file=m68k/dpx2g.h ! fi else tm_file=m68k/dpx2.h fi *************** *** 651,662 **** header_files=math-68881.h ;; ! m68k-hp-bsd*) # HP 9000/3xx running Berkeley Unix ! tm_file=m68k/hp3bsd.h use_collect2=yes header_files=math-68881.h ;; ! m68k-hp-bsd4.4) # HP 9000/3xx running 4.4bsd ! tm_file=m68k/hp3bsd44.h ! xmake_file=m68k/x-hp3bsd44 use_collect2=yes header_files=math-68881.h --- 714,725 ---- header_files=math-68881.h ;; ! m68k-hp-bsd4.4*) # HP 9000/3xx running 4.4bsd ! tm_file=m68k/hp3bsd44.h ! xmake_file=m68k/x-hp3bsd44 use_collect2=yes header_files=math-68881.h ;; ! m68k-hp-bsd*) # HP 9000/3xx running Berkeley Unix ! tm_file=m68k/hp3bsd.h use_collect2=yes header_files=math-68881.h *************** *** 790,793 **** --- 853,868 ---- header_files=math-68881.h ;; + m68k-*-lynxos) + tm_file=m68k/lynx.h + xm_file=xm-lynx.h + xmake_file=x-lynx + # ??? Due to bugs in /bin/sh, it is too much trouble to get + # the fixincludes script to run correctly, so just don't do it. + # There are only a very few very minor things that need fixing + # anyways. Also, a number of headers files do not have final + # newlines, which causes them to be incorrectly editted by sed. + fixincludes=Makefile.in + header_files=math-68881.h + ;; m68000-convergent-sysv*) cpu_type=m68k *************** *** 855,859 **** --- 930,940 ---- tmake_file=m88k/t-dgux fi + fixincludes=fixinc.dgux ;; + m88k-mot*-sysv4*) #added by kev for Motorola delta machines + tm_file=m88k/mot-sysv4.h #added by kev + xmake_file=m88k/x-sysv4 #added by kev + tmake_file=m88k/t-sysv4 #added by kev + ;; #added by kev m88k-*-sysv4*) tm_file=m88k/sysv4.h *************** *** 884,887 **** --- 965,969 ---- tm_file=m88k/sysv3.h xm_file=m88k/xm-sysv3.h + xmake_file=m88k/x-sysv3 if [ x$gas = xyes ] then *************** *** 892,897 **** # fx80-alliant-*) # Alliant FX/80 # ;; ! arm-*-*) # Acorn RISC machine ;; c1-convex-*) # Convex C1 cpu_type=convex --- 974,992 ---- # fx80-alliant-*) # Alliant FX/80 # ;; ! arm-*-riscix1.[01]*) # Acorn RISC machine (early versions) ! tm_file=arm/riscix1-1.h ! use_collect2=yes ! ;; ! arm-*-riscix*) # Acorn RISC machine ! if [ x$gas = xyes ] ! then ! tm_file=arm/rix-gas.h ! else ! tm_file=arm/riscix.h ! fi ! use_collect2=yes ;; + arm-*-*) # generic version + ;; c1-convex-*) # Convex C1 cpu_type=convex *************** *** 919,927 **** use_collect2=yes ;; mips-sgi-irix4loser*) # Mostly like a MIPS. if [ x$stabs = xyes ]; then ! tm_file=mips/iris4gl.h else ! tm_file=mips/iris4loser.h fi xm_file=mips/xm-iris4.h --- 1014,1034 ---- use_collect2=yes ;; + # mips-sgi-irix5*) # Mostly like a MIPS. + # tm_file=mips/iris5.h + # xm_file=mips/xm-iris4.h + # broken_install=yes + # xmake_file=mips/x-iris + # # mips-tfile doesn't work yet + # tmake_file=mips/t-mips-gas + # if [ x$gnu_ld != xyes ] + # then + # use_collect2=yes + # fi + # ;; mips-sgi-irix4loser*) # Mostly like a MIPS. if [ x$stabs = xyes ]; then ! tm_file=mips/iris4gl.h else ! tm_file=mips/iris4loser.h fi xm_file=mips/xm-iris4.h *************** *** 930,938 **** if [ x$gas = xyes ] then ! tmake_file=mips/t-mips-gas fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi ;; --- 1037,1047 ---- if [ x$gas = xyes ] then ! tmake_file=mips/t-mips-gas ! else ! extra_passes="mips-tfile mips-tdump" fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi ;; *************** *** 939,945 **** mips-sgi-irix4*) # Mostly like a MIPS. if [ x$stabs = xyes ]; then ! tm_file=mips/iris4-gdb.h else ! tm_file=mips/iris4.h fi xm_file=mips/xm-iris4.h --- 1048,1054 ---- mips-sgi-irix4*) # Mostly like a MIPS. if [ x$stabs = xyes ]; then ! tm_file=mips/iris4-gdb.h else ! tm_file=mips/iris4.h fi xm_file=mips/xm-iris4.h *************** *** 948,956 **** if [ x$gas = xyes ] then ! tmake_file=mips/t-mips-gas fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi ;; --- 1057,1067 ---- if [ x$gas = xyes ] then ! tmake_file=mips/t-mips-gas ! else ! extra_passes="mips-tfile mips-tdump" fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi ;; *************** *** 957,974 **** mips-sgi-*) # Mostly like a MIPS. if [ x$stabs = xyes ]; then ! tm_file=mips/iris3-gdb.h else ! tm_file=mips/iris3.h fi xm_file=mips/xm-iris3.h broken_install=yes ! xmake_file=mips/x-iris if [ x$gas = xyes ] then ! tmake_file=mips/t-mips-gas fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi ;; --- 1068,1087 ---- mips-sgi-*) # Mostly like a MIPS. if [ x$stabs = xyes ]; then ! tm_file=mips/iris3-gdb.h else ! tm_file=mips/iris3.h fi xm_file=mips/xm-iris3.h broken_install=yes ! xmake_file=mips/x-iris3 if [ x$gas = xyes ] then ! tmake_file=mips/t-mips-gas ! else ! extra_passes="mips-tfile mips-tdump" fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi ;; *************** *** 975,981 **** mips-*-ultrix*) # Decstation. if [ x$stabs = xyes ]; then ! tm_file=mips/ultrix-gdb.h else ! tm_file=mips/ultrix.h fi xmake_file=mips/x-ultrix --- 1088,1094 ---- mips-*-ultrix*) # Decstation. if [ x$stabs = xyes ]; then ! tm_file=mips/ultrix-gdb.h else ! tm_file=mips/ultrix.h fi xmake_file=mips/x-ultrix *************** *** 982,992 **** if [ x$gas = xyes ] then ! tmake_file=mips/t-mips-gas else ! tmake_file=mips/t-ultrix fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi ;; --- 1095,1106 ---- if [ x$gas = xyes ] then ! tmake_file=mips/t-mips-gas else ! tmake_file=mips/t-ultrix ! extra_passes="mips-tfile mips-tdump" fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi ;; *************** *** 999,1005 **** mips-dec-osf*) # Decstation running OSF/1 as shipped by DIGITAL if [ x$stabs = xyes ]; then ! tm_file=mips/dec-gosf1.h else ! tm_file=mips/dec-osf1.h fi xmake_file=mips/x-dec-osf1 --- 1113,1119 ---- mips-dec-osf*) # Decstation running OSF/1 as shipped by DIGITAL if [ x$stabs = xyes ]; then ! tm_file=mips/dec-gosf1.h else ! tm_file=mips/dec-osf1.h fi xmake_file=mips/x-dec-osf1 *************** *** 1006,1031 **** if [ x$gas = xyes ] then ! tmake_file=mips/t-mips-gas else ! tmake_file=mips/t-ultrix fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi ;; mips-sony-bsd* | mips-sony-newsos*) # Sony NEWS 3600 or risc/news. if [ x$stabs = xyes ]; then ! tm_file=mips/news4-gdb.h else ! tm_file=mips/news4.h fi if [ x$gas = xyes ] then ! tmake_file=mips/t-mips-gas fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi xmake_file=mips/x-sony --- 1120,1165 ---- if [ x$gas = xyes ] then ! tmake_file=mips/t-mips-gas else ! tmake_file=mips/t-ultrix ! extra_passes="mips-tfile mips-tdump" fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi ;; + mips-dec-bsd*) # Decstation running 4.4 BSD + tm_file=mips/dec-bsd.h + xmake_file= + tmake_file= + fixincludes= + if [ x$gas = xyes ] + then + tmake_file=mips/t-mips-gas + else + tmake_file=mips/t-ultrix + extra_passes="mips-tfile mips-tdump" + fi + if [ x$gnu_ld != xyes ] + then + use_collect2=yes + fi + ;; mips-sony-bsd* | mips-sony-newsos*) # Sony NEWS 3600 or risc/news. if [ x$stabs = xyes ]; then ! tm_file=mips/news4-gdb.h else ! tm_file=mips/news4.h fi if [ x$gas = xyes ] then ! tmake_file=mips/t-mips-gas ! else ! extra_passes="mips-tfile mips-tdump" fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi xmake_file=mips/x-sony *************** *** 1035,1041 **** # t-svr4 is not right because this system doesn't use ELF. if [ x$stabs = xyes ]; then ! tm_file=mips/news5-gdb.h else ! tm_file=mips/news5.h fi xm_file=mips/xm-news.h --- 1169,1175 ---- # t-svr4 is not right because this system doesn't use ELF. if [ x$stabs = xyes ]; then ! tm_file=mips/news5-gdb.h else ! tm_file=mips/news5.h fi xm_file=mips/xm-news.h *************** *** 1042,1050 **** if [ x$gas = xyes ] then ! tmake_file=mips/t-mips-gas fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi ;; --- 1176,1186 ---- if [ x$gas = xyes ] then ! tmake_file=mips/t-mips-gas ! else ! extra_passes="mips-tfile mips-tdump" fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi ;; *************** *** 1051,1067 **** mips-*-riscos[56789]bsd* | mips-*-riscos[56789]-bsd*) if [ x$stabs = xyes ]; then # MIPS BSD 4.3, RISC-OS 5.0 ! tm_file=mips/bsd-5-gdb.h else ! tm_file=mips/bsd-5.h fi if [ x$gas = xyes ] then ! tmake_file=mips/t-mips-gas fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi fixincludes=fixinc.mips ;; mips-*-bsd* | mips-*-riscosbsd* | mips-*-riscos[1234]bsd* \ --- 1187,1207 ---- mips-*-riscos[56789]bsd* | mips-*-riscos[56789]-bsd*) if [ x$stabs = xyes ]; then # MIPS BSD 4.3, RISC-OS 5.0 ! tm_file=mips/bsd-5-gdb.h else ! tm_file=mips/bsd-5.h fi if [ x$gas = xyes ] then ! tmake_file=mips/t-bsd-gas ! else ! tmake_file=mips/t-bsd ! extra_passes="mips-tfile mips-tdump" fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi fixincludes=fixinc.mips + broken_install=yes ;; mips-*-bsd* | mips-*-riscosbsd* | mips-*-riscos[1234]bsd* \ *************** *** 1068,1101 **** | mips-*-riscos-bsd* | mips-*-riscos[1234]-bsd*) if [ x$stabs = xyes ]; then # MIPS BSD 4.3, RISC-OS 4.0 ! tm_file=mips/bsd-4-gdb.h else ! tm_file=mips/bsd-4.h fi if [ x$gas = xyes ] then ! tmake_file=mips/t-mips-gas fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi ;; mips-*-riscos[56789]sysv4* | mips-*-riscos[56789]-sysv4*) if [ x$stabs = xyes ]; then # MIPS System V.4., RISC-OS 5.0 ! tm_file=mips/svr4-5-gdb.h else ! tm_file=mips/svr4-5.h fi ! xm_file=mips/xm-sysv.h xmake_file=mips/x-sysv if [ x$gas = xyes ] then ! tmake_file=mips/t-mips-gas fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi fixincludes=fixinc.mips ;; mips-*-sysv4* | mips-*-riscos[1234]sysv4* | mips-*-riscossysv4* \ --- 1208,1249 ---- | mips-*-riscos-bsd* | mips-*-riscos[1234]-bsd*) if [ x$stabs = xyes ]; then # MIPS BSD 4.3, RISC-OS 4.0 ! tm_file=mips/bsd-4-gdb.h else ! tm_file=mips/bsd-4.h fi if [ x$gas = xyes ] then ! tmake_file=mips/t-bsd-gas ! else ! tmake_file=mips/t-bsd ! extra_passes="mips-tfile mips-tdump" fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi + broken_install=yes ;; mips-*-riscos[56789]sysv4* | mips-*-riscos[56789]-sysv4*) if [ x$stabs = xyes ]; then # MIPS System V.4., RISC-OS 5.0 ! tm_file=mips/svr4-5-gdb.h else ! tm_file=mips/svr4-5.h fi ! xm_file=mips/xm-sysv4.h xmake_file=mips/x-sysv if [ x$gas = xyes ] then ! tmake_file=mips/t-svr4-gas ! else ! tmake_file=mips/t-svr4 ! extra_passes="mips-tfile mips-tdump" fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi fixincludes=fixinc.mips + broken_install=yes ;; mips-*-sysv4* | mips-*-riscos[1234]sysv4* | mips-*-riscossysv4* \ *************** *** 1102,1108 **** | mips-*-riscos[1234]-sysv4* | mips-*-riscos-sysv4*) if [ x$stabs = xyes ]; then # MIPS System V.4. RISC-OS 4.0 ! tm_file=mips/svr4-4-gdb.h else ! tm_file=mips/svr4-4.h fi xm_file=mips/xm-sysv.h --- 1250,1256 ---- | mips-*-riscos[1234]-sysv4* | mips-*-riscos-sysv4*) if [ x$stabs = xyes ]; then # MIPS System V.4. RISC-OS 4.0 ! tm_file=mips/svr4-4-gdb.h else ! tm_file=mips/svr4-4.h fi xm_file=mips/xm-sysv.h *************** *** 1110,1125 **** if [ x$gas = xyes ] then ! tmake_file=mips/t-mips-gas fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi ;; mips-*-riscos[56789]sysv* | mips-*-riscos[56788]-sysv*) if [ x$stabs = xyes ]; then # MIPS System V.3, RISC-OS 5.0 ! tm_file=mips/svr3-5-gdb.h else ! tm_file=mips/svr3-5.h fi xm_file=mips/xm-sysv.h --- 1258,1277 ---- if [ x$gas = xyes ] then ! tmake_file=mips/t-svr4-gas ! else ! tmake_file=mips/t-svr4 ! extra_passes="mips-tfile mips-tdump" fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi + broken_install=yes ;; mips-*-riscos[56789]sysv* | mips-*-riscos[56788]-sysv*) if [ x$stabs = xyes ]; then # MIPS System V.3, RISC-OS 5.0 ! tm_file=mips/svr3-5-gdb.h else ! tm_file=mips/svr3-5.h fi xm_file=mips/xm-sysv.h *************** *** 1127,1143 **** if [ x$gas = xyes ] then ! tmake_file=mips/t-mips-gas fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi fixincludes=fixinc.mips ;; mips-*-sysv* | mips-*riscos*sysv*) if [ x$stabs = xyes ]; then # MIPS System V.3, RISC-OS 4.0 ! tm_file=mips/svr3-4-gdb.h else ! tm_file=mips/svr3-4.h fi xm_file=mips/xm-sysv.h --- 1279,1299 ---- if [ x$gas = xyes ] then ! tmake_file=mips/t-svr3-gas ! else ! tmake_file=mips/t-svr3 ! extra_passes="mips-tfile mips-tdump" fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi fixincludes=fixinc.mips + broken_install=yes ;; mips-*-sysv* | mips-*riscos*sysv*) if [ x$stabs = xyes ]; then # MIPS System V.3, RISC-OS 4.0 ! tm_file=mips/svr3-4-gdb.h else ! tm_file=mips/svr3-4.h fi xm_file=mips/xm-sysv.h *************** *** 1145,1184 **** if [ x$gas = xyes ] then ! tmake_file=mips/t-mips-gas fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi ;; mips-*riscos[56789]*) # Default MIPS RISC-OS 5.0. if [ x$stabs = xyes ]; then ! tm_file=mips/mips-5-gdb.h else ! tm_file=mips/mips-5.h fi if [ x$gas = xyes ] then ! tmake_file=mips/t-mips-gas fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi fixincludes=fixinc.mips ;; mips-*-*) # Default MIPS RISC-OS 4.0. if [ x$stabs = xyes ]; then ! tm_file=mips/mips-4-gdb.h else ! tm_file=mips/mips.h fi if [ x$gas = xyes ] then ! tmake_file=mips/t-mips-gas fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi ;; --- 1301,1349 ---- if [ x$gas = xyes ] then ! tmake_file=mips/t-svr3-gas ! else ! tmake_file=mips/t-svr3 ! extra_passes="mips-tfile mips-tdump" fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi + broken_install=yes ;; mips-*riscos[56789]*) # Default MIPS RISC-OS 5.0. if [ x$stabs = xyes ]; then ! tm_file=mips/mips-5-gdb.h else ! tm_file=mips/mips-5.h fi if [ x$gas = xyes ] then ! tmake_file=mips/t-mips-gas ! else ! extra_passes="mips-tfile mips-tdump" fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi fixincludes=fixinc.mips + broken_install=yes ;; mips-*-*) # Default MIPS RISC-OS 4.0. if [ x$stabs = xyes ]; then ! tm_file=mips/mips-4-gdb.h else ! tm_file=mips/mips.h fi if [ x$gas = xyes ] then ! tmake_file=mips/t-mips-gas ! else ! extra_passes="mips-tfile mips-tdump" fi if [ x$gnu_ld != xyes ] then ! use_collect2=yes fi ;; *************** *** 1216,1223 **** ;; rs6000-ibm-aix3.[01]*) use_collect2=yes ;; rs6000-ibm-aix*) ! tm_file=rs6000/aix32.h use_collect2=yes ;; --- 1381,1394 ---- ;; rs6000-ibm-aix3.[01]*) + tm_file=rs6000/aix31.h + xmake_file=rs6000/x-aix31 use_collect2=yes ;; rs6000-ibm-aix*) ! use_collect2=yes ! ;; ! powerpc-ibm-aix*) ! cpu_type=rs6000 ! tm_file=rs6000/powerpc.h use_collect2=yes ;; *************** *** 1225,1229 **** cpu_type=pa tm_file=pa/pa1-utahmach.h ! use_collect2=no ;; hppa1.0-*-mach*) --- 1396,1400 ---- cpu_type=pa tm_file=pa/pa1-utahmach.h ! use_collect2=yes ;; hppa1.0-*-mach*) *************** *** 1230,1234 **** cpu_type=pa tm_file=pa/pa-utahmach.h ! use_collect2=no ;; hppa1.1-*-bsd*) --- 1401,1405 ---- cpu_type=pa tm_file=pa/pa-utahmach.h ! use_collect2=yes ;; hppa1.1-*-bsd*) *************** *** 1256,1259 **** --- 1427,1445 ---- use_collect2=yes ;; + hppa1.0-*-hpux8.02*) + cpu_type=pa + xm_file=pa/xm-pahpux.h + xmake_file=pa/x-pa-hpux + tmake_file=t-libc-ok + if [ x$gas = xyes ] + then + tm_file=pa/pa-ghpux.h + else + tm_file=pa/pa-oldas.h + fi + broken_install=yes + install_headers_dir=install-headers-cpio + use_collect2=yes + ;; hppa1.1-*-hpux8.02*) cpu_type=pa *************** *** 1263,1268 **** if [ x$gas = xyes ] then ! echo "GAS accepts new syntax only." ! exit 1 else tm_file=pa/pa1-oldas.h --- 1449,1453 ---- if [ x$gas = xyes ] then ! tm_file=pa/pa1-ghpux.h else tm_file=pa/pa1-oldas.h *************** *** 1313,1316 **** --- 1498,1509 ---- ;; alpha-*-osf*) + if [ x$stabs = xyes ] + then + tm_file=alpha/alpha-gdb.h + fi + if [ x$gas != xyes ] + then + extra_passes="mips-tfile mips-tdump" + fi broken_install=yes use_collect2=yes *************** *** 1421,1427 **** # Set up the list of links to be made. # $links is the list of link names, and $files is the list of names to link to. ! files="$host_xm_file $tm_file $md_file $out_file $xm_file $build_xm_file" ! links="config.h tm.h md aux-output.c tconfig.h hconfig.h" # Make the links. while [ -n "$files" ] --- 1614,1629 ---- # Set up the list of links to be made. # $links is the list of link names, and $files is the list of names to link to. ! files="$host_xm_file $tm_file $out_file $xm_file $build_xm_file $md_file" ! links="config.h tm.h aux-output.c tconfig.h hconfig.h" ! ! if [ -n "${cpp_md_flags}" ] ; then ! links="$links md.pre-cpp" ! else ! links="$links md" ! fi + rm -f config.bak + if [ -f config.status ]; then mv -f config.status config.bak; fi + # Make the links. while [ -n "$files" ] *************** *** 1439,1443 **** $remove -f $link - 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 || $copy ${srcdir}/config/$file $link --- 1641,1644 ---- *************** *** 1503,1507 **** # Set EXTRA_HEADERS according to header_files. # This substitutes for lots of t-* files. ! if [ x$header_files = x ] then true else --- 1704,1708 ---- # Set EXTRA_HEADERS according to header_files. # This substitutes for lots of t-* files. ! if [ "x$header_files" = x ] then true else *************** *** 1512,1515 **** --- 1713,1727 ---- fi + # Set EXTRA_PASSES according to extra_passes. + # This substitutes for lots of t-* files. + if [ "x$extra_passes" = x ] + then true + else + rm -f Makefile.xx + sed "s/^EXTRA_PASSES =/EXTRA_PASSES = $extra_passes/" Makefile.tem > Makefile.xx + rm -f Makefile.tem + mv Makefile.xx Makefile.tem + fi + # Add a definition of USE_COLLECT2 if system wants one. # Also tell toplev.c what to do. *************** *** 1531,1536 **** else rm -f Makefile.xx ! (echo "MAYBE_TARGET_DEFAULT = -DTARGET_CPU_DEFAULT=$target_cpu_default")\ ! | cat - Makefile.tem > Makefile.xx rm -f Makefile.tem mv Makefile.xx Makefile.tem --- 1743,1750 ---- else rm -f Makefile.xx ! # This used cat, but rfg@netcom.com said that ran into NFS bugs. ! sed -e "/^# Makefile for GNU C compiler./c\\ ! MAYBE_TARGET_DEFAULT = -DTARGET_CPU_DEFAULT=$target_cpu_default\\ ! \# Makefile for GNU C compiler." Makefile.tem > Makefile.xx rm -f Makefile.tem mv Makefile.xx Makefile.tem *************** *** 1537,1540 **** --- 1751,1763 ---- fi + # Add a CPP_MD dependence if the real md file is in md.pre-cpp. + if [ -n "${cpp_md_flags}" ] ; then + rm -f Makefile.xx + (echo "CPP_MD = md.pre-cpp cpp" ; echo "CPP_MD_FLAGS = $cpp_md_flags" ; echo "MD_FILE = md") \ + | cat - Makefile.tem > Makefile.xx + rm -f Makefile.tem + mv Makefile.xx Makefile.tem + fi + # Conditionalize the makefile for this target machine. if [ -f ${srcdir}/config/${tmake_file} ] *************** *** 1608,1614 **** echo "#!/bin/sh # GCC was configured as follows: ! ${srcdir}/configure" $arguments > config.status ! echo echo host=$canon_host target=$canon_target build=$canon_build >> config.status ! chmod a+x config.status if [ x$canon_host = x$canon_target ] --- 1831,1845 ---- echo "#!/bin/sh # GCC was configured as follows: ! ${srcdir}/configure" $arguments > config.new ! echo echo host=$canon_host target=$canon_target build=$canon_build >> config.new ! chmod a+x config.new ! if [ -f config.bak ] && cmp config.bak config.new >/dev/null 2>/dev/null; ! then ! mv -f config.bak config.status ! rm -f config.new ! else ! mv -f config.new config.status ! rm -f config.bak ! fi if [ x$canon_host = x$canon_target ] diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/configure.bat gcc-2.5.0/configure.bat *** gcc-2.4.5/configure.bat Mon May 17 18:07:27 1993 --- gcc-2.5.0/configure.bat Sat Oct 9 17:38:19 1993 *************** *** 22,25 **** --- 22,26 ---- echo "s/:\$/: \$/g ">> config.sed echo "s/^ \ *\.\// go32 / ">> config.sed + echo "s/<\ *\$(srcdir)\//< $(srcdir)\\/g ">> config.sed echo "s/^ \$(srcdir)\/move-if-change/ update/ ">> config.sed echo "s/^USE_/# USE_/ ">> config.sed *************** *** 27,30 **** --- 28,34 ---- echo "s/ | sed 's,\^\\\.\/,,'`//g ">> config.sed echo "s/^ cd \$(srcdir)[ ]*;// ">> config.sed + + echo "/^# USE_HOST_OBSTACK/ i\ ">> config.sed + echo "USE_HOST_OBSTACK=obstack.o ">> config.sed echo "/^stamp-attrtab/,/update/ { ">> config.sed diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/convert.c gcc-2.5.0/convert.c *** gcc-2.4.5/convert.c Wed Apr 28 06:15:18 1993 --- gcc-2.5.0/convert.c Thu Jul 29 01:57:03 1993 *************** *** 292,296 **** case NEGATE_EXPR: case BIT_NOT_EXPR: ! case ABS_EXPR: { register tree typex = type; --- 292,297 ---- case NEGATE_EXPR: case BIT_NOT_EXPR: ! /* This is not correct for ABS_EXPR, ! since we must test the sign before truncation. */ { register tree typex = type; diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/cp-call.c gcc-2.5.0/cp-call.c *** gcc-2.4.5/cp-call.c Mon May 24 16:06:26 1993 --- gcc-2.5.0/cp-call.c Fri Oct 8 14:59:19 1993 *************** *** 1,5 **** /* Functions related to invoking methods and overloaded functions. Copyright (C) 1987, 1992, 1993 Free Software Foundation, Inc. ! Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. --- 1,6 ---- /* Functions related to invoking methods and overloaded functions. Copyright (C) 1987, 1992, 1993 Free Software Foundation, Inc. ! Contributed by Michael Tiemann (tiemann@cygnus.com) and ! hacked by Brendan Kehoe (brendan@cygnus.com). This file is part of GNU CC. *************** *** 26,29 **** --- 27,31 ---- #include #include "cp-tree.h" + #include "cp-class.h" #include "flags.h" *************** *** 43,53 **** /* Compute the ease with which a conversion can be performed between an expected and the given type. */ ! static int convert_harshness (); #define EVIL_HARSHNESS(ARG) ((ARG) & 1) #define ELLIPSIS_HARSHNESS(ARG) ((ARG) & 2) - #define USER_HARSHNESS(ARG) ((ARG) & 4) #define CONTRAVARIANT_HARSHNESS(ARG) ((ARG) & 8) - #define BASE_DERIVED_HARSHNESS(ARG) ((ARG) & 16) #define INT_TO_BD_HARSHNESS(ARG) (((ARG) << 5) | 16) #define INT_FROM_BD_HARSHNESS(ARG) ((ARG) >> 5) --- 45,59 ---- /* Compute the ease with which a conversion can be performed between an expected and the given type. */ ! static int convert_harshness_old (); ! static struct harshness_code convert_harshness_ansi (); + /* OLD METHOD */ + /* Note the old method also uses USER_HARSHNESS, BASE_DERIVED_HARSHNESS, + CONST_HARSHNESS. */ + #define EVIL 1 + #define TRIVIAL 0 #define EVIL_HARSHNESS(ARG) ((ARG) & 1) #define ELLIPSIS_HARSHNESS(ARG) ((ARG) & 2) #define CONTRAVARIANT_HARSHNESS(ARG) ((ARG) & 8) #define INT_TO_BD_HARSHNESS(ARG) (((ARG) << 5) | 16) #define INT_FROM_BD_HARSHNESS(ARG) ((ARG) >> 5) *************** *** 55,63 **** #define INT_FROM_EASY_HARSHNESS(ARG) ((ARG) >> 5) #define ONLY_EASY_HARSHNESS(ARG) (((ARG) & 31) == 0) #define CONST_HARSHNESS(ARG) ((ARG) & 2048) ! /* Ordering function for overload resolution. */ int ! rank_for_overload (x, y) struct candidate *x, *y; { --- 61,106 ---- #define INT_FROM_EASY_HARSHNESS(ARG) ((ARG) >> 5) #define ONLY_EASY_HARSHNESS(ARG) (((ARG) & 31) == 0) + + + /* NEW METHOD */ + #define EVIL_RETURN(ARG) ((ARG).code = EVIL_CODE, (ARG)) + #define QUAL_RETURN(ARG) ((ARG).code = QUAL_CODE, (ARG)) + #define TRIVIAL_RETURN(ARG) ((ARG).code = TRIVIAL_CODE, (ARG)) + #define ZERO_RETURN(ARG) ((ARG).code = 0, (ARG)) + + #define USER_HARSHNESS(ARG) ((ARG) & 4) + #define BASE_DERIVED_HARSHNESS(ARG) ((ARG) & 16) #define CONST_HARSHNESS(ARG) ((ARG) & 2048) ! /* Ordering function for overload resolution. Compare two candidates ! by gross quality. */ int ! rank_for_overload_ansi (x, y) ! struct candidate *x, *y; ! { ! if (y->h.code & (EVIL_CODE|ELLIPSIS_CODE|USER_CODE)) ! return y->h.code - x->h.code; ! if (x->h.code & (EVIL_CODE|ELLIPSIS_CODE|USER_CODE)) ! return -1; ! ! /* This is set by compute_conversion_costs, for calling a non-const ! member function from a const member function. */ ! if ((y->v.ansi_harshness[0].code & CONST_CODE) ^ (x->v.ansi_harshness[0].code & CONST_CODE)) ! return y->v.ansi_harshness[0].code - x->v.ansi_harshness[0].code; ! ! if (y->h.code & STD_CODE) ! { ! if (x->h.code & STD_CODE) ! return y->h.distance - x->h.distance; ! return 1; ! } ! if (x->h.code & STD_CODE) ! return -1; ! ! return y->h.code - x->h.code; ! } ! ! int ! rank_for_overload_old (x, y) struct candidate *x, *y; { *************** *** 64,69 **** if (y->evil - x->evil) return y->evil - x->evil; ! if (CONST_HARSHNESS (y->harshness[0]) ^ CONST_HARSHNESS (x->harshness[0])) ! return y->harshness[0] - x->harshness[0]; if (y->ellipsis - x->ellipsis) return y->ellipsis - x->ellipsis; --- 107,112 ---- if (y->evil - x->evil) return y->evil - x->evil; ! if (CONST_HARSHNESS (y->v.old_harshness[0]) ^ CONST_HARSHNESS (x->v.old_harshness[0])) ! return y->v.old_harshness[0] - x->v.old_harshness[0]; if (y->ellipsis - x->ellipsis) return y->ellipsis - x->ellipsis; *************** *** 75,78 **** --- 118,748 ---- } + int + rank_for_overload (x, y) + struct candidate *x, *y; + { + if (flag_ansi_overloading) + return rank_for_overload_ansi (x, y); + else + return rank_for_overload_old (x, y); + } + + /* Compare two candidates, argument by argument. */ + int + rank_for_ideal (x, y) + struct candidate *x, *y; + { + int i; + + if (x->h_len != y->h_len) + abort (); + + for (i = 0; i < x->h_len; i++) + { + if (y->v.ansi_harshness[i].code - x->v.ansi_harshness[i].code) + return y->v.ansi_harshness[i].code - x->v.ansi_harshness[i].code; + if ((y->v.ansi_harshness[i].code & STD_CODE) + && (y->v.ansi_harshness[i].distance - x->v.ansi_harshness[i].distance)) + return y->v.ansi_harshness[i].distance - x->v.ansi_harshness[i].distance; + + /* They're both the same code. Now see if we're dealing with an + integral promotion that needs a finer grain of accuracy. */ + if (y->v.ansi_harshness[0].code & PROMO_CODE + && (y->v.ansi_harshness[i].int_penalty ^ x->v.ansi_harshness[i].int_penalty)) + return y->v.ansi_harshness[i].int_penalty - x->v.ansi_harshness[i].int_penalty; + } + return 0; + } + + /* TYPE is the type we wish to convert to. PARM is the parameter + we have to work with. We use a somewhat arbitrary cost function + to measure this conversion. */ + static struct harshness_code + convert_harshness_ansi (type, parmtype, parm) + register tree type, parmtype; + tree parm; + { + struct harshness_code h; + register enum tree_code codel; + register enum tree_code coder; + + h.code = 0; + h.distance = 0; + h.int_penalty = 0; + + #ifdef GATHER_STATISTICS + n_convert_harshness++; + #endif + + if (TYPE_PTRMEMFUNC_P (type)) + type = TYPE_PTRMEMFUNC_FN_TYPE (type); + if (TYPE_PTRMEMFUNC_P (parmtype)) + parmtype = TYPE_PTRMEMFUNC_FN_TYPE (parmtype); + + codel = TREE_CODE (type); + coder = TREE_CODE (parmtype); + + if (TYPE_MAIN_VARIANT (parmtype) == TYPE_MAIN_VARIANT (type)) + return ZERO_RETURN (h); + + if (coder == ERROR_MARK) + return EVIL_RETURN (h); + + if (codel == POINTER_TYPE + && (coder == METHOD_TYPE || coder == FUNCTION_TYPE)) + { + tree p1, p2; + struct harshness_code h1, h2; + + /* Get to the METHOD_TYPE or FUNCTION_TYPE that this might be. */ + type = TREE_TYPE (type); + + if (coder != TREE_CODE (type)) + return EVIL_RETURN (h); + + /* We allow the default conversion between function type + and pointer-to-function type for free. */ + if (type == parmtype) + return ZERO_RETURN (h); + + /* Compare return types. */ + p1 = TREE_TYPE (type); + p2 = TREE_TYPE (parmtype); + h2 = convert_harshness_ansi (p1, p2, NULL_TREE); + if (h2.code & EVIL_CODE) + return h2; + + h1.code = TRIVIAL_CODE; + h1.distance = 0; + + if (h2.distance != 0) + { + tree binfo; + + /* This only works for pointers. */ + if (TREE_CODE (p1) != POINTER_TYPE + && TREE_CODE (p1) != REFERENCE_TYPE) + return EVIL_RETURN (h); + + p1 = TREE_TYPE (p1); + p2 = TREE_TYPE (p2); + if (h2.distance < 0) + binfo = get_binfo (p2, p1, 0); + else + binfo = get_binfo (p1, p2, 0); + + if (! BINFO_OFFSET_ZEROP (binfo)) + { + static int explained = 0; + if (h2.distance < 0) + message_2_types (sorry, "cannot cast `%d' to `%d' at function call site", p2, p1); + else + message_2_types (sorry, "cannot cast `%d' to `%d' at function call site", p1, p2); + + if (! explained++) + sorry ("(because pointer values change during conversion)"); + return EVIL_RETURN (h); + } + } + + h1.code |= h2.code; + if (h2.distance > h1.distance) + h1.distance = h2.distance; + + p1 = TYPE_ARG_TYPES (type); + p2 = TYPE_ARG_TYPES (parmtype); + while (p1 && TREE_VALUE (p1) != void_type_node + && p2 && TREE_VALUE (p2) != void_type_node) + { + h2 = convert_harshness_ansi (TREE_VALUE (p1), TREE_VALUE (p2), + NULL_TREE); + if (h2.code & EVIL_CODE) + return h2; + + if (h2.distance) + { + /* This only works for pointers and references. */ + if (TREE_CODE (TREE_VALUE (p1)) != POINTER_TYPE + && TREE_CODE (TREE_VALUE (p1)) != REFERENCE_TYPE) + return EVIL_RETURN (h); + h2.distance = - h2.distance; + } + + h1.code |= h2.code; + if (h2.distance > h1.distance) + h1.distance = h2.distance; + p1 = TREE_CHAIN (p1); + p2 = TREE_CHAIN (p2); + } + if (p1 == p2) + return h1; + if (p2) + { + if (p1) + return EVIL_RETURN (h); + h1.code |= ELLIPSIS_CODE; + return h1; + } + if (p1) + { + if (TREE_PURPOSE (p1) == NULL_TREE) + h1.code |= EVIL_CODE; + return h1; + } + } + else if (codel == POINTER_TYPE && coder == OFFSET_TYPE) + { + /* Get to the OFFSET_TYPE that this might be. */ + type = TREE_TYPE (type); + + if (coder != TREE_CODE (type)) + return EVIL_RETURN (h); + + if (TYPE_OFFSET_BASETYPE (type) == TYPE_OFFSET_BASETYPE (parmtype)) + h.code = 0; + else if (UNIQUELY_DERIVED_FROM_P (TYPE_OFFSET_BASETYPE (type), + TYPE_OFFSET_BASETYPE (parmtype))) + { + h.code = STD_CODE; + h.distance = 1; + } + else if (UNIQUELY_DERIVED_FROM_P (TYPE_OFFSET_BASETYPE (parmtype), + TYPE_OFFSET_BASETYPE (type))) + { + h.code = STD_CODE; + h.distance = -1; + } + else + return EVIL_RETURN (h); + /* Now test the OFFSET_TYPE's target compatibility. */ + type = TREE_TYPE (type); + parmtype = TREE_TYPE (parmtype); + } + + if (coder == UNKNOWN_TYPE) + { + if (codel == FUNCTION_TYPE + || codel == METHOD_TYPE + || (codel == POINTER_TYPE + && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE + || TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE))) + return TRIVIAL_RETURN (h); + return EVIL_RETURN (h); + } + + if (coder == VOID_TYPE) + return EVIL_RETURN (h); + + if (codel == ENUMERAL_TYPE || codel == INTEGER_TYPE) + { + /* Control equivalence of ints an enums. */ + + if (codel == ENUMERAL_TYPE + && flag_int_enum_equivalence == 0) + { + /* Enums can be converted to ints, but not vice-versa. */ + if (coder != ENUMERAL_TYPE + || TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (parmtype)) + return EVIL_RETURN (h); + } + + /* else enums and ints (almost) freely interconvert. */ + + if (coder == INTEGER_TYPE || coder == ENUMERAL_TYPE) + { + if ((TREE_UNSIGNED (type) ^ TREE_UNSIGNED (parmtype)) + || codel != coder + || TYPE_MODE (type) != TYPE_MODE (parmtype)) + { + /* Make sure a value-preserving condition [from a smaller type to + a larger type] is preferred to a possibly value-destroying + standard conversion [from a larger type to a smaller type]. */ + if (TYPE_PRECISION (type) >= TYPE_PRECISION (parmtype)) + { + h.code = PROMO_CODE; + /* A char, short, wchar_t, etc., should promote to an int if + it can handle it, otherwise to an unsigned. So we'll make + an unsigned. */ + if (type != integer_type_node) + h.int_penalty = 1; + } + else + h.code = STD_CODE; + } + + /* If the three above conditions didn't trigger, we have found two + very similar types. On systems where they're the same size, we + can end up here with TYPE as `long' and PARMTYPE as `int'. Make + sure we realize that, even though they're the same mode, we will + have to do some sort of integral promotion on the type, since + they're not the same. */ + if (! comptypes (type, parmtype, 1) && h.code == 0) + { + /* This call to common_type will return the best type for the + combination. If it matches TYPE, that means we'll be converting + from a so-called smaller type (in PARMTYPE) to the larger in TYPE, + thus an integral promotion. Otherwise, it must be going from a + larger type in PARMTYPE to a smaller expected type in TYPE, so we + make it a standard conversion instead. */ + if (common_type (type, parmtype) == type) + h.code = PROMO_CODE; + else + h.code = STD_CODE; + } + + return h; + } + else if (coder == REAL_TYPE) + { + h.code = STD_CODE; + h.distance = 0; + return h; + } + } + + if (codel == REAL_TYPE) + { + if (coder == REAL_TYPE) + { + /* Shun converting between float and double if a choice exists. */ + if (TYPE_MODE (type) != TYPE_MODE (parmtype)) + { + h.code = PROMO_CODE; + return h; + } + return ZERO_RETURN (h); + } + else if (coder == INTEGER_TYPE || coder == ENUMERAL_TYPE) + { + h.code = STD_CODE; + h.distance = 0; + return h; + } + } + + /* Convert arrays which have not previously been converted. */ + if (codel == ARRAY_TYPE) + codel = POINTER_TYPE; + if (coder == ARRAY_TYPE) + coder = POINTER_TYPE; + + /* Conversions among pointers */ + if (codel == POINTER_TYPE && coder == POINTER_TYPE) + { + register tree ttl = TYPE_MAIN_VARIANT (TREE_TYPE (type)); + register tree ttr = TYPE_MAIN_VARIANT (TREE_TYPE (parmtype)); + int penalty = 4 * (ttl != ttr); + + /* Anything converts to void *. void * converts to anything. + Since these may be `const void *' (etc.) use VOID_TYPE + instead of void_type_node. Otherwise, the targets must be the same, + except that we do allow (at some cost) conversion between signed and + unsinged pointer types. */ + + if ((TREE_CODE (ttl) == METHOD_TYPE + || TREE_CODE (ttl) == FUNCTION_TYPE) + && TREE_CODE (ttl) == TREE_CODE (ttr)) + { + if (comptypes (ttl, ttr, -1)) + { + h.code = penalty ? STD_CODE : 0; + h.distance = 0; + } + else + h.code = EVIL_CODE; + return h; + } + + #if 1 + if (TREE_CODE (ttl) != VOID_TYPE && TREE_CODE (ttr) != VOID_TYPE) + { + if (TREE_UNSIGNED (ttl) != TREE_UNSIGNED (ttr)) + { + ttl = unsigned_type (ttl); + ttr = unsigned_type (ttr); + penalty = 10; + } + if (! comp_target_types (ttl, ttr, 0)) + return EVIL_RETURN (h); + } + #else + if (!(TREE_CODE (ttl) == VOID_TYPE + || TREE_CODE (ttr) == VOID_TYPE + || (TREE_UNSIGNED (ttl) ^ TREE_UNSIGNED (ttr) + && (ttl = unsigned_type (ttl), + ttr = unsigned_type (ttr), + penalty = 10, 0)) + || (comp_target_types (ttl, ttr, 0)))) + return EVIL_RETURN (h); + #endif + + if (penalty == 10 || ttr == ttl) + { + tree tmp1 = TREE_TYPE (type), tmp2 = TREE_TYPE (parmtype); + + /* If one was unsigned but the other wasn't, then we need to + do a standard conversion from T to unsigned T. */ + if (penalty == 10) + h.code = PROMO_CODE; /* was STD_CODE */ + else + h.code = 0; + + /* Note conversion from `T*' to `const T*', + or `T*' to `volatile T*'. */ + if (ttl == ttr + && ((TYPE_READONLY (tmp1) != TREE_READONLY (tmp2)) + || (TYPE_VOLATILE (tmp1) != TYPE_VOLATILE (tmp2)))) + h.code |= QUAL_CODE; + + h.distance = 0; + return h; + } + + + if (TREE_CODE (ttl) == RECORD_TYPE && TREE_CODE (ttr) == RECORD_TYPE) + { + int b_or_d = get_base_distance (ttl, ttr, 0, 0); + if (b_or_d < 0) + { + b_or_d = get_base_distance (ttr, ttl, 0, 0); + if (b_or_d < 0) + return EVIL_RETURN (h); + h.distance = -b_or_d; + } + else + h.distance = b_or_d; + h.code = STD_CODE; + return h; + } + + /* If converting from a `class*' to a `void*', make it + less favorable than any inheritance relationship. */ + if (TREE_CODE (ttl) == VOID_TYPE && IS_AGGR_TYPE (ttr)) + { + h.code = STD_CODE; + h.distance = CLASSTYPE_MAX_DEPTH (ttr)+1; + return h; + } + h.code = penalty ? STD_CODE : PROMO_CODE; + return h; + } + + if (codel == POINTER_TYPE && coder == INTEGER_TYPE) + { + /* This is not a bad match, but don't let it beat + integer-enum combinations. */ + if (parm && integer_zerop (parm)) + { + h.code = STD_CODE; + h.distance = 0; + return h; + } + } + + /* C++: one of the types must be a reference type. */ + { + tree ttl, ttr; + register tree intype = TYPE_MAIN_VARIANT (parmtype); + register enum tree_code form = TREE_CODE (intype); + int penalty; + + if (codel == REFERENCE_TYPE || coder == REFERENCE_TYPE) + { + ttl = TYPE_MAIN_VARIANT (type); + + if (codel == REFERENCE_TYPE) + { + ttl = TREE_TYPE (ttl); + + /* When passing a non-const argument into a const reference, + dig it a little, so a non-const reference is preferred over + this one. (mrs) */ + if (parm && TREE_READONLY (ttl) && ! TREE_READONLY (parm)) + penalty = 2; + else + penalty = 0; + + ttl = TYPE_MAIN_VARIANT (ttl); + + if (form == OFFSET_TYPE) + { + intype = TREE_TYPE (intype); + form = TREE_CODE (intype); + } + + if (form == REFERENCE_TYPE) + { + intype = TYPE_MAIN_VARIANT (TREE_TYPE (intype)); + + if (ttl == intype) + return ZERO_RETURN (h); + penalty = 2; + } + else + { + /* Can reference be built up? */ + if (ttl == intype && penalty == 0) { + /* Because the READONLY and VIRTUAL bits are not always in + the type, this extra check is necessary. The problem + should be fixed someplace else, and this extra code + removed. + + Also, if type if a reference, the readonly bits could + either be in the outer type (with reference) or on the + inner type (the thing being referenced). (mrs) */ + if (parm + && ((TREE_READONLY (parm) + && ! (TYPE_READONLY (type) + || (TREE_CODE (type) == REFERENCE_TYPE + && TYPE_READONLY (TREE_TYPE (type))))) + || (TREE_SIDE_EFFECTS (parm) + && ! (TYPE_VOLATILE (type) + || (TREE_CODE (type) == REFERENCE_TYPE + && TYPE_VOLATILE (TREE_TYPE (type))))))) + penalty = 2; + else + return ZERO_RETURN (h); + } + else + penalty = 2; + } + } + else if (form == REFERENCE_TYPE) + { + if (parm) + { + tree tmp = convert_from_reference (parm); + intype = TYPE_MAIN_VARIANT (TREE_TYPE (tmp)); + } + else + { + intype = parmtype; + do + intype = TREE_TYPE (intype); + while (TREE_CODE (intype) == REFERENCE_TYPE); + intype = TYPE_MAIN_VARIANT (intype); + } + + if (ttl == intype) + return ZERO_RETURN (h); + else + penalty = 2; + } + + if (TREE_UNSIGNED (ttl) ^ TREE_UNSIGNED (intype)) + { + ttl = unsigned_type (ttl); + intype = unsigned_type (intype); + penalty += 2; + } + + ttr = intype; + + /* If the initializer is not an lvalue, then it does not + matter if we make life easier for the programmer + by creating a temporary variable with which to + hold the result. */ + if (parm && (coder == INTEGER_TYPE + || coder == ENUMERAL_TYPE + || coder == REAL_TYPE) + && ! lvalue_p (parm)) + { + h = convert_harshness_ansi (ttl, ttr, NULL_TREE); + if (penalty) + h.code |= STD_CODE; + h.distance = 0; + return h; + } + + if (ttl == ttr) + { + if (penalty > 2) + { + h.code = STD_CODE; + h.distance = 0; + } + else + { + h.code = TRIVIAL_CODE; + /* We set this here so that build_overload_call_real will be + able to see the penalty we found, rather than just looking + at a TRIVIAL_CODE with no other information. */ + h.int_penalty = penalty; + } + return h; + } + + /* Pointers to voids always convert for pointers. But + make them less natural than more specific matches. */ + if (TREE_CODE (ttl) == POINTER_TYPE && TREE_CODE (ttr) == POINTER_TYPE) + { + if (TREE_TYPE (ttl) == void_type_node + || TREE_TYPE (ttr) == void_type_node) + { + h.code = STD_CODE; + h.distance = 0; + return h; + } + } + + if (parm && codel != REFERENCE_TYPE) + { + h = convert_harshness_ansi (ttl, ttr, NULL_TREE); + if (penalty) + h.code |= STD_CODE; + h.distance = 0; + return h; + } + + /* Here it does matter. If this conversion is from derived to base, + allow it. Otherwise, types must be compatible in the strong sense. */ + if (TREE_CODE (ttl) == RECORD_TYPE && TREE_CODE (ttr) == RECORD_TYPE) + { + int b_or_d = get_base_distance (ttl, ttr, 0, 0); + if (b_or_d < 0) + { + b_or_d = get_base_distance (ttr, ttl, 0, 0); + if (b_or_d < 0) + return EVIL_RETURN (h); + h.distance = -b_or_d; + } + /* Say that this conversion is relatively painless. + If it turns out that there is a user-defined X(X&) + constructor, then that will be invoked, but that's + preferable to dealing with other user-defined conversions + that may produce surprising results. */ + else + h.distance = b_or_d; + h.code = STD_CODE; + return h; + } + + if (comp_target_types (ttl, intype, 1)) + { + if (penalty) + h.code = STD_CODE; + h.distance = 0; + return h; + } + } + } + if (codel == RECORD_TYPE && coder == RECORD_TYPE) + { + int b_or_d = get_base_distance (type, parmtype, 0, 0); + if (b_or_d < 0) + { + b_or_d = get_base_distance (parmtype, type, 0, 0); + if (b_or_d < 0) + return EVIL_RETURN (h); + h.distance = -b_or_d; + } + else + h.distance = b_or_d; + h.code = STD_CODE; + return h; + } + return EVIL_RETURN (h); + } + /* TYPE is the type we wish to convert to. PARM is the parameter we have to work with. We use a somewhat arbitrary cost function *************** *** 79,88 **** to measure this conversion. */ static int ! convert_harshness (type, parmtype, parm) register tree type, parmtype; tree parm; { ! register enum tree_code codel = TREE_CODE (type); ! register enum tree_code coder = TREE_CODE (parmtype); #ifdef GATHER_STATISTICS --- 749,758 ---- to measure this conversion. */ static int ! convert_harshness_old (type, parmtype, parm) register tree type, parmtype; tree parm; { ! register enum tree_code codel; ! register enum tree_code coder; #ifdef GATHER_STATISTICS *************** *** 90,98 **** #endif if (TYPE_MAIN_VARIANT (parmtype) == TYPE_MAIN_VARIANT (type)) ! return 0; if (coder == ERROR_MARK) ! return 1; if (codel == POINTER_TYPE --- 760,776 ---- #endif + if (TYPE_PTRMEMFUNC_P (type)) + type = TYPE_PTRMEMFUNC_FN_TYPE (type); + if (TYPE_PTRMEMFUNC_P (parmtype)) + parmtype = TYPE_PTRMEMFUNC_FN_TYPE (parmtype); + + codel = TREE_CODE (type); + coder = TREE_CODE (parmtype); + if (TYPE_MAIN_VARIANT (parmtype) == TYPE_MAIN_VARIANT (type)) ! return TRIVIAL; if (coder == ERROR_MARK) ! return EVIL; if (codel == POINTER_TYPE *************** *** 106,110 **** if (coder != TREE_CODE (type)) ! return 1; harshness = 0; --- 784,788 ---- if (coder != TREE_CODE (type)) ! return EVIL; harshness = 0; *************** *** 113,117 **** and pointer-to-function type for free. */ if (type == parmtype) ! return 0; /* Compare return types. */ --- 791,795 ---- and pointer-to-function type for free. */ if (type == parmtype) ! return TRIVIAL; /* Compare return types. */ *************** *** 118,124 **** p1 = TREE_TYPE (type); p2 = TREE_TYPE (parmtype); ! new_harshness = convert_harshness (p1, p2, NULL_TREE); ! if (new_harshness & 1) ! return 1; if (BASE_DERIVED_HARSHNESS (new_harshness)) --- 796,802 ---- p1 = TREE_TYPE (type); p2 = TREE_TYPE (parmtype); ! new_harshness = convert_harshness_old (p1, p2, NULL_TREE); ! if (EVIL_HARSHNESS (new_harshness)) ! return EVIL; if (BASE_DERIVED_HARSHNESS (new_harshness)) *************** *** 129,133 **** if (TREE_CODE (p1) != POINTER_TYPE && TREE_CODE (p1) != REFERENCE_TYPE) ! return 1; p1 = TREE_TYPE (p1); --- 807,811 ---- if (TREE_CODE (p1) != POINTER_TYPE && TREE_CODE (p1) != REFERENCE_TYPE) ! return EVIL; p1 = TREE_TYPE (p1); *************** *** 148,152 **** if (! explained++) sorry ("(because pointer values change during conversion)"); ! return 1; } } --- 826,830 ---- if (! explained++) sorry ("(because pointer values change during conversion)"); ! return EVIL; } } *************** *** 159,165 **** && p2 && TREE_VALUE (p2) != void_type_node) { ! new_harshness = convert_harshness (TREE_VALUE (p1), TREE_VALUE (p2), NULL_TREE); if (EVIL_HARSHNESS (new_harshness)) ! return 1; if (BASE_DERIVED_HARSHNESS (new_harshness)) --- 837,844 ---- && p2 && TREE_VALUE (p2) != void_type_node) { ! new_harshness = convert_harshness_old (TREE_VALUE (p1), ! TREE_VALUE (p2), NULL_TREE); if (EVIL_HARSHNESS (new_harshness)) ! return EVIL; if (BASE_DERIVED_HARSHNESS (new_harshness)) *************** *** 168,172 **** if (TREE_CODE (TREE_VALUE (p1)) != POINTER_TYPE && TREE_CODE (TREE_VALUE (p1)) != REFERENCE_TYPE) ! return 1; new_harshness ^= CONTRAVARIANT_HARSHNESS (new_harshness); harshness |= new_harshness; --- 847,851 ---- if (TREE_CODE (TREE_VALUE (p1)) != POINTER_TYPE && TREE_CODE (TREE_VALUE (p1)) != REFERENCE_TYPE) ! return EVIL; new_harshness ^= CONTRAVARIANT_HARSHNESS (new_harshness); harshness |= new_harshness; *************** *** 185,189 **** return harshness; if (p2) ! return p1 ? 1 : (harshness | ELLIPSIS_HARSHNESS (-1)); if (p1) return harshness | (TREE_PURPOSE (p1) == NULL_TREE); --- 864,868 ---- return harshness; if (p2) ! return p1 ? EVIL : (harshness | ELLIPSIS_HARSHNESS (-1)); if (p1) return harshness | (TREE_PURPOSE (p1) == NULL_TREE); *************** *** 199,203 **** if (coder != TREE_CODE (type)) ! return 1; harshness = 0; --- 878,882 ---- if (coder != TREE_CODE (type)) ! return EVIL; harshness = 0; *************** *** 212,216 **** harshness = CONTRAVARIANT_HARSHNESS (-1); else ! return 1; /* Now test the OFFSET_TYPE's target compatibility. */ type = TREE_TYPE (type); --- 891,895 ---- harshness = CONTRAVARIANT_HARSHNESS (-1); else ! return EVIL; /* Now test the OFFSET_TYPE's target compatibility. */ type = TREE_TYPE (type); *************** *** 225,234 **** && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE || TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE))) ! return 0; ! return 1; } if (coder == VOID_TYPE) ! return 1; if (codel == ENUMERAL_TYPE || codel == INTEGER_TYPE) --- 904,913 ---- && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE || TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE))) ! return TRIVIAL; ! return EVIL; } if (coder == VOID_TYPE) ! return EVIL; if (codel == ENUMERAL_TYPE || codel == INTEGER_TYPE) *************** *** 242,246 **** if (coder != ENUMERAL_TYPE || TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (parmtype)) ! return 1; } --- 921,925 ---- if (coder != ENUMERAL_TYPE || TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (parmtype)) ! return EVIL; } *************** *** 266,270 **** if (TYPE_MODE (type) != TYPE_MODE (parmtype)) return INT_TO_EASY_HARSHNESS (2); ! return 0; } else if (coder == INTEGER_TYPE || coder == ENUMERAL_TYPE) --- 945,949 ---- if (TYPE_MODE (type) != TYPE_MODE (parmtype)) return INT_TO_EASY_HARSHNESS (2); ! return TRIVIAL; } else if (coder == INTEGER_TYPE || coder == ENUMERAL_TYPE) *************** *** 296,300 **** if (comptypes (ttl, ttr, -1)) return INT_TO_EASY_HARSHNESS (penalty); ! return 1; } --- 975,979 ---- if (comptypes (ttl, ttr, -1)) return INT_TO_EASY_HARSHNESS (penalty); ! return EVIL; } *************** *** 306,310 **** penalty = 10, 0)) || (comp_target_types (ttl, ttr, 0)))) ! return 1; if (penalty == 10) --- 985,989 ---- penalty = 10, 0)) || (comp_target_types (ttl, ttr, 0)))) ! return EVIL; if (penalty == 10) *************** *** 320,324 **** b_or_d = get_base_distance (ttr, ttl, 0, 0); if (b_or_d < 0) ! return 1; return CONTRAVARIANT_HARSHNESS (-1); } --- 999,1003 ---- b_or_d = get_base_distance (ttr, ttl, 0, 0); if (b_or_d < 0) ! return EVIL; return CONTRAVARIANT_HARSHNESS (-1); } *************** *** 376,380 **** if (ttl == intype) ! return 0; penalty = 2; } --- 1055,1059 ---- if (ttl == intype) ! return TRIVIAL; penalty = 2; } *************** *** 383,390 **** /* Can reference be built up? */ if (ttl == intype && penalty == 0) { ! /* Because the READONLY bits and VOLATILE bits are not ! always in the type, this extra check is necessary. The ! problem should be fixed someplace else, and this extra ! code removed. Also, if type if a reference, the readonly bits could --- 1062,1069 ---- /* Can reference be built up? */ if (ttl == intype && penalty == 0) { ! /* Because the READONLY bits and VIRTUAL bits are not always ! in the type, this extra check is necessary. The problem ! should be fixed someplace else, and this extra code ! removed. Also, if type if a reference, the readonly bits could *************** *** 393,399 **** if (parm && ((TREE_READONLY (parm) ! && ! (TYPE_READONLY (type) ! || (TREE_CODE (type) == REFERENCE_TYPE ! && TYPE_READONLY (TREE_TYPE (type))))) || (TREE_SIDE_EFFECTS (parm) && ! (TYPE_VOLATILE (type) --- 1072,1078 ---- if (parm && ((TREE_READONLY (parm) ! && ! (TYPE_READONLY (type) ! || (TREE_CODE (type) == REFERENCE_TYPE ! && TYPE_READONLY (TREE_TYPE (type))))) || (TREE_SIDE_EFFECTS (parm) && ! (TYPE_VOLATILE (type) *************** *** 400,407 **** || (TREE_CODE (type) == REFERENCE_TYPE && TYPE_VOLATILE (TREE_TYPE (type))))))) - penalty = 2; else ! return 0; } else --- 1079,1085 ---- || (TREE_CODE (type) == REFERENCE_TYPE && TYPE_VOLATILE (TREE_TYPE (type))))))) penalty = 2; else ! return TRIVIAL; } else *************** *** 428,432 **** if (ttl == intype) ! return 0; else penalty = 2; --- 1106,1110 ---- if (ttl == intype) ! return TRIVIAL; else penalty = 2; *************** *** 450,454 **** || coder == REAL_TYPE) && ! lvalue_p (parm)) ! return (convert_harshness (ttl, ttr, NULL_TREE) | INT_TO_EASY_HARSHNESS (penalty)); --- 1128,1132 ---- || coder == REAL_TYPE) && ! lvalue_p (parm)) ! return (convert_harshness_old (ttl, ttr, NULL_TREE) | INT_TO_EASY_HARSHNESS (penalty)); *************** *** 468,472 **** if (parm && codel != REFERENCE_TYPE) ! return (convert_harshness (ttl, ttr, NULL_TREE) | INT_TO_EASY_HARSHNESS (penalty)); --- 1146,1150 ---- if (parm && codel != REFERENCE_TYPE) ! return (convert_harshness_old (ttl, ttr, NULL_TREE) | INT_TO_EASY_HARSHNESS (penalty)); *************** *** 481,485 **** b_or_d = get_base_distance (ttr, ttl, 0, 0); if (b_or_d < 0) ! return 1; return CONTRAVARIANT_HARSHNESS (-1); } --- 1159,1163 ---- b_or_d = get_base_distance (ttr, ttl, 0, 0); if (b_or_d < 0) ! return EVIL; return CONTRAVARIANT_HARSHNESS (-1); } *************** *** 503,507 **** b_or_d = get_base_distance (parmtype, type, 0, 0); if (b_or_d < 0) ! return 1; return CONTRAVARIANT_HARSHNESS (-1); } --- 1181,1185 ---- b_or_d = get_base_distance (parmtype, type, 0, 0); if (b_or_d < 0) ! return EVIL; return CONTRAVARIANT_HARSHNESS (-1); } *************** *** 508,525 **** return INT_TO_BD_HARSHNESS (b_or_d); } ! return 1; } ! /* Algorithm: Start out with no strikes against. For each argument ! which requires a (subjective) hard conversion (such as between ! floating point and integer), issue a strike. If there are the same ! number of formal and actual parameters in the list, there will be at ! least on strike, otherwise an exact match would have been found. If ! there are not the same number of arguments in the type lists, we are ! not dead yet: a `...' means that we can have more parms then were ! declared, and if we wind up in the default argument section of the ! list those can be used as well. If an exact match could be found for ! one of those cases, return it immediately. Otherwise, rank the fields ! so that fields with fewer strikes are tried first. Conversions between builtin and user-defined types are allowed, but --- 1186,1198 ---- return INT_TO_BD_HARSHNESS (b_or_d); } ! return EVIL; } ! /* Algorithm: For each argument, calculate how difficult it is to ! make FUNCTION accept that argument. If we can easily tell that ! FUNCTION won't be acceptable to one of the arguments, then we ! don't need to compute the ease of converting the other arguments, ! since it will never show up in the intersection of all arguments' ! favorite functions. Conversions between builtin and user-defined types are allowed, but *************** *** 529,533 **** void ! compute_conversion_costs (function, tta_in, cp, arglen) tree function; tree tta_in; --- 1202,1493 ---- void ! compute_conversion_costs_ansi (function, tta_in, cp, arglen) ! tree function; ! tree tta_in; ! struct candidate *cp; ! int arglen; ! { ! tree ttf_in = TYPE_ARG_TYPES (TREE_TYPE (function)); ! tree ttf = ttf_in; ! tree tta = tta_in; ! ! /* Start out with no strikes against. */ ! int evil_strikes = 0; ! int ellipsis_strikes = 0; ! int user_strikes = 0; ! int b_or_d_strikes = 0; ! int easy_strikes = 0; ! ! int strike_index = 0, win; ! struct harshness_code lose; ! ! #ifdef GATHER_STATISTICS ! n_compute_conversion_costs++; ! #endif ! ! cp->function = function; ! cp->arg = tta ? TREE_VALUE (tta) : NULL_TREE; ! cp->u.bad_arg = 0; /* optimistic! */ ! ! cp->h.code = 0; ! cp->h.distance = 0; ! cp->h.int_penalty = 0; ! bzero (cp->v.ansi_harshness, (arglen+1) * sizeof (short)); ! ! while (ttf && tta) ! { ! struct harshness_code h; ! ! if (ttf == void_list_node) ! break; ! ! if (type_unknown_p (TREE_VALUE (tta))) ! { ! /* Must perform some instantiation here. */ ! tree rhs = TREE_VALUE (tta); ! tree lhstype = TREE_VALUE (ttf); ! ! /* Keep quiet about possible contravariance violations. */ ! int old_inhibit_warnings = inhibit_warnings; ! inhibit_warnings = 1; ! ! /* @@ This is to undo what `grokdeclarator' does to ! parameter types. It really should go through ! something more general. */ ! ! TREE_TYPE (tta) = unknown_type_node; ! rhs = instantiate_type (lhstype, rhs, 0); ! inhibit_warnings = old_inhibit_warnings; ! ! if (TREE_CODE (rhs) == ERROR_MARK) ! h.code = EVIL_CODE; ! else ! h = convert_harshness_ansi (lhstype, TREE_TYPE (rhs), rhs); ! } ! else ! h = convert_harshness_ansi (TREE_VALUE (ttf), ! TREE_TYPE (TREE_VALUE (tta)), ! TREE_VALUE (tta)); ! ! cp->v.ansi_harshness[strike_index] = h; ! if ((h.code & EVIL_CODE) ! || ((h.code & STD_CODE) && h.distance < 0)) ! { ! cp->u.bad_arg = strike_index; ! evil_strikes = 1; ! } ! else if (h.code & ELLIPSIS_CODE) ! ellipsis_strikes += 1; ! #if 0 ! /* This is never set by `convert_harshness_ansi'. */ ! else if (h.code & USER_CODE) ! { ! user_strikes += 1; ! } ! #endif ! else ! { ! if ((h.code & STD_CODE) && h.distance) ! { ! if (h.distance > b_or_d_strikes) ! b_or_d_strikes = h.distance; ! } ! else ! easy_strikes += (h.code & (STD_CODE|PROMO_CODE|TRIVIAL_CODE)); ! cp->h.code |= h.code; ! /* Make sure we communicate this. */ ! cp->h.int_penalty += h.int_penalty; ! } ! ! ttf = TREE_CHAIN (ttf); ! tta = TREE_CHAIN (tta); ! strike_index += 1; ! } ! ! if (tta) ! { ! /* ran out of formals, and parmlist is fixed size. */ ! if (ttf /* == void_type_node */) ! { ! cp->h.code = EVIL_CODE; ! cp->u.bad_arg = -1; ! return; ! } ! else ! ellipsis_strikes += list_length (tta); ! } ! else if (ttf && ttf != void_list_node) ! { ! /* ran out of actuals, and no defaults. */ ! if (TREE_PURPOSE (ttf) == NULL_TREE) ! { ! cp->h.code = EVIL_CODE; ! cp->u.bad_arg = -2; ! return; ! } ! /* Store index of first default. */ ! cp->v.ansi_harshness[arglen].distance = strike_index+1; ! } ! else ! cp->v.ansi_harshness[arglen].distance = 0; ! ! /* Argument list lengths work out, so don't need to check them again. */ ! if (evil_strikes) ! { ! /* We do not check for derived->base conversions here, since in ! no case would they give evil strike counts, unless such conversions ! are somehow ambiguous. */ ! ! /* See if any user-defined conversions apply. ! But make sure that we do not loop. */ ! static int dont_convert_types = 0; ! ! if (dont_convert_types) ! { ! cp->h.code = EVIL_CODE; ! return; ! } ! ! win = 0; /* Only get one chance to win. */ ! ttf = TYPE_ARG_TYPES (TREE_TYPE (function)); ! tta = tta_in; ! strike_index = 0; ! evil_strikes = 0; ! ! while (ttf && tta) ! { ! if (ttf == void_list_node) ! break; ! ! lose = cp->v.ansi_harshness[strike_index]; ! if ((lose.code & EVIL_CODE) ! || ((lose.code & STD_CODE) && lose.distance < 0)) ! { ! tree actual_type = TREE_TYPE (TREE_VALUE (tta)); ! tree formal_type = TREE_VALUE (ttf); ! ! dont_convert_types = 1; ! ! if (TREE_CODE (formal_type) == REFERENCE_TYPE) ! formal_type = TREE_TYPE (formal_type); ! if (TREE_CODE (actual_type) == REFERENCE_TYPE) ! actual_type = TREE_TYPE (actual_type); ! ! if (formal_type != error_mark_node ! && actual_type != error_mark_node) ! { ! formal_type = TYPE_MAIN_VARIANT (formal_type); ! actual_type = TYPE_MAIN_VARIANT (actual_type); ! ! if (TYPE_HAS_CONSTRUCTOR (formal_type)) ! { ! /* If it has a constructor for this type, ! try to use it. */ ! /* @@ There is no way to save this result yet, so ! success is a NULL_TREE for now. */ ! if (convert_to_aggr (formal_type, TREE_VALUE (tta), 0, 1) ! != error_mark_node) ! win++; ! } ! if (TYPE_LANG_SPECIFIC (actual_type) ! && TYPE_HAS_CONVERSION (actual_type)) ! { ! if (TREE_CODE (formal_type) == INTEGER_TYPE ! && TYPE_HAS_INT_CONVERSION (actual_type)) ! win++; ! else if (TREE_CODE (formal_type) == REAL_TYPE ! && TYPE_HAS_REAL_CONVERSION (actual_type)) ! win++; ! else ! { ! tree conv; ! /* Don't issue warnings since we're only groping ! around for the right answer, we haven't yet ! committed to going with this solution. */ ! int old_inhibit_warnings = inhibit_warnings; ! ! inhibit_warnings = 1; ! conv = build_type_conversion (CALL_EXPR, TREE_VALUE (ttf), TREE_VALUE (tta), 0); ! inhibit_warnings = old_inhibit_warnings; ! ! if (conv) ! { ! if (conv == error_mark_node) ! win += 2; ! else ! win++; ! } ! else if (TREE_CODE (TREE_VALUE (ttf)) == REFERENCE_TYPE) ! { ! conv = build_type_conversion (CALL_EXPR, formal_type, TREE_VALUE (tta), 0); ! if (conv) ! { ! if (conv == error_mark_node) ! win += 2; ! else ! win++; ! } ! } ! } ! } ! } ! dont_convert_types = 0; ! ! if (win == 1) ! { ! user_strikes += 1; ! cp->v.ansi_harshness[strike_index].code = USER_CODE; ! win = 0; ! } ! else ! { ! if (cp->u.bad_arg > strike_index) ! cp->u.bad_arg = strike_index; ! ! evil_strikes = win ? 2 : 1; ! break; ! } ! } ! ! ttf = TREE_CHAIN (ttf); ! tta = TREE_CHAIN (tta); ! strike_index += 1; ! } ! } ! ! /* Const member functions get a small penalty because defaulting ! to const is less useful than defaulting to non-const. */ ! /* This is bogus, it does not correspond to anything in the ARM. ! This code will be fixed when this entire section is rewritten ! to conform to the ARM. (mrs) */ ! if (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE) ! { ! if (TYPE_READONLY (TREE_TYPE (TREE_VALUE (ttf_in)))) ! { ! cp->v.ansi_harshness[0].code |= TRIVIAL_CODE; ! ++easy_strikes; ! } ! else ! { ! /* Calling a non-const member function from a const member function ! is probably invalid, but for now we let it only draw a warning. ! We indicate that such a mismatch has occurred by setting the ! harshness to a maximum value. */ ! if (TREE_CODE (TREE_TYPE (TREE_VALUE (tta_in))) == POINTER_TYPE ! && (TYPE_READONLY (TREE_TYPE (TREE_TYPE (TREE_VALUE (tta_in)))))) ! cp->v.ansi_harshness[0].code |= CONST_CODE; ! } ! } ! ! if (evil_strikes) ! cp->h.code = EVIL_CODE; ! if (ellipsis_strikes) ! cp->h.code |= ELLIPSIS_CODE; ! if (user_strikes) ! cp->h.code |= USER_CODE; ! } ! ! void ! compute_conversion_costs_old (function, tta_in, cp, arglen) tree function; tree tta_in; *************** *** 556,560 **** cp->u.bad_arg = 0; /* optimistic! */ ! bzero (cp->harshness, (arglen+1) * sizeof (short)); while (ttf && tta) --- 1516,1520 ---- cp->u.bad_arg = 0; /* optimistic! */ ! bzero (cp->v.old_harshness, (arglen+1) * sizeof (short)); while (ttf && tta) *************** *** 587,591 **** else { ! harshness = convert_harshness (lhstype, TREE_TYPE (rhs), rhs); /* harshness |= 2; */ } --- 1547,1552 ---- else { ! harshness = convert_harshness_old (lhstype, TREE_TYPE (rhs), ! rhs); /* harshness |= 2; */ } *************** *** 592,598 **** } else ! harshness = convert_harshness (TREE_VALUE (ttf), TREE_TYPE (TREE_VALUE (tta)), TREE_VALUE (tta)); ! cp->harshness[strike_index] = harshness; if (EVIL_HARSHNESS (harshness) || CONTRAVARIANT_HARSHNESS (harshness)) --- 1553,1561 ---- } else ! harshness = convert_harshness_old (TREE_VALUE (ttf), ! TREE_TYPE (TREE_VALUE (tta)), ! TREE_VALUE (tta)); ! cp->v.old_harshness[strike_index] = harshness; if (EVIL_HARSHNESS (harshness) || CONTRAVARIANT_HARSHNESS (harshness)) *************** *** 606,610 **** } #if 0 ! /* This is never set by `convert_harshness'. */ else if (USER_HARSHNESS (harshness)) { --- 1569,1573 ---- } #if 0 ! /* This is never set by `convert_harshness_old'. */ else if (USER_HARSHNESS (harshness)) { *************** *** 632,635 **** --- 1595,1599 ---- return; } + else ellipsis_strikes += list_length (tta); } else if (ttf && ttf != void_list_node) *************** *** 643,649 **** } /* Store index of first default. */ ! cp->harshness[arglen] = strike_index+1; } ! else cp->harshness[arglen] = 0; /* Argument list lengths work out, so don't need to check them again. */ --- 1607,1614 ---- } /* Store index of first default. */ ! cp->v.old_harshness[arglen] = strike_index+1; } ! else ! cp->v.old_harshness[arglen] = 0; /* Argument list lengths work out, so don't need to check them again. */ *************** *** 675,679 **** break; ! lose = cp->harshness[strike_index]; if (EVIL_HARSHNESS (lose) || CONTRAVARIANT_HARSHNESS (lose)) --- 1640,1644 ---- break; ! lose = cp->v.old_harshness[strike_index]; if (EVIL_HARSHNESS (lose) || CONTRAVARIANT_HARSHNESS (lose)) *************** *** 743,747 **** { user_strikes += 1; ! cp->harshness[strike_index] = USER_HARSHNESS (-1); win = 0; } --- 1708,1712 ---- { user_strikes += 1; ! cp->v.old_harshness[strike_index] = USER_HARSHNESS (-1); win = 0; } *************** *** 771,775 **** if (TYPE_READONLY (TREE_TYPE (TREE_VALUE (ttf_in)))) { ! cp->harshness[0] += INT_TO_EASY_HARSHNESS (1); ++easy_strikes; } --- 1736,1740 ---- if (TYPE_READONLY (TREE_TYPE (TREE_VALUE (ttf_in)))) { ! cp->v.old_harshness[0] += INT_TO_EASY_HARSHNESS (1); ++easy_strikes; } *************** *** 782,786 **** if (TREE_CODE (TREE_TYPE (TREE_VALUE (tta_in))) == POINTER_TYPE && (TYPE_READONLY (TREE_TYPE (TREE_TYPE (TREE_VALUE (tta_in)))))) ! cp->harshness[0] |= CONST_HARSHNESS (-1); } } --- 1747,1751 ---- if (TREE_CODE (TREE_TYPE (TREE_VALUE (tta_in))) == POINTER_TYPE && (TYPE_READONLY (TREE_TYPE (TREE_TYPE (TREE_VALUE (tta_in)))))) ! cp->v.old_harshness[0] |= CONST_HARSHNESS (-1); } } *************** *** 793,796 **** --- 1758,1774 ---- } + void + compute_conversion_costs (function, tta_in, cp, arglen) + tree function; + tree tta_in; + struct candidate *cp; + int arglen; + { + if (flag_ansi_overloading) + compute_conversion_costs_ansi (function, tta_in, cp, arglen); + else + compute_conversion_costs_old (function, tta_in, cp, arglen); + } + /* When one of several possible overloaded functions and/or methods can be called, choose the best candidate for overloading. *************** *** 806,810 **** static struct candidate * ! ideal_candidate (basetype, candidates, n_candidates, parms, len) tree basetype; struct candidate *candidates; --- 1784,1788 ---- static struct candidate * ! ideal_candidate_old (basetype, candidates, n_candidates, parms, len) tree basetype; struct candidate *candidates; *************** *** 844,858 **** for (ttf = TYPE_ARG_TYPES (TREE_TYPE (cp[i].function)), ttf0 = TYPE_ARG_TYPES (TREE_TYPE (cp[-1].function)), ! index = 0; ! index < len; ! ttf = TREE_CHAIN (ttf), ttf0 = TREE_CHAIN (ttf0), index++) ! if (USER_HARSHNESS (cp[i].harshness[index])) ! { ! /* If our "best" candidate also needs a conversion, ! it must be the same one. */ ! if (USER_HARSHNESS (cp[-1].harshness[index]) ! && TREE_VALUE (ttf) != TREE_VALUE (ttf0)) ! goto non_subset; ! } i++; } --- 1822,1841 ---- for (ttf = TYPE_ARG_TYPES (TREE_TYPE (cp[i].function)), ttf0 = TYPE_ARG_TYPES (TREE_TYPE (cp[-1].function)), ! index = 0; index < len; index++) ! { ! if (USER_HARSHNESS (cp[i].v.old_harshness[index])) ! { ! /* If our "best" candidate also needs a conversion, ! it must be the same one. */ ! if (USER_HARSHNESS (cp[-1].v.old_harshness[index]) ! && TREE_VALUE (ttf) != TREE_VALUE (ttf0)) ! goto non_subset; ! } ! ttf = TREE_CHAIN (ttf); ! ttf0 = TREE_CHAIN (ttf0); ! /* Handle `...' gracefully. */ ! if (ttf == NULL_TREE || ttf0 == NULL_TREE) ! break; ! } i++; } *************** *** 905,909 **** tta = TREE_CHAIN (tta), ttf = TREE_CHAIN (ttf), index++) { ! if (USER_HARSHNESS (cp[i].harshness[index])) { tree this_parm = build_type_conversion (CALL_EXPR, TREE_VALUE (ttf), TREE_PURPOSE (tta), 2); --- 1888,1901 ---- tta = TREE_CHAIN (tta), ttf = TREE_CHAIN (ttf), index++) { ! /* If this is a varargs function, there's no conversion to do, ! but don't accept an arg that needs a copy ctor. */ ! if (ttf == NULL_TREE) ! { ! /* FIXME: verify that we cannot get here with an ! arg that needs a ctor. */ ! break; ! } ! ! if (USER_HARSHNESS (cp[i].v.old_harshness[index])) { tree this_parm = build_type_conversion (CALL_EXPR, TREE_VALUE (ttf), TREE_PURPOSE (tta), 2); *************** *** 945,950 **** if (TREE_CODE (TREE_TYPE (f1)) == METHOD_TYPE && TREE_CODE (TREE_TYPE (f2)) == METHOD_TYPE ! && BASE_DERIVED_HARSHNESS (cp[i].harshness[0]) ! && cp[best].harshness[0] < cp[i].harshness[0]) { #if 0 --- 1937,1942 ---- if (TREE_CODE (TREE_TYPE (f1)) == METHOD_TYPE && TREE_CODE (TREE_TYPE (f2)) == METHOD_TYPE ! && BASE_DERIVED_HARSHNESS (cp[i].v.old_harshness[0]) ! && cp[best].v.old_harshness[0] < cp[i].v.old_harshness[0]) { #if 0 *************** *** 965,978 **** { /* Type conversions must be piecewise equivalent. */ ! if (USER_HARSHNESS (cp[best].harshness[index]) ! != USER_HARSHNESS (cp[i].harshness[index])) goto ret0; /* If there's anything we like better about the other function, consider it ambiguous. */ ! if (cp[i].harshness[index] < cp[best].harshness[index]) goto ret0; /* If any single one it diffent, then the whole is not identical. */ ! if (cp[i].harshness[index] != cp[best].harshness[index]) identical = 0; } --- 1957,1970 ---- { /* Type conversions must be piecewise equivalent. */ ! if (USER_HARSHNESS (cp[best].v.old_harshness[index]) ! != USER_HARSHNESS (cp[i].v.old_harshness[index])) goto ret0; /* If there's anything we like better about the other function, consider it ambiguous. */ ! if (cp[i].v.old_harshness[index] < cp[best].v.old_harshness[index]) goto ret0; /* If any single one it diffent, then the whole is not identical. */ ! if (cp[i].v.old_harshness[index] != cp[best].v.old_harshness[index]) identical = 0; } *************** *** 1001,1005 **** tta = TREE_CHAIN (tta), ttf = TREE_CHAIN (ttf), index++) { ! if (USER_HARSHNESS (cp[best].harshness[index])) { /* We must now fill in the slot we left behind. --- 1993,1997 ---- tta = TREE_CHAIN (tta), ttf = TREE_CHAIN (ttf), index++) { ! if (USER_HARSHNESS (cp[best].v.old_harshness[index])) { /* We must now fill in the slot we left behind. *************** *** 1010,1014 **** exact_conversions -= 1; } ! else TREE_VALUE (tta) = TREE_PURPOSE (tta); } return cp + best; --- 2002,2007 ---- exact_conversions -= 1; } ! else ! TREE_VALUE (tta) = TREE_PURPOSE (tta); } return cp + best; *************** *** 1020,1031 **** candidate is forced to use user-defined conversion when best is not. */ if (cp[-2].user == 0 ! && cp[-1].harshness[len] != 0 && cp[-2].harshness[len] != 0) { tree tt1 = TYPE_ARG_TYPES (TREE_TYPE (cp[-1].function)); tree tt2 = TYPE_ARG_TYPES (TREE_TYPE (cp[-2].function)); ! unsigned i = cp[-1].harshness[len]; ! if (cp[-2].harshness[len] < i) ! i = cp[-2].harshness[len]; while (--i > 0) { --- 2013,2024 ---- candidate is forced to use user-defined conversion when best is not. */ if (cp[-2].user == 0 ! && cp[-1].v.old_harshness[len] != 0 && cp[-2].v.old_harshness[len] != 0) { tree tt1 = TYPE_ARG_TYPES (TREE_TYPE (cp[-1].function)); tree tt2 = TYPE_ARG_TYPES (TREE_TYPE (cp[-2].function)); ! unsigned i = cp[-1].v.old_harshness[len]; ! if (cp[-2].v.old_harshness[len] < i) ! i = cp[-2].v.old_harshness[len]; while (--i > 0) { *************** *** 1065,1073 **** && ! UNIQUELY_DERIVED_FROM_P (base1, newbase)) { ! error_with_aggr_type (basetype, "ambiguous request for function from distinct base classes of type `%s'"); ! error (" first candidate is `%s'", ! fndecl_as_string (0, candidates[best].function, 1)); ! error (" second candidate is `%s'", ! fndecl_as_string (0, candidates[i].function, 1)); cp[-1].evil = 1; return cp - 1; --- 2058,2066 ---- && ! UNIQUELY_DERIVED_FROM_P (base1, newbase)) { ! cp_error ("ambiguous request for function from distinct base classes of type `%T'", basetype); ! cp_error_at (" first candidate is `%#D'", ! candidates[best].function); ! cp_error_at (" second candidate is `%#D'", ! candidates[i].function); cp[-1].evil = 1; return cp - 1; *************** *** 1080,1084 **** } } ! else return cp - 1; } } --- 2073,2078 ---- } } ! else ! return cp - 1; } } *************** *** 1099,1103 **** && TREE_CODE (TREE_TYPE (TREE_VALUE (p1))) == FUNCTION_TYPE && TREE_VALUE (p1) != TREE_VALUE (p2)) ! return 0; p1 = TREE_CHAIN (p1); p2 = TREE_CHAIN (p2); --- 2093,2097 ---- && TREE_CODE (TREE_TYPE (TREE_VALUE (p1))) == FUNCTION_TYPE && TREE_VALUE (p1) != TREE_VALUE (p2)) ! return NULL; p1 = TREE_CHAIN (p1); p2 = TREE_CHAIN (p2); *************** *** 1104,1108 **** } if (p1 || p2) ! return 0; } --- 2098,2102 ---- } if (p1 || p2) ! return NULL; } *************** *** 1117,1123 **** --- 2111,2237 ---- parms = TREE_CHAIN (parms); } + return NULL; + } + + /* Subroutine of ideal_candidate. See if X or Y is a better match + than the other. */ + static int + strictly_better (x, y) + unsigned short x, y; + { + unsigned short xor; + + if (x == y) + return 0; + + xor = x ^ y; + if (xor >= x || xor >= y) + return 1; return 0; } + static struct candidate * + ideal_candidate_ansi (basetype, candidates, n_candidates, parms, len) + tree basetype; + struct candidate *candidates; + int n_candidates; + tree parms; + int len; + { + struct candidate *cp = candidates+n_candidates; + int i, j, best_code; + + /* For each argument, sort the functions from best to worst for the arg. + For each function that's not best for this arg, set its overall + harshness to EVIL so that other args won't like it. The candidate + list for the last argument is the intersection of all the best-liked + functions. */ + + for (i = 0; i < len; i++) + { + qsort (candidates, n_candidates, sizeof (struct candidate), + rank_for_overload); + best_code = cp[-1].h.code; + + /* To find out functions that are worse than that represented + by BEST_CODE, we can't just do a comparison like h.code>best_code. + The total harshness for the "best" fn may be 8|8 for two args, and + the harshness for the next-best may be 8|2. If we just compared, + that would be checking 8>10, which would lead to the next-best + being disqualified. What we actually want to do is get rid + of functions that are definitely worse than that represented + by best_code, i.e. those which have bits set higher than the + highest in best_code. Sooooo, what we do is clear out everything + represented by best_code, and see if we still come up with something + higher. If so (e.g., 8|8 vs 8|16), it'll disqualify it properly. */ + for (j = n_candidates-2; j >= 0; j--) + if ((candidates[j].h.code & ~best_code) > best_code) + candidates[j].h.code = EVIL_CODE; + } + + if (cp[-1].h.code & EVIL_CODE) + return NULL; + + /* If they're at least as good as each other, do an arg-by-arg check. */ + if (! strictly_better (cp[-1].h.code, cp[-2].h.code)) + { + int better = 0; + int worse = 0; + + for (j = 0; j < n_candidates; j++) + if (! strictly_better (candidates[j].h.code, best_code)) + break; + + qsort (candidates+j, n_candidates-j, sizeof (struct candidate), + rank_for_ideal); + for (i = 0; i < len; i++) + { + if (cp[-1].v.ansi_harshness[i].code < cp[-2].v.ansi_harshness[i].code) + better = 1; + else if (cp[-1].v.ansi_harshness[i].code > cp[-2].v.ansi_harshness[i].code) + worse = 1; + else if (cp[-1].v.ansi_harshness[i].code & STD_CODE) + { + /* If it involves a standard conversion, let the + inheritance lattice be the final arbiter. */ + if (cp[-1].v.ansi_harshness[i].distance > cp[-2].v.ansi_harshness[i].distance) + worse = 1; + else if (cp[-1].v.ansi_harshness[i].distance < cp[-2].v.ansi_harshness[i].distance) + better = 1; + } + else if (cp[-1].v.ansi_harshness[i].code & PROMO_CODE) + { + /* For integral promotions, take into account a finer granularity for + determining which types should be favored over others in such + promotions. */ + if (cp[-1].v.ansi_harshness[i].int_penalty > cp[-2].v.ansi_harshness[i].int_penalty) + worse = 1; + else if (cp[-1].v.ansi_harshness[i].int_penalty < cp[-2].v.ansi_harshness[i].int_penalty) + better = 1; + } + } + + if (! better || worse) + return NULL; + } + return cp-1; + } + + static struct candidate * + ideal_candidate (basetype, candidates, n_candidates, parms, len) + tree basetype; + struct candidate *candidates; + int n_candidates; + tree parms; + int len; + { + if (flag_ansi_overloading) + return ideal_candidate_ansi (basetype, candidates, n_candidates, parms, + len); + else + return ideal_candidate_old (basetype, candidates, n_candidates, parms, + len); + } + /* Assume that if the class referred to is not in the current class hierarchy, that it may be remote. *************** *** 1132,1135 **** --- 2246,2250 ---- if (current_class_type == NULL_TREE) return 0; + if (parent == current_class_type) return 0; *************** *** 1169,1174 **** static tree build_field_call (basetype_path, instance_ptr, name, parms, err_name) ! tree basetype_path; ! tree instance_ptr, name, parms; char *err_name; { --- 2284,2288 ---- static tree build_field_call (basetype_path, instance_ptr, name, parms, err_name) ! tree basetype_path, instance_ptr, name, parms; char *err_name; { *************** *** 1200,1207 **** if (TREE_CODE (TREE_TYPE (instance)) == POINTER_TYPE) ! if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) == FUNCTION_TYPE) ! return build_function_call (instance, parms); ! else if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) == METHOD_TYPE) ! return build_function_call (instance, tree_cons (NULL_TREE, current_class_decl, parms)); } return NULL_TREE; --- 2314,2323 ---- if (TREE_CODE (TREE_TYPE (instance)) == POINTER_TYPE) ! { ! if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) == FUNCTION_TYPE) ! return build_function_call (instance, parms); ! else if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) == METHOD_TYPE) ! return build_function_call (instance, tree_cons (NULL_TREE, current_class_decl, parms)); ! } } return NULL_TREE; *************** *** 1216,1219 **** --- 2332,2336 ---- if (field == error_mark_node) return error_mark_node; + if (field) { *************** *** 1221,1224 **** --- 2338,2344 ---- tree ftype = TREE_TYPE (field); + if (TREE_CODE (ftype) == REFERENCE_TYPE) + ftype = TREE_TYPE (ftype); + if (TYPE_LANG_SPECIFIC (ftype) && TYPE_OVERLOADS_CALL_EXPR (ftype)) { *************** *** 1227,1231 **** instance_ptr = convert_pointer_to (basetype, instance_ptr); ! instance = build_indirect_ref (instance_ptr, NULL); return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, build_component_ref_1 (instance, field, 0), --- 2347,2351 ---- instance_ptr = convert_pointer_to (basetype, instance_ptr); ! instance = build_indirect_ref (instance_ptr, NULL_PTR); return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, build_component_ref_1 (instance, field, 0), *************** *** 1240,1244 **** tree ref = build_component_ref_1 (build_indirect_ref (instance_ptr, ! NULL), field, LOOKUP_COMPLAIN); if (ref == error_mark_node) --- 2360,2364 ---- tree ref = build_component_ref_1 (build_indirect_ref (instance_ptr, ! NULL_PTR), field, LOOKUP_COMPLAIN); if (ref == error_mark_node) *************** *** 1279,1282 **** --- 2399,2411 ---- } + #if 0 + /* XXX This needs to be fixed better. */ + if (TREE_CODE (type) == UNINSTANTIATED_P_TYPE) + { + sorry ("nested class lookup in template type"); + return NULL_TREE; + } + #endif + /* Look for a TYPE_DECL. */ for (tags = TYPE_FIELDS (type); tags; tags = TREE_CHAIN (tags)) *************** *** 1377,1384 **** tree build_scoped_method_call (exp, scopes, name, parms) ! tree exp; ! tree scopes; ! tree name; ! tree parms; { /* Because this syntactic form does not allow --- 2506,2510 ---- tree build_scoped_method_call (exp, scopes, name, parms) ! tree exp, scopes, name, parms; { /* Because this syntactic form does not allow *************** *** 1392,1401 **** tree type = TREE_TYPE (exp); if (type == error_mark_node || basename == NULL_TREE ! || ! is_aggr_typedef (basename, 1)) return error_mark_node; ! if (! IS_AGGR_TYPE (type)) { error ("base object of scoped method call is not of aggregate type"); --- 2518,2532 ---- tree type = TREE_TYPE (exp); + /* Destructors can be "called" for simple types; see 5.2.4 and 12.4 */ if (type == error_mark_node || basename == NULL_TREE ! || (TREE_CODE (name) != BIT_NOT_EXPR ! && ! is_aggr_typedef (basename, 1))) return error_mark_node; ! if (TREE_CODE (type) == REFERENCE_TYPE) ! type = TREE_TYPE (type); ! ! if (TREE_CODE (name) != BIT_NOT_EXPR && ! IS_AGGR_TYPE (type)) { error ("base object of scoped method call is not of aggregate type"); *************** *** 1411,1415 **** if (TREE_CODE (exp) == INDIRECT_REF) decl = build_indirect_ref (convert_pointer_to (binfo, ! build_unary_op (ADDR_EXPR, exp, 0)), NULL); else decl = build_scoped_ref (exp, scopes); --- 2542,2546 ---- if (TREE_CODE (exp) == INDIRECT_REF) decl = build_indirect_ref (convert_pointer_to (binfo, ! build_unary_op (ADDR_EXPR, exp, 0)), NULL_PTR); else decl = build_scoped_ref (exp, scopes); *************** *** 1420,1437 **** /* Explicit call to destructor. */ name = TREE_OPERAND (name, 0); ! if (! is_aggr_typedef (name, 1)) ! return error_mark_node; ! if (TREE_TYPE (decl) != IDENTIFIER_TYPE_VALUE (name)) ! { ! error_with_aggr_type (TREE_TYPE (decl), ! "qualified type `%s' does not match destructor type `%s'", ! IDENTIFIER_POINTER (name)); return error_mark_node; } - if (! TYPE_HAS_DESTRUCTOR (TREE_TYPE (decl))) - error_with_aggr_type (TREE_TYPE (decl), "type `%s' has no destructor"); return build_delete (TREE_TYPE (decl), decl, integer_two_node, LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, ! 0, 0); } --- 2551,2567 ---- /* Explicit call to destructor. */ name = TREE_OPERAND (name, 0); ! if (TREE_TYPE (decl) != ! (IDENTIFIER_CLASS_VALUE (name) ! ? IDENTIFIER_CLASS_TYPE_VALUE (name) ! : IDENTIFIER_TYPE_VALUE (name))) ! { ! cp_error ! ("qualified type `%T' does not match destructor type `%T'", ! TREE_TYPE (decl), name); return error_mark_node; } return build_delete (TREE_TYPE (decl), decl, integer_two_node, LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, ! 0); } *************** *** 1530,1542 **** } - #if 0 - /* C++ 2.1 does not allow this, but ANSI probably will. */ - if (TREE_CODE (name) == BIT_NOT_EXPR) - { - error ("invalid call to destructor, use qualified name `%s::~%s'", - IDENTIFIER_POINTER (name), IDENTIFIER_POINTER (name)); - return error_mark_node; - } - #else if (TREE_CODE (name) == BIT_NOT_EXPR) { --- 2660,2663 ---- *************** *** 1548,1556 **** error ("destructors take no parameters"); basetype = IDENTIFIER_TYPE_VALUE (name); if (! TYPE_HAS_DESTRUCTOR (basetype)) { - #if 0 /* ARM says tp->~T() without T::~T() is valid. */ - error_with_aggr_type (basetype, "type `%s' has no destructor"); - #endif /* A destructive destructor wouldn't be a bad idea, but let's not bother for now. */ --- 2669,2676 ---- error ("destructors take no parameters"); basetype = IDENTIFIER_TYPE_VALUE (name); + if (basetype == NULL_TREE) + basetype = IDENTIFIER_CLASS_TYPE_VALUE (name); if (! TYPE_HAS_DESTRUCTOR (basetype)) { /* A destructive destructor wouldn't be a bad idea, but let's not bother for now. */ *************** *** 1564,1570 **** return build_delete (build_pointer_type (basetype), instance_ptr, integer_two_node, ! LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0, 0); } - #endif /* Initialize name for error reporting. */ --- 2684,2689 ---- return build_delete (build_pointer_type (basetype), instance_ptr, integer_two_node, ! LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0); } /* Initialize name for error reporting. */ *************** *** 1791,1795 **** variable (such as a post-increment), may happen twice. */ instance_ptr = save_expr (instance_ptr); ! instance = build_indirect_ref (instance_ptr, NULL); } else if (TREE_CODE (TREE_TYPE (instance)) == POINTER_TYPE) --- 2910,2914 ---- variable (such as a post-increment), may happen twice. */ instance_ptr = save_expr (instance_ptr); ! instance = build_indirect_ref (instance_ptr, NULL_PTR); } else if (TREE_CODE (TREE_TYPE (instance)) == POINTER_TYPE) *************** *** 1796,1800 **** { /* This happens when called for operator new (). */ ! instance = build_indirect_ref (instance, NULL); } --- 2915,2919 ---- { /* This happens when called for operator new (). */ ! instance = build_indirect_ref (instance, NULL_PTR); } *************** *** 1806,1810 **** { /* This is worth complaining about, I think. */ ! error_with_aggr_type (basetype, "cannot lookup method in incomplete type `%s'"); return error_mark_node; } --- 2925,2929 ---- { /* This is worth complaining about, I think. */ ! cp_error ("cannot lookup method in incomplete type `%T'", basetype); return error_mark_node; } *************** *** 1876,1880 **** instance_ptr = save_expr (instance_ptr); TREE_CALLS_NEW (instance_ptr) = 1; ! instance = build_indirect_ref (instance_ptr, NULL); /* If it's a default argument initialized from a ctor, what we get --- 2995,2999 ---- instance_ptr = save_expr (instance_ptr); TREE_CALLS_NEW (instance_ptr) = 1; ! instance = build_indirect_ref (instance_ptr, NULL_PTR); /* If it's a default argument initialized from a ctor, what we get *************** *** 1931,1935 **** name_kind = "method"; } ! else name_kind = "method"; if (basetype_path == NULL_TREE) --- 3050,3055 ---- name_kind = "method"; } ! else ! name_kind = "method"; if (basetype_path == NULL_TREE) *************** *** 1968,1971 **** --- 3088,3092 ---- = (struct candidate *) alloca ((ever_seen+1) * sizeof (struct candidate)); + bzero (candidates, (ever_seen + 1) * sizeof (struct candidate)); cp = candidates; len = list_length (parms); *************** *** 1994,1999 **** my_friendly_abort (167); ! cp->harshness ! = (unsigned short *)alloca ((len+1) * sizeof (short)); result = build_overload_call (name, friend_parms, 0, cp); /* If it turns out to be the one we were actually looking for --- 3115,3128 ---- my_friendly_abort (167); ! if (flag_ansi_overloading) ! { ! cp->v.ansi_harshness ! = (struct harshness_code *)alloca ((len+1) * sizeof (struct harshness_code)); ! cp->h_len = len; ! } ! else ! cp->v.old_harshness ! = (unsigned short *)alloca ((len+1) * sizeof (short)); ! result = build_overload_call (name, friend_parms, 0, cp); /* If it turns out to be the one we were actually looking for *************** *** 2003,2018 **** return result; ! while (cp->evil == 0) ! { ! /* non-standard uses: set the field to 0 to indicate ! we are using a non-member function. */ ! cp->u.field = 0; ! if (cp->harshness[len] == 0 ! && cp->harshness[len] == 0 ! && cp->user == 0 && cp->b_or_d == 0 ! && cp->easy < best) ! best = cp->easy; ! cp += 1; ! } } } --- 3132,3159 ---- return result; ! if (flag_ansi_overloading) ! while ((cp->h.code & EVIL_CODE) == 0) ! { ! /* non-standard uses: set the field to 0 to indicate ! we are using a non-member function. */ ! cp->u.field = 0; ! if (cp->v.ansi_harshness[len].distance == 0 ! && cp->h.code < best) ! best = cp->h.code; ! cp += 1; ! } ! else ! while (cp->evil == 0) ! { ! /* non-standard uses: set the field to 0 to indicate ! we are using a non-member function. */ ! cp->u.field = 0; ! if (cp->v.old_harshness[len] == 0 ! && cp->v.old_harshness[len] == 0 ! && cp->ellipsis == 0 && cp->user == 0 && cp->b_or_d == 0 ! && cp->easy < best) ! best = cp->easy; ! cp += 1; ! } } } *************** *** 2081,2091 **** n_inner_fields_searched++; #endif ! cp->harshness ! = (unsigned short *)alloca ((len+1) * sizeof (short)); if (DECL_STATIC_FUNCTION_P (function)) these_parms = TREE_CHAIN (these_parms); compute_conversion_costs (function, these_parms, cp, len); ! cp->b_or_d += b_or_d; ! if (cp->evil == 0) { cp->u.field = function; --- 3222,3244 ---- n_inner_fields_searched++; #endif ! if (flag_ansi_overloading) ! { ! cp->v.ansi_harshness ! = (struct harshness_code *)alloca ((len+1) * sizeof (struct harshness_code)); ! cp->h_len = len; ! } ! else ! cp->v.old_harshness ! = (unsigned short *)alloca ((len+1) * sizeof (short)); ! if (DECL_STATIC_FUNCTION_P (function)) these_parms = TREE_CHAIN (these_parms); compute_conversion_costs (function, these_parms, cp, len); ! ! if (!flag_ansi_overloading) ! cp->b_or_d += b_or_d; ! ! if ((flag_ansi_overloading && (cp->h.code & EVIL_CODE) == 0) ! || (!flag_ansi_overloading && cp->evil == 0)) { cp->u.field = function; *************** *** 2109,2113 **** /* No "two-level" conversions. */ ! if (flags & LOOKUP_NO_CONVERSION && cp->user != 0) continue; --- 3262,3270 ---- /* No "two-level" conversions. */ ! if (flags & LOOKUP_NO_CONVERSION ! && ((flag_ansi_overloading ! && (cp->h.code & USER_CODE)) ! || (!flag_ansi_overloading ! && cp->user != 0))) continue; *************** *** 2117,2124 **** ambiguity. */ if (! TYPE_USES_MULTIPLE_INHERITANCE (save_basetype) ! && cp->harshness[len] == 0 ! && CONST_HARSHNESS (cp->harshness[0]) == 0 ! && cp->user == 0 && cp->b_or_d == 0 ! && cp->easy < best) { if (! DECL_STATIC_FUNCTION_P (function)) --- 3274,3285 ---- ambiguity. */ if (! TYPE_USES_MULTIPLE_INHERITANCE (save_basetype) ! && ((flag_ansi_overloading ! && cp->v.ansi_harshness[len].distance == 0 ! && cp->h.code < best) ! || (!flag_ansi_overloading ! && cp->v.old_harshness[len] == 0 ! && CONST_HARSHNESS (cp->v.old_harshness[0]) == 0 ! && cp->ellipsis == 0 && cp->user == 0 && cp->b_or_d == 0 ! && cp->easy < best))) { if (! DECL_STATIC_FUNCTION_P (function)) *************** *** 2135,2148 **** baselink = next_baselink (baselink); b_or_d += 1; } if (pass == 0) { /* No exact match could be found. Now try to find match using default conversions. */ ! if ((flags & LOOKUP_GLOBAL) && IDENTIFIER_GLOBAL_VALUE (name)) ! if (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == FUNCTION_DECL) ! ever_seen += 1; ! else if (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == TREE_LIST) ! ever_seen += list_length (IDENTIFIER_GLOBAL_VALUE (name)); if (ever_seen == 0) --- 3296,3316 ---- baselink = next_baselink (baselink); b_or_d += 1; + /* Don't grab functions from base classes. lookup_fnfield will + do the work to get us down into the right place. */ + baselink = NULL_TREE; } if (pass == 0) { + tree igv = IDENTIFIER_GLOBAL_VALUE (name); + /* No exact match could be found. Now try to find match using default conversions. */ ! if ((flags & LOOKUP_GLOBAL) && igv) ! { ! if (TREE_CODE (igv) == FUNCTION_DECL) ! ever_seen += 1; ! else if (TREE_CODE (igv) == TREE_LIST) ! ever_seen += list_length (igv); ! } if (ever_seen == 0) *************** *** 2154,2158 **** error ("no global or non-hidden member function `%s' defined", err_name); else ! error_with_aggr_type (save_basetype, "no non-hidden member function `%s::%s' defined", err_name); return error_mark_node; } --- 3322,3326 ---- error ("no global or non-hidden member function `%s' defined", err_name); else ! cp_error ("no non-hidden member function `%T::%s' defined", save_basetype, err_name); return error_mark_node; } *************** *** 2177,2184 **** return error_mark_node; } ! if (cp->evil) return error_mark_node; } ! else if (cp[-1].evil == 2) { error ("ambiguous type conversion requested for %s `%s'", --- 3345,3354 ---- return error_mark_node; } ! if ((flag_ansi_overloading && (cp->h.code & EVIL_CODE)) ! || (!flag_ansi_overloading && cp->evil)) return error_mark_node; } ! else if ((flag_ansi_overloading && (cp[-1].h.code & EVIL_CODE)) ! || (!flag_ansi_overloading && cp[-1].evil == 2)) { error ("ambiguous type conversion requested for %s `%s'", *************** *** 2186,2190 **** return error_mark_node; } ! else cp--; /* The global function was the best, so use it. */ --- 3356,3361 ---- return error_mark_node; } ! else ! cp--; /* The global function was the best, so use it. */ *************** *** 2223,2229 **** return NULL_TREE; if (static_call_context && TREE_CODE (TREE_TYPE (cp->function)) == METHOD_TYPE) ! error_with_aggr_type (TREE_TYPE (TREE_TYPE (instance_ptr)), ! "object missing in call to `%s::%s'", ! err_name); else report_type_mismatch (cp, parms, name_kind, err_name); --- 3394,3400 ---- return NULL_TREE; if (static_call_context && TREE_CODE (TREE_TYPE (cp->function)) == METHOD_TYPE) ! cp_error ("object missing in call to `%T::%s'", ! TREE_TYPE (TREE_TYPE (instance_ptr)), ! err_name); else report_type_mismatch (cp, parms, name_kind, err_name); *************** *** 2238,2252 **** { if (saw_protected) ! msg = "%s `%%s' (and the like) are private or protected"; else ! msg = "the %s `%%s' is private"; } else { ! msg = "the %s `%%s' is protected"; seen = saw_protected; } sprintf (buf, msg, name_kind); ! error_with_decl (seen, buf); error ("within this context"); } --- 3409,3423 ---- { if (saw_protected) ! msg = "%s `%%D' (and the like) are private or protected"; else ! msg = "the %s `%%D' is private"; } else { ! msg = "the %s `%%D' is protected"; seen = saw_protected; } sprintf (buf, msg, name_kind); ! cp_error_at (buf, seen); error ("within this context"); } *************** *** 2262,2265 **** --- 3433,3437 ---- tag_name = "union"; + /* FIXME: is this doing the right thing? */ buf = (char *)alloca (30 + strlen (err_name)); strcpy (buf, "%s has no method named `%s'"); *************** *** 2272,2280 **** found_and_maybe_warn: ! if (CONST_HARSHNESS (cp->harshness[0])) { if (flags & LOOKUP_COMPLAIN) { ! error_with_decl (cp->function, "non-const member function `%s'"); error ("called for const object at this point in file"); } --- 3444,3455 ---- found_and_maybe_warn: ! if ((flag_ansi_overloading ! && (cp->v.ansi_harshness[0].code & CONST_CODE)) ! || (!flag_ansi_overloading ! && CONST_HARSHNESS (cp->v.old_harshness[0]))) { if (flags & LOOKUP_COMPLAIN) { ! cp_error_at ("non-const member function `%D'", cp->function); error ("called for const object at this point in file"); } *************** *** 2371,2378 **** } } ! else if (! TREE_STATIC (function)) { ! error_with_aggr_type (basetype, "cannot call member function `%s::%s' without object", ! err_name); return error_mark_node; } --- 3546,3556 ---- } } ! /* Only allow a static member function to call another static member ! function. */ ! else if (DECL_LANG_SPECIFIC (function) ! && !DECL_STATIC_FUNCTION_P (function)) { ! cp_error ("cannot call member function `%T::%s' without object", ! basetype, err_name); return error_mark_node; } *************** *** 2402,2406 **** basetype = DECL_CLASS_CONTEXT (function); instance_ptr = convert_pointer_to (basetype, instance_ptr); ! instance = build_indirect_ref (instance_ptr, NULL); } parms = tree_cons (NULL_TREE, instance_ptr, --- 3580,3584 ---- basetype = DECL_CLASS_CONTEXT (function); instance_ptr = convert_pointer_to (basetype, instance_ptr); ! instance = build_indirect_ref (instance_ptr, NULL_PTR); } parms = tree_cons (NULL_TREE, instance_ptr, *************** *** 2416,2425 **** if (!integer_zerop (TREE_VALUE (parms))) { ! instance_ptr = convert_pointer_to (build_type_variant (basetype, constp, volatilep), ! TREE_VALUE (parms)); if (TREE_CODE (instance_ptr) == COND_EXPR) { instance_ptr = save_expr (instance_ptr); ! instance = build_indirect_ref (instance_ptr, NULL); } else if (TREE_CODE (instance_ptr) == NOP_EXPR --- 3594,3605 ---- if (!integer_zerop (TREE_VALUE (parms))) { ! tree binfo = get_binfo (basetype, TREE_TYPE (TREE_TYPE (TREE_VALUE (parms))), 0); ! instance_ptr = convert_pointer_to_real (binfo, TREE_VALUE (parms)); ! instance_ptr = convert_pointer_to (build_type_variant (basetype, constp, volatilep), instance_ptr); ! if (TREE_CODE (instance_ptr) == COND_EXPR) { instance_ptr = save_expr (instance_ptr); ! instance = build_indirect_ref (instance_ptr, NULL_PTR); } else if (TREE_CODE (instance_ptr) == NOP_EXPR *************** *** 2433,2437 **** || TREE_CODE (instance) != INDIRECT_REF || TREE_OPERAND (instance, 0) != instance_ptr) ! instance = build_indirect_ref (instance_ptr, NULL); } parms = tree_cons (NULL_TREE, instance_ptr, --- 3613,3617 ---- || TREE_CODE (instance) != INDIRECT_REF || TREE_OPERAND (instance, 0) != instance_ptr) ! instance = build_indirect_ref (instance_ptr, NULL_PTR); } parms = tree_cons (NULL_TREE, instance_ptr, *************** *** 2447,2458 **** OPERATOR_METHOD_FORMAT, OPERATOR_METHOD_LENGTH)) ! #if 0 ! && (may_be_remote (basetype) ! || (C_C_D ? TREE_TYPE (instance) != current_class_type : 1)) ! #else ! /* This change by Larry Ketcham. */ ! && (may_be_remote (basetype) || instance != C_C_D) ! #endif ! ) { tree fn_as_int; --- 3627,3631 ---- OPERATOR_METHOD_FORMAT, OPERATOR_METHOD_LENGTH)) ! && (may_be_remote (basetype) || instance != C_C_D)) { tree fn_as_int; *************** *** 2511,2516 **** function = default_conversion (function); ! result = ! build_nt (CALL_EXPR, function, parms, NULL_TREE); TREE_TYPE (result) = value_type; --- 3684,3688 ---- function = default_conversion (function); ! result = build_nt (CALL_EXPR, function, parms, NULL_TREE); TREE_TYPE (result) = value_type; *************** *** 2559,2569 **** if (final_cp) { ! final_cp[0].evil = 0; ! final_cp[0].user = 0; ! final_cp[0].b_or_d = 0; ! final_cp[0].easy = 0; ! final_cp[0].function = 0; ! /* end marker. */ ! final_cp[1].evil = 1; } --- 3731,3752 ---- if (final_cp) { ! if (flag_ansi_overloading) ! { ! final_cp[0].h.code = 0; ! final_cp[0].h.distance = 0; ! final_cp[0].function = 0; ! /* end marker. */ ! final_cp[1].h.code = EVIL_CODE; ! } ! else ! { ! final_cp[0].evil = 0; ! final_cp[0].user = 0; ! final_cp[0].b_or_d = 0; ! final_cp[0].easy = 0; ! final_cp[0].function = 0; ! /* end marker. */ ! final_cp[1].evil = 1; ! } } *************** *** 2575,2579 **** { if (final_cp) ! final_cp->evil = 1; return error_mark_node; } --- 3758,3767 ---- { if (final_cp) ! { ! if (flag_ansi_overloading) ! final_cp->h.code = EVIL_CODE; ! else ! final_cp->evil = 1; ! } return error_mark_node; } *************** *** 2593,2606 **** else parmtypes = void_list_node; - overload_name = build_decl_overload (fnname, parmtypes, 0); ! /* Now check to see whether or not we can win. ! Note that if we are called from `build_method_call', ! then we cannot have a mis-match, because we would have ! already found such a winning case. */ ! ! if (IDENTIFIER_GLOBAL_VALUE (overload_name)) ! if (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (overload_name)) != TREE_LIST) ! return build_function_call (DECL_MAIN_VARIANT (IDENTIFIER_GLOBAL_VALUE (overload_name)), parms); functions = IDENTIFIER_GLOBAL_VALUE (fnname); --- 3781,3802 ---- else parmtypes = void_list_node; ! if (! flag_ansi_overloading) ! { ! /* This is a speed improvement that ends up not working properly in ! the situation of fns with and without default parameters. I turned ! this off in the new method so it'll go through the argument matching ! code to properly diagnose a match/failure. (bpk) */ ! overload_name = build_decl_overload (fnname, parmtypes, 0); ! ! /* Now check to see whether or not we can win. ! Note that if we are called from `build_method_call', ! then we cannot have a mis-match, because we would have ! already found such a winning case. */ ! ! if (IDENTIFIER_GLOBAL_VALUE (overload_name)) ! if (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (overload_name)) != TREE_LIST) ! return build_function_call (DECL_MAIN_VARIANT (IDENTIFIER_GLOBAL_VALUE (overload_name)), parms); ! } functions = IDENTIFIER_GLOBAL_VALUE (fnname); *************** *** 2611,2615 **** error ("only member functions apply"); if (final_cp) ! final_cp->evil = 1; return error_mark_node; } --- 3807,3816 ---- error ("only member functions apply"); if (final_cp) ! { ! if (flag_ansi_overloading) ! final_cp->h.code = EVIL_CODE; ! else ! final_cp->evil = 1; ! } return error_mark_node; } *************** *** 2634,2638 **** IDENTIFIER_POINTER (TREE_PURPOSE (functions))); if (final_cp) ! final_cp->evil = 1; return error_mark_node; } --- 3835,3844 ---- IDENTIFIER_POINTER (TREE_PURPOSE (functions))); if (final_cp) ! { ! if (flag_ansi_overloading) ! final_cp->h.code = EVIL_CODE; ! else ! final_cp->evil = 1; ! } return error_mark_node; } *************** *** 2655,2661 **** } else ! { ! length = list_length (functions); ! } if (final_cp) --- 3861,3865 ---- } else ! length = list_length (functions); if (final_cp) *************** *** 2662,2666 **** candidates = final_cp; else ! candidates = (struct candidate *)alloca ((length+1) * sizeof (struct candidate)); cp = candidates; --- 3866,3874 ---- candidates = final_cp; else ! { ! candidates ! = (struct candidate *)alloca ((length+1) * sizeof (struct candidate)); ! bzero (candidates, (length + 1) * sizeof (struct candidate)); ! } cp = candidates; *************** *** 2667,2672 **** my_friendly_assert (TREE_CODE (TREE_VALUE (functions)) != TREE_LIST, 169); - /* OUTER is the list of FUNCTION_DECLS, in a TREE_LIST. */ for (outer = functions; outer; outer = TREE_CHAIN (outer)) { --- 3875,3880 ---- my_friendly_assert (TREE_CODE (TREE_VALUE (functions)) != TREE_LIST, 169); + /* OUTER is the list of FUNCTION_DECLS, in a TREE_LIST. */ for (outer = functions; outer; outer = TREE_CHAIN (outer)) { *************** *** 2682,2694 **** code = TREE_CODE (DECL_TEMPLATE_RESULT (function)); if (code == CONST_DECL) ! error_with_decl (function, "enumeral value `%s' conflicts with function of same name"); else if (code == VAR_DECL) ! if (TREE_STATIC (function)) ! error_with_decl (function, "variable `%s' conflicts with function of same name"); ! else ! error_with_decl (function, "constant field `%s' conflicts with function of same name"); else if (code == TYPE_DECL) continue; ! else my_friendly_abort (2); error ("at this point in file"); continue; --- 3890,3911 ---- code = TREE_CODE (DECL_TEMPLATE_RESULT (function)); if (code == CONST_DECL) ! cp_error_at ! ("enumeral value `%D' conflicts with function of same name", ! function); else if (code == VAR_DECL) ! { ! if (TREE_STATIC (function)) ! cp_error_at ! ("variable `%D' conflicts with function of same name", ! function); ! else ! cp_error_at ! ("constant field `%D' conflicts with function of same name", ! function); ! } else if (code == TYPE_DECL) continue; ! else ! my_friendly_abort (2); error ("at this point in file"); continue; *************** *** 2704,2712 **** parms, &template_cost); if (i == 0) ! function = instantiate_template (function, targs); } if (TREE_CODE (function) == TEMPLATE_DECL) ! /* Unconverted template -- failed match. */ ! cp->evil = 1, cp->function = function, cp->u.bad_arg = -4; else { --- 3921,3952 ---- parms, &template_cost); if (i == 0) ! { ! struct candidate *cp2; ! ! function = instantiate_template (function, targs); ! /* Now check that the template instantiated for this is not ! the same as a function that's in the list due to some ! previous instantiation. */ ! cp2 = candidates; ! while (cp2 != cp) ! if (cp2->function == function) ! break; ! else ! cp2 += 1; ! if (cp2->function == function) ! continue; ! } } + if (TREE_CODE (function) == TEMPLATE_DECL) ! { ! /* Unconverted template -- failed match. */ ! cp->function = function; ! cp->u.bad_arg = -4; ! if (flag_ansi_overloading) ! cp->h.code = EVIL_CODE; ! else ! cp->evil = 1; ! } else { *************** *** 2715,2735 **** /* Can't use alloca here, since result might be passed to calling function. */ ! cp->harshness ! = (unsigned short *)oballoc ((parmlength+1) * sizeof (short)); compute_conversion_costs (function, parms, cp, parmlength); ! /* Should really add another field... */ ! cp->easy = cp->easy * 128 + template_cost; ! if (cp[0].evil == 0) ! { ! cp[1].evil = 1; ! if (final_cp ! && cp[0].user == 0 && cp[0].b_or_d == 0 ! && template_cost == 0 ! && cp[0].easy <= 1) { ! final_cp[0].easy = cp[0].easy; ! return function; } - cp++; } } --- 3955,4015 ---- /* Can't use alloca here, since result might be passed to calling function. */ ! if (flag_ansi_overloading) ! { ! cp->v.ansi_harshness ! = (struct harshness_code *)oballoc ((parmlength+1) * sizeof (struct harshness_code)); ! cp->h_len = parmlength; ! } ! else ! cp->v.old_harshness ! = (unsigned short *)oballoc ((parmlength+1) * sizeof (short)); ! compute_conversion_costs (function, parms, cp, parmlength); ! ! if (flag_ansi_overloading) ! /* Make sure this is clear as well. */ ! cp->h.int_penalty += template_cost; ! else ! /* Should really add another field... */ ! cp->easy = cp->easy * 128 + template_cost; ! ! /* It seemed easier to have both if stmts in here, rather ! than excluding the hell out of it with flag_ansi_overloading ! everywhere. (bpk) */ ! if (flag_ansi_overloading) ! { ! if ((cp[0].h.code & EVIL_CODE) == 0) ! { ! cp[1].h.code = EVIL_CODE; ! ! /* int_penalty is set by convert_harshness_ansi for cases ! where we need to know about any penalties that would ! otherwise make a TRIVIAL_CODE pass. */ ! if (final_cp ! && template_cost == 0 ! && cp[0].h.code <= TRIVIAL_CODE ! && cp[0].h.int_penalty == 0) ! { ! final_cp[0].h = cp[0].h; ! return function; ! } ! cp++; ! } ! } ! else ! { ! if (cp[0].evil == 0) { ! cp[1].evil = 1; ! if (final_cp ! && cp[0].user == 0 && cp[0].b_or_d == 0 ! && template_cost == 0 ! && cp[0].easy <= 1) ! { ! final_cp[0].easy = cp[0].easy; ! return function; ! } ! cp++; } } } *************** *** 2741,2745 **** /* Leave marker. */ ! cp[0].evil = 1; if (cp - candidates > 1) { --- 4021,4028 ---- /* Leave marker. */ ! if (flag_ansi_overloading) ! cp[0].h.code = EVIL_CODE; ! else ! cp[0].evil = 1; if (cp - candidates > 1) { *************** *** 2750,2754 **** { if (complain) ! error ("call of overloaded `%s' is ambiguous", IDENTIFIER_POINTER (fnname)); return error_mark_node; } --- 4033,4037 ---- { if (complain) ! cp_error ("call of overloaded `%D' is ambiguous", fnname); return error_mark_node; } *************** *** 2759,2763 **** { cp -= 1; ! if (cp->evil > 1) { if (complain) --- 4042,4047 ---- { cp -= 1; ! if ((flag_ansi_overloading && (cp->h.code & EVIL_CODE)) ! || (!flag_ansi_overloading && cp->evil > 1)) { if (complain) diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/cp-class.c gcc-2.5.0/cp-class.c *** gcc-2.4.5/cp-class.c Tue Apr 27 01:32:21 1993 --- gcc-2.5.0/cp-class.c Fri Oct 8 14:59:31 1993 *************** *** 28,35 **** #include "flags.h" - #ifdef DEBUG_CP_BINDING_LEVELS - #include "cp-decl.h" - #endif - #include "obstack.h" #define obstack_chunk_alloc xmalloc --- 28,31 ---- *************** *** 38,41 **** --- 34,39 ---- extern struct obstack permanent_obstack; + extern void set_class_shadows PROTO ((tree)); + /* Way of stacking class types. */ static tree *current_class_base, *current_class_stack; *************** *** 74,79 **** tree current_class_name; /* IDENTIFIER_NODE: name of current class */ tree current_class_type; /* _TYPE: the type of the current class */ ! static tree prev_class_type; /* _TYPE: the previous type that was a class */ ! static tree get_vfield_name PROTO((tree)); tree the_null_vtable_entry; --- 72,78 ---- tree current_class_name; /* IDENTIFIER_NODE: name of current class */ tree current_class_type; /* _TYPE: the type of the current class */ ! tree previous_class_type; /* _TYPE: the previous type that was a class */ ! tree previous_class_values; /* TREE_LIST: copy of the class_shadowed list ! when leaving an outermost class scope. */ static tree get_vfield_name PROTO((tree)); tree the_null_vtable_entry; *************** *** 173,177 **** if (last) nonnull_expr = convert_pointer_to (last, nonnull_expr); ! ind = build_indirect_ref (nonnull_expr, NULL); nonnull_expr = build_vbase_pointer (ind, last_virtual); if (nonnull == 0 && !flag_assume_nonnull_objects --- 172,176 ---- if (last) nonnull_expr = convert_pointer_to (last, nonnull_expr); ! ind = build_indirect_ref (nonnull_expr, NULL_PTR); nonnull_expr = build_vbase_pointer (ind, last_virtual); if (nonnull == 0 && !flag_assume_nonnull_objects *************** *** 193,197 **** else { ! error_with_aggr_type (last_virtual, "cannot cast up from virtual baseclass `%s'"); return error_mark_node; } --- 192,197 ---- else { ! cp_error ("cannot cast up from virtual baseclass `%T'", ! last_virtual); return error_mark_node; } *************** *** 292,298 **** static int doing_hard_virtuals; - /* The names of the entries in the virtual table structure. */ - static tree delta_name, pfn_name; - /* XXX This is set but never used. (bpk) */ #if 0 --- 292,295 ---- *************** *** 346,357 **** } ! /* Given an object INSTANCE, return an expression which yields ! the virtual function corresponding to INDEX. There are many special cases for INSTANCE which we take care of here, mainly to avoid creating extra tree nodes when we don't have to. */ tree ! build_vfn_ref (ptr_to_instptr, instance, index) tree *ptr_to_instptr, instance; ! tree index; { extern int building_cleanup; --- 343,354 ---- } ! /* Given an object INSTANCE, return an expression which yields the ! virtual function corresponding to INDEX. There are many special cases for INSTANCE which we take care of here, mainly to avoid creating extra tree nodes when we don't have to. */ tree ! build_vfn_ref (ptr_to_instptr, instance, idx) tree *ptr_to_instptr, instance; ! tree idx; { extern int building_cleanup; *************** *** 367,371 **** || current_vtable_decl == error_mark_node || !UNIQUELY_DERIVED_FROM_P (DECL_FCONTEXT (CLASSTYPE_VFIELD (current_class_type)), basetype)) ! vtbl = build_indirect_ref (build_vfield_ref (instance, basetype), NULL); else vtbl = current_vtable_decl; --- 364,368 ---- || current_vtable_decl == error_mark_node || !UNIQUELY_DERIVED_FROM_P (DECL_FCONTEXT (CLASSTYPE_VFIELD (current_class_type)), basetype)) ! vtbl = build_indirect_ref (build_vfield_ref (instance, basetype), NULL_PTR); else vtbl = current_vtable_decl; *************** *** 411,425 **** else vtbl = build_indirect_ref (build_vfield_ref (instance, basetype), ! NULL); } assemble_external (vtbl); ! aref = build_array_ref (vtbl, index); if (!building_cleanup && TREE_CODE (aref) == INDIRECT_REF) TREE_OPERAND (aref, 0) = save_expr (TREE_OPERAND (aref, 0)); *ptr_to_instptr = build (PLUS_EXPR, TREE_TYPE (*ptr_to_instptr), *ptr_to_instptr, ! convert (integer_type_node, build_component_ref (aref, delta_name, 0, 0))); ! return build_component_ref (aref, pfn_name, 0, 0); } --- 408,426 ---- else vtbl = build_indirect_ref (build_vfield_ref (instance, basetype), ! NULL_PTR); } assemble_external (vtbl); ! aref = build_array_ref (vtbl, idx); ! ! /* Save the intermediate result in a SAVE_EXPR so we don't have to ! compute each component of the virtual function pointer twice. */ if (!building_cleanup && TREE_CODE (aref) == INDIRECT_REF) TREE_OPERAND (aref, 0) = save_expr (TREE_OPERAND (aref, 0)); + /* FIXME: This is what breaks vtables on the alpha. */ *ptr_to_instptr = build (PLUS_EXPR, TREE_TYPE (*ptr_to_instptr), *ptr_to_instptr, ! convert (integer_type_node, build_component_ref (aref, delta_identifier, 0, 0))); ! return build_component_ref (aref, pfn_identifier, 0, 0); } *************** *** 436,440 **** if (write_virtuals >= 2) { ! if (CLASSTYPE_INTERFACE_UNKNOWN (type) == 0) { TREE_PUBLIC (decl) = 1; --- 437,441 ---- if (write_virtuals >= 2) { ! if (CLASSTYPE_INTERFACE_KNOWN (type)) { TREE_PUBLIC (decl) = 1; *************** *** 462,467 **** --- 463,474 ---- int i; for (i = 0; ptr[i] == OPERATOR_TYPENAME_FORMAT[i]; i++) ; + #if 0 + /* We don't take off the numbers; prepare_fresh_vtable uses the + DECL_ASSEMBLER_NAME for the type, which includes the number + in `3foo'. If we were to pull them off here, we'd end up with + something like `_vt.foo.3bar', instead of a uniform definition. */ while (ptr[i] >= '0' && ptr[i] <= '9') i += 1; + #endif sprintf (buf, VTABLE_NAME_FORMAT, ptr+i); return get_identifier (buf); *************** *** 505,511 **** --- 512,525 ---- TREE_STATIC (decl) = 1; + #ifndef WRITABLE_VTABLES + /* Make them READONLY by default. (mrs) */ + TREE_READONLY (decl) = 1; + #endif + /* At one time the vtable info was grabbed 2 words at a time. This + fails on sparc unless you have 8-byte alignment. (tiemann) */ DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node), DECL_ALIGN (decl)); + /* Why is this conditional? (mrs) */ if (binfo && write_virtuals >= 0) DECL_VIRTUAL_P (decl) = 1; *************** *** 525,528 **** --- 539,605 ---- } + /* Given a base type PARENT, and a derived type TYPE, build + a name which distinguishes exactly the PARENT member of TYPE's type. + + FORMAT is a string which controls how sprintf formats the name + we have generated. + + For example, given + + class A; class B; class C : A, B; + + it is possible to distinguish "A" from "C's A". And given + + class L; + class A : L; class B : L; class C : A, B; + + it is possible to distinguish "L" from "A's L", and also from + "C's L from A". + + Make sure to use the DECL_ASSEMBLER_NAME of the TYPE_NAME of the + type, as template have DECL_NAMEs like: X, whereas the + DECL_ASSEMBLER_NAME is set to be something the assembler can handle. + */ + static tree + build_type_pathname (format, parent, type) + char *format; + tree parent, type; + { + extern struct obstack temporary_obstack; + char *first, *base, *name; + int i; + tree id; + + parent = TYPE_MAIN_VARIANT (parent); + + /* Remember where to cut the obstack to. */ + first = obstack_base (&temporary_obstack); + + /* Put on TYPE+PARENT. */ + obstack_grow (&temporary_obstack, + TYPE_ASSEMBLER_NAME_STRING (type), + TYPE_ASSEMBLER_NAME_LENGTH (type)); + #ifdef JOINER + obstack_1grow (&temporary_obstack, JOINER); + #else + obstack_1grow (&temporary_obstack, '_'); + #endif + obstack_grow0 (&temporary_obstack, + TYPE_ASSEMBLER_NAME_STRING (parent), + TYPE_ASSEMBLER_NAME_LENGTH (parent)); + i = obstack_object_size (&temporary_obstack); + base = obstack_base (&temporary_obstack); + obstack_finish (&temporary_obstack); + + /* Put on FORMAT+TYPE+PARENT. */ + obstack_blank (&temporary_obstack, strlen (format) + i + 1); + name = obstack_base (&temporary_obstack); + sprintf (name, format, base); + id = get_identifier (name); + obstack_free (&temporary_obstack, first); + + return id; + } + /* Give TYPE a new virtual function table which is initialized with a skeleton-copy of its original initialization. The only *************** *** 557,560 **** --- 634,641 ---- BINFO_VTABLE (binfo) = pushdecl_top_level (new_decl); DECL_VIRTUAL_P (new_decl) = 1; + #ifndef WRITABLE_VTABLES + /* Make them READONLY by default. (mrs) */ + TREE_READONLY (new_decl) = 1; + #endif DECL_ALIGN (new_decl) = DECL_ALIGN (orig_decl); *************** *** 660,664 **** /* Put new entry ENTRY into virtual function table initializer ! VIRTUALS. The virtual function table is for type CONTEXT. Also update DECL_VINDEX (FNDECL). */ --- 741,745 ---- /* Put new entry ENTRY into virtual function table initializer ! VIRTUALS. Also update DECL_VINDEX (FNDECL). */ *************** *** 665,670 **** static void ! modify_vtable_entry (old_entry_in_list, new_entry, fndecl, context) ! tree old_entry_in_list, new_entry, fndecl, context; { tree base_pfn = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (old_entry_in_list)); --- 746,751 ---- static void ! modify_vtable_entry (old_entry_in_list, new_entry, fndecl) ! tree old_entry_in_list, new_entry, fndecl; { tree base_pfn = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (old_entry_in_list)); *************** *** 683,687 **** { tree elts = CONSTRUCTOR_ELTS (new_entry); - tree vfield = CLASSTYPE_VFIELD (context); if (! doing_hard_virtuals) --- 764,767 ---- *************** *** 693,714 **** return; } - - #if 0 - my_friendly_abort (3); - - /* Compute the relative offset of vtable we are really looking for. */ - TREE_VALUE (elts) = size_binop (PLUS_EXPR, - size_int (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (vfield)) - /* ??? This may be wrong. */ - / BITS_PER_UNIT), - TREE_VALUE (elts)); - /* Say what index to use when we use that vtable. */ - #ifndef VTABLE_USES_MASK - vindex = build_int_2 (TREE_INT_CST_LOW (vindex) - & ~((unsigned HOST_WIDE_INT) 1 - << (BITS_PER_WORD -1)), 0); - #endif - TREE_VALUE (TREE_CHAIN (elts)) = vindex; - #endif } } --- 773,776 ---- *************** *** 767,770 **** --- 829,848 ---- path = BINFO_INHERITANCE_CHAIN (path); } + /* Make sure that: + + RRB + | + RL RR + \ / + L R + \ / + C + + returns 0. VF_BASETYPE_VALUE is RL, base_context is RRB, type is C, + and the vfield we are checking is R. */ + if (VF_BASETYPE_VALUE (vfields) + && get_base_distance (base_context, VF_BASETYPE_VALUE (vfields), 0, &path) == -1 + && get_base_distance (VF_BASETYPE_VALUE (vfields), base_context, 0, &path) == -1) + return 0; return 1; } *************** *** 813,822 **** tree base, path; - /* This can go away when the new searching strategy as a little mileage on it. */ - #define NEW_SEARCH 1 - #if NEW_SEARCH if (!related_vslot (base_fndecl, vfields, t)) continue; - #endif /* Find the right base class for this derived class, call it BASE. */ --- 891,896 ---- *************** *** 823,852 **** base = VF_BASETYPE_VALUE (vfields); - #if NEW_SEARCH == 0 - if (base != base_context) - { - /* If BASE_FNDECL is not contained in the vtable accessed by - the vslot, don't try to modify the vtable. - - Virtual functions from virtual baseclasses are not in derived - virtual function tables. This is an implementation decision; - it keeps there from being a combinatorial explosion in the - number of different vtables which must be maintained. */ - - /* In this case, we need to know whether BASE is derived - from BASE_CONTEXT in any case, even the case where the - derivation is ambiguous. */ - int distance = get_base_distance (base, base_context, 0, (tree *)0); - if (distance < 0 && distance != -2) - continue; - - /* BASE_FNDECL is defined in a class derived from - the base class owning this VFIELD. */ - } - #endif - /* Get the path starting from the deepest base class CONTEXT of T (i.e., first defn of BASE_FNDECL). */ ! get_base_distance (base_context, t, 0, &path); /* Get our best approximation of what to use for constructing --- 897,903 ---- base = VF_BASETYPE_VALUE (vfields); /* Get the path starting from the deepest base class CONTEXT of T (i.e., first defn of BASE_FNDECL). */ ! get_base_distance (DECL_CONTEXT (base_fndecl), t, 0, &path); /* Get our best approximation of what to use for constructing *************** *** 924,928 **** modify_vtable_entry (get_vtable_entry (BINFO_VIRTUALS (binfo), base_fndecl), build_vtable_entry (this_offset, pfn), ! fndecl, base_context); } for (vbases = CLASSTYPE_VBASECLASSES (t); vbases; vbases = TREE_CHAIN (vbases)) --- 975,979 ---- modify_vtable_entry (get_vtable_entry (BINFO_VIRTUALS (binfo), base_fndecl), build_vtable_entry (this_offset, pfn), ! fndecl); } for (vbases = CLASSTYPE_VBASECLASSES (t); vbases; vbases = TREE_CHAIN (vbases)) *************** *** 976,982 **** prepare_fresh_vtable (vbases, context_binfo, t); } ! modify_vtable_entry (get_vtable_entry (BINFO_VIRTUALS (vbases), base_fndecl), build_vtable_entry (this_offset, pfn), ! fndecl, base_context); skip: {} } --- 1027,1034 ---- prepare_fresh_vtable (vbases, context_binfo, t); } ! modify_vtable_entry (get_vtable_entry (BINFO_VIRTUALS (vbases), ! base_fndecl), build_vtable_entry (this_offset, pfn), ! fndecl); skip: {} } *************** *** 1027,1032 **** if (i >= 256 || index_table[i] == 0) { ! index = build_int_2 (((unsigned HOST_WIDE_INT) 1 ! << (BITS_PER_WORD - 1)) | i, ~0); if (i < 256) index_table[i] = index; --- 1079,1083 ---- if (i >= 256 || index_table[i] == 0) { ! index = build_int_2 (i, 0); if (i < 256) index_table[i] = index; *************** *** 1287,1302 **** if (TREE_CODE (field) == CONST_DECL && TREE_CODE (x) == CONST_DECL) ! error_with_decl (x, "duplicate enum value `%s'"); else if (TREE_CODE (field) == CONST_DECL || TREE_CODE (x) == CONST_DECL) ! error_with_decl (x, "duplicate field `%s' (as enum and non-enum)"); else if (TREE_CODE (field) == TYPE_DECL && TREE_CODE (x) == TYPE_DECL) ! error_with_decl (x, "duplicate class scope type `%s'"); else if (TREE_CODE (field) == TYPE_DECL || TREE_CODE (x) == TYPE_DECL) ! error_with_decl (x, "duplicate field `%s' (as type and non-type)"); else ! error_with_decl (x, "duplicate member `%s'"); if (prev == 0) fields = TREE_CHAIN (fields); --- 1338,1355 ---- if (TREE_CODE (field) == CONST_DECL && TREE_CODE (x) == CONST_DECL) ! cp_error_at ("duplicate enum value `%D'", x); else if (TREE_CODE (field) == CONST_DECL || TREE_CODE (x) == CONST_DECL) ! cp_error_at ("duplicate field `%D' (as enum and non-enum)", ! x); else if (TREE_CODE (field) == TYPE_DECL && TREE_CODE (x) == TYPE_DECL) ! cp_error_at ("duplicate class scope type `%D'", x); else if (TREE_CODE (field) == TYPE_DECL || TREE_CODE (x) == TYPE_DECL) ! cp_error_at ("duplicate field `%D' (as type and non-type)", ! x); else ! cp_error_at ("duplicate member `%D'", x); if (prev == 0) fields = TREE_CHAIN (fields); *************** *** 1332,1343 **** if (TREE_CODE (TREE_TYPE (fdecl)) == FUNCTION_DECL) { ! error_with_decl (TREE_TYPE (fdecl), "conflicting visibility specifications for method `%s', ignored"); } ! else error ("conflicting visibility specifications for field `%s', ignored", IDENTIFIER_POINTER (DECL_NAME (fdecl))); } else if (TREE_PRIVATE (fdecl) && visibility != visibility_private) ! error_with_decl (fdecl, "cannot make private `%s' non-private"); ! else if (TREE_PROTECTED (fdecl) && visibility == visibility_public) ! error_with_decl (fdecl, "cannot make protected `%s' public"); /* ARM 11.3: an access declaration may not be used to restrict access to a member that is accessible in the base class. */ --- 1385,1402 ---- if (TREE_CODE (TREE_TYPE (fdecl)) == FUNCTION_DECL) { ! cp_error_at ("conflicting visibility specifications for method `%D', ignored", TREE_TYPE (fdecl)); } ! else ! error ("conflicting visibility specifications for field `%s', ignored", ! IDENTIFIER_POINTER (DECL_NAME (fdecl))); } else if (TREE_PRIVATE (fdecl) && visibility != visibility_private) ! cp_error_at ("cannot make private `%D' non-private", fdecl); ! else if (TREE_PROTECTED (fdecl)) ! { ! if (visibility == visibility_public) ! cp_error_at ("cannot make protected `%D' public", fdecl); ! goto alter; ! } /* ARM 11.3: an access declaration may not be used to restrict access to a member that is accessible in the base class. */ *************** *** 1345,1351 **** && (visibility == visibility_private || visibility == visibility_protected)) ! error_with_decl (fdecl, "cannot reduce visibility of public member `%s'"); else if (elem == NULL_TREE) { DECL_VISIBILITY (fdecl) = tree_cons (t, (tree)visibility, DECL_VISIBILITY (fdecl)); --- 1404,1411 ---- && (visibility == visibility_private || visibility == visibility_protected)) ! cp_error_at ("cannot reduce visibility of public member `%D'", fdecl); else if (elem == NULL_TREE) { + alter: DECL_VISIBILITY (fdecl) = tree_cons (t, (tree)visibility, DECL_VISIBILITY (fdecl)); *************** *** 1377,1382 **** while (vfields) { ! tree base_binfo = get_binfo (VF_BASETYPE_VALUE (vfields), for_type, 0); ! if (CLASSTYPE_NEEDS_VIRTUAL_REINIT (VF_BASETYPE_VALUE (vfields))) { tree base_offset = get_vfield_offset (base_binfo); --- 1437,1446 ---- while (vfields) { ! tree basetype = VF_NORMAL_VALUE (vfields) ! ? TYPE_MAIN_VARIANT (VF_NORMAL_VALUE (vfields)) ! : VF_BASETYPE_VALUE (vfields); ! ! tree base_binfo = get_binfo (basetype, for_type, 0); ! if (CLASSTYPE_NEEDS_VIRTUAL_REINIT (basetype)) { tree base_offset = get_vfield_offset (base_binfo); *************** *** 1527,1531 **** char needs_default_ctor; char cant_have_default_ctor; - char needs_const_ctor; char cant_have_const_ctor; char members_need_dtors; --- 1591,1594 ---- *************** *** 1587,1593 **** else if (TYPE_HAS_CONSTRUCTOR (basetype)) b->cant_have_default_ctor = 1; ! if (TYPE_GETS_CONST_INIT_REF (basetype)) ! b->needs_const_ctor = 1; ! else if (TYPE_GETS_INIT_REF (basetype)) b->cant_have_const_ctor = 1; --- 1650,1655 ---- else if (TYPE_HAS_CONSTRUCTOR (basetype)) b->cant_have_default_ctor = 1; ! if (TYPE_GETS_INIT_REF (basetype) ! && !TYPE_GETS_CONST_INIT_REF (basetype)) b->cant_have_const_ctor = 1; *************** *** 1658,1661 **** --- 1720,1724 ---- if (first_vfn_base_index < 0) { + tree vfields; first_vfn_base_index = i; *************** *** 1662,1666 **** b->has_virtual = CLASSTYPE_VSIZE (basetype); b->vfield = CLASSTYPE_VFIELD (basetype); ! b->vfields = CLASSTYPE_VFIELDS (basetype); CLASSTYPE_VFIELD (t) = b->vfield; } --- 1725,1744 ---- b->has_virtual = CLASSTYPE_VSIZE (basetype); b->vfield = CLASSTYPE_VFIELD (basetype); ! b->vfields = copy_list (CLASSTYPE_VFIELDS (basetype)); ! vfields = b->vfields; ! while (vfields) ! { ! if (VF_BINFO_VALUE (vfields) == NULL_TREE ! || ! TREE_VIA_VIRTUAL (VF_BINFO_VALUE (vfields))) ! { ! tree value = VF_BASETYPE_VALUE (vfields); ! if (DECL_NAME (CLASSTYPE_VFIELD (value)) ! == DECL_NAME (CLASSTYPE_VFIELD (basetype))) ! VF_NORMAL_VALUE (b->vfields) = basetype; ! else ! VF_NORMAL_VALUE (b->vfields) = VF_NORMAL_VALUE (vfields); ! } ! vfields = TREE_CHAIN (vfields); ! } CLASSTYPE_VFIELD (t) = b->vfield; } *************** *** 1691,1694 **** --- 1769,1789 ---- b->vfield = CLASSTYPE_VFIELD (basetype); CLASSTYPE_VFIELD (t) = b->vfield; + /* When we install the first one, set the VF_NORMAL_VALUE + to be the current class, as this it is the most derived + class. Hopefully, this is not set to something else + later. (mrs) */ + vfields = b->vfields; + while (vfields) + { + if (DECL_NAME (CLASSTYPE_VFIELD (t)) + == DECL_NAME (CLASSTYPE_VFIELD (basetype))) + { + VF_NORMAL_VALUE (vfields) = t; + /* There should only be one of them! And it should + always be found, if we get into here. (mrs) */ + break; + } + vfields = TREE_CHAIN (vfields); + } } } *************** *** 1774,1785 **** if (n_baseclasses) { ! /* Notice whether this class has type conversion functions defined. ! Also report whether joining two types yields an ambiguity in the ! virtual function table, e.g., ! ! struct A { virtual int f (); }; ! struct B { virtual int f (); }; ! struct C : A, B { / * no f (); * / }; / / error, ambiguous ! */ tree binfo = TYPE_BINFO (t); tree binfos = BINFO_BASETYPES (binfo); --- 1869,1873 ---- if (n_baseclasses) { ! /* Notice whether this class has type conversion functions defined. */ tree binfo = TYPE_BINFO (t); tree binfos = BINFO_BASETYPES (binfo); *************** *** 1988,1993 **** { /* ANSI C++ June 5 1992 WP 12.5.5.1 */ ! error_with_decl (fn_fields, "operator delete cannot be overloaded"); ! error_with_decl (x, "previous declaration here"); } if (DECL_ASSEMBLER_NAME (fn_fields) == DECL_ASSEMBLER_NAME (x)) --- 2076,2081 ---- { /* ANSI C++ June 5 1992 WP 12.5.5.1 */ ! cp_error_at ("operator delete cannot be overloaded", fn_fields); ! cp_error_at ("previous declaration here", x); } if (DECL_ASSEMBLER_NAME (fn_fields) == DECL_ASSEMBLER_NAME (x)) *************** *** 2006,2013 **** } if (x == 0) ! if (*testp) ! DECL_CHAIN (prev_x) = fn_fields; ! else ! *testp = fn_fields; } else --- 2094,2103 ---- } if (x == 0) ! { ! if (*testp) ! DECL_CHAIN (prev_x) = fn_fields; ! else ! *testp = fn_fields; ! } } else *************** *** 2050,2054 **** tree dtor, prev; ! for (dtor = TREE_VEC_ELT (method_vec, 0); dtor; prev = dtor, dtor = DECL_CHAIN (dtor)) { if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (dtor))) --- 2140,2146 ---- tree dtor, prev; ! for (dtor = TREE_VEC_ELT (method_vec, 0); ! dtor; ! prev = dtor, dtor = DECL_CHAIN (dtor)) { if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (dtor))) *************** *** 2056,2064 **** if (TREE_PRIVATE (dtor) && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE ! && DECL_FRIENDLIST (TYPE_NAME (t)) == NULL_TREE) ! warning_with_decl (TYPE_NAME (t), "class `%s' only defines a private destructor and has no friends"); break; } } /* Wild parse errors can cause this to happen. */ if (dtor == NULL_TREE) --- 2148,2159 ---- if (TREE_PRIVATE (dtor) && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE ! && DECL_FRIENDLIST (TYPE_NAME (t)) == NULL_TREE ! && warn_ctor_dtor_privacy) ! warning ("class `%s' only defines a private destructor and has no friends", ! TYPE_NAME_STRING (t)); break; } } + /* Wild parse errors can cause this to happen. */ if (dtor == NULL_TREE) *************** *** 2199,2203 **** CLASSTYPE_BINFO_AS_LIST (t) = binfo_as_list; CLASSTYPE_INTERFACE_ONLY (t) = interface_only; ! CLASSTYPE_INTERFACE_UNKNOWN (t) = interface_unknown; CLASSTYPE_VBASE_SIZE (t) = integer_zero_node; TYPE_REDEFINED (t) = 1; --- 2294,2298 ---- CLASSTYPE_BINFO_AS_LIST (t) = binfo_as_list; CLASSTYPE_INTERFACE_ONLY (t) = interface_only; ! SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown); CLASSTYPE_VBASE_SIZE (t) = integer_zero_node; TYPE_REDEFINED (t) = 1; *************** *** 2277,2285 **** { extern int interface_only, interface_unknown; int old; int round_up_size = 1; - /* Set non-zero to debug using default functions. - Not set by program. */ - static int debug_default_functions = 0; enum tree_code code = TREE_CODE (t); --- 2372,2379 ---- { extern int interface_only, interface_unknown; + extern tree EHS_type; + int old; int round_up_size = 1; enum tree_code code = TREE_CODE (t); *************** *** 2298,2302 **** int needs_default_ctor; int cant_have_default_ctor; - int needs_const_ctor; int cant_have_const_ctor; --- 2392,2395 ---- *************** *** 2331,2335 **** if (warn_anon && code != UNION_TYPE && ANON_AGGRNAME_P (name)) { ! warning ("un-usable class ignored (anonymous classes and unions are useless)"); err_name = "(anon)"; } --- 2424,2428 ---- if (warn_anon && code != UNION_TYPE && ANON_AGGRNAME_P (name)) { ! warning ("anonymous class type not used to declare any objects"); err_name = "(anon)"; } *************** *** 2359,2363 **** CLASSTYPE_GOT_SEMICOLON (t) = 0; CLASSTYPE_INTERFACE_ONLY (t) = interface_only; ! CLASSTYPE_INTERFACE_UNKNOWN (t) = interface_unknown; if (flag_dossier) --- 2452,2456 ---- CLASSTYPE_GOT_SEMICOLON (t) = 0; CLASSTYPE_INTERFACE_ONLY (t) = interface_only; ! SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown); if (flag_dossier) *************** *** 2398,2402 **** needs_default_ctor = base_info.needs_default_ctor; cant_have_default_ctor = base_info.cant_have_default_ctor; - needs_const_ctor = base_info.needs_const_ctor; cant_have_const_ctor = base_info.cant_have_const_ctor; members_need_dtors = base_info.members_need_dtors; --- 2491,2494 ---- *************** *** 2415,2419 **** needs_default_ctor = 0; cant_have_default_ctor = 0; - needs_const_ctor = 0; cant_have_const_ctor = 0; members_need_dtors = 0; --- 2507,2510 ---- *************** *** 2421,2425 **** } ! if (write_virtuals == 3 && ! CLASSTYPE_INTERFACE_UNKNOWN (t) && current_lang_name == lang_name_cplusplus) { --- 2512,2516 ---- } ! if (write_virtuals == 3 && CLASSTYPE_INTERFACE_KNOWN (t) && current_lang_name == lang_name_cplusplus) { *************** *** 2470,2494 **** && TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE) { ! #if 0 ! /* @@ Um. This doesn't seem to be handled properly, at ! least in my PT test cases. Not sure if it's really ! supposed to work for non-PT cases. Let's find out. */ ! static tree t, d; ! d = DECL_NAME (x); ! t = TYPE_IDENTIFIER (TREE_TYPE (x)); ! if (d == t) continue; ! if (IDENTIFIER_TEMPLATE (t)) ! { ! t = DECL_NAME (TREE_PURPOSE (IDENTIFIER_TEMPLATE (t))); ! my_friendly_assert (t == d, 173); ! continue; ! } ! else if (IDENTIFIER_CLASS_VALUE (t)) ! my_friendly_assert (TREE_TYPE (DECL_NAME (d)) ! == TREE_TYPE (DECL_NAME (TREE_TYPE (t))), ! 174); ! else ! abort (); ! #endif continue; } --- 2561,2572 ---- && TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE) { ! /* Make sure we set this up. In find_scoped_type, it explicitly ! looks for a TYPE_DECL in the TYPE_FIELDS list. If we don't ! do this here, we'll miss including this TYPE_DECL in the ! list. */ ! if (! fields) ! fields = x; ! last_x = x; ! DECL_CONTEXT (x) = t; continue; } *************** *** 2509,2515 **** continue; ! if (last_x) TREE_CHAIN (last_x) = TREE_CHAIN (x); ! if (! fn_fields) fn_fields = x; ! else TREE_CHAIN (tail) = x; tail = x; --- 2587,2596 ---- continue; ! if (last_x) ! TREE_CHAIN (last_x) = TREE_CHAIN (x); ! if (! fn_fields) ! fn_fields = x; ! else ! TREE_CHAIN (tail) = x; tail = x; *************** *** 2542,2548 **** tree fdecl = TREE_OPERAND (DECL_NAME (x), 1); ! if (last_x) TREE_CHAIN (last_x) = TREE_CHAIN (x); ! /* Make type T see field decl FDECL with ! the visibility VISIBILITY. */ if (TREE_CODE (fdecl) == TREE_LIST) { --- 2623,2629 ---- tree fdecl = TREE_OPERAND (DECL_NAME (x), 1); ! if (last_x) ! TREE_CHAIN (last_x) = TREE_CHAIN (x); ! /* Make type T see field decl FDECL with visibility VISIBILITY.*/ if (TREE_CODE (fdecl) == TREE_LIST) { *************** *** 2555,2559 **** } } ! else alter_visibility (t, fdecl, visibility); CLASSTYPE_ALTERS_VISIBILITIES_P (t) = 1; continue; --- 2636,2641 ---- } } ! else ! alter_visibility (t, fdecl, visibility); CLASSTYPE_ALTERS_VISIBILITIES_P (t) = 1; continue; *************** *** 2560,2572 **** } ! /* If this is of reference type, check if it needs an init. */ if (TREE_CODE (x) != TYPE_DECL ! && TREE_CODE (TREE_TYPE (x)) == REFERENCE_TYPE ! && DECL_INITIAL (x) == 0) ! ref_sans_init = 1; /* ``A local class cannot have static data members.'' ARM 9.4 */ if (current_function_decl && TREE_STATIC (x)) ! error_with_decl (x, "field `%s' in local class cannot be static"); /* When this goes into scope, it will be a non-local reference. */ --- 2642,2668 ---- } ! /* If this is of reference type, check if it needs an init. Also ! do a little ANSI jig if necessary. */ if (TREE_CODE (x) != TYPE_DECL ! && TREE_CODE (TREE_TYPE (x)) == REFERENCE_TYPE) ! { ! if (DECL_INITIAL (x) == NULL_TREE) ! ref_sans_init = 1; ! ! /* ARM $12.6.2: [A member initializer list] is the only ! way to initialize a nonstatic const and reference ! [member]. */ ! if (! TYPE_HAS_CONSTRUCTOR (t) && !TREE_STATIC (x)) ! { ! if (DECL_NAME (x)) ! cp_pedwarn_at ("non-static reference `%D' in class without a constructor", x); ! else ! cp_pedwarn_at ("non-static reference in class without a constructor", x); ! } ! } /* ``A local class cannot have static data members.'' ARM 9.4 */ if (current_function_decl && TREE_STATIC (x)) ! cp_error ("field `%D' in local class cannot be static", x); /* When this goes into scope, it will be a non-local reference. */ *************** *** 2578,2582 **** if (TREE_CODE (TREE_TYPE (x)) == FUNCTION_TYPE) { ! error_with_decl (x, "field `%s' invalidly declared function type"); TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x)); } --- 2674,2679 ---- if (TREE_CODE (TREE_TYPE (x)) == FUNCTION_TYPE) { ! cp_error ("field `%D' invalidly declared function type", ! x); TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x)); } *************** *** 2583,2587 **** else if (TREE_CODE (TREE_TYPE (x)) == METHOD_TYPE) { ! error_with_decl (x, "field `%s' invalidly declared method type"); TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x)); } --- 2680,2684 ---- else if (TREE_CODE (TREE_TYPE (x)) == METHOD_TYPE) { ! cp_error ("field `%D' invalidly declared method type", x); TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x)); } *************** *** 2588,2592 **** else if (TREE_CODE (TREE_TYPE (x)) == OFFSET_TYPE) { ! error_with_decl (x, "field `%s' invalidly declared offset type"); TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x)); } --- 2685,2689 ---- else if (TREE_CODE (TREE_TYPE (x)) == OFFSET_TYPE) { ! cp_error ("field `%D' invalidly declared offset type", x); TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x)); } *************** *** 2606,2614 **** if (TYPE_LANG_SPECIFIC (TREE_TYPE (x))) { if (TYPE_HAS_DEFAULT_CONSTRUCTOR (TREE_TYPE (x))) needs_default_ctor = 1; ! if (TYPE_GETS_CONST_INIT_REF (TREE_TYPE (x))) ! needs_const_ctor = 1; ! else if (TYPE_GETS_INIT_REF (TREE_TYPE (x))) cant_have_const_ctor = 1; } --- 2703,2713 ---- if (TYPE_LANG_SPECIFIC (TREE_TYPE (x))) { + /* It's possible that the type does have a default + constructor, *and* have GETS_INIT_REF set, if + the class has a non-const copy constructor. */ if (TYPE_HAS_DEFAULT_CONSTRUCTOR (TREE_TYPE (x))) needs_default_ctor = 1; ! if (TYPE_GETS_INIT_REF (TREE_TYPE (x)) ! && !TYPE_GETS_CONST_INIT_REF (TREE_TYPE (x))) cant_have_const_ctor = 1; } *************** *** 2623,2630 **** { C_TYPE_FIELDS_READONLY (t) = 1; ! if (DECL_INITIAL (x) == 0) const_sans_init = 1; } ! else { /* A field that is pseudo-const makes the structure likewise. */ --- 2722,2740 ---- { C_TYPE_FIELDS_READONLY (t) = 1; ! if (DECL_INITIAL (x) == NULL_TREE) const_sans_init = 1; + + /* ARM $12.6.2: [A member initializer list] is the only + way to initialize a nonstatic const and reference + [member]. */ + if (! TYPE_HAS_CONSTRUCTOR (t) && !TREE_STATIC (x)) + { + if (DECL_NAME (x)) + cp_pedwarn_at ("non-static const member `%D' in class without a constructor", x); + else + cp_pedwarn_at ("non-static const member in class without a constructor", x); + } } ! else { /* A field that is pseudo-const makes the structure likewise. */ *************** *** 2643,2653 **** else if (TREE_CODE (x) == VAR_DECL && TREE_CODE (t) == UNION_TYPE) /* Unions cannot have static members. */ ! error_with_decl (x, "field `%s' declared static in union"); ! if (! fields) fields = x; DECL_FIELD_CONTEXT (x) = t; /* We could be making an extern "C" function a friend. */ ! if (DECL_LANG_SPECIFIC (x)) DECL_CLASS_CONTEXT (x) = t; DECL_FIELD_SIZE (x) = 0; --- 2753,2768 ---- else if (TREE_CODE (x) == VAR_DECL && TREE_CODE (t) == UNION_TYPE) /* Unions cannot have static members. */ ! cp_error ("field `%D' declared static in union", x); ! if (! fields) ! fields = x; DECL_FIELD_CONTEXT (x) = t; + /* We could be making an extern "C" function a friend. */ ! if (TREE_CODE (x) == FUNCTION_DECL ! && DECL_LANG_SPECIFIC (x) ! && DECL_VIRTUAL_P (x)) DECL_CLASS_CONTEXT (x) = t; + DECL_FIELD_SIZE (x) = 0; *************** *** 2664,2675 **** && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE) { ! error_with_decl (x, "bit-field `%s' has invalid type"); DECL_INITIAL (x) = NULL; } - if (DECL_INITIAL (x) && pedantic - && TREE_TYPE (x) != integer_type_node - && TREE_TYPE (x) != unsigned_type_node - && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE) - warning_with_decl (x, "bit-field `%s' type invalid in ANSI C++"); /* Detect and ignore out of range field width. */ --- 2779,2785 ---- && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE) { ! cp_error ("bit-field `%D' has invalid type", x); DECL_INITIAL (x) = NULL; } /* Detect and ignore out of range field width. */ *************** *** 2681,2690 **** { DECL_INITIAL (x) = NULL; ! 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 ((unsigned)width > TYPE_PRECISION (TREE_TYPE (x))) --- 2791,2800 ---- { DECL_INITIAL (x) = NULL; ! cp_error ("negative width in bit-field `%D'", x); } else if (width == 0 && DECL_NAME (x) != 0) { DECL_INITIAL (x) = NULL; + cp_error ("zero width for bit-field `%D'", x); } else if ((unsigned)width > TYPE_PRECISION (TREE_TYPE (x))) *************** *** 2691,2695 **** { DECL_INITIAL (x) = NULL; ! warning_with_decl (x, "width of `%s' exceeds its type"); } } --- 2801,2805 ---- { DECL_INITIAL (x) = NULL; ! cp_warning ("width of `%D' exceeds its type", x); } } *************** *** 2741,2745 **** if (TYPE_NEEDS_CONSTRUCTING (type) || TYPE_NEEDS_DESTRUCTOR (type)) ! error_with_decl (x, "member `%s' with constructor or destructor not allowed in union"); TYPE_GETS_ASSIGNMENT (t) |= TYPE_GETS_ASSIGNMENT (type); TYPE_GETS_INIT_REF (t) |= TYPE_GETS_INIT_REF (type); --- 2851,2855 ---- if (TYPE_NEEDS_CONSTRUCTING (type) || TYPE_NEEDS_DESTRUCTOR (type)) ! cp_error ("member `%D' with constructor or destructor not allowed in union", x); TYPE_GETS_ASSIGNMENT (t) |= TYPE_GETS_ASSIGNMENT (type); TYPE_GETS_INIT_REF (t) |= TYPE_GETS_INIT_REF (type); *************** *** 2795,2799 **** { /* Here we must cons up a destructor on the fly. */ ! tree dtor = cons_up_default_function (t, name, needs_virtual_dtor != 0); --- 2905,2909 ---- { /* Here we must cons up a destructor on the fly. */ ! tree dtor = cons_up_default_function (t, name, fields, needs_virtual_dtor != 0); *************** *** 2803,2808 **** else { ! if (! fn_fields) fn_fields = dtor; ! else TREE_CHAIN (tail) = dtor; tail = dtor; --- 2913,2920 ---- else { ! if (! fn_fields) ! fn_fields = dtor; ! else ! TREE_CHAIN (tail) = dtor; tail = dtor; *************** *** 2821,2848 **** } ! if (debug_default_functions) ! { ! if ((TYPE_NEEDS_CONSTRUCTOR (t) || TYPE_HAS_CONSTRUCTOR (t) || needs_ctor) ! && ! TYPE_HAS_INIT_REF (t)) ! { ! tree default_fn = cons_up_default_function (t, name, 4); ! TREE_CHAIN (default_fn) = fn_fields; ! fn_fields = default_fn; ! TYPE_HAS_INIT_REF (t) = 1; ! default_fn = cons_up_default_function (t, name, 3); ! TREE_CHAIN (default_fn) = fn_fields; ! fn_fields = default_fn; ! nonprivate_method = 1; ! } ! if (! TYPE_HAS_DEFAULT_CONSTRUCTOR (t) ! && needs_default_ctor && ! cant_have_default_ctor) ! { ! tree default_fn = cons_up_default_function (t, name, 2); ! TREE_CHAIN (default_fn) = fn_fields; ! fn_fields = default_fn; ! TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 1; ! nonprivate_method = 1; ! } } --- 2933,2967 ---- } ! /* Create default constructor, if needed. */ ! /* ARM $12.1: A default constructor will be generated for a class X ! only if no constructor has been declared for class X. So we ! check TYPE_HAS_CONSTRUCTOR also, to make sure we don't generate ! one if they declared a constructor in this class. */ ! if (! TYPE_HAS_DEFAULT_CONSTRUCTOR (t) ! && ! TYPE_HAS_CONSTRUCTOR (t) ! && needs_default_ctor && ! cant_have_default_ctor) ! { ! tree default_fn = cons_up_default_function (t, name, fields, 2); ! TREE_CHAIN (default_fn) = fn_fields; ! fn_fields = default_fn; ! TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 1; ! nonprivate_method = 1; ! } ! ! /* Create default copy constructor, if needed. Don't do it for ! the exception handler. */ ! if ((TYPE_NEEDS_CONSTRUCTOR (t) || TYPE_HAS_CONSTRUCTOR (t) || needs_ctor) ! && ! TYPE_HAS_INIT_REF (t) && t != EHS_type) ! { ! /* ARM 12.18: You get either X(X&) or X(const X&), but ! not both. --Chip */ ! tree default_fn = ! cons_up_default_function (t, name, fields, ! cant_have_const_ctor ? 4 : 3); ! TREE_CHAIN (default_fn) = fn_fields; ! fn_fields = default_fn; ! TYPE_HAS_INIT_REF (t) = 1; ! nonprivate_method = 1; } *************** *** 2867,2871 **** break; } ! if (nonprivate_ctor == 0) warning ("class `%s' only defines private constructors and has no friends", err_name); --- 2986,2991 ---- break; } ! ! if (nonprivate_ctor == 0 && warn_ctor_dtor_privacy) warning ("class `%s' only defines private constructors and has no friends", err_name); *************** *** 2886,2890 **** /* We build this decl with ptr_type_node, and change the type when we know what it should be. */ ! vfield = build_lang_field_decl (FIELD_DECL, get_vfield_name (t), ptr_type_node); /* If you change any of the below, take a look at all the other VFIELD_BASEs and VTABLE_BASEs in the code, and change --- 3006,3011 ---- /* We build this decl with ptr_type_node, and change the type when we know what it should be. */ ! vfield = build_lang_field_decl (FIELD_DECL, get_vfield_name (t), ! ptr_type_node); /* If you change any of the below, take a look at all the other VFIELD_BASEs and VTABLE_BASEs in the code, and change *************** *** 2910,2914 **** last_x = vfield; } ! else fields = vfield; vfields = chainon (vfields, CLASSTYPE_AS_LIST (t)); } --- 3031,3036 ---- last_x = vfield; } ! else ! fields = vfield; vfields = chainon (vfields, CLASSTYPE_AS_LIST (t)); } *************** *** 2929,2933 **** && DECL_INITIAL (TREE_CHAIN (x))) TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x)); ! else x = TREE_CHAIN (x); } /* Delete all duplicate fields from the fields */ --- 3051,3056 ---- && DECL_INITIAL (TREE_CHAIN (x))) TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x)); ! else ! x = TREE_CHAIN (x); } /* Delete all duplicate fields from the fields */ *************** *** 2945,2948 **** --- 3068,3108 ---- /* Pass layout information about base classes to layout_type, if any. */ + { + tree field; + for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field)) + { + if (TREE_STATIC (field)) + continue; + if (TREE_CODE (field) != FIELD_DECL) + continue; + + /* If this field is an anonymous union, + give each union-member the same position as the union has. + + ??? This is a real kludge because it makes the structure + of the types look strange. This feature is only used by + C++, which should have build_component_ref build two + COMPONENT_REF operations, one for the union and one for + the inner field. We set the offset of this field to zero + so that either the old or the correct method will work. + Setting DECL_FIELD_CONTEXT is wrong unless the inner fields are + moved into the type of this field, but nothing seems to break + by doing this. */ + + if (DECL_NAME (field) == 0 + && TREE_CODE (TREE_TYPE (field)) == UNION_TYPE) + { + tree uelt = TYPE_FIELDS (TREE_TYPE (field)); + for (; uelt; uelt = TREE_CHAIN (uelt)) + { + DECL_FIELD_CONTEXT (uelt) = DECL_FIELD_CONTEXT (field); + DECL_FIELD_BITPOS (uelt) = DECL_FIELD_BITPOS (field); + } + + DECL_FIELD_BITPOS (field) = integer_zero_node; + } + } + } + if (n_baseclasses) { *************** *** 2956,2959 **** --- 3116,3121 ---- TYPE_ALIGN (pseudo_basetype) = CLASSTYPE_ALIGN (t); DECL_ALIGN (base_layout_decl) = TYPE_ALIGN (pseudo_basetype); + /* Don't re-use old size. */ + DECL_SIZE (base_layout_decl) = 0; } *************** *** 2960,2963 **** --- 3122,3162 ---- layout_type (t); + { + tree field; + for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field)) + { + if (TREE_STATIC (field)) + continue; + if (TREE_CODE (field) != FIELD_DECL) + continue; + + /* If this field is an anonymous union, + give each union-member the same position as the union has. + + ??? This is a real kludge because it makes the structure + of the types look strange. This feature is only used by + C++, which should have build_component_ref build two + COMPONENT_REF operations, one for the union and one for + the inner field. We set the offset of this field to zero + so that either the old or the correct method will work. + Setting DECL_FIELD_CONTEXT is wrong unless the inner fields are + moved into the type of this field, but nothing seems to break + by doing this. */ + + if (DECL_NAME (field) == 0 + && TREE_CODE (TREE_TYPE (field)) == UNION_TYPE) + { + tree uelt = TYPE_FIELDS (TREE_TYPE (field)); + for (; uelt; uelt = TREE_CHAIN (uelt)) + { + DECL_FIELD_CONTEXT (uelt) = DECL_FIELD_CONTEXT (field); + DECL_FIELD_BITPOS (uelt) = DECL_FIELD_BITPOS (field); + } + + DECL_FIELD_BITPOS (field) = integer_zero_node; + } + } + } + if (n_baseclasses) TYPE_FIELDS (t) = TREE_CHAIN (TYPE_FIELDS (t)); *************** *** 3103,3107 **** if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t))) ! build_vtable (binfo_value (TYPE_BINFO_BASETYPE (t, first_vfn_base_index), t), t); /* Update the dossier pointer for this class. */ --- 3302,3306 ---- if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t))) ! build_vtable (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), first_vfn_base_index), t); /* Update the dossier pointer for this class. */ *************** *** 3120,3124 **** else if (first_vfn_base_index >= 0) { ! tree binfo = get_binfo (DECL_FIELD_CONTEXT (vfield), t, 0); /* This class contributes nothing new to the virtual function --- 3319,3329 ---- else if (first_vfn_base_index >= 0) { ! tree binfo = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), first_vfn_base_index); ! #if 0 ! /* For testing. */ ! tree binfo1 = get_binfo (DECL_FIELD_CONTEXT (vfield), t, 0); ! if (binfo != binfo1) ! warning ("binfos are different in vtable creation"); ! #endif /* This class contributes nothing new to the virtual function *************** *** 3203,3206 **** --- 3408,3413 ---- TREE_TYPE (TYPE_BINFO_VTABLE (t)) = atype; layout_decl (TYPE_BINFO_VTABLE (t), 0); + /* At one time the vtable info was grabbed 2 words at a time. This + fails on sparc unless you have 8-byte alignment. (tiemann) */ DECL_ALIGN (TYPE_BINFO_VTABLE (t)) = MAX (TYPE_ALIGN (double_type_node), *************** *** 3224,3235 **** /* Promote each bit-field's type to int if it is narrower than that. There's more: complete the rtl for any static member objects which ! is of the same type we're working on. ! */ for (x = fields; x; x = TREE_CHAIN (x)) { if (DECL_BIT_FIELD (x) ! && C_PROMOTING_INTEGER_TYPE_P (TREE_TYPE (x))) ! TREE_TYPE (x) = TREE_UNSIGNED (TREE_TYPE (x)) ! ? unsigned_type_node : integer_type_node; if (TREE_CODE (x) == VAR_DECL && TREE_STATIC (x) && TREE_TYPE (x) == t) --- 3431,3455 ---- /* Promote each bit-field's type to int if it is narrower than that. There's more: complete the rtl for any static member objects which ! is of the same type we're working on. */ for (x = fields; x; x = TREE_CHAIN (x)) { if (DECL_BIT_FIELD (x) ! && (C_PROMOTING_INTEGER_TYPE_P (TREE_TYPE (x)) ! || DECL_FIELD_SIZE (x) < TYPE_PRECISION (integer_type_node))) ! { ! tree type = TREE_TYPE (x); ! ! /* Preserve unsignedness if traditional or if not really getting ! any wider. */ ! if (TREE_UNSIGNED (type) ! && (flag_traditional ! || ! (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node) ! && DECL_FIELD_SIZE (x) == TYPE_PRECISION (integer_type_node)))) ! TREE_TYPE (x) = unsigned_type_node; ! else ! TREE_TYPE (x) = integer_type_node; ! } ! if (TREE_CODE (x) == VAR_DECL && TREE_STATIC (x) && TREE_TYPE (x) == t) *************** *** 3249,3252 **** --- 3469,3480 ---- { tree tag = build_lang_decl (TYPE_DECL, TREE_PURPOSE (x), TREE_VALUE (x)); + #ifdef DWARF_DEBUGGING_INFO + if (write_symbols == DWARF_DEBUG) + { + /* Notify dwarfout.c that this TYPE_DECL node represent a + gratuitous typedef. */ + DECL_IGNORED_P (tag) = 1; + } + #endif /* DWARF_DEBUGGING_INFO */ DECL_CONTEXT (tag) = t; DECL_CLASS_CONTEXT (tag) = t; *************** *** 3290,3298 **** if (CLASSTYPE_VSIZE (t) != 0) { - #if 0 - if (!TYPE_USES_COMPLEX_INHERITANCE (t)) - TYPE_NONCOPIED_PARTS (t) = build_tree_list (default_conversion (TYPE_BINFO_VTABLE (t)), vfield); - #endif - if ((flag_this_is_variable & 1) == 0) { --- 3518,3521 ---- *************** *** 3304,3308 **** if (DECL_FIELD_CONTEXT (vfield) != t) { ! tree binfo = binfo_value (DECL_FIELD_CONTEXT (vfield), t); tree offset = BINFO_OFFSET (binfo); --- 3527,3531 ---- if (DECL_FIELD_CONTEXT (vfield) != t) { ! tree binfo = get_binfo (DECL_FIELD_CONTEXT (vfield), t, 0); tree offset = BINFO_OFFSET (binfo); *************** *** 3318,3321 **** --- 3541,3550 ---- CLASSTYPE_VFIELD (t) = vfield; } + + /* In addition to this one, all the other vfields should be listed. */ + /* Before that can be done, we have to have FIELD_DECLs for them, and + a place to find them. */ + TYPE_NONCOPIED_PARTS (t) = build_tree_list (default_conversion (TYPE_BINFO_VTABLE (t)), vfield); + if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (t) && DECL_VINDEX (TREE_VEC_ELT (method_vec, 0)) == NULL_TREE) *************** *** 3376,3410 **** /* This has to be done after we have sorted out what to do with the enclosing type. */ ! /* Be smarter about nested classes here. If a type is nested, ! only output it if we would output the enclosing type. */ ! if (DECL_CONTEXT (TYPE_NAME (t)) ! && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (TYPE_NAME (t)))) == 't') ! DECL_IGNORED_P (TYPE_NAME (t)) = TREE_ASM_WRITTEN (TYPE_NAME (t)); #endif ! /* If the type has methods, we want to think about cutting down ! the amount of symbol table stuff we output. The value stored in ! the TYPE_DECL's DECL_IGNORED_P slot is a first approximation. ! For example, if a member function is seen and we decide to ! write out that member function, then we can change the value ! of the DECL_IGNORED_P slot, and the type will be output when ! that member function's debug info is written out. */ ! if (CLASSTYPE_METHOD_VEC (t)) ! { ! extern tree pending_vtables; ! ! /* Don't output full info about any type ! which does not have its implementation defined here. */ ! if (TYPE_VIRTUAL_P (t) && write_virtuals == 2) ! DECL_IGNORED_P (TYPE_NAME (t)) ! = (value_member (TYPE_IDENTIFIER (t), pending_vtables) == 0); else if (CLASSTYPE_INTERFACE_ONLY (t)) DECL_IGNORED_P (TYPE_NAME (t)) = 1; - else if (CLASSTYPE_INTERFACE_UNKNOWN (t)) - /* Only a first approximation! */ - DECL_IGNORED_P (TYPE_NAME (t)) = 1; } - else if (CLASSTYPE_INTERFACE_ONLY (t)) - DECL_IGNORED_P (TYPE_NAME (t)) = 1; /* Finish debugging output for this type. */ --- 3605,3645 ---- /* This has to be done after we have sorted out what to do with the enclosing type. */ ! if (write_symbols != DWARF_DEBUG) ! { ! /* Be smarter about nested classes here. If a type is nested, ! only output it if we would output the enclosing type. */ ! if (DECL_CONTEXT (TYPE_NAME (t)) ! && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (TYPE_NAME (t)))) == 't') ! DECL_IGNORED_P (TYPE_NAME (t)) = TREE_ASM_WRITTEN (TYPE_NAME (t)); ! } #endif ! if (write_symbols != DWARF_DEBUG) ! { ! /* If the type has methods, we want to think about cutting down ! the amount of symbol table stuff we output. The value stored in ! the TYPE_DECL's DECL_IGNORED_P slot is a first approximation. ! For example, if a member function is seen and we decide to ! write out that member function, then we can change the value ! of the DECL_IGNORED_P slot, and the type will be output when ! that member function's debug info is written out. */ ! if (CLASSTYPE_METHOD_VEC (t)) ! { ! extern tree pending_vtables; ! ! /* Don't output full info about any type ! which does not have its implementation defined here. */ ! if (TYPE_VIRTUAL_P (t) && write_virtuals == 2) ! DECL_IGNORED_P (TYPE_NAME (t)) ! = (value_member (TYPE_IDENTIFIER (t), pending_vtables) == 0); ! else if (CLASSTYPE_INTERFACE_ONLY (t)) ! DECL_IGNORED_P (TYPE_NAME (t)) = 1; ! else if (CLASSTYPE_INTERFACE_UNKNOWN (t)) ! /* Only a first approximation! */ ! DECL_IGNORED_P (TYPE_NAME (t)) = 1; ! } else if (CLASSTYPE_INTERFACE_ONLY (t)) DECL_IGNORED_P (TYPE_NAME (t)) = 1; } /* Finish debugging output for this type. */ *************** *** 3540,3546 **** current_lang_stack = current_lang_base; - delta_name = get_identifier (VTABLE_DELTA_NAME); - pfn_name = get_identifier (VTABLE_PFN_NAME); - /* Keep these values lying around. */ the_null_vtable_entry = build_vtable_entry (integer_zero_node, integer_zero_node); --- 3775,3778 ---- *************** *** 3609,3618 **** int modify; { - #ifdef DEBUG_CP_BINDING_LEVELS - indent_to (stderr, debug_bindings_indentation); - fprintf (stderr, "pushclass"); - debug_bindings_indentation += 4; - #endif - push_memoized_context (type, modify); --- 3841,3844 ---- *************** *** 3634,3647 **** current_class_type = type; ! if (prev_class_type != NULL_TREE ! && (type != prev_class_type ! || TYPE_SIZE (prev_class_type) == NULL_TREE /* ??? Is this necessary any more? */ ! || IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (prev_class_type))) && (current_class_depth == 1 || modify == 3)) { /* Forcibly remove any old class remnants. */ popclass (-1); ! prev_class_type = 0; } --- 3860,3879 ---- current_class_type = type; ! #if NEW_CLASS_SCOPING ! if (previous_class_type != NULL_TREE ! && (type != previous_class_type || TYPE_SIZE (previous_class_type) == NULL_TREE) ! && current_class_depth == 1) ! #else ! if (previous_class_type != NULL_TREE ! && (type != previous_class_type ! || TYPE_SIZE (previous_class_type) == NULL_TREE /* ??? Is this necessary any more? */ ! || IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (previous_class_type))) && (current_class_depth == 1 || modify == 3)) + #endif { /* Forcibly remove any old class remnants. */ popclass (-1); ! previous_class_type = NULL_TREE; } *************** *** 3665,3669 **** overload_template_name (current_class_name, 0); } ! else if (type != prev_class_type) { build_mi_matrix (type); --- 3897,3905 ---- overload_template_name (current_class_name, 0); } ! #if !NEW_CLASS_SCOPING ! else if (type != previous_class_type) ! #else ! else if (type != previous_class_type || current_class_depth > 1) ! #endif { build_mi_matrix (type); *************** *** 3670,3677 **** push_class_decls (type); free_mi_matrix (); ! prev_class_type = type; } else ! unuse_fields (type); for (tags = CLASSTYPE_TAGS (type); tags; tags = TREE_CHAIN (tags)) --- 3906,3933 ---- push_class_decls (type); free_mi_matrix (); ! #if NEW_CLASS_SCOPING ! if (current_class_depth == 1) ! #endif ! previous_class_type = type; } + #if NEW_CLASS_SCOPING else ! { ! tree item; ! ! /* Hooray, our cacheing was successful, let's just install the ! cached class_shadowed list, and walk through it to get the ! IDENTIFIER_TYPE_VALUEs correct. */ ! set_class_shadows (previous_class_values); ! for (item = previous_class_values; item; item = TREE_CHAIN (item)) ! { ! tree id = TREE_PURPOSE (item); ! tree decl = IDENTIFIER_CLASS_VALUE (id); ! ! if (TREE_CODE (decl) == TYPE_DECL) ! set_identifier_type_value (id, TREE_TYPE (decl)); ! } ! } ! #endif for (tags = CLASSTYPE_TAGS (type); tags; tags = TREE_CHAIN (tags)) *************** *** 3681,3684 **** --- 3937,3941 ---- continue; pushtag (TREE_PURPOSE (tags), TREE_VALUE (tags)); + #if !NEW_CLASS_SCOPING if (IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (tags)) == NULL_TREE && TREE_CODE (TYPE_NAME (TREE_VALUE (tags))) == TYPE_DECL) *************** *** 3685,3688 **** --- 3942,3946 ---- IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (tags)) = TYPE_NAME (TREE_VALUE (tags)); + #endif } *************** *** 3692,3699 **** if (flag_cadillac) cadillac_push_class (type); - - #ifdef DEBUG_CP_BINDING_LEVELS - debug_bindings_indentation -= 4; - #endif } --- 3950,3953 ---- *************** *** 3706,3715 **** int modify; { - #ifdef DEBUG_CP_BINDING_LEVELS - indent_to (stderr, debug_bindings_indentation); - fprintf (stderr, "popclass"); - debug_bindings_indentation += 4; - #endif - if (flag_cadillac) cadillac_pop_class (); --- 3960,3963 ---- *************** *** 3718,3728 **** { /* Back this old class out completely. */ ! tree tags = CLASSTYPE_TAGS (prev_class_type); ! ! pop_class_decls (prev_class_type); while (tags) { TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0; IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (tags)) = NULL_TREE; tags = TREE_CHAIN (tags); } --- 3966,3987 ---- { /* Back this old class out completely. */ ! tree tags = CLASSTYPE_TAGS (previous_class_type); ! #if NEW_CLASS_SCOPING ! tree t; ! ! /* This code can be seen as a cache miss. When we've cached a ! class' scope's bindings and we can't use them, we need to reset ! them. This is it! */ ! for (t = previous_class_values; t; t = TREE_CHAIN(t)) ! IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE; ! #else ! pop_class_decls (previous_class_type); ! #endif while (tags) { TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0; + #if !NEW_CLASS_SCOPING IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (tags)) = NULL_TREE; + #endif tags = TREE_CHAIN (tags); } *************** *** 3739,3744 **** --- 3998,4005 ---- { TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0; + #if !NEW_CLASS_SCOPING if (TREE_PURPOSE (tags)) IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (tags)) = NULL_TREE; + #endif tags = TREE_CHAIN (tags); } *************** *** 3746,3751 **** --- 4007,4021 ---- if (TREE_CODE (current_class_type) == UNINSTANTIATED_P_TYPE) undo_template_name_overload (current_class_name, 0); + poplevel_class (); + #if NEW_CLASS_SCOPING + /* Since poplevel_class does the popping of class decls nowadays, + this really only frees the obstack used for these decls. + That's why it had to be moved down here. */ + if (modify) + pop_class_decls (current_class_type); + #endif + current_class_depth--; current_class_type = *--current_class_stack; *************** *** 3759,3765 **** if (current_vtable_decl) current_vtable_decl = build_indirect_ref (current_vtable_decl, ! NULL); } ! current_class_decl = lookup_name (get_identifier (THIS_NAME), 0); if (current_class_decl) { --- 4029,4035 ---- if (current_vtable_decl) current_vtable_decl = build_indirect_ref (current_vtable_decl, ! NULL_PTR); } ! current_class_decl = lookup_name (this_identifier, 0); if (current_class_decl) { *************** *** 3778,3782 **** C_C_D = current_class_decl; } ! else C_C_D = NULL_TREE; } else --- 4048,4053 ---- C_C_D = current_class_decl; } ! else ! C_C_D = NULL_TREE; } else *************** *** 3791,3798 **** ret: ; ! #ifdef DEBUG_CP_BINDING_LEVELS ! debug_bindings_indentation -= 4; ! #endif } /* Set global variables CURRENT_LANG_NAME to appropriate value --- 4062,4100 ---- ret: ; ! } ! ! #if NEW_CLASS_SCOPING ! /* When entering a class scope, all enclosing class scopes' names with ! static meaning (static variables, static functions, types and enumerators) ! have to be visible. This recursive function calls pushclass for all ! enclosing class contexts until global or a local scope is reached. ! TYPE is the enclosed class and MODIFY is equivalent with the pushclass ! formal of the same name. */ ! ! void ! push_nested_class (type, modify) ! tree type; ! int modify; ! { ! tree context = DECL_CONTEXT (TYPE_NAME (type)); ! ! if (context && TREE_CODE (context) == RECORD_TYPE) ! push_nested_class (context, 2); ! pushclass (type, modify); ! } ! ! /* Undoes a push_nested_class call. MODIFY is passed on to popclass. */ ! ! void ! pop_nested_class (modify) ! int modify; ! { ! tree context = DECL_CONTEXT (TYPE_NAME (current_class_type)); ! ! popclass (modify); ! if (context && TREE_CODE (context) == RECORD_TYPE) ! pop_nested_class (modify); } + #endif /* Set global variables CURRENT_LANG_NAME to appropriate value *************** *** 4273,4274 **** --- 4575,4590 ---- #endif } + + #if NEW_CLASS_SCOPING + /* Push an obstack which is sufficiently long-lived to hold such class + decls that may be cached in the previous_class_values list. For now, let's + use the permanent obstack, later we may create a dedicated obstack just + for this purpose. The effect is undone by pop_obstacks. */ + void + maybe_push_cache_obstack () + { + push_obstacks_nochange (); + if (current_class_depth == 1) + current_obstack = &permanent_obstack; + } + #endif diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/cp-class.h gcc-2.5.0/cp-class.h *** gcc-2.4.5/cp-class.h Sat Apr 24 02:42:43 1993 --- gcc-2.5.0/cp-class.h Fri Jul 9 17:13:21 1993 *************** *** 71,91 **** this is not enough. */ struct candidate { ! tree function; /* A FUNCTION_DECL */ ! unsigned char evil; /* !0 if this will never convert. */ ! unsigned char ellipsis; /* !0 if a match against an ellipsis occurred */ ! unsigned char user; /* !0 if at least one user-defined type conv. */ ! unsigned short b_or_d; /* count number of derived->base or ! base->derived conv. */ ! unsigned short easy; /* count number of builtin type conv. */ tree arg; /* first parm to function. */ ! unsigned short *harshness; /* Indexed by argument number, encodes ! evil, user, d_to_b, and easy strikes for ! that argument. ! At end of array, we store the index+1 ! of where we started using default ! parameters, or 0 if there are none. */ union { --- 71,136 ---- this is not enough. */ + /* These macros and harshness_code are used by the NEW METHOD. */ + #define EVIL_CODE (1<<7) + #define CONST_CODE (1<<6) + #define ELLIPSIS_CODE (1<<5) + #define USER_CODE (1<<4) + #define STD_CODE (1<<3) + #define PROMO_CODE (1<<2) + #define QUAL_CODE (1<<1) + #define TRIVIAL_CODE (1<<0) + + struct harshness_code + { + /* What kind of conversion is involved. */ + unsigned short code; + + /* The inheritance distance. */ + short distance; + + /* For a PROMO_CODE, Any special penalties involved in integral conversions. + This exists because $4.1 of the ARM states that something like + `short unsigned int' should promote to `int', not `unsigned int'. + If, for example, it tries to match two fns, f(int) and f(unsigned), + f(int) should be a better match than f(unsigned) by this rule. Without + this extra metric, they both only appear as "integral promotions", which + will lead to an ambiguity. + For a TRIVIAL_CODE, This is also used by build_overload_call_real and + convert_harshness to keep track of other information we need. */ + unsigned short int_penalty; + }; + struct candidate { ! /* OLD METHOD */ ! unsigned char evil; /* !0 if this will never convert. */ ! unsigned char ellipsis; /* !0 if a match against an ellipsis occurred */ ! unsigned char user; /* !0 if at least one user-defined type conv. */ ! unsigned short b_or_d; /* count number of derived->base or ! base->derived conv. */ ! unsigned short easy; /* count number of builtin type conv. */ ! /* NEW METHOD */ ! struct harshness_code h; /* Used for single-argument conversions. */ ! ! int h_len; /* The length of the harshness vector. */ ! ! /* Both methods. */ ! tree function; /* A FUNCTION_DECL */ tree arg; /* first parm to function. */ ! ! /* This union is only here while we maintain both the old and new ! argument matching schemes. When it goes away, all v.ansi_harshness ! references will be just `harshness'. */ ! union ! { ! /* Indexed by argument number, encodes evil, user, d_to_b, and easy ! strikes for that argument. At end of array, we store the index+1 ! of where we started using default parameters, or 0 if there are ! none. */ ! struct harshness_code *ansi_harshness; /* NEW METHOD */ ! unsigned short *old_harshness; /* OLD METHOD */ ! } v; ! union { diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/cp-cvt.c gcc-2.5.0/cp-cvt.c *** gcc-2.4.5/cp-cvt.c Wed May 5 00:29:05 1993 --- gcc-2.5.0/cp-cvt.c Fri Oct 8 14:59:41 1993 *************** *** 29,32 **** --- 29,33 ---- #include "flags.h" #include "cp-tree.h" + #include "cp-class.h" #include "convert.h" *************** *** 44,48 **** Here is a list of all the functions that assume that widening and narrowing is always done with a NOP_EXPR: ! In c-convert.c, convert_to_integer. In c-typeck.c, build_binary_op_nodefault (boolean ops), and truthvalue_conversion. --- 45,49 ---- Here is a list of all the functions that assume that widening and narrowing is always done with a NOP_EXPR: ! In convert.c, convert_to_integer. In c-typeck.c, build_binary_op_nodefault (boolean ops), and truthvalue_conversion. *************** *** 56,60 **** --- 57,105 ---- /* Subroutines of `convert'. */ + /* Build a thunk. What it is, is an entry point that when called will + adjust the this pointer (the first argument) by offset, and then + goto the real address of the function given by REAL_ADDR that we + would like called. What we return is the address of the thunk. */ static tree + build_thunk (offset, real_addr) + tree offset, real_addr; + { + if (TREE_CODE (real_addr) != ADDR_EXPR + || TREE_CODE (TREE_OPERAND (real_addr, 0)) != FUNCTION_DECL) + { + sorry ("MI pointer to member conversion too complex"); + return error_mark_node; + } + sorry ("MI pointer to member conversion too complex"); + return error_mark_node; + } + + /* Convert a `pointer to member' (POINTER_TYPE to METHOD_TYPE) into + another `pointer to method'. This may involved the creation of + a thunk to handle the this offset calculation. */ + static tree + convert_fn_ptr (type, expr) + tree type, expr; + { + tree binfo = get_binfo (TYPE_METHOD_BASETYPE (TREE_TYPE (TREE_TYPE (expr))), + TYPE_METHOD_BASETYPE (TREE_TYPE (type)), + 1); + if (binfo == error_mark_node) + { + error (" in pointer to member conversion"); + return error_mark_node; + } + if (binfo == NULL_TREE) + { + /* ARM 4.8 restriction. */ + error ("invalid pointer to member conversion"); + return error_mark_node; + } + if (BINFO_OFFSET_ZEROP (binfo)) + return build1 (NOP_EXPR, type, expr); + return build1 (NOP_EXPR, type, build_thunk (BINFO_OFFSET (binfo), expr)); + } + + static tree cp_convert_to_pointer (type, expr) tree type, expr; *************** *** 99,102 **** --- 144,153 ---- } } + if (TYPE_MAIN_VARIANT (type) != intype + && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE + && TREE_CODE (type) == POINTER_TYPE + && TREE_CODE (TREE_TYPE (intype)) == METHOD_TYPE) + return convert_fn_ptr (type, expr); + return build1 (NOP_EXPR, type, expr); } *************** *** 155,159 **** { ambig: ! error_with_aggr_type (TREE_TYPE (type), "type `%s' is ambiguous baseclass of `%s'", TYPE_NAME_STRING (TREE_TYPE (intype))); return error_mark_node; --- 206,210 ---- { ambig: ! cp_error ("type `%T' is ambiguous baseclass of `%s'", TREE_TYPE (type), TYPE_NAME_STRING (TREE_TYPE (intype))); return error_mark_node; *************** *** 207,211 **** return error_mark_node; if (basetype == NULL_TREE) ! return (tree) error_not_base_type (target_type, argtype); basetype = BINFO_TYPE (binfo); } --- 258,262 ---- return error_mark_node; if (basetype == NULL_TREE) ! return error_not_base_type (target_type, argtype); basetype = BINFO_TYPE (binfo); } *************** *** 483,488 **** else TREE_TYPE (rval) = type; ! return build (COMPOUND_EXPR, type, ! build (MODIFY_EXPR, argtype, temp, arg), rval); } } --- 534,541 ---- else TREE_TYPE (rval) = type; ! ! temp = build (MODIFY_EXPR, argtype, temp, arg); ! TREE_SIDE_EFFECTS (temp) = 1; ! return build (COMPOUND_EXPR, type, temp, rval); } } *************** *** 587,597 **** /* @@ Perhaps this should try to go through a constructor first @@ for proper initialization, but I am not sure when that ! @@ is needed or desirable. ! ! @@ The second disjunct is provided to make references behave ! @@ as some people think they should, i.e., an interconvertibility ! @@ between references to builtin types (such as short and ! @@ unsigned short). There should be no conversion between ! @@ types whose codes are different, or whose sizes are different. */ if (((IS_AGGR_TYPE (type) || IS_AGGR_TYPE (intype)) --- 640,644 ---- /* @@ Perhaps this should try to go through a constructor first @@ for proper initialization, but I am not sure when that ! @@ is needed or desirable. */ if (((IS_AGGR_TYPE (type) || IS_AGGR_TYPE (intype)) *************** *** 598,603 **** && comptypes (type, intype, strict)) || (!IS_AGGR_TYPE (type) ! && TREE_CODE (type) == TREE_CODE (intype) ! && int_size_in_bytes (type) == int_size_in_bytes (intype))) { /* Section 13. */ --- 645,657 ---- && comptypes (type, intype, strict)) || (!IS_AGGR_TYPE (type) ! #if 1 ! && ((TREE_CODE (type) == TREE_CODE (intype) ! && int_size_in_bytes (type) == int_size_in_bytes (intype)) ! || TREE_READONLY (TREE_TYPE (reftype))))) ! #else ! && (comptypes (type, intype, 1) ! || TREE_READONLY (TREE_TYPE (reftype))))) ! #endif ! { /* Section 13. */ *************** *** 664,672 **** if (init != error_mark_node) ! if (rval) ! { ! error ("both constructor and type conversion operator apply"); ! return error_mark_node; ! } init = build_method_call (NULL_TREE, constructor_name (type), --- 718,735 ---- if (init != error_mark_node) ! { ! if (rval) ! { ! error ("both constructor and type conversion operator apply"); ! return error_mark_node; ! } ! } ! else ! { ! /* If a type conversion operator works, then pass that along ! to the ctor. */ ! if (rval != NULL_TREE) ! expr = rval; ! } init = build_method_call (NULL_TREE, constructor_name (type), *************** *** 682,691 **** } my_friendly_assert (form != OFFSET_TYPE, 189); ! /* This is in two pieces for now, because pointer to first becomes ! invalid once type_as_string is called again. */ ! error ("cannot convert type `%s'", type_as_string (intype)); ! error (" to type `%s'", type_as_string (reftype)); return error_mark_node; --- 745,757 ---- } + if (rval) + { + /* If we found a way to convert earlier, then use it. */ + return rval; + } + my_friendly_assert (form != OFFSET_TYPE, 189); ! cp_error ("cannot convert type `%T' to type `%T'", intype, reftype); return error_mark_node; *************** *** 711,715 **** { nval = build1 (NOP_EXPR, build_pointer_type (target_type), val); ! nval = build_indirect_ref (nval, 0); /* The below was missing, are other important flags missing too? */ TREE_SIDE_EFFECTS (nval) = TREE_SIDE_EFFECTS (val); --- 777,781 ---- { nval = build1 (NOP_EXPR, build_pointer_type (target_type), val); ! nval = build_indirect_ref (nval, NULL_PTR); /* The below was missing, are other important flags missing too? */ TREE_SIDE_EFFECTS (nval) = TREE_SIDE_EFFECTS (val); *************** *** 723,727 **** TREE_READONLY (nval) = TYPE_READONLY (target_type); /* The below was missing, are other important flags missing too? */ ! TREE_SIDE_EFFECTS (nval) = TREE_SIDE_EFFECTS (val); return nval; } --- 789,793 ---- TREE_READONLY (nval) = TYPE_READONLY (target_type); /* The below was missing, are other important flags missing too? */ ! TREE_SIDE_EFFECTS (nval) |= TREE_SIDE_EFFECTS (val); return nval; } *************** *** 824,830 **** { function = fndecl; ! cp->harshness = (unsigned short *)alloca (3 * sizeof (short)); compute_conversion_costs (fndecl, parmlist, cp, 2); ! if (cp->evil == 0) { cp->u.field = fndecl; --- 890,904 ---- { function = fndecl; ! if (flag_ansi_overloading) ! { ! cp->v.ansi_harshness = (struct harshness_code *)alloca (3 * sizeof (struct harshness_code)); ! cp->h_len = 2; ! } ! else ! cp->v.old_harshness = (unsigned short *)alloca (3 * sizeof (short)); ! compute_conversion_costs (fndecl, parmlist, cp, 2); ! if ((flag_ansi_overloading && (cp->h.code & EVIL_CODE) == 0) ! || (!flag_ansi_overloading && cp->evil == 0)) { cp->u.field = fndecl; *************** *** 850,858 **** : 1) { ! if (cp->user == 0 && cp->b_or_d == 0 ! && cp->easy <= 1) ! { ! goto found_and_ok; ! } cp++; } --- 924,932 ---- : 1) { ! if ((flag_ansi_overloading && cp->h.code <= TRIVIAL_CODE) ! || (!flag_ansi_overloading ! && cp->user == 0 && cp->b_or_d == 0 ! && cp->easy <= 1)) ! goto found_and_ok; cp++; } *************** *** 881,885 **** --cp; ! if (cp->evil > 1) { if (msgp) --- 955,960 ---- --cp; ! if ((flag_ansi_overloading && (cp->h.code & EVIL_CODE)) ! || (!flag_ansi_overloading && cp->evil > 1)) { if (msgp) *************** *** 951,958 **** } ! /* Call this when we know (for any reason) that expr is ! not, in fact, zero. */ tree ! convert_pointer_to (binfo, expr) tree binfo, expr; { --- 1026,1037 ---- } ! /* Call this when we know (for any reason) that expr is not, in fact, ! zero. This routine is like convert_pointer_to, but it pays ! attention to which specific instance of what type we want to ! convert to. This routine should eventually become ! convert_to_pointer after all references to convert_to_pointer ! are removed. */ tree ! convert_pointer_to_real (binfo, expr) tree binfo, expr; { *************** *** 966,970 **** { type = binfo; - binfo = TYPE_BINFO (binfo); } else --- 1045,1048 ---- *************** *** 989,993 **** tree path; int distance ! = get_base_distance (type, TYPE_MAIN_VARIANT (TREE_TYPE (intype)), 0, &path); --- 1067,1071 ---- tree path; int distance ! = get_base_distance (binfo, TYPE_MAIN_VARIANT (TREE_TYPE (intype)), 0, &path); *************** *** 999,1004 **** error ("cannot convert a pointer of type `%s'", TYPE_NAME_STRING (TREE_TYPE (intype))); ! error_with_aggr_type (type, "to a pointer of type `%s'"); return error_mark_node; } --- 1077,1084 ---- error ("cannot convert a pointer of type `%s'", TYPE_NAME_STRING (TREE_TYPE (intype))); ! cp_error ("to a pointer of type `%T'", type); + if (distance == -2) + cp_error ("because `%T' is an ambiguous base class", type); return error_mark_node; } *************** *** 1012,1015 **** --- 1092,1116 ---- } + /* Call this when we know (for any reason) that expr is + not, in fact, zero. This routine gets a type out of the first + argument and uses it to search for the type to convert to. If there + is more than one instance of that type in the expr, the conversion is + ambiguous. This routine should eventually go away, and all + callers should use convert_to_pointer_real. */ + tree + convert_pointer_to (binfo, expr) + tree binfo, expr; + { + tree type; + + if (TREE_CODE (binfo) == TREE_VEC) + type = BINFO_TYPE (binfo); + else if (IS_AGGR_TYPE (binfo)) + type = binfo; + else + type = binfo; + return convert_pointer_to_real (type, expr); + } + /* Same as above, but don't abort if we get an "ambiguous" baseclass. There's only one virtual baseclass we are looking for, and once *************** *** 1065,1068 **** --- 1166,1171 ---- if (code == VOID_TYPE) { + /* We're converting to a void type; see if they have an + `operator void'. */ tree rval = build_type_conversion (NOP_EXPR, type, e, 0); /* If we can convert to void type via a type conversion, do so. */ *************** *** 1102,1108 **** && form == INTEGER_TYPE) { ! if (pedantic) pedwarn ("anachronistic conversion from integer type to enumeral type `%s'", TYPE_NAME_STRING (type)); if (flag_pedantic_errors) return error_mark_node; --- 1205,1214 ---- && form == INTEGER_TYPE) { ! if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type))) ! pedwarn ("anachronistic conversion from integer type to anonymous enumeral type"); ! else pedwarn ("anachronistic conversion from integer type to enumeral type `%s'", TYPE_NAME_STRING (type)); + if (flag_pedantic_errors) return error_mark_node; *************** *** 1109,1114 **** } if (form == OFFSET_TYPE) ! error_with_decl (TYPE_NAME (TYPE_OFFSET_BASETYPE (intype)), ! "pointer-to-member expression object not composed with type `%s' object"); else if (IS_AGGR_TYPE (intype)) { --- 1215,1220 ---- } if (form == OFFSET_TYPE) ! cp_error_at ("pointer-to-member expression object not composed with type `%D' object", ! TYPE_NAME (TYPE_OFFSET_BASETYPE (intype))); else if (IS_AGGR_TYPE (intype)) { *************** *** 1227,1231 **** if (init == error_mark_node) { ! error_with_aggr_type (type, "in conversion to type `%s'"); return error_mark_node; } --- 1333,1337 ---- if (init == error_mark_node) { ! cp_error ("in conversion to type `%T'", type); return error_mark_node; } *************** *** 1365,1369 **** basetype = TYPE_MAIN_VARIANT (basetype); if (! TYPE_LANG_SPECIFIC (basetype) || ! TYPE_HAS_CONVERSION (basetype)) ! return 0; if (TREE_CODE (xtype) == POINTER_TYPE --- 1471,1475 ---- basetype = TYPE_MAIN_VARIANT (basetype); if (! TYPE_LANG_SPECIFIC (basetype) || ! TYPE_HAS_CONVERSION (basetype)) ! return NULL_TREE; if (TREE_CODE (xtype) == POINTER_TYPE *************** *** 1402,1406 **** if (TYPE_BINFO_BASETYPES (basetype)) basetype = TYPE_BINFO_BASETYPE (basetype, 0); ! else break; } --- 1508,1513 ---- if (TYPE_BINFO_BASETYPES (basetype)) basetype = TYPE_BINFO_BASETYPE (basetype, 0); ! else ! break; } *************** *** 1449,1453 **** if (TYPE_BINFO_BASETYPES (basetype)) basetype = TYPE_BINFO_BASETYPE (basetype, 0); ! else break; } /* No free conversions for reference types, right?. */ --- 1556,1561 ---- if (TYPE_BINFO_BASETYPES (basetype)) basetype = TYPE_BINFO_BASETYPE (basetype, 0); ! else ! break; } /* No free conversions for reference types, right?. */ *************** *** 1484,1488 **** if (TYPE_BINFO_BASETYPES (basetype)) basetype = TYPE_BINFO_BASETYPE (basetype, 0); ! else break; } } --- 1592,1597 ---- if (TYPE_BINFO_BASETYPES (basetype)) basetype = TYPE_BINFO_BASETYPE (basetype, 0); ! else ! break; } } *************** *** 1507,1511 **** if (TYPE_BINFO_BASETYPES (basetype)) basetype = TYPE_BINFO_BASETYPE (basetype, 0); ! else break; } } --- 1616,1621 ---- if (TYPE_BINFO_BASETYPES (basetype)) basetype = TYPE_BINFO_BASETYPE (basetype, 0); ! else ! break; } } *************** *** 1528,1532 **** if (TYPE_BINFO_BASETYPES (basetype)) basetype = TYPE_BINFO_BASETYPE (basetype, 0); ! else break; } } --- 1638,1643 ---- if (TYPE_BINFO_BASETYPES (basetype)) basetype = TYPE_BINFO_BASETYPE (basetype, 0); ! else ! break; } } *************** *** 1541,1544 **** --- 1652,1656 ---- return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure); } + if (TREE_CODE (type) == REAL_TYPE && TYPE_HAS_REAL_CONVERSION (basetype) *************** *** 1546,1549 **** --- 1658,1670 ---- && CLASSTYPE_CONVERSION (basetype, real_conv) != error_mark_node) { + /* Only accept using an operator double() if there isn't a conflicting + operator int(). */ + if (flag_ansi_overloading && TYPE_HAS_INT_CONVERSION (basetype)) + { + error ("two possible conversions for type `%s'", + TYPE_NAME_STRING (type)); + return error_mark_node; + } + typename = DECL_NAME (CLASSTYPE_CONVERSION (basetype, real_conv)); return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure); *************** *** 1588,1592 **** if (TYPE_BINFO_BASETYPES (basetype)) basetype = TYPE_BINFO_BASETYPE (basetype, 0); ! else break; } if (! not_again) --- 1709,1714 ---- if (TYPE_BINFO_BASETYPES (basetype)) basetype = TYPE_BINFO_BASETYPE (basetype, 0); ! else ! break; } if (! not_again) *************** *** 1664,1670 **** char *name1, *name2; ! if (TREE_CODE (type1) == REFERENCE_TYPE) type1 = TREE_TYPE (type1); ! if (TREE_CODE (type2) == REFERENCE_TYPE) type2 = TREE_TYPE (type2); --- 1786,1794 ---- char *name1, *name2; ! if (TREE_CODE (type1) == REFERENCE_TYPE ! || TREE_CODE (type1) == POINTER_TYPE) type1 = TREE_TYPE (type1); ! if (TREE_CODE (type2) == REFERENCE_TYPE ! || TREE_CODE (type2) == POINTER_TYPE) type2 = TREE_TYPE (type2); *************** *** 1771,1775 **** if (TYPE_HAS_INT_CONVERSION (type) && TYPE_HAS_REAL_CONVERSION (type)) ! warning ("ambiguous type conversion for type `%s', defaulting to int", name); if (TYPE_HAS_INT_CONVERSION (type)) *arg = build_type_conversion (code, integer_type_node, *arg, 1); --- 1895,1900 ---- if (TYPE_HAS_INT_CONVERSION (type) && TYPE_HAS_REAL_CONVERSION (type)) ! warning ("ambiguous type conversion for type `%s', defaulting to int", ! name); if (TYPE_HAS_INT_CONVERSION (type)) *arg = build_type_conversion (code, integer_type_node, *arg, 1); *************** *** 1782,1786 **** error ("ambiguous pointer conversion"); } ! if (*arg == 0) { error ("default type conversion for type `%s' failed", name); --- 1907,1911 ---- error ("ambiguous pointer conversion"); } ! if (*arg == NULL_TREE) { error ("default type conversion for type `%s' failed", name); diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/cp-decl.c gcc-2.5.0/cp-decl.c *** gcc-2.4.5/cp-decl.c Sun Jun 13 16:59:26 1993 --- gcc-2.5.0/cp-decl.c Fri Oct 8 19:55:08 1993 *************** *** 44,47 **** --- 44,49 ---- extern struct obstack permanent_obstack; + extern int current_class_depth; + /* Stack of places to restore the search obstack back to. */ *************** *** 287,290 **** --- 289,295 ---- parameter for destructors. */ tree this_identifier, in_charge_identifier; + /* Used in pointer to member functions, and in vtables. */ + tree pfn_identifier, index_identifier, delta_identifier, delta2_identifier; + tree pfn_or_delta2_identifier; /* A list (chain of TREE_LIST nodes) of named label uses. *************** *** 399,407 **** tree current_function_return_value; - /* Nonzero means warn about multiple (redundant) decls for the same single - variable or function. */ - - extern int warn_redundant_decls; - /* Set to nonzero by `grokdeclarator' for a function whose return type is defaulted, if warnings for this are desired. */ --- 404,407 ---- *************** *** 460,463 **** --- 460,469 ---- extern int spew_debug; + + /* This is a copy of the class_shadowed list of the previous class binding + contour when at global scope. It's used to reset IDENTIFIER_CLASS_VALUEs + when entering another class scope (i.e. a cache miss). */ + extern tree previous_class_values; + /* Allocate a level of searching. */ *************** *** 479,482 **** --- 485,489 ---- struct stack_level *stack; { + #if !NEW_CLASS_SCOPING tree *bp, *tp; struct obstack *obstack = stack->obstack; *************** *** 489,492 **** --- 496,500 ---- IDENTIFIER_CLASS_VALUE (DECL_NAME (*tp)) = NULL_TREE; } + #endif return pop_stack_level (stack); } *************** *** 596,602 **** /* Two bits left for this word. */ ! #if PARANOID ! unsigned char depth; ! #endif }; --- 604,611 ---- /* Two bits left for this word. */ ! #if defined(DEBUG_CP_BINDING_LEVELS) ! /* Binding depth at which this level began. */ ! unsigned binding_depth; ! #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ }; *************** *** 629,673 **** static int keep_next_level_flag; ! #if PARANOID ! /* Perform sanity checking on binding levels. Normally not needed. */ ! void ! binding_levels_sane () ! { ! struct binding_level *b = current_binding_level; ! static int n; ! if (++n < 3) ! return; ! my_friendly_assert (global_binding_level != 0, 126); ! my_friendly_assert (current_binding_level != 0, 127); ! for (b = current_binding_level; b != global_binding_level; b = b->level_chain) ! { ! my_friendly_assert (b->level_chain != 0, 128); ! my_friendly_assert (b->depth == 1 + b->level_chain->depth, 129); ! } ! if (class_binding_level) ! for (b = class_binding_level; ! b != global_binding_level && b != current_binding_level; ! b = b->level_chain) ! { ! my_friendly_assert (b->level_chain != 0, 130); ! my_friendly_assert (b->depth == 1 + b->level_chain->depth, 131); ! } ! my_friendly_assert (global_binding_level->depth == 0, 132); ! my_friendly_assert (global_binding_level->level_chain == 0, 133); ! return; ! } ! #else ! #define binding_levels_sane() ((void)(1)) ! #endif ! #ifdef DEBUG_CP_BINDING_LEVELS ! int debug_bindings_indentation; ! #endif static void - #if !PARANOID && defined (__GNUC__) - __inline - #endif push_binding_level (newlevel, tag_transparent, keep) struct binding_level *newlevel; --- 638,656 ---- static int keep_next_level_flag; ! #if defined(DEBUG_CP_BINDING_LEVELS) ! static int binding_depth = 0; ! static int is_class_level = 0; ! static void ! indent () ! { ! register unsigned i; ! for (i = 0; i < binding_depth*2; i++) ! putc (' ', stderr); ! } ! #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ static void push_binding_level (newlevel, tag_transparent, keep) struct binding_level *newlevel; *************** *** 674,686 **** int tag_transparent, keep; { - binding_levels_sane(); /* Add this level to the front of the chain (stack) of levels that are active. */ - #ifdef DEBUG_CP_BINDING_LEVELS - indent_to (stderr, debug_bindings_indentation); - fprintf (stderr, "pushing binding level "); - fprintf (stderr, HOST_PTR_PRINTF, newlevel); - fprintf (stderr, "\n"); - #endif *newlevel = clear_binding_level; if (class_binding_level) --- 657,662 ---- *************** *** 698,722 **** newlevel->more_exceptions_ok = 1; newlevel->keep = keep; ! #if PARANOID ! newlevel->depth = (newlevel->level_chain ! ? newlevel->level_chain->depth + 1 ! : 0); ! #endif ! binding_levels_sane(); } static void - #if !PARANOID && defined (__GNUC__) - __inline - #endif pop_binding_level () { ! binding_levels_sane(); ! #ifdef DEBUG_CP_BINDING_LEVELS ! indent_to (stderr, debug_bindings_indentation); ! fprintf (stderr, "popping binding level "); ! fprintf (stderr, HOST_PTR_PRINTF, current_binding_level); ! fprintf (stderr, "\n"); ! #endif if (global_binding_level) { --- 674,693 ---- newlevel->more_exceptions_ok = 1; newlevel->keep = keep; ! #if defined(DEBUG_CP_BINDING_LEVELS) ! newlevel->binding_depth = binding_depth; ! indent (); ! fprintf (stderr, "push %s level 0x%08x line %d\n", ! (is_class_level) ? "class" : "block", newlevel, lineno); ! is_class_level = 0; ! binding_depth++; ! #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ } static void pop_binding_level () { ! if (class_binding_level) ! current_binding_level = class_binding_level; ! if (global_binding_level) { *************** *** 726,729 **** --- 697,717 ---- } /* Pop the current level, and free the structure for reuse. */ + #if defined(DEBUG_CP_BINDING_LEVELS) + binding_depth--; + indent (); + fprintf (stderr, "pop %s level 0x%08x line %d\n", + (is_class_level) ? "class" : "block", + current_binding_level, lineno); + if (is_class_level != (current_binding_level == class_binding_level)) + #if 0 /* XXX Don't abort when we're watching how things are being managed. */ + abort (); + #else + { + indent (); + fprintf (stderr, "XXX is_class_level != (current_binding_level == class_binding_level)\n"); + } + #endif + is_class_level = 0; + #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ { register struct binding_level *level = current_binding_level; *************** *** 730,752 **** current_binding_level = current_binding_level->level_chain; level->level_chain = free_binding_level; ! #ifdef DEBUG_CP_BINDING_LEVELS ! memset (level, 0x69, sizeof (*level)); ! #else ! free_binding_level = level; ! #if PARANOID ! level->depth = ~0; /* ~0 assumes that the depth is unsigned. */ ! #endif ! #endif ! if (current_binding_level->parm_flag == 2) ! { ! class_binding_level = current_binding_level; ! do ! { ! current_binding_level = current_binding_level->level_chain; ! } ! while (current_binding_level->parm_flag == 2); ! } } - binding_levels_sane(); } --- 718,733 ---- current_binding_level = current_binding_level->level_chain; level->level_chain = free_binding_level; ! #if 0 /* defined(DEBUG_CP_BINDING_LEVELS) */ ! if (level->binding_depth != binding_depth) ! abort (); ! #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ ! free_binding_level = level; ! ! class_binding_level = current_binding_level; ! if (class_binding_level->parm_flag != 2) ! class_binding_level = 0; ! while (current_binding_level->parm_flag == 2) ! current_binding_level = current_binding_level->level_chain; } } *************** *** 826,829 **** --- 807,817 ---- } + void + set_class_shadows (shadows) + tree shadows; + { + class_binding_level->class_shadowed = shadows; + } + /* Enter a new binding level. If TAG_TRANSPARENT is nonzero, do so only for the name space of variables, *************** *** 836,845 **** register struct binding_level *newlevel = NULL_BINDING_LEVEL; - #ifdef DEBUG_CP_BINDING_LEVELS - indent_to (stderr, debug_bindings_indentation); - fprintf (stderr, "pushlevel"); - debug_bindings_indentation += 4; - #endif - /* If this is the top level of a function, just make sure that NAMED_LABELS is 0. --- 824,827 ---- *************** *** 851,855 **** --- 833,841 ---- /* Reuse or create a struct for this binding level. */ + #if defined(DEBUG_CP_BINDING_LEVELS) + if (0) + #else /* !defined(DEBUG_CP_BINDING_LEVELS) */ if (free_binding_level) + #endif /* !defined(DEBUG_CP_BINDING_LEVELS) */ { newlevel = free_binding_level; *************** *** 862,871 **** } push_binding_level (newlevel, tag_transparent, keep_next_level_flag); ! GNU_xref_start_scope ((int) newlevel); keep_next_level_flag = 0; - - #ifdef DEBUG_CP_BINDING_LEVELS - debug_bindings_indentation -= 4; - #endif } --- 848,853 ---- } push_binding_level (newlevel, tag_transparent, keep_next_level_flag); ! GNU_xref_start_scope ((HOST_WIDE_INT) newlevel); keep_next_level_flag = 0; } *************** *** 926,936 **** int block_previously_created; - #ifdef DEBUG_CP_BINDING_LEVELS - indent_to (stderr, debug_bindings_indentation); - fprintf (stderr, "poplevel"); - debug_bindings_indentation += 4; - #endif - - binding_levels_sane(); GNU_xref_end_scope ((HOST_WIDE_INT) current_binding_level, (HOST_WIDE_INT) current_binding_level->level_chain, --- 908,911 ---- *************** *** 996,1000 **** TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1; else ! output_inline_function (decl); } --- 971,979 ---- TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1; else ! { ! push_function_context (); ! output_inline_function (decl); ! pop_function_context (); ! } } *************** *** 1014,1018 **** BLOCK_TYPE_TAGS (block) = tags; BLOCK_SUBBLOCKS (block) = subblocks; ! remember_end_note (block); } --- 993,1002 ---- BLOCK_TYPE_TAGS (block) = tags; BLOCK_SUBBLOCKS (block) = subblocks; ! /* If we created the block earlier on, and we are just diddling it now, ! then it already should have a proper BLOCK_END_NOTE value associated ! with it, so avoid trashing that. Otherwise, for a new block, install ! a new BLOCK_END_NOTE value. */ ! if (! block_previously_created) ! remember_end_note (block); } *************** *** 1075,1079 **** if (DECL_INITIAL (label) == NULL_TREE) { ! error_with_decl (label, "label `%s' used but not defined"); /* Avoid crashing later. */ define_label (input_filename, 1, DECL_NAME (label)); --- 1059,1063 ---- if (DECL_INITIAL (label) == NULL_TREE) { ! cp_error_at ("label `%D' used but not defined", label); /* Avoid crashing later. */ define_label (input_filename, 1, DECL_NAME (label)); *************** *** 1080,1086 **** } else if (warn_unused && !TREE_USED (label)) ! warning_with_decl (label, ! "label `%s' defined but not used"); ! SET_IDENTIFIER_LABEL_VALUE (DECL_NAME (label), 0); /* Put the labels into the "variables" of the --- 1064,1069 ---- } else if (warn_unused && !TREE_USED (label)) ! cp_warning_at ("label `%D' defined but not used", label); ! SET_IDENTIFIER_LABEL_VALUE (DECL_NAME (label), NULL_TREE); /* Put the labels into the "variables" of the *************** *** 1121,1125 **** = chainon (current_binding_level->blocks, block); } - /* If we did not make a block for the level just exited, any blocks made for inner levels --- 1104,1107 ---- *************** *** 1128,1136 **** of something else. */ else if (subblocks) ! if (keep == 2) ! current_binding_level->blocks = chainon (subblocks, current_binding_level->blocks); ! else ! current_binding_level->blocks ! = chainon (current_binding_level->blocks, subblocks); /* Take care of compiler's internal binding structures. */ --- 1110,1121 ---- of something else. */ else if (subblocks) ! { ! if (keep == 2) ! current_binding_level->blocks ! = chainon (subblocks, current_binding_level->blocks); ! else ! current_binding_level->blocks ! = chainon (current_binding_level->blocks, subblocks); ! } /* Take care of compiler's internal binding structures. */ *************** *** 1143,1154 **** #endif expand_end_bindings (getdecls (), keep, 1); block = poplevel (keep, reverse, real_functionbody); } if (block) TREE_USED (block) = 1; - binding_levels_sane(); - #ifdef DEBUG_CP_BINDING_LEVELS - debug_bindings_indentation -= 4; - #endif return block; } --- 1128,1144 ---- #endif expand_end_bindings (getdecls (), keep, 1); + /* Each and every BLOCK node created here in `poplevel' is important + (e.g. for proper debugging information) so if we created one + earlier, mark it as "used". */ + if (block) + TREE_USED (block) = 1; block = poplevel (keep, reverse, real_functionbody); } + + /* Each and every BLOCK node created here in `poplevel' is important + (e.g. for proper debugging information) so if we created one + earlier, mark it as "used". */ if (block) TREE_USED (block) = 1; return block; } *************** *** 1214,1227 **** pushlevel_class () { ! binding_levels_sane(); ! #ifdef DEBUG_CP_BINDING_LEVELS ! indent_to (stderr, debug_bindings_indentation); ! fprintf (stderr, "pushlevel_class"); ! debug_bindings_indentation += 4; ! #endif ! pushlevel (0); decl_stack = push_decl_level (decl_stack, &decl_obstack); class_binding_level = current_binding_level; class_binding_level->parm_flag = 2; do { --- 1204,1237 ---- pushlevel_class () { ! register struct binding_level *newlevel; ! ! /* Reuse or create a struct for this binding level. */ ! #if defined(DEBUG_CP_BINDING_LEVELS) ! if (0) ! #else /* !defined(DEBUG_CP_BINDING_LEVELS) */ ! if (free_binding_level) ! #endif /* !defined(DEBUG_CP_BINDING_LEVELS) */ ! { ! newlevel = free_binding_level; ! free_binding_level = free_binding_level->level_chain; ! } ! else ! { ! /* Create a new `struct binding_level'. */ ! newlevel = (struct binding_level *) xmalloc (sizeof (struct binding_level)); ! } ! ! #if defined(DEBUG_CP_BINDING_LEVELS) ! is_class_level = 1; ! #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ ! ! push_binding_level (newlevel, 0, 0); ! decl_stack = push_decl_level (decl_stack, &decl_obstack); class_binding_level = current_binding_level; class_binding_level->parm_flag = 2; + /* We have just pushed into a new binding level. Now, fake out the rest + of the compiler. Set the `current_binding_level' back to point to + the most closely containing non-class binding level. */ do { *************** *** 1229,1236 **** } while (current_binding_level->parm_flag == 2); - binding_levels_sane(); - #ifdef DEBUG_CP_BINDING_LEVELS - debug_bindings_indentation -= 4; - #endif } --- 1239,1242 ---- *************** *** 1243,1261 **** tree shadowed; ! #ifdef DEBUG_CP_BINDING_LEVELS ! indent_to (stderr, debug_bindings_indentation); ! fprintf (stderr, "poplevel_class"); ! debug_bindings_indentation += 4; ! #endif ! binding_levels_sane(); ! if (level == (struct binding_level *)0) ! { ! while (current_binding_level && class_binding_level == (struct binding_level *)0) ! block = poplevel (0, 0, 0); ! if (current_binding_level == (struct binding_level *)0) ! fatal ("syntax error too serious"); ! level = class_binding_level; ! } decl_stack = pop_decl_level (decl_stack); for (shadowed = level->shadowed; shadowed; shadowed = TREE_CHAIN (shadowed)) IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (shadowed)) = TREE_VALUE (shadowed); --- 1249,1256 ---- tree shadowed; ! my_friendly_assert (level != 0, 354); ! decl_stack = pop_decl_level (decl_stack); + #if !NEW_CLASS_SCOPING for (shadowed = level->shadowed; shadowed; shadowed = TREE_CHAIN (shadowed)) IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (shadowed)) = TREE_VALUE (shadowed); *************** *** 1264,1267 **** --- 1259,1284 ---- for (shadowed = level->type_shadowed; shadowed; shadowed = TREE_CHAIN (shadowed)) IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (shadowed)) = TREE_VALUE (shadowed); + #else + for (shadowed = level->shadowed; shadowed; shadowed = TREE_CHAIN (shadowed)) + IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (shadowed)) = TREE_VALUE (shadowed); + /* If we're leaving a toplevel class, don't bother to do the setting + of IDENTIFER_CLASS_VALUE to NULL_TREE, since first of all this slot + shouldn't even be used when current_class_type isn't set, and second, + if we don't touch it here, we're able to use the caching effect if the + next time we're entering a class scope, it is the same class. */ + if (current_class_depth != 1) + for (shadowed = level->class_shadowed; + shadowed; + shadowed = TREE_CHAIN (shadowed)) + IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed)) = TREE_VALUE (shadowed); + else + /* Remember to save what IDENTIFIER's were bound in this scope so we + can recover from cache misses. */ + previous_class_values = class_binding_level->class_shadowed; + for (shadowed = level->type_shadowed; + shadowed; + shadowed = TREE_CHAIN (shadowed)) + IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (shadowed)) = TREE_VALUE (shadowed); + #endif GNU_xref_end_scope ((HOST_WIDE_INT) class_binding_level, *************** *** 1271,1290 **** class_binding_level->tag_transparent); - class_binding_level = level->level_chain; if (class_binding_level->parm_flag != 2) class_binding_level = (struct binding_level *)0; ! #ifdef DEBUG_CP_BINDING_LEVELS ! indent_to (stderr, debug_bindings_indentation); ! fprintf (stderr, "popping class binding level "); ! fprintf (stderr, HOST_PTR_PRINTF, level); ! fprintf (stderr, "\n"); ! memset (level, 0x69, sizeof (*level)); ! debug_bindings_indentation -= 4; ! #else ! level->level_chain = free_binding_level; ! free_binding_level = level; ! #endif ! binding_levels_sane(); return block; --- 1288,1301 ---- class_binding_level->tag_transparent); if (class_binding_level->parm_flag != 2) class_binding_level = (struct binding_level *)0; ! /* Now, pop out of the the binding level which we created up in the ! `pushlevel_class' routine. */ ! #if defined(DEBUG_CP_BINDING_LEVELS) ! is_class_level = 1; ! #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ ! ! pop_binding_level (); return block; *************** *** 1474,1477 **** --- 1485,1489 ---- tree class_name, class_type, class_decl, function_decl; struct binding_level *class_bindings; + tree previous_class_type; }; static struct saved_scope *current_saved_scope; *************** *** 1486,1493 **** tree old_bindings = NULL_TREE; - #ifdef DEBUG_CP_BINDING_LEVELS - fprintf (stderr, "PUSH_TO_TOP_LEVEL\n"); - #endif - /* Have to include global_binding_level, because class-level decls aren't listed anywhere useful. */ --- 1498,1501 ---- *************** *** 1520,1524 **** --- 1528,1535 ---- IDENTIFIER_LOCAL_VALUE (id) = NULL_TREE; IDENTIFIER_CLASS_VALUE (id) = NULL_TREE; + #if !NEW_CLASS_SCOPING + /* The type unwinding below should take care of this. */ adjust_type_value (id); + #endif } TREE_CHAIN (binding) = old_bindings; *************** *** 1541,1547 **** --- 1552,1560 ---- s->function_decl = current_function_decl; s->class_bindings = class_binding_level; + s->previous_class_type = previous_class_type; current_class_name = current_class_type = current_class_decl = NULL_TREE; current_function_decl = NULL_TREE; class_binding_level = (struct binding_level *)0; + previous_class_type = NULL_TREE; s->prev = current_saved_scope; *************** *** 1548,1552 **** s->old_bindings = old_bindings; current_saved_scope = s; - binding_levels_sane(); } --- 1561,1564 ---- *************** *** 1557,1565 **** tree t; ! #ifdef DEBUG_CP_BINDING_LEVELS ! fprintf (stderr, "POP_FROM_TOP_LEVEL\n"); ! #endif - binding_levels_sane(); current_binding_level = s->old_binding_level; current_saved_scope = s->prev; --- 1569,1575 ---- tree t; ! if (previous_class_type) ! previous_class_type = NULL_TREE; current_binding_level = s->old_binding_level; current_saved_scope = s->prev; *************** *** 1583,1588 **** current_function_decl = s->function_decl; class_binding_level = s->class_bindings; free (s); - binding_levels_sane(); } --- 1593,1598 ---- current_function_decl = s->function_decl; class_binding_level = s->class_bindings; + previous_class_type = s->previous_class_type; free (s); } *************** *** 1604,1607 **** --- 1614,1631 ---- tree type; { + #if NEW_CLASS_SCOPING + if (class_binding_level) + { + tree old_type_value = IDENTIFIER_TYPE_VALUE (id); + class_binding_level->type_shadowed + = tree_cons (id, old_type_value, class_binding_level->type_shadowed); + } + else if (current_binding_level != global_binding_level) + { + tree old_type_value = IDENTIFIER_TYPE_VALUE (id); + current_binding_level->type_shadowed + = tree_cons (id, old_type_value, current_binding_level->type_shadowed); + } + #else if (current_binding_level != global_binding_level) { *************** *** 1616,1619 **** --- 1640,1644 ---- = tree_cons (id, old_type_value, class_binding_level->type_shadowed); } + #endif SET_IDENTIFIER_TYPE_VALUE (id, type); } *************** *** 1641,1644 **** --- 1666,1675 ---- } IDENTIFIER_LOCAL_VALUE (id) = type; + + #if NEW_CLASS_SCOPING + /* If this is a TYPE_DECL, push it into the type value slot. */ + if (TREE_CODE (type) == TYPE_DECL) + set_identifier_type_value (id, TREE_TYPE (type)); + #endif } *************** *** 1662,1665 **** --- 1693,1703 ---- IDENTIFIER_POINTER (name)); DECL_NESTED_TYPENAME (decl) = get_identifier (buf); + + /* When NEW_CLASS_SCOPING is set to 1: + + This is a special usage of IDENTIFIER_TYPE_VALUE which have no + correspondence in any binding_level. This is ok since the + DECL_NESTED_TYPENAME is just a convenience identifier whose + IDENTIFIER_TYPE_VALUE will remain constant from now on. */ SET_IDENTIFIER_TYPE_VALUE (DECL_NESTED_TYPENAME (decl), type); } *************** *** 1692,1696 **** else { ! /* Typedef for unnamed struct; some other situations. TYPE_NAME is null; what's right here? */ } --- 1730,1734 ---- else { ! /* XXX: Typedef for unnamed struct; some other situations. TYPE_NAME is null; what's right here? */ } *************** *** 1697,1702 **** return decl; } - #endif void pushtag (name, type) --- 1735,1740 ---- return decl; } #endif + void pushtag (name, type) *************** *** 1749,1754 **** DECL_ASSEMBLER_NAME (d) = get_identifier (build_overload_name (type, 1, 1)); #endif ! /* mark the binding layer marker as internal. (mrs) */ ! DECL_SOURCE_LINE (d) = 0; set_identifier_type_value (name, type); } --- 1787,1800 ---- DECL_ASSEMBLER_NAME (d) = get_identifier (build_overload_name (type, 1, 1)); #endif ! #ifdef DWARF_DEBUGGING_INFO ! if (write_symbols == DWARF_DEBUG) ! { ! /* Mark the TYPE_DECL node we created just above as an ! gratuitous one. We need to do this so that dwarfout.c ! will understand that it is not supposed to output a ! TAG_typedef DIE for it. */ ! DECL_IGNORED_P (d) = 1; ! } ! #endif /* DWARF_DEBUGGING_INFO */ set_identifier_type_value (name, type); } *************** *** 1775,1783 **** /* Make nested declarations go into class-level scope. */ d = build_lang_field_decl (TYPE_DECL, name, type); set_identifier_type_value (name, type); d = pushdecl_class_level (d); } - if (ANON_AGGRNAME_P (name)) - DECL_IGNORED_P (d) = 1; TYPE_NAME (type) = d; --- 1821,1853 ---- /* Make nested declarations go into class-level scope. */ d = build_lang_field_decl (TYPE_DECL, name, type); + #ifdef DWARF_DEBUGGING_INFO + if (write_symbols == DWARF_DEBUG) + { + /* Mark the TYPE_DECL node we created just above as an + gratuitous one. We need to do this so that dwarfout.c + will understand that it is not supposed to output a + TAG_typedef DIE for it. */ + DECL_IGNORED_P (d) = 1; + } + #endif /* DWARF_DEBUGGING_INFO */ + #if !NEW_CLASS_SCOPING set_identifier_type_value (name, type); + #else + /* Make sure we're in this type's scope when we push the + decl for a template, otherwise class_binding_level will + be NULL and we'll end up dying inside of + push_class_level_binding. */ + if (TREE_CODE (type) == UNINSTANTIATED_P_TYPE) + pushclass (type, 0); d = pushdecl_class_level (d); + if (TREE_CODE (type) == UNINSTANTIATED_P_TYPE) + popclass (0); + #endif + } + if (write_symbols != DWARF_DEBUG) + { + if (ANON_AGGRNAME_P (name)) + DECL_IGNORED_P (d) = 1; } TYPE_NAME (type) = d; *************** *** 1804,1807 **** --- 1874,1878 ---- DECL_CLASS_CONTEXT (d) = current_class_type; } + TYPE_CONTEXT (type) = DECL_CONTEXT (d); } if (b->parm_flag == 2) *************** *** 1808,1812 **** --- 1879,1885 ---- { TREE_NONLOCAL_FLAG (type) = 1; + #if !NEW_CLASS_SCOPING IDENTIFIER_CLASS_VALUE (name) = TYPE_NAME (type); + #endif if (TYPE_SIZE (current_class_type) == NULL_TREE) CLASSTYPE_TAGS (current_class_type) = b->tags; *************** *** 1880,1884 **** /* Subroutine of duplicate_decls: return truthvalue of whether ! or not types of these decls match. */ static int decls_match (newdecl, olddecl) --- 1953,1961 ---- /* Subroutine of duplicate_decls: return truthvalue of whether ! or not types of these decls match. ! ! For C++, we must compare the parameter list so that `int' can match ! `int&' in a parameter position, but `int&' is not confused with ! `const int&'. */ static int decls_match (newdecl, olddecl) *************** *** 1911,1917 **** { if (TREE_CODE (f1) == OFFSET_TYPE) ! compiler_error_with_decl (newdecl, "`%s' redeclared as member function"); else ! compiler_error_with_decl (newdecl, "`%s' redeclared as non-member function"); return 0; } --- 1988,1994 ---- { if (TREE_CODE (f1) == OFFSET_TYPE) ! cp_compiler_error ("`%D' redeclared as member function", newdecl); else ! cp_compiler_error ("`%D' redeclared as non-member function", newdecl); return 0; } *************** *** 1918,1924 **** if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (f1)), ! TYPE_MAIN_VARIANT (TREE_TYPE (f2)), 1)) ! types_match = compparms (p1, p2, 1); ! else types_match = 0; } else --- 1995,2002 ---- if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (f1)), ! TYPE_MAIN_VARIANT (TREE_TYPE (f2)), 2)) ! types_match = compparms (p1, p2, 2); ! else ! types_match = 0; } else *************** *** 1950,1955 **** int olddecl_friend = 0, types_match; int new_defines_function; - register unsigned saved_old_decl_uid; - register int saved_old_decl_friend_p; if (TREE_CODE (olddecl) == TREE_LIST --- 2028,2031 ---- *************** *** 1962,1965 **** --- 2038,2042 ---- there is an ambiguity or not. */ tree olddecls = olddecl; + tree previous_c_decl = NULL_TREE; /* If the overload list is empty, just install the decl. */ *************** *** 1972,1975 **** --- 2049,2055 ---- while (olddecls) { + if (DECL_LANGUAGE (TREE_VALUE (olddecls)) == lang_c) + previous_c_decl = TREE_VALUE (olddecls); + if (decls_match (newdecl, TREE_VALUE (olddecls))) { *************** *** 1979,1984 **** != DECL_LANGUAGE (TREE_VALUE (olddecls))) { ! error_with_decl (newdecl, "declaration of `%s' with different language linkage"); ! error_with_decl (TREE_VALUE (olddecls), "previous declaration here"); } types_match = 1; --- 2059,2066 ---- != DECL_LANGUAGE (TREE_VALUE (olddecls))) { ! cp_error ! ("declaration of `%#D' with different language linkage", ! newdecl); ! cp_error_at ("previous declaration here", TREE_VALUE (olddecls)); } types_match = 1; *************** *** 1988,1994 **** } if (olddecls) ! olddecl = TREE_VALUE (olddecl); else ! return 1; } else --- 2070,2090 ---- } if (olddecls) ! olddecl = TREE_VALUE (olddecls); else ! { ! if (previous_c_decl != NULL_TREE ! && DECL_LANGUAGE (newdecl) == lang_c) ! { ! cp_error ("declaration of C function `%#D' conflicts with previous declaration", newdecl); ! cp_error_at ("`%#D' declared previously at this point in file", previous_c_decl); ! } ! else ! { ! /* If we found no match, make this join the other ! overloaded decls. */ ! DECL_OVERLOADED (newdecl) = 1; ! } ! return 1; ! } } else *************** *** 1999,2005 **** } ! if ((TREE_TYPE (newdecl) && TREE_CODE (TREE_TYPE (newdecl)) == ERROR_MARK) ! || (TREE_TYPE (olddecl) && TREE_CODE (TREE_TYPE (olddecl)) == ERROR_MARK)) ! types_match = 0; /* If this decl has linkage, and the old one does too, maybe no error. */ --- 2095,2108 ---- } ! /* If either the type of the new decl or the type of the old decl is an ! error_mark_node, then that implies that we have already issued an ! error (earlier) for some bogus type specification, and in that case, ! it is rather pointless to harass the user with yet more error message ! about the same declaration, so well just pretent the types match here. */ ! if ((TREE_TYPE (newdecl) ! && TREE_CODE (TREE_TYPE (newdecl)) == ERROR_MARK) ! || (TREE_TYPE (olddecl) ! && TREE_CODE (TREE_TYPE (olddecl)) == ERROR_MARK)) ! types_match = 1; /* If this decl has linkage, and the old one does too, maybe no error. */ *************** *** 2006,2013 **** if (TREE_CODE (olddecl) != TREE_CODE (newdecl)) { ! error_with_decl (newdecl, "`%s' redeclared as different kind of symbol"); if (TREE_CODE (olddecl) == TREE_LIST) olddecl = TREE_VALUE (olddecl); ! error_with_decl (olddecl, "previous declaration of `%s'"); /* New decl is completely inconsistent with the old one => --- 2109,2116 ---- if (TREE_CODE (olddecl) != TREE_CODE (newdecl)) { ! cp_error ("`%#D' redeclared as different kind of symbol", newdecl); if (TREE_CODE (olddecl) == TREE_LIST) olddecl = TREE_VALUE (olddecl); ! cp_error_at ("previous declaration of `%#D'", olddecl); /* New decl is completely inconsistent with the old one => *************** *** 2017,2038 **** } - if (TREE_CODE (newdecl) == FUNCTION_DECL) - { - /* Now that functions must hold information normally held - by field decls, there is extra work to do so that - declaration information does not get destroyed during - definition. */ - if (DECL_VINDEX (olddecl)) - DECL_VINDEX (newdecl) = DECL_VINDEX (olddecl); - if (DECL_CONTEXT (olddecl)) - DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl); - if (DECL_CLASS_CONTEXT (olddecl)) - DECL_CLASS_CONTEXT (newdecl) = DECL_CLASS_CONTEXT (olddecl); - if (DECL_CHAIN (newdecl) == NULL_TREE) - DECL_CHAIN (newdecl) = DECL_CHAIN (olddecl); - if (DECL_PENDING_INLINE_INFO (newdecl) == (struct pending_inline *)0) - DECL_PENDING_INLINE_INFO (newdecl) = DECL_PENDING_INLINE_INFO (olddecl); - } - if (flag_traditional && TREE_CODE (newdecl) == FUNCTION_DECL && IDENTIFIER_IMPLICIT_DECL (DECL_ASSEMBLER_NAME (newdecl)) == olddecl) --- 2120,2123 ---- *************** *** 2040,2050 **** after implicit decl. */ ; ! else if (TREE_CODE (olddecl) == FUNCTION_DECL ! && DECL_BUILT_IN (olddecl)) { if (!types_match) { ! error_with_decl (newdecl, "declaration of `%s'"); ! error_with_decl (olddecl, "conflicts with built-in declaration `%s'"); } } --- 2125,2147 ---- after implicit decl. */ ; ! else if (TREE_CODE (olddecl) == FUNCTION_DECL && DECL_BUILT_IN (olddecl)) { + /* A function declaration for a built-in function. */ + if (!TREE_PUBLIC (newdecl)) + { + /* If you declare a built-in function name as static, the + built-in definition is overridden, + but optionally warn this was a bad choice of name. */ + if (warn_shadow) + cp_warning ("shadowing built-in function `%#D'", newdecl); + /* Discard the old built-in function. */ + return 0; + } if (!types_match) { ! cp_warning ("declaration of `%#D'", newdecl); ! cp_warning ("conflicts with built-in declaration `%#D'", ! olddecl); ! return 0; } } *************** *** 2060,2064 **** { give_error = 1; ! error_with_decl (newdecl, "conflicting types for `%s'"); } --- 2157,2167 ---- { give_error = 1; ! ! /* Since we're doing this before finish_struct can set the ! line number on NEWDECL, we just do a regular error here. */ ! if (DECL_SOURCE_LINE (newdecl) == 0) ! cp_error ("conflicting types for `%#D'", newdecl); ! else ! cp_error_at ("conflicting types for `%#D'", newdecl); } *************** *** 2075,2078 **** --- 2178,2182 ---- /* Classify the problem further. */ register tree t = TYPE_ARG_TYPES (oldtype); + if (t == NULL_TREE) t = TYPE_ARG_TYPES (newtype); *************** *** 2083,2086 **** --- 2187,2191 ---- if (TREE_CHAIN (t) == NULL_TREE && type != void_type_node) { + give_error = 1; error ("A parameter list with an ellipsis can't match"); error ("an empty parameter name list declaration."); *************** *** 2091,2094 **** --- 2196,2200 ---- || C_PROMOTING_INTEGER_TYPE_P (type)) { + give_error = 1; error ("An argument type that has a default promotion"); error ("can't match an empty parameter name list declaration."); *************** *** 2098,2102 **** } if (give_error) ! error_with_decl (olddecl, "previous declaration of `%s'"); /* There is one thing GNU C++ cannot tolerate: a constructor --- 2204,2208 ---- } if (give_error) ! cp_error_at ("previous declaration as `%#D'", olddecl); /* There is one thing GNU C++ cannot tolerate: a constructor *************** *** 2148,2154 **** { /* Prototype decl follows defn w/o prototype. */ ! warning_with_decl (newdecl, "prototype for `%s'"); ! warning_with_decl (olddecl, ! "follows non-prototype definition here"); } --- 2254,2259 ---- { /* Prototype decl follows defn w/o prototype. */ ! cp_warning_at ("prototype for `%#D'", newdecl); ! cp_warning_at ("follows non-prototype definition here", olddecl); } *************** *** 2157,2161 **** && (TREE_READONLY (newdecl) != TREE_READONLY (olddecl) || TREE_THIS_VOLATILE (newdecl) != TREE_THIS_VOLATILE (olddecl))) ! error_with_decl (newdecl, "type qualifiers for `%s' conflict with previous decl"); } --- 2262,2285 ---- && (TREE_READONLY (newdecl) != TREE_READONLY (olddecl) || TREE_THIS_VOLATILE (newdecl) != TREE_THIS_VOLATILE (olddecl))) ! cp_error_at ("type qualifiers for `%D' conflict with previous decl", newdecl); ! } ! ! /* We have committed to returning 1 at this point. */ ! if (TREE_CODE (newdecl) == FUNCTION_DECL) ! { ! /* Now that functions must hold information normally held ! by field decls, there is extra work to do so that ! declaration information does not get destroyed during ! definition. */ ! if (DECL_VINDEX (olddecl)) ! DECL_VINDEX (newdecl) = DECL_VINDEX (olddecl); ! if (DECL_CONTEXT (olddecl)) ! DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl); ! if (DECL_CLASS_CONTEXT (olddecl)) ! DECL_CLASS_CONTEXT (newdecl) = DECL_CLASS_CONTEXT (olddecl); ! if (DECL_CHAIN (newdecl) == NULL_TREE) ! DECL_CHAIN (newdecl) = DECL_CHAIN (olddecl); ! if (DECL_PENDING_INLINE_INFO (newdecl) == (struct pending_inline *)0) ! DECL_PENDING_INLINE_INFO (newdecl) = DECL_PENDING_INLINE_INFO (olddecl); } *************** *** 2163,2173 **** if (TREE_CODE (olddecl) == TYPE_DECL) { ! if (TYPE_LANG_SPECIFIC (TREE_TYPE (newdecl)) ! && TYPE_LANG_SPECIFIC (TREE_TYPE (olddecl))) { ! CLASSTYPE_VSIZE (TREE_TYPE (newdecl)) ! = CLASSTYPE_VSIZE (TREE_TYPE (olddecl)); ! CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (newdecl)) ! = CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (olddecl)); } /* why assert here? Just because debugging information is --- 2287,2299 ---- if (TREE_CODE (olddecl) == TYPE_DECL) { ! register tree newtype = TREE_TYPE (newdecl); ! register tree oldtype = TREE_TYPE (olddecl); ! ! if (newtype != error_mark_node && oldtype != error_mark_node ! && TYPE_LANG_SPECIFIC (newtype) && TYPE_LANG_SPECIFIC (oldtype)) { ! CLASSTYPE_VSIZE (newtype) = CLASSTYPE_VSIZE (oldtype); ! CLASSTYPE_FRIEND_CLASSES (newtype) ! = CLASSTYPE_FRIEND_CLASSES (oldtype); } /* why assert here? Just because debugging information is *************** *** 2194,2199 **** && !(new_defines_function && DECL_INITIAL (olddecl) == NULL_TREE)) { ! warning_with_decl (newdecl, "redundant redeclaration of `%s' in same scope"); ! warning_with_decl (olddecl, "previous declaration of `%s'"); } --- 2320,2325 ---- && !(new_defines_function && DECL_INITIAL (olddecl) == NULL_TREE)) { ! cp_warning ("redundant redeclaration of `%D' in same scope", newdecl); ! cp_warning ("previous declaration of `%D'", olddecl); } *************** *** 2225,2230 **** if (! compexcepttypes (TREE_TYPE (newdecl), TREE_TYPE(olddecl), 0)) { ! error_with_decl (newdecl, "declaration of `%s' raises different exceptions..."); ! error_with_decl (olddecl, "...from previous declaration here"); } } --- 2351,2356 ---- if (! compexcepttypes (TREE_TYPE (newdecl), TREE_TYPE(olddecl), 0)) { ! cp_error ("declaration of `%D' raises different exceptions...", newdecl); ! cp_error_at ("...from previous declaration here", olddecl); } } *************** *** 2359,2370 **** #endif - /* We are about to copy the contexts of newdecl into olddecl, so save a - few tidbits of information from olddecl that we may need to restore - after the copying takes place. */ - - saved_old_decl_uid = DECL_UID (olddecl); - saved_old_decl_friend_p - = DECL_LANG_SPECIFIC (olddecl) ? DECL_FRIEND_P (olddecl) : 0; - if (TREE_CODE (newdecl) == FUNCTION_DECL) { --- 2485,2488 ---- *************** *** 2418,2430 **** DECL_FRIEND_P (olddecl) = 1; - /* Restore some pieces of information which were originally in olddecl. */ - - DECL_UID (olddecl) = saved_old_decl_uid; - if (DECL_LANG_SPECIFIC (olddecl)) - DECL_FRIEND_P (olddecl) |= saved_old_decl_friend_p; - return 1; } void adjust_type_value (id) --- 2536,2544 ---- DECL_FRIEND_P (olddecl) = 1; return 1; } + #if !NEW_CLASS_SCOPING + /* This was always a hack, that never should've been necessary. */ void adjust_type_value (id) *************** *** 2462,2465 **** --- 2576,2580 ---- SET_IDENTIFIER_TYPE_VALUE (id, NULL_TREE); } + #endif /* Record a decl-node X as belonging to the current lexical scope. *************** *** 2527,2531 **** /* error_mark_node is 0 for a while during initialization! */ t = NULL_TREE; ! error_with_decl (x, "`%s' used prior to declaration"); } --- 2642,2646 ---- /* error_mark_node is 0 for a while during initialization! */ t = NULL_TREE; ! cp_error_at ("`%#D' used prior to declaration", x); } *************** *** 2572,2584 **** current_function_decl = t; if (IDENTIFIER_IMPLICIT_DECL (name)) ! warning ("`%s' was declared implicitly `extern' and later `static'", ! lang_printable_name (t)); else ! warning ("`%s' was declared `extern' and later `static'", ! lang_printable_name (t)); warning_with_file_and_line (file, line, "previous declaration of `%s'", ! lang_printable_name (t)); } return t; } --- 2687,2724 ---- current_function_decl = t; if (IDENTIFIER_IMPLICIT_DECL (name)) ! cp_warning ("`%D' was declared implicitly `extern' and later `static'", t); else ! cp_warning ("`%D' was declared `extern' and later `static'", ! t); warning_with_file_and_line (file, line, "previous declaration of `%s'", ! decl_as_string (t, 0)); ! } ! #if 0 ! /* This is turned off until I have time to do it right (bpk). */ ! ! /* Also warn if they did a prototype with `static' on it, but ! then later left the `static' off. */ ! else if (! TREE_PUBLIC (name) && TREE_PUBLIC (x)) ! { ! if (DECL_LANG_SPECIFIC (t) && DECL_FRIEND_P (t)) ! return t; ! ! if (current_function_decl == x) ! current_function_decl = t; ! ! if (extra_warnings) ! { ! cp_warning ("`static' missing from declaration of `%D'", t); ! warning_with_file_and_line (file, line, ! "previous declaration of `%s'", ! decl_as_string (t, 0)); ! } ! ! /* Now fix things so it'll do what they expect. */ ! if (current_function_decl) ! TREE_PUBLIC (current_function_decl) = 0; } + #endif return t; } *************** *** 2585,2595 **** /* If declaring a type as a typedef, and the type has no known ! typedef name, install this TYPE_DECL as its typedef name. ! ! C++: If it had an anonymous aggregate or enum name, ! give it a `better' one. */ if (TREE_CODE (x) == TYPE_DECL) { ! tree name = TYPE_NAME (TREE_TYPE (x)); if (name == NULL_TREE || TREE_CODE (name) != TYPE_DECL) --- 2725,2733 ---- /* If declaring a type as a typedef, and the type has no known ! typedef name, install this TYPE_DECL as its typedef name. */ if (TREE_CODE (x) == TYPE_DECL) { ! tree type = TREE_TYPE (x); ! tree name = (type != error_mark_node) ? TYPE_NAME (type) : x; if (name == NULL_TREE || TREE_CODE (name) != TYPE_DECL) *************** *** 2599,2603 **** name = x; if (global_bindings_p ()) ! TYPE_NAME (TREE_TYPE (x)) = x; } else --- 2737,2741 ---- name = x; if (global_bindings_p ()) ! TYPE_NAME (type) = x; } else *************** *** 2604,2612 **** { tree tname = DECL_NAME (name); if (global_bindings_p () && ANON_AGGRNAME_P (tname)) { ! /* do gratuitous C++ typedefing, and make sure that ! we access this type either through TREE_TYPE field ! or via the tags list. */ TYPE_NAME (TREE_TYPE (x)) = x; pushtag (tname, TREE_TYPE (x)); --- 2742,2751 ---- { tree tname = DECL_NAME (name); + if (global_bindings_p () && ANON_AGGRNAME_P (tname)) { ! /* do gratuitous C++ typedefing, and make sure that ! we access this type either through TREE_TYPE field ! or via the tags list. */ TYPE_NAME (TREE_TYPE (x)) = x; pushtag (tname, TREE_TYPE (x)); *************** *** 2614,2641 **** } my_friendly_assert (TREE_CODE (name) == TYPE_DECL, 140); if (DECL_NAME (name) && !DECL_NESTED_TYPENAME (name)) ! set_nested_typename (x, current_class_name, DECL_NAME (name), ! TREE_TYPE (x)); ! if (TYPE_NAME (TREE_TYPE (x)) && TYPE_IDENTIFIER (TREE_TYPE (x))) ! set_identifier_type_value (DECL_NAME (x), TREE_TYPE (x)); ! /* was using TYPE_IDENTIFIER (TREE_TYPE (x)) */ ! } ! ! /* Multiple external decls of the same identifier ought to match. */ ! ! if (DECL_EXTERNAL (x) && IDENTIFIER_GLOBAL_VALUE (name) != NULL_TREE ! && (DECL_EXTERNAL (IDENTIFIER_GLOBAL_VALUE (name)) ! || TREE_PUBLIC (IDENTIFIER_GLOBAL_VALUE (name))) ! /* We get warnings about inline functions where they are defined. ! Avoid duplicate warnings where they are used. */ ! && !DECL_INLINE (x)) ! { ! if (! comptypes (TREE_TYPE (x), ! TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (name)), 1)) ! { ! warning_with_decl (x, ! "type mismatch with previous external decl"); ! warning_with_decl (IDENTIFIER_GLOBAL_VALUE (name), ! "previous external decl of `%s'"); } } --- 2753,2788 ---- } my_friendly_assert (TREE_CODE (name) == TYPE_DECL, 140); + if (DECL_NAME (name) && !DECL_NESTED_TYPENAME (name)) ! set_nested_typename (x, current_class_name, ! DECL_NAME (name), type); ! ! if (type != error_mark_node ! && TYPE_NAME (type) ! && TYPE_IDENTIFIER (type)) ! set_identifier_type_value (DECL_NAME (x), type); ! } ! ! /* Multiple external decls of the same identifier ought to match. ! ! We get warnings about inline functions where they are defined. ! Avoid duplicate warnings where they are used. */ ! if (TREE_PUBLIC (x) && !DECL_INLINE (x)) ! { ! tree decl; ! ! if (IDENTIFIER_GLOBAL_VALUE (name) != NULL_TREE ! && (DECL_EXTERNAL (IDENTIFIER_GLOBAL_VALUE (name)) ! || TREE_PUBLIC (IDENTIFIER_GLOBAL_VALUE (name)))) ! decl = IDENTIFIER_GLOBAL_VALUE (name); ! else ! decl = NULL_TREE; ! ! if (decl && ! comptypes (TREE_TYPE (x), TREE_TYPE (decl), 1) ! /* If old decl is built-in, we already warned if we should. */ ! && !DECL_BUILT_IN (decl)) ! { ! cp_pedwarn_at ("type mismatch with previous external decl", x); ! cp_pedwarn_at ("previous external decl of `%D'", decl); } } *************** *** 2669,2681 **** || t == NULL_TREE || TREE_CODE (t) == TYPE_DECL) - #if 0 - /* This has not be thoroughly tested yet. */ - /* It allows better dwarf debugging. */ - IDENTIFIER_GLOBAL_VALUE (name) - = TREE_CODE_CLASS (TREE_CODE (x)) == 'd' - ? x : build_decl (TYPE_DECL, NULL, TREE_TYPE (x)); - #else IDENTIFIER_GLOBAL_VALUE (name) = x; - #endif /* Don't forget if the function was used via an implicit decl. */ --- 2816,2820 ---- *************** *** 2694,2699 **** && ! (TREE_CODE (x) == FUNCTION_DECL && TREE_TYPE (TREE_TYPE (x)) == integer_type_node)) ! warning ("`%s' was previously implicitly declared to return `int'", ! lang_printable_name (x)); /* If this decl is `static' and an `extern' was seen previously, --- 2833,2838 ---- && ! (TREE_CODE (x) == FUNCTION_DECL && TREE_TYPE (TREE_TYPE (x)) == integer_type_node)) ! cp_warning ! ("`%D' was previously implicitly declared to return `int'", x); /* If this decl is `static' and an `extern' was seen previously, *************** *** 2704,2712 **** { if (IDENTIFIER_IMPLICIT_DECL (name)) ! warning ("`%s' was declared implicitly `extern' and later `static'", ! lang_printable_name (x)); else ! warning ("`%s' was declared `extern' and later `static'", ! lang_printable_name (x)); } } --- 2843,2852 ---- { if (IDENTIFIER_IMPLICIT_DECL (name)) ! cp_warning ! ("`%D' was declared implicitly `extern' and later `static'", ! x); else ! cp_warning ! ("`%D' was declared `extern' and later `static'", x); } } *************** *** 2728,2732 **** /* We have one. Their types must agree. */ if (! comptypes (TREE_TYPE (x), TREE_TYPE (oldglobal), 1)) ! warning_with_decl (x, "extern declaration of `%s' doesn't match global one"); else { --- 2868,2875 ---- /* We have one. Their types must agree. */ if (! comptypes (TREE_TYPE (x), TREE_TYPE (oldglobal), 1)) ! { ! cp_warning ("extern declaration of `%#D' doesn't match", x); ! cp_warning_at ("global declaration `%#D'", oldglobal); ! } else { *************** *** 2739,2742 **** --- 2882,2886 ---- ? NULL_TREE : DECL_INITIAL (oldglobal)); DECL_SAVED_INSNS (x) = DECL_SAVED_INSNS (oldglobal); + DECL_FRAME_SIZE (x) = DECL_FRAME_SIZE (oldglobal); DECL_ARGUMENTS (x) = DECL_ARGUMENTS (oldglobal); DECL_RESULT (x) = DECL_RESULT (oldglobal); *************** *** 2785,2790 **** /* ARM $8.3 */ if (b->parm_flag == 1) ! pedwarn ("declaration of `%s' shadows a parameter", ! IDENTIFIER_POINTER (name)); } /* Maybe warn if shadowing something else. */ --- 2929,2933 ---- /* ARM $8.3 */ if (b->parm_flag == 1) ! cp_error ("declaration of `%#D' shadows a parameter", name); } /* Maybe warn if shadowing something else. */ *************** *** 2829,2833 **** --- 2972,2978 ---- if (TREE_CODE (x) == TYPE_DECL && name != NULL_TREE) { + #if !NEW_CLASS_SCOPING adjust_type_value (name); + #endif if (current_class_name) { *************** *** 2835,2839 **** --- 2980,2986 ---- set_nested_typename (x, current_class_name, DECL_NAME (x), TREE_TYPE (x)); + #if !NEW_CLASS_SCOPING adjust_type_value (DECL_NESTED_TYPENAME (x)); + #endif } } *************** *** 2929,2932 **** --- 3076,3088 ---- if (name) { + #if NEW_CLASS_SCOPING + push_class_level_binding (name, x); + if (TREE_CODE (x) == TYPE_DECL) + { + set_identifier_type_value (name, TREE_TYPE (x)); + if (!DECL_NESTED_TYPENAME (x)) + set_nested_typename (x, current_class_name, name, TREE_TYPE (x)); + } + #else tree oldclass = IDENTIFIER_CLASS_VALUE (name); if (oldclass) *************** *** 2937,2940 **** --- 3093,3097 ---- if (TREE_CODE (x) == TYPE_DECL && !DECL_NESTED_TYPENAME (x)) set_nested_typename (x, current_class_name, name, TREE_TYPE (x)); + #endif } return x; *************** *** 2941,2944 **** --- 3098,3119 ---- } + #if NEW_CLASS_SCOPING + /* Make the declaration(s) of X appear in CLASS scope + under the name NAME. */ + void + push_class_level_binding (name, x) + tree name; + tree x; + { + maybe_push_cache_obstack (); + class_binding_level->class_shadowed + = tree_cons (name, IDENTIFIER_CLASS_VALUE (name), + class_binding_level->class_shadowed); + pop_obstacks (); + IDENTIFIER_CLASS_VALUE (name) = x; + obstack_ptr_grow (&decl_obstack, x); + } + #endif + /* Tell caller how to interpret a TREE_LIST which contains chains of FUNCTION_DECLS. */ *************** *** 2990,2995 **** if (DECL_LANGUAGE (glob) == lang_c) { ! error_with_decl (decl, "C-language function `%s' overloaded here"); ! error_with_decl (glob, "Previous C-language version of this function was `%s'"); } } --- 3165,3170 ---- if (DECL_LANGUAGE (glob) == lang_c) { ! cp_error ("C-language function `%D' overloaded here", decl); ! cp_error_at ("Previous C-language version of this function was `%D'", glob); } } *************** *** 3010,3014 **** if (TREE_CODE (glob) == FUNCTION_DECL && DECL_LANGUAGE (glob) != DECL_LANGUAGE (decl) ! && comptypes (TREE_TYPE (glob), TREE_TYPE (decl), 1)) { if (current_lang_stack == current_lang_base) --- 3185,3189 ---- if (TREE_CODE (glob) == FUNCTION_DECL && DECL_LANGUAGE (glob) != DECL_LANGUAGE (decl) ! && comptypes (TREE_TYPE (glob), TREE_TYPE (decl), 2)) { if (current_lang_stack == current_lang_base) *************** *** 3019,3024 **** else { ! error_with_decl (decl, "conflicting language contexts for declaration of `%s';"); ! error_with_decl (glob, "conflicts with previous declaration here"); } } --- 3194,3199 ---- else { ! cp_error ("conflicting language contexts for declaration of `%D';", decl); ! cp_error_at ("conflicts with previous declaration here", glob); } } *************** *** 3026,3031 **** { my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (glob)) == 'd', 143); ! error_with_decl (glob, "non-function declaration `%s'"); ! error_with_decl (decl, "conflicts with function declaration `%s'"); } glob = tree_cons (orig_name, glob, NULL_TREE); --- 3201,3206 ---- { my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (glob)) == 'd', 143); ! cp_error ("non-function declaration `%D'", glob); ! cp_error_at ("conflicts with function declaration `%D'", decl); } glob = tree_cons (orig_name, glob, NULL_TREE); *************** *** 3049,3061 **** { if (TREE_CODE (TREE_VALUE (tmp)) == FUNCTION_DECL - && DECL_LANGUAGE (TREE_VALUE (tmp)) != DECL_LANGUAGE (decl) && comptypes (TREE_TYPE (TREE_VALUE (tmp)), TREE_TYPE (decl), ! 1)) { ! error_with_decl (decl, ! "conflicting language contexts for declaration of `%s';"); ! error_with_decl (TREE_VALUE (tmp), ! "conflicts with previous declaration here"); } if (TREE_CODE (TREE_VALUE (tmp)) != TEMPLATE_DECL && DECL_ASSEMBLER_NAME (TREE_VALUE (tmp)) == name) --- 3224,3245 ---- { if (TREE_CODE (TREE_VALUE (tmp)) == FUNCTION_DECL && comptypes (TREE_TYPE (TREE_VALUE (tmp)), TREE_TYPE (decl), ! 2)) { ! if (DECL_LANGUAGE (TREE_VALUE (tmp)) != DECL_LANGUAGE (decl)) ! { ! cp_error_at ("conflicting language contexts for declaration of `%D';", decl); ! cp_error_at ("conflicts with previous declaration here", TREE_VALUE (tmp)); ! } ! else if (TREE_CODE (TREE_VALUE (tmp)) != TEMPLATE_DECL ! && DECL_ASSEMBLER_NAME (TREE_VALUE (tmp)) != name) ! { ! cp_error ("new declaration `%#D'", decl); ! cp_error_at ("ambiguates old declaration `%#D'", ! TREE_VALUE (tmp)); ! } } + /* If we really have seen this before, then if it ambiguates + something, we've already given an error before. */ if (TREE_CODE (TREE_VALUE (tmp)) != TEMPLATE_DECL && DECL_ASSEMBLER_NAME (TREE_VALUE (tmp)) == name) *************** *** 3071,3076 **** if (decls) { ! error_with_decl (decl, "C-language function `%s' overloaded here"); ! error_with_decl (TREE_VALUE (decls), "Previous C-language version of this function was `%s'"); } } --- 3255,3262 ---- if (decls) { ! cp_error ("C-language function `%D' overloaded here", decl); ! cp_error_at ! ("Previous C-language version of this function was `%D'", ! TREE_VALUE (decls)); } } *************** *** 3125,3130 **** && IDENTIFIER_IMPLICIT_DECL (functionid) == NULL_TREE) { ! pedwarn ("implicit declaration of function `%s'", ! IDENTIFIER_POINTER (functionid)); } --- 3311,3315 ---- && IDENTIFIER_IMPLICIT_DECL (functionid) == NULL_TREE) { ! cp_pedwarn ("implicit declaration of function `%#D'", decl); } *************** *** 3151,3155 **** constructs like "typedef struct foo { ... } foo" would look like an erroneous redeclaration. */ ! if (TREE_TYPE (olddecl) == TREE_TYPE (newdecl)) return 0; else --- 3336,3340 ---- constructs like "typedef struct foo { ... } foo" would look like an erroneous redeclaration. */ ! if (comptypes (newdecl, olddecl, 0)) return 0; else *************** *** 3219,3225 **** register tree decl = IDENTIFIER_LABEL_VALUE (id); if ((decl == NULL_TREE || DECL_SOURCE_LINE (decl) == 0) ! && (named_label_uses == 0 || TREE_PURPOSE (named_label_uses) != current_binding_level->names || TREE_VALUE (named_label_uses) != decl)) --- 3404,3417 ---- register tree decl = IDENTIFIER_LABEL_VALUE (id); + if (current_function_decl == NULL_TREE) + { + error ("label `%s' referenced outside of any function", + IDENTIFIER_POINTER (id)); + return NULL_TREE; + } + if ((decl == NULL_TREE || DECL_SOURCE_LINE (decl) == 0) ! && (named_label_uses == NULL_TREE || TREE_PURPOSE (named_label_uses) != current_binding_level->names || TREE_VALUE (named_label_uses) != decl)) *************** *** 3277,3282 **** { shadowed_labels = tree_cons (NULL_TREE, decl, shadowed_labels); ! SET_IDENTIFIER_LABEL_VALUE (name, 0); ! SET_IDENTIFIER_LABEL_VALUE (decl, 0); } --- 3469,3474 ---- { shadowed_labels = tree_cons (NULL_TREE, decl, shadowed_labels); ! SET_IDENTIFIER_LABEL_VALUE (name, NULL_TREE); ! SET_IDENTIFIER_LABEL_VALUE (decl, NULL_TREE); } *************** *** 3304,3308 **** { shadowed_labels = tree_cons (NULL_TREE, decl, shadowed_labels); ! SET_IDENTIFIER_LABEL_VALUE (name, 0); decl = lookup_label (name); } --- 3496,3500 ---- { shadowed_labels = tree_cons (NULL_TREE, decl, shadowed_labels); ! SET_IDENTIFIER_LABEL_VALUE (name, NULL_TREE); decl = lookup_label (name); } *************** *** 3310,3314 **** if (DECL_INITIAL (decl) != NULL_TREE) { ! error_with_decl (decl, "duplicate label `%s'"); return 0; } --- 3502,3506 ---- if (DECL_INITIAL (decl) != NULL_TREE) { ! cp_error ("duplicate label `%D'", decl); return 0; } *************** *** 3347,3353 **** { if (IDENTIFIER_ERROR_LOCUS (decl) == NULL_TREE) ! error_with_decl (decl, "invalid jump to label `%s'"); SET_IDENTIFIER_ERROR_LOCUS (decl, current_function_decl); ! error_with_decl (new_decls, "crosses initialization of `%s'"); } new_decls = TREE_CHAIN (new_decls); --- 3539,3545 ---- { if (IDENTIFIER_ERROR_LOCUS (decl) == NULL_TREE) ! cp_error ("invalid jump to label `%D'", decl); SET_IDENTIFIER_ERROR_LOCUS (decl, current_function_decl); ! cp_error ("crosses initialization of `%D'", new_decls); } new_decls = TREE_CHAIN (new_decls); *************** *** 3378,3382 **** { static int explained = 0; ! error_with_decl (TREE_PURPOSE (cleanup), "destructor needed for `%s'"); error ("where case label appears here"); if (!explained) --- 3570,3574 ---- { static int explained = 0; ! cp_error ("destructor needed for `%D'", TREE_PURPOSE (cleanup)); error ("where case label appears here"); if (!explained) *************** *** 3619,3628 **** tree t, prev = NULL_TREE, d = TYPE_NAME (type); struct binding_level *b; my_friendly_assert (TREE_CODE (d) == TYPE_DECL, 144); /* If the type value has already been globalized, then we're set. */ ! if (IDENTIFIER_GLOBAL_VALUE (DECL_NAME (d)) == d) return; ! if (IDENTIFIER_HAS_TYPE_VALUE (DECL_NAME (d))) { /* If this type already made it into the global tags, --- 3811,3824 ---- tree t, prev = NULL_TREE, d = TYPE_NAME (type); struct binding_level *b; + tree name = DECL_NAME (d); + #if NEW_CLASS_SCOPING + tree class_shadower = NULL_TREE, type_shadower = NULL_TREE, shadow; + #endif my_friendly_assert (TREE_CODE (d) == TYPE_DECL, 144); /* If the type value has already been globalized, then we're set. */ ! if (IDENTIFIER_GLOBAL_VALUE (name) == d) return; ! if (IDENTIFIER_HAS_TYPE_VALUE (name)) { /* If this type already made it into the global tags, *************** *** 3632,3638 **** } set_identifier_type_value (DECL_NESTED_TYPENAME (d), NULL_TREE); ! DECL_NESTED_TYPENAME (d) = DECL_NAME (d); DECL_CONTEXT (d) = NULL_TREE; if (class_binding_level) b = class_binding_level; --- 3828,3840 ---- } + #if NEW_CLASS_SCOPING + if (DECL_LANG_SPECIFIC (d)) + DECL_CLASS_CONTEXT (d) = NULL_TREE; + #else set_identifier_type_value (DECL_NESTED_TYPENAME (d), NULL_TREE); ! #endif DECL_CONTEXT (d) = NULL_TREE; + TYPE_CONTEXT (d) = NULL_TREE; + DECL_NESTED_TYPENAME (d) = name; if (class_binding_level) b = class_binding_level; *************** *** 3646,3649 **** --- 3848,3856 ---- if (TREE_VALUE (t) == type) goto found; + #if NEW_CLASS_SCOPING + /* Find (im?)possible objects shadowing the type we're globalizing. */ + class_shadower = purpose_member (name, b->class_shadowed); + type_shadower = purpose_member (name, b->type_shadowed); + #endif b = b->level_chain; } *************** *** 3671,3675 **** --- 3878,3937 ---- b->tags = TREE_CHAIN (t); + #if NEW_CLASS_SCOPING + /* Find and remove the corresponding entry from the class_shadowed list, + and move the shadowed value to a possibly later shadow. If there were + no such beast (could there ever be?), install the previously shadowed + value as the IDENTIFIER_CLASS_VALUE. */ + prev = NULL_TREE; + for (shadow = b->class_shadowed; + shadow != NULL_TREE; + prev = shadow, shadow = TREE_CHAIN (shadow)) + if (TREE_PURPOSE (shadow) == name) + break; + + if (shadow) + { + /* An example where shadow is NULL is when you have something + like `class foo { public: struct bar; bar *x(); };', since + bar isn't added to the class_shadowed list until it's been + defined. */ + + if (prev) + TREE_CHAIN (prev) = TREE_CHAIN (shadow); + else + b->class_shadowed = TREE_CHAIN (shadow); + + if (class_shadower) + TREE_VALUE (class_shadower) = TREE_VALUE (shadow); + else + IDENTIFIER_CLASS_VALUE (name) = TREE_VALUE (shadow); + } + + /* Find and remove the corresponding entry from the type_shadowed list, + and move the shadowed value to a possibly later shadow. If there were + no such beast (could there ever be?), install the previously shadowed + value as the IDENTIFIER_TYPE_VALUE. */ + prev = NULL_TREE; + for (shadow = b->type_shadowed; + shadow != NULL_TREE; + prev = shadow, shadow = TREE_CHAIN (shadow)) + if (TREE_PURPOSE (shadow) == name) + break; + + if (shadow) + { + if (prev) + TREE_CHAIN (prev) = TREE_CHAIN (shadow); + else + b->type_shadowed = TREE_CHAIN (shadow); + + if (type_shadower) + TREE_VALUE (type_shadower) = TREE_VALUE (shadow); + else + SET_IDENTIFIER_TYPE_VALUE (name, TREE_VALUE (shadow)); + } + #else set_identifier_type_value (TREE_PURPOSE (t), TREE_VALUE (t)); + #endif global_binding_level->tags = perm_tree_cons (TREE_PURPOSE (t), TREE_VALUE (t), *************** *** 3867,3871 **** static void ! sigsegv (sig) int sig; { --- 4129,4133 ---- static void ! signal_catch (sig) int sig; { *************** *** 3880,3883 **** --- 4142,4148 ---- signal (SIGABRT, SIG_DFL); #endif + #ifdef SIGBUS + signal (SIGBUS, SIG_DFL); + #endif my_friendly_abort (0); } *************** *** 3907,3910 **** --- 4172,4177 ---- tname = get_identifier (name); + TYPE_BUILT_IN (type) = 1; + if (tname) { *************** *** 4009,4013 **** --- 4276,4284 ---- /* Data type of memcpy. */ tree memcpy_ftype; + /* Data type of strncpy. */ + tree strncpy_ftype; int wchar_type_size; + tree temp; + tree array_domain_type; /* Have to make these distinct before we try using them. */ *************** *** 4027,4043 **** code, catch them and at least give the user a chance of working around compiler bugs. */ ! signal (SIGSEGV, sigsegv); ! /* We will also catch aborts in the back-end through sigsegv and give the ! user a chance to see where the error might be, and to defeat aborts in ! the back-end when there have been errors previously in their code. */ #ifdef SIGIOT ! signal (SIGIOT, sigsegv); #endif #ifdef SIGILL ! signal (SIGILL, sigsegv); #endif #ifdef SIGABRT ! signal (SIGABRT, sigsegv); #endif --- 4298,4318 ---- code, catch them and at least give the user a chance of working around compiler bugs. */ ! signal (SIGSEGV, signal_catch); ! /* We will also catch aborts in the back-end through signal_catch and ! give the user a chance to see where the error might be, and to defeat ! aborts in the back-end when there have been errors previously in their ! code. */ #ifdef SIGIOT ! signal (SIGIOT, signal_catch); #endif #ifdef SIGILL ! signal (SIGILL, signal_catch); #endif #ifdef SIGABRT ! signal (SIGABRT, signal_catch); ! #endif ! #ifdef SIGBUS ! signal (SIGBUS, signal_catch); #endif *************** *** 4061,4064 **** --- 4336,4344 ---- this_identifier = get_identifier (THIS_NAME); in_charge_identifier = get_identifier (IN_CHARGE_NAME); + pfn_identifier = get_identifier (VTABLE_PFN_NAME); + index_identifier = get_identifier (VTABLE_INDEX_NAME); + delta_identifier = get_identifier (VTABLE_DELTA_NAME); + delta2_identifier = get_identifier (VTABLE_DELTA2_NAME); + pfn_or_delta2_identifier = get_identifier ("__pfn_or_delta2"); /* Define `int' and `char' first so that dbx will output them first. */ *************** *** 4090,4098 **** Note that stddef.h uses `unsigned long', and this must agree, even of long and int are the same size. */ ! if (flag_traditional) ! sizetype = long_integer_type_node; ! else ! sizetype ! = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))); ptrdiff_type_node --- 4370,4377 ---- Note that stddef.h uses `unsigned long', and this must agree, even of long and int are the same size. */ ! sizetype ! = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))); ! if (flag_traditional && TREE_UNSIGNED (sizetype)) ! sizetype = signed_type (sizetype); ptrdiff_type_node *************** *** 4190,4202 **** record_builtin_type (RID_MAX, NULL, string_type_node); ! /* make a type for arrays of 256 characters. ! 256 is picked randomly because we have a type for integers from 0 to 255. With luck nothing will ever really depend on the length of this array type. */ char_array_type_node ! = build_array_type (char_type_node, unsigned_char_type_node); /* Likewise for arrays of ints. */ int_array_type_node ! = build_array_type (integer_type_node, unsigned_char_type_node); /* This is just some anonymous class type. Nobody should ever --- 4469,4487 ---- record_builtin_type (RID_MAX, NULL, string_type_node); ! /* Make a type to be the domain of a few array types ! whose domains don't really matter. ! 200 is small enough that it always fits in size_t ! and large enough that it can hold most function names for the ! initializations of __FUNCTION__ and __PRETTY_FUNCTION__. */ ! array_domain_type = build_index_type (build_int_2 (200, 0)); ! ! /* make a type for arrays of characters. With luck nothing will ever really depend on the length of this array type. */ char_array_type_node ! = build_array_type (char_type_node, array_domain_type); /* Likewise for arrays of ints. */ int_array_type_node ! = build_array_type (integer_type_node, array_domain_type); /* This is just some anonymous class type. Nobody should ever *************** *** 4257,4260 **** --- 4542,4556 ---- endlink))); + #if 0 + /* Not yet. */ + strncpy_ftype /* strncpy prototype */ + = build_function_type (string_type_node, + tree_cons (NULL_TREE, string_type_node, + tree_cons (NULL_TREE, const_string_type_node, + tree_cons (NULL_TREE, + sizetype, + endlink)))); + #endif + int_ftype_string_string /* strcmp prototype */ = build_function_type (integer_type_node, *************** *** 4352,4355 **** --- 4648,4674 ---- BUILT_IN_ARGS_INFO, NULL_PTR); + /* Untyped call and return. */ + builtin_function ("__builtin_apply_args", + build_function_type (ptr_type_node, NULL_TREE), + BUILT_IN_APPLY_ARGS, NULL_PTR); + + temp = tree_cons (NULL_TREE, + build_pointer_type (build_function_type (void_type_node, + NULL_TREE)), + tree_cons (NULL_TREE, + ptr_type_node, + tree_cons (NULL_TREE, + sizetype, + endlink))); + builtin_function ("__builtin_apply", + build_function_type (ptr_type_node, temp), + BUILT_IN_APPLY, NULL_PTR); + builtin_function ("__builtin_return", + build_function_type (void_type_node, + tree_cons (NULL_TREE, + ptr_type_node, + endlink)), + BUILT_IN_RETURN, NULL_PTR); + /* Currently under experimentation. */ builtin_function ("__builtin_memcpy", memcpy_ftype, *************** *** 4361,4364 **** --- 4680,4688 ---- builtin_function ("__builtin_strcpy", string_ftype_ptr_ptr, BUILT_IN_STRCPY, "strcpy"); + #if 0 + /* Not yet. */ + builtin_function ("__builtin_strncpy", strncpy_ftype, + BUILT_IN_STRNCPY, "strncpy"); + #endif builtin_function ("__builtin_strlen", sizet_ftype_string, BUILT_IN_STRLEN, "strlen"); *************** *** 4376,4379 **** --- 4700,4707 ---- builtin_function ("strcmp", int_ftype_string_string, BUILT_IN_STRCMP, NULL_PTR); builtin_function ("strcpy", string_ftype_ptr_ptr, BUILT_IN_STRCPY, NULL_PTR); + #if 0 + /* Not yet. */ + builtin_function ("strncpy", strncpy_ftype, BUILT_IN_STRNCPY, NULL_PTR); + #endif builtin_function ("strlen", sizet_ftype_string, BUILT_IN_STRLEN, NULL_PTR); builtin_function ("sin", double_ftype_double, BUILT_IN_SIN, NULL_PTR); *************** *** 4430,4434 **** /* This is for wide string constants. */ wchar_array_type_node ! = build_array_type (wchar_type_node, unsigned_char_type_node); /* This is a hack that should go away when we deliver the --- 4758,4762 ---- /* This is for wide string constants. */ wchar_array_type_node ! = build_array_type (wchar_type_node, array_domain_type); /* This is a hack that should go away when we deliver the *************** *** 4444,4450 **** vtable_entry_type = make_lang_type (RECORD_TYPE); ! fields[0] = build_lang_field_decl (FIELD_DECL, get_identifier (VTABLE_DELTA_NAME), short_integer_type_node); ! fields[1] = build_lang_field_decl (FIELD_DECL, get_identifier (VTABLE_INDEX_NAME), short_integer_type_node); ! fields[2] = build_lang_field_decl (FIELD_DECL, get_identifier (VTABLE_PFN_NAME), ptr_type_node); finish_builtin_type (vtable_entry_type, VTBL_PTR_TYPE, fields, 2, double_type_node); --- 4772,4778 ---- vtable_entry_type = make_lang_type (RECORD_TYPE); ! fields[0] = build_lang_field_decl (FIELD_DECL, delta_identifier, short_integer_type_node); ! fields[1] = build_lang_field_decl (FIELD_DECL, index_identifier, short_integer_type_node); ! fields[2] = build_lang_field_decl (FIELD_DECL, pfn_identifier, ptr_type_node); finish_builtin_type (vtable_entry_type, VTBL_PTR_TYPE, fields, 2, double_type_node); *************** *** 4453,4457 **** fields[3] = copy_node (fields[2]); TREE_TYPE (fields[3]) = short_integer_type_node; ! DECL_NAME (fields[3]) = get_identifier (VTABLE_DELTA2_NAME); DECL_MODE (fields[3]) = TYPE_MODE (short_integer_type_node); DECL_SIZE (fields[3]) = TYPE_SIZE (short_integer_type_node); --- 4781,4785 ---- fields[3] = copy_node (fields[2]); TREE_TYPE (fields[3]) = short_integer_type_node; ! DECL_NAME (fields[3]) = delta2_identifier; DECL_MODE (fields[3]) = TYPE_MODE (short_integer_type_node); DECL_SIZE (fields[3]) = TYPE_SIZE (short_integer_type_node); *************** *** 4621,4627 **** /* Create the global bindings for __FUNCTION__ and __PRETTY_FUNCTION__. */ declare_function_name (); - - /* Warnings about failure to return values are too valuable to forego. */ - warn_return_type = 1; } --- 4949,4952 ---- *************** *** 4678,4681 **** --- 5003,5007 ---- int found_tag = 0; int warned = 0; + int static_or_extern = 0; register tree link; register enum tree_code code, ok_code = ERROR_MARK; *************** *** 4728,4731 **** --- 5054,5060 ---- } } + else if (value == ridpointers[(int) RID_STATIC] + || value == ridpointers[(int) RID_EXTERN]) + static_or_extern = 1; } *************** *** 4752,4783 **** error ("anonymous union cannot have a function member"); } ! else if (ok_code == RECORD_TYPE ! && found_tag == 1 ! && TYPE_LANG_SPECIFIC (t) ! && CLASSTYPE_DECLARED_EXCEPTION (t)) { ! if (TYPE_SIZE (t)) ! error_with_aggr_type (t, "redeclaration of exception `%s'"); ! else { ! tree ename, decl; ! push_obstacks (&permanent_obstack, &permanent_obstack); ! pushclass (t, 0); ! finish_exception (t, NULL_TREE); ! ename = TYPE_NAME (t); ! if (TREE_CODE (ename) == TYPE_DECL) ! ename = DECL_NAME (ename); ! decl = build_lang_field_decl (VAR_DECL, ename, t); ! finish_exception_decl (current_class_name, decl); ! end_exception_decls (); ! pop_obstacks (); } } - else if (!warned && found_tag > 1) - warning ("multiple types in one declaration"); } --- 5081,5120 ---- error ("anonymous union cannot have a function member"); } ! else { ! /* Anonymous unions are objects, that's why we only check for ! static/extern specifiers in this branch. */ ! if (static_or_extern) ! error ("static/extern can only be specified for objects and functions"); ! ! if (ok_code == RECORD_TYPE ! && found_tag == 1 ! && TYPE_LANG_SPECIFIC (t) ! && CLASSTYPE_DECLARED_EXCEPTION (t)) { ! if (TYPE_SIZE (t)) ! cp_error ("redeclaration of exception `%T'", t); ! else ! { ! tree ename, decl; ! push_obstacks (&permanent_obstack, &permanent_obstack); ! pushclass (t, 0); ! finish_exception (t, NULL_TREE); ! ename = TYPE_NAME (t); ! if (TREE_CODE (ename) == TYPE_DECL) ! ename = DECL_NAME (ename); ! decl = build_lang_field_decl (VAR_DECL, ename, t); ! finish_exception_decl (current_class_name, decl); ! end_exception_decls (); ! pop_obstacks (); ! } } + else if (!warned && found_tag > 1) + warning ("multiple types in one declaration"); } } *************** *** 4816,4820 **** tree start_decl (declarator, declspecs, initialized, raises) ! tree declspecs, declarator; int initialized; tree raises; --- 5153,5157 ---- tree start_decl (declarator, declspecs, initialized, raises) ! tree declarator, declspecs; int initialized; tree raises; *************** *** 4907,4911 **** } d = build_lang_decl (TEMPLATE_DECL, DECL_NAME (decl), TREE_TYPE (decl)); ! TREE_PUBLIC (d) = TREE_PUBLIC (decl) = 0; TREE_STATIC (d) = TREE_STATIC (decl); DECL_EXTERNAL (d) = (DECL_EXTERNAL (decl) --- 5244,5250 ---- } d = build_lang_decl (TEMPLATE_DECL, DECL_NAME (decl), TREE_TYPE (decl)); ! if (interface_unknown && flag_external_templates) ! warn_if_unknown_interface (); ! TREE_PUBLIC (d) = TREE_PUBLIC (decl) = flag_external_templates && !interface_unknown; TREE_STATIC (d) = TREE_STATIC (decl); DECL_EXTERNAL (d) = (DECL_EXTERNAL (decl) *************** *** 5214,5217 **** --- 5553,5563 ---- } + if (TREE_CODE (type) == REFERENCE_TYPE + && TREE_CODE (init) == CONSTRUCTOR) + { + error ("ANSI C++ forbids use of initializer list for a reference initializer"); + return; + } + if (TREE_CODE (init) == TREE_LIST) init = build_compound_expr (init); *************** *** 5315,5319 **** if (TREE_CODE (decl) == VAR_DECL) SET_DECL_REFERENCE_SLOT (decl, error_mark_node); ! error_with_decl (decl, "constructor failed to build reference initializer"); return; } --- 5661,5665 ---- if (TREE_CODE (decl) == VAR_DECL) SET_DECL_REFERENCE_SLOT (decl, error_mark_node); ! cp_error_at ("constructor failed to build reference initializer", decl); return; } *************** *** 5381,5385 **** else { ! error_with_decl (decl, "type mismatch in initialization of `%s' (use `const')"); DECL_INITIAL (decl) = error_mark_node; } --- 5727,5731 ---- else { ! cp_error ("type mismatch in initialization of `%D' (use `const')", decl); DECL_INITIAL (decl) = error_mark_node; } *************** *** 5579,5583 **** && CONSTRUCTOR_ELTS (init) != NULL_TREE) { ! error_with_decl (decl, "`%s' must be initialized by constructor, not by `{...}'"); init = error_mark_node; } --- 5925,5929 ---- && CONSTRUCTOR_ELTS (init) != NULL_TREE) { ! cp_error ("`%D' must be initialized by constructor, not by `{...}'", decl); init = error_mark_node; } *************** *** 5646,5650 **** } else if (TREE_CODE_CLASS (TREE_CODE (type)) == 't' ! && (IS_AGGR_TYPE (type) || TYPE_NEEDS_CONSTRUCTING (type))) { tree ctype = type; --- 5992,5997 ---- } else if (TREE_CODE_CLASS (TREE_CODE (type)) == 't' ! && (IS_AGGR_TYPE (type) || TYPE_NEEDS_CONSTRUCTING (type)) ! && init != NULL_TREE) { tree ctype = type; *************** *** 5654,5660 **** { if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (ctype)) ! error_with_decl (decl, "structure `%s' with uninitialized const members"); if (CLASSTYPE_REF_FIELDS_NEED_INIT (ctype)) ! error_with_decl (decl, "structure `%s' with uninitialized reference members"); } --- 6001,6007 ---- { if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (ctype)) ! cp_error ("structure `%D' with uninitialized const members", decl); if (CLASSTYPE_REF_FIELDS_NEED_INIT (ctype)) ! cp_error ("structure `%D' with uninitialized reference members", decl); } *************** *** 5662,5666 **** && !TYPE_NEEDS_CONSTRUCTING (type) && (TYPE_READONLY (type) || TREE_READONLY (decl))) ! error_with_decl (decl, "uninitialized const `%s'"); /* Initialize variables in need of static initialization --- 6009,6013 ---- && !TYPE_NEEDS_CONSTRUCTING (type) && (TYPE_READONLY (type) || TREE_READONLY (decl))) ! cp_error ("uninitialized const `%D'", decl); /* Initialize variables in need of static initialization *************** *** 5689,5695 **** external linkage and must be initialized. ($8.4; $12.1)'' ARM 7.1.6 However, if it's `const int foo = 1; const int foo;', don't complain ! about the second decl, since it does have an initializer before. */ ! if (! DECL_INITIAL (decl) && (!pedantic || !current_class_type)) ! error_with_decl (decl, "uninitialized const `%s'"); } --- 6036,6047 ---- external linkage and must be initialized. ($8.4; $12.1)'' ARM 7.1.6 However, if it's `const int foo = 1; const int foo;', don't complain ! about the second decl, since it does have an initializer before. ! We deliberately don't complain about arrays, because they're ! supposed to be initialized by a constructor. */ ! if (! DECL_INITIAL (decl) ! && TREE_CODE (type) != ARRAY_TYPE ! && (!pedantic || !current_class_type)) ! error ("uninitialized const `%s'", ! IDENTIFIER_POINTER (DECL_NAME (decl))); } *************** *** 5718,5722 **** if (failure == 1) ! error_with_decl (decl, "initializer fails to determine size of `%s'"); if (failure == 2) --- 6070,6074 ---- if (failure == 1) ! cp_error ("initializer fails to determine size of `%D'", decl); if (failure == 2) *************** *** 5723,5728 **** { if (do_default) ! error_with_decl (decl, "array size missing in `%s'"); ! else if (!pedantic && TREE_STATIC (decl)) DECL_EXTERNAL (decl) = 1; } --- 6075,6084 ---- { if (do_default) ! cp_error ("array size missing in `%D'", decl); ! /* If a `static' var's size isn't known, make it extern as ! well as static, so it does not get allocated. If it's not ! `static', then don't mark it extern; finish_incomplete_decl ! will give it a default size and it will get allocated. */ ! else if (!pedantic && TREE_STATIC (decl) && !TREE_PUBLIC (decl)) DECL_EXTERNAL (decl) = 1; } *************** *** 5731,5735 **** && tree_int_cst_lt (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), integer_zero_node)) ! error_with_decl (decl, "zero-size array `%s'"); layout_decl (decl, 0); --- 6087,6091 ---- && tree_int_cst_lt (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), integer_zero_node)) ! cp_error ("zero-size array `%D'", decl); layout_decl (decl, 0); *************** *** 5738,5741 **** --- 6094,6101 ---- if (TREE_CODE (decl) == VAR_DECL) { + if (DECL_SIZE (decl) == NULL_TREE + && TYPE_SIZE (TREE_TYPE (decl)) != NULL_TREE) + layout_decl (decl, 0); + if (TREE_STATIC (decl) && DECL_SIZE (decl) == NULL_TREE) { *************** *** 5745,5749 **** then it may cause an error message later. */ if (!DECL_EXTERNAL (decl) || DECL_INITIAL (decl) != NULL_TREE) ! error_with_decl (decl, "storage size of `%s' isn't known"); init = NULL_TREE; } --- 6105,6109 ---- then it may cause an error message later. */ if (!DECL_EXTERNAL (decl) || DECL_INITIAL (decl) != NULL_TREE) ! cp_error ("storage size of `%D' isn't known", decl); init = NULL_TREE; } *************** *** 5753,5757 **** Don't talk about array types here, since we took care of that message in grokdeclarator. */ ! error_with_decl (decl, "storage size of `%s' isn't known"); TREE_TYPE (decl) = error_mark_node; } --- 6113,6117 ---- Don't talk about array types here, since we took care of that message in grokdeclarator. */ ! cp_error ("storage size of `%D' isn't known", decl); TREE_TYPE (decl) = error_mark_node; } *************** *** 5763,5767 **** && DECL_SIZE (decl) != NULL_TREE && ! TREE_CONSTANT (DECL_SIZE (decl))) ! error_with_decl (decl, "storage size of `%s' isn't constant"); if (!DECL_EXTERNAL (decl) && TYPE_NEEDS_DESTRUCTOR (type)) --- 6123,6132 ---- && DECL_SIZE (decl) != NULL_TREE && ! TREE_CONSTANT (DECL_SIZE (decl))) ! { ! if (TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST) ! constant_expression_warning (DECL_SIZE (decl)); ! else ! cp_error ("storage size of `%D' isn't constant", decl); ! } if (!DECL_EXTERNAL (decl) && TYPE_NEEDS_DESTRUCTOR (type)) *************** *** 5801,5805 **** || TREE_CODE (decl) == RESULT_DECL) { ! int toplev = current_binding_level == global_binding_level; int was_temp = ((flag_traditional --- 6166,6172 ---- || TREE_CODE (decl) == RESULT_DECL) { ! /* ??? FIXME: What about nested classes? */ ! int toplev = (current_binding_level == global_binding_level ! || pseudo_global_level_p ()); int was_temp = ((flag_traditional *************** *** 5923,5933 **** while (parmtypes && parmtypes != void_list_node) { if (TREE_PURPOSE (parmtypes)) { tree fnname, fndecl; ! tree *argp = prev ! ? & TREE_CHAIN (prev) ! : & TYPE_ARG_TYPES (type); *argp = NULL_TREE; fnname = build_decl_overload (original_name, TYPE_ARG_TYPES (type), 0); --- 6290,6315 ---- while (parmtypes && parmtypes != void_list_node) { + /* The default value for the parameter in parmtypes is + stored in the TREE_PURPOSE of the TREE_LIST. */ if (TREE_PURPOSE (parmtypes)) { tree fnname, fndecl; ! tree *argp; + /* ARM $13.4: An overloaded operator cannot have + default arguments. */ + if (IDENTIFIER_OPNAME_P (original_name)) + { + error ("overloaded operator cannot have default arguments", + operator_name_string (original_name)); + TREE_PURPOSE (parmtypes) = NULL_TREE; + prev = parmtypes; + parmtypes = TREE_CHAIN (parmtypes); + continue; + } + + argp = prev ? & TREE_CHAIN (prev) + : & TYPE_ARG_TYPES (type); + *argp = NULL_TREE; fnname = build_decl_overload (original_name, TYPE_ARG_TYPES (type), 0); *************** *** 5968,5972 **** build_static_gc_entry (decl, type); } ! else if (current_binding_level != global_binding_level) { /* This is a declared decl which must live until the --- 6350,6354 ---- build_static_gc_entry (decl, type); } ! else if (! toplev) { /* This is a declared decl which must live until the *************** *** 6020,6024 **** { if (! expand_decl_cleanup (decl, cleanup)) ! error_with_decl (decl, "parser lost in parsing declaration of `%s'"); } } --- 6402,6406 ---- { if (! expand_decl_cleanup (decl, cleanup)) ! cp_error ("parser lost in parsing declaration of `%D'", decl); } } *************** *** 6074,6079 **** if (oldstatic) { ! if (TREE_PURPOSE (oldstatic)) ! error_with_decl (decl, "multiple initializations given for `%s'"); } else if (current_binding_level != global_binding_level) --- 6456,6461 ---- if (oldstatic) { ! if (TREE_PURPOSE (oldstatic) && init != NULL_TREE) ! cp_error ("multiple initializations given for `%D'", decl); } else if (current_binding_level != global_binding_level) *************** *** 6142,6146 **** register int nelts = list_length (CONSTRUCTOR_ELTS (initial_value)); ! maxindex = build_int_2 (nelts - 1, 0); } else --- 6524,6528 ---- register int nelts = list_length (CONSTRUCTOR_ELTS (initial_value)); ! maxindex = build_int_2 (nelts - 1, - (nelts == 0)); } else *************** *** 6151,6155 **** /* Prevent further error messages. */ ! maxindex = build_int_2 (1, 0); } } --- 6533,6537 ---- /* Prevent further error messages. */ ! maxindex = build_int_2 (0, 0); } } *************** *** 6158,6162 **** { if (do_default) ! maxindex = build_int_2 (1, 0); value = 2; } --- 6540,6544 ---- { if (do_default) ! maxindex = build_int_2 (0, 0); value = 2; } *************** *** 6194,6197 **** --- 6576,6599 ---- /* Subroutine of `grokdeclarator'. */ + /* Generate errors possibly applicable for a given set of specifiers. + This is for ARM $7.1.2. */ + static void + bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises) + tree object; + char *type; + int virtualp, quals, friendp, raises; + { + if (virtualp) + cp_error ("`%D' declared as a `virtual' %s", object, type); + if (inlinep) + cp_error ("`%D' declared as an `inline' %s", object, type); + if (quals) + cp_error ("`const' and `volatile' function specifiers on `%D' invalid in %s declaration", object, type); + if (friendp) + cp_error_at ("invalid friend declaration", object); + if (raises) + cp_error_at ("invalid raises declaration", object); + } + /* CTYPE is class type, or null if non-class. TYPE is type this FUNCTION_DECL should have, either FUNCTION_TYPE *************** *** 6280,6283 **** --- 6682,6691 ---- /* ANSI C++ June 5 1992 WP 12.5.4.1 */ error ("operator delete cannot be overloaded"); + + #if 0 + /* Duplicated in coerce_delete_type -jason */ + if (TREE_TYPE (type) != void_type_node) + error ("operator delete must return void"); + #endif } else if (DECL_NAME (decl) == ansi_opname[(int) POSTINCREMENT_EXPR] *************** *** 6298,6302 **** --- 6706,6758 ---- } } + else if (declarator == ansi_opname[(int) NEW_EXPR]) + { + #if 0 + /* Partially duplicated in coerce_new_type -- but only for methods + Where should these things be resolved? -jason */ + tree args = TYPE_ARG_TYPES (type); + + if (ctype && args && TREE_CODE (type) == METHOD_TYPE) + /* remove this */ + args = TREE_CHAIN (args); + + if (TREE_VALUE (args) != sizetype) + error ("the first argument to operator new must be of type size_t"); + if (TREE_TYPE (type) != ptr_type_node + || TREE_TYPE (TREE_TYPE (type)) != void_type_node)) + error ("operator new must return void *"); + #endif + } + else if (IDENTIFIER_OPNAME_P (declarator) + /* && declarator != ansi_opname[(int) NEW_EXPR] + && declarator != ansi_opname[(int) DELETE_EXPR] Handled above */ + && ctype == NULL_TREE) + { + /* An operator function must either be a non-static member function or + take at least one argument of a class, a reference to a class, an + enumeration, or a reference to an enumeration. 13.4 */ + tree p; + + for (p = TYPE_ARG_TYPES (type); + TREE_VALUE (p) != void_type_node; + p = TREE_CHAIN (p)) + { + tree arg = TREE_VALUE (p); + if (TREE_CODE (arg) == REFERENCE_TYPE) + arg = TREE_TYPE (arg); + + /* This lets bad template code slip through. -jason */ + if (IS_AGGR_TYPE (arg) + || TREE_CODE (arg) == ENUMERAL_TYPE + || TREE_CODE (arg) == TEMPLATE_TYPE_PARM) + goto foundaggr; + } + cp_error ("`%D' must have an argument of class or enumerated type", + declarator); + foundaggr: + ; + } + /* Caller will do the rest of this. */ if (check < 0) *************** *** 6324,6328 **** IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl)) = decl; else if (TREE_CODE (tmp) != TREE_CODE (decl)) ! error_with_decl (decl, "inconsistent declarations for `%s'"); else { --- 6780,6784 ---- IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl)) = decl; else if (TREE_CODE (tmp) != TREE_CODE (decl)) ! cp_error ("inconsistent declarations for `%D'", decl); else { *************** *** 6364,6368 **** IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl)) = decl; else if (TREE_CODE (tmp) != TREE_CODE (decl)) ! error_with_decl (decl, "inconsistent declarations for `%s'"); else { --- 6820,6824 ---- IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl)) = decl; else if (TREE_CODE (tmp) != TREE_CODE (decl)) ! cp_error ("inconsistent declarations for `%D'", decl); else { *************** *** 6390,6393 **** --- 6846,6854 ---- if (tmp) { + /* If this function overrides some virtual in some base + class, then the function itself is also necessarily + virtual, even if the user didn't explicitly say so. */ + DECL_VIRTUAL_P (decl) = 1; + /* The TMP we really want is the one from the deepest baseclass on this path, taking care not to *************** *** 6396,6401 **** if (staticp) { ! error_with_decl (decl, "method `%s' may not be declared static"); ! error_with_decl (tmp, "(since `%s' declared virtual in base class.)"); break; } --- 6857,6862 ---- if (staticp) { ! cp_error ("method `%D' may not be declared static", decl); ! cp_error_at ("(since `%D' declared virtual in base class.)", tmp); break; } *************** *** 6443,6447 **** && (write_virtuals == 2 || (write_virtuals == 3 ! && ! CLASSTYPE_INTERFACE_UNKNOWN (ctype)))) TREE_PUBLIC (decl) = 1; } --- 6904,6908 ---- && (write_virtuals == 2 || (write_virtuals == 3 ! && CLASSTYPE_INTERFACE_KNOWN (ctype)))) TREE_PUBLIC (decl) = 1; } *************** *** 6461,6474 **** /* This implements the "one definition rule" for global variables. Note that declarator can come in as null when we're doing work ! on an anonymous union. */ if (declarator && IDENTIFIER_GLOBAL_VALUE (declarator) && current_binding_level == global_binding_level && TREE_STATIC (IDENTIFIER_GLOBAL_VALUE (declarator)) ! && (! (specbits & RIDBIT (RID_EXTERN)) || initialized)) { error ("redefinition of `%s'", IDENTIFIER_POINTER (declarator)); ! error_with_decl (IDENTIFIER_GLOBAL_VALUE (declarator), ! "previously defined here"); } --- 6922,6936 ---- /* This implements the "one definition rule" for global variables. Note that declarator can come in as null when we're doing work ! on an anonymous union. Don't complain about duplicate ! definitions of `extern "C"' vars. */ if (declarator && IDENTIFIER_GLOBAL_VALUE (declarator) && current_binding_level == global_binding_level && TREE_STATIC (IDENTIFIER_GLOBAL_VALUE (declarator)) ! && current_lang_name == lang_name_cplusplus ! && (RIDBIT_NOTSETP (RID_EXTERN, specbits) || initialized)) { error ("redefinition of `%s'", IDENTIFIER_POINTER (declarator)); ! cp_error_at ("previously defined here", IDENTIFIER_GLOBAL_VALUE (declarator)); } *************** *** 6520,6526 **** } } ! else decl = build_decl (VAR_DECL, declarator, type); ! if (specbits & RIDBIT (RID_EXTERN)) { DECL_THIS_EXTERN (decl) = 1; --- 6982,6989 ---- } } ! else ! decl = build_decl (VAR_DECL, declarator, type); ! if (RIDBIT_SETP (RID_EXTERN, specbits)) { DECL_THIS_EXTERN (decl) = 1; *************** *** 6541,6545 **** else if (current_binding_level == global_binding_level) { ! TREE_PUBLIC (decl) = ! (specbits & RIDBIT (RID_STATIC)); TREE_STATIC (decl) = ! DECL_EXTERNAL (decl); } --- 7004,7008 ---- else if (current_binding_level == global_binding_level) { ! TREE_PUBLIC (decl) = RIDBIT_NOTSETP (RID_STATIC, specbits); TREE_STATIC (decl) = ! DECL_EXTERNAL (decl); } *************** *** 6547,6551 **** else { ! TREE_STATIC (decl) = !! (specbits & RIDBIT (RID_STATIC)); TREE_PUBLIC (decl) = DECL_EXTERNAL (decl); } --- 7010,7014 ---- else { ! TREE_STATIC (decl) = !! RIDBIT_SETP (RID_STATIC, specbits); TREE_PUBLIC (decl) = DECL_EXTERNAL (decl); } *************** *** 6553,6556 **** --- 7016,7063 ---- } + /* Create a canonical pointer to member function type. */ + + static tree + build_ptrmemfunc_type (type) + tree type; + { + tree fields[4]; + tree t; + tree u; + + /* If a canonical type already exists for this type, use it. We use + this method instead of type_hash_canon, because it only does a + simple equality check on the list of field members. */ + + if (t = TYPE_GET_PTRMEMFUNC_TYPE (type)) + return t; + + u = make_lang_type (UNION_TYPE); + fields[0] = build_lang_field_decl (FIELD_DECL, pfn_identifier, type); + fields[1] = build_lang_field_decl (FIELD_DECL, delta2_identifier, short_integer_type_node); + finish_builtin_type (u, "__ptrmemfunc_type", fields, 1, ptr_type_node); + TYPE_NAME (u) = NULL_TREE; + + t = make_lang_type (RECORD_TYPE); + + /* Let the front-end know this is a pointer to member function. */ + TYPE_PTRMEMFUNC_FLAG(t) = 1; + + fields[0] = build_lang_field_decl (FIELD_DECL, delta_identifier, short_integer_type_node); + fields[1] = build_lang_field_decl (FIELD_DECL, index_identifier, short_integer_type_node); + fields[2] = build_lang_field_decl (FIELD_DECL, pfn_or_delta2_identifier, u); + finish_builtin_type (t, "__ptrmemfunc_type", fields, 2, ptr_type_node); + + /* Zap out the name so that the back-end will give us the debugging + information for this anonymous RECORD_TYPE. */ + TYPE_NAME (t) = NULL_TREE; + + TYPE_SET_PTRMEMFUNC_TYPE (type, t); + + /* Seems to be wanted. */ + CLASSTYPE_GOT_SEMICOLON (t) = 1; + return t; + } + /* Given declspecs and a declarator, determine the name and type of the object declared *************** *** 6618,6624 **** tree raises; { ! extern int current_class_depth; ! ! RID_BIT_TYPE specbits = 0; int nclasses = 0; tree spec; --- 7125,7129 ---- tree raises; { ! RID_BIT_TYPE specbits; int nclasses = 0; tree spec; *************** *** 6653,6656 **** --- 7158,7162 ---- tree quals = NULL_TREE; + RIDBIT_RESET_ALL (specbits); if (decl_context == FUNCDEF) funcdef_flag = 1, decl_context = NORMAL; *************** *** 6693,6698 **** ? TYPE_NAME (TREE_VALUE (declspecs)) : NULL_TREE); ! if (type && TREE_CODE (type) == TYPE_DECL ! && IS_AGGR_TYPE (TREE_TYPE (type)) && parmlist_is_exprlist (TREE_OPERAND (decl, 1))) { --- 7199,7208 ---- ? TYPE_NAME (TREE_VALUE (declspecs)) : NULL_TREE); ! /* We used to restrict this to just aggregate types for ! function-call notation for initialization. But since it ! can be done for more than aggregates (e.g., `int a(b);'), ! it's no longer restrained. */ ! if (type ! && TREE_CODE (type) == TYPE_DECL && parmlist_is_exprlist (TREE_OPERAND (decl, 1))) { *************** *** 6726,6729 **** --- 7236,7245 ---- else declarator = TREE_OPERAND (declarator, 0); + + /* When dealing with scalar initializations we have to get + rid of the surrounding TREE_LIST around the initializer. */ + if (! IS_AGGR_TYPE (TREE_TYPE (type))) + init = TREE_VALUE (init); + decl = start_decl (declarator, declspecs, 1, NULL_TREE); finish_decl (decl, init, NULL_TREE, 1); *************** *** 6948,6952 **** default: ! my_friendly_abort (155); } if (name == NULL) --- 7464,7468 ---- default: ! return 0; /* We used to do a 155 abort here. */ } if (name == NULL) *************** *** 7053,7061 **** if (ridpointers[i] == id) { ! if (i == (int) RID_LONG && (specbits & RIDBIT (i))) { if (pedantic) pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id)); ! else if (longlong) error ("`long long long' is too long for GCC"); else --- 7569,7580 ---- if (ridpointers[i] == id) { ! if (i == (int) RID_LONG && RIDBIT_SETP (i, specbits)) { + #if 0 if (pedantic) pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id)); ! else ! #endif ! if (longlong) error ("`long long long' is too long for GCC"); else *************** *** 7062,7068 **** longlong = 1; } ! else if (specbits & RIDBIT (i)) warning ("duplicate `%s'", IDENTIFIER_POINTER (id)); ! specbits |= RIDBIT (i); goto found; } --- 7581,7587 ---- longlong = 1; } ! else if (RIDBIT_SETP (i, specbits)) warning ("duplicate `%s'", IDENTIFIER_POINTER (id)); ! RIDBIT_SET (i, specbits); goto found; } *************** *** 7106,7111 **** if (funcdef_flag && explicit_warn_return_type && return_type == return_normal ! && ! (specbits & (RIDBIT (RID_SIGNED) | RIDBIT (RID_UNSIGNED) ! | RIDBIT (RID_LONG) | RIDBIT (RID_SHORT)))) warn_about_return_type = 1; /* Save warning until we know what is really going on. */ --- 7625,7632 ---- if (funcdef_flag && explicit_warn_return_type && return_type == return_normal ! && ! (RIDBIT_SETP (RID_SIGNED, specbits) ! || RIDBIT_SETP (RID_UNSIGNED, specbits) ! || RIDBIT_SETP (RID_LONG, specbits) ! || RIDBIT_SETP (RID_SHORT, specbits))) warn_about_return_type = 1; /* Save warning until we know what is really going on. */ *************** *** 7123,7127 **** type = TYPE_POINTER_TO (ctor_return_type); } ! else if ((specbits & RIDBIT (RID_FRIEND)) && IS_AGGR_TYPE (type) && ! TYPE_BEING_DEFINED (type) --- 7644,7648 ---- type = TYPE_POINTER_TO (ctor_return_type); } ! else if (RIDBIT_SETP (RID_FRIEND, specbits) && IS_AGGR_TYPE (type) && ! TYPE_BEING_DEFINED (type) *************** *** 7146,7153 **** /* Long double is a special combination. */ ! if ((specbits & RIDBIT (RID_LONG)) && TYPE_MAIN_VARIANT (type) == double_type_node) { ! specbits &= ~ RIDBIT (RID_LONG); type = build_type_variant (long_double_type_node, TYPE_READONLY (type), TYPE_VOLATILE (type)); --- 7667,7674 ---- /* Long double is a special combination. */ ! if (RIDBIT_SETP (RID_LONG, specbits) && TYPE_MAIN_VARIANT (type) == double_type_node) { ! RIDBIT_RESET (RID_LONG, specbits); type = build_type_variant (long_double_type_node, TYPE_READONLY (type), TYPE_VOLATILE (type)); *************** *** 7156,7161 **** /* Check all other uses of type modifiers. */ ! if (specbits & (RIDBIT (RID_UNSIGNED) | RIDBIT (RID_SIGNED) ! | RIDBIT (RID_LONG) | RIDBIT (RID_SHORT))) { int ok = 0; --- 7677,7684 ---- /* Check all other uses of type modifiers. */ ! if (RIDBIT_SETP (RID_UNSIGNED, specbits) ! || RIDBIT_SETP (RID_SIGNED, specbits) ! || RIDBIT_SETP (RID_LONG, specbits) ! || RIDBIT_SETP (RID_SHORT, specbits)) { int ok = 0; *************** *** 7165,7181 **** else if (TREE_CODE (type) != INTEGER_TYPE || type == wchar_type_node) error ("long, short, signed or unsigned invalid for `%s'", name); ! else if ((specbits & RIDBIT (RID_LONG)) ! && (specbits & RIDBIT (RID_SHORT))) error ("long and short specified together for `%s'", name); ! else if (((specbits & RIDBIT (RID_LONG)) ! || (specbits & RIDBIT (RID_SHORT))) && explicit_char) error ("long or short specified with char for `%s'", name); ! else if (((specbits & RIDBIT (RID_LONG)) ! || (specbits & RIDBIT (RID_SHORT))) && TREE_CODE (type) == REAL_TYPE) error ("long or short specified with floating type for `%s'", name); ! else if ((specbits & RIDBIT (RID_SIGNED)) ! && (specbits & RIDBIT (RID_UNSIGNED))) error ("signed and unsigned given together for `%s'", name); else --- 7688,7704 ---- else if (TREE_CODE (type) != INTEGER_TYPE || type == wchar_type_node) error ("long, short, signed or unsigned invalid for `%s'", name); ! else if (RIDBIT_SETP (RID_LONG, specbits) ! && RIDBIT_SETP (RID_SHORT, specbits)) error ("long and short specified together for `%s'", name); ! else if ((RIDBIT_SETP (RID_LONG, specbits) ! || RIDBIT_SETP (RID_SHORT, specbits)) && explicit_char) error ("long or short specified with char for `%s'", name); ! else if ((RIDBIT_SETP (RID_LONG, specbits) ! || RIDBIT_SETP (RID_SHORT, specbits)) && TREE_CODE (type) == REAL_TYPE) error ("long or short specified with floating type for `%s'", name); ! else if (RIDBIT_SETP (RID_SIGNED, specbits) ! && RIDBIT_SETP (RID_UNSIGNED, specbits)) error ("signed and unsigned given together for `%s'", name); else *************** *** 7194,7199 **** if (! ok) { ! specbits &= ~ (RIDBIT (RID_UNSIGNED) | RIDBIT (RID_SIGNED) ! | RIDBIT (RID_LONG) | RIDBIT (RID_SHORT)); longlong = 0; } --- 7717,7724 ---- if (! ok) { ! RIDBIT_RESET (RID_UNSIGNED, specbits); ! RIDBIT_RESET (RID_SIGNED, specbits); ! RIDBIT_RESET (RID_LONG, specbits); ! RIDBIT_RESET (RID_SHORT, specbits); longlong = 0; } *************** *** 7202,7206 **** /* Decide whether an integer type is signed or not. Optionally treat bitfields as signed by default. */ ! if ((specbits & RIDBIT (RID_UNSIGNED)) /* Traditionally, all bitfields are unsigned. */ || (bitfield && flag_traditional) --- 7727,7731 ---- /* Decide whether an integer type is signed or not. Optionally treat bitfields as signed by default. */ ! if (RIDBIT_SETP (RID_UNSIGNED, specbits) /* Traditionally, all bitfields are unsigned. */ || (bitfield && flag_traditional) *************** *** 7212,7222 **** && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl))) && TREE_CODE (type) != ENUMERAL_TYPE ! && !(specbits & RIDBIT (RID_SIGNED)))) { if (longlong) type = long_long_unsigned_type_node; ! else if (specbits & RIDBIT (RID_LONG)) type = long_unsigned_type_node; ! else if (specbits & RIDBIT (RID_SHORT)) type = short_unsigned_type_node; else if (type == char_type_node) --- 7737,7747 ---- && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl))) && TREE_CODE (type) != ENUMERAL_TYPE ! && RIDBIT_NOTSETP (RID_SIGNED, specbits))) { if (longlong) type = long_long_unsigned_type_node; ! else if (RIDBIT_SETP (RID_LONG, specbits)) type = long_unsigned_type_node; ! else if (RIDBIT_SETP (RID_SHORT, specbits)) type = short_unsigned_type_node; else if (type == char_type_node) *************** *** 7227,7231 **** type = unsigned_type_node; } ! else if ((specbits & RIDBIT (RID_SIGNED)) && type == char_type_node) type = signed_char_type_node; --- 7752,7756 ---- type = unsigned_type_node; } ! else if (RIDBIT_SETP (RID_SIGNED, specbits) && type == char_type_node) type = signed_char_type_node; *************** *** 7232,7238 **** else if (longlong) type = long_long_integer_type_node; ! else if (specbits & RIDBIT (RID_LONG)) type = long_integer_type_node; ! else if (specbits & RIDBIT (RID_SHORT)) type = short_integer_type_node; --- 7757,7763 ---- else if (longlong) type = long_long_integer_type_node; ! else if (RIDBIT_SETP (RID_LONG, specbits)) type = long_integer_type_node; ! else if (RIDBIT_SETP (RID_SHORT, specbits)) type = short_integer_type_node; *************** *** 7241,7248 **** Likewise for VOLATILEP. */ ! constp = !! (specbits & RIDBIT (RID_CONST)) + TYPE_READONLY (type); ! volatilep = !! (specbits & RIDBIT (RID_VOLATILE)) + TYPE_VOLATILE (type); staticp = 0; ! inlinep = !! (specbits & RIDBIT (RID_INLINE)); if (constp > 1) warning ("duplicate `const'"); --- 7766,7773 ---- Likewise for VOLATILEP. */ ! constp = !! RIDBIT_SETP (RID_CONST, specbits) + TYPE_READONLY (type); ! volatilep = !! RIDBIT_SETP (RID_VOLATILE, specbits) + TYPE_VOLATILE (type); staticp = 0; ! inlinep = !! RIDBIT_SETP (RID_INLINE, specbits); if (constp > 1) warning ("duplicate `const'"); *************** *** 7249,7254 **** if (volatilep > 1) warning ("duplicate `volatile'"); ! virtualp = specbits & RIDBIT (RID_VIRTUAL); ! if (specbits & RIDBIT (RID_STATIC)) staticp = 1 + (decl_context == FIELD); --- 7774,7779 ---- if (volatilep > 1) warning ("duplicate `volatile'"); ! virtualp = RIDBIT_SETP (RID_VIRTUAL, specbits); ! if (RIDBIT_SETP (RID_STATIC, specbits)) staticp = 1 + (decl_context == FIELD); *************** *** 7258,7273 **** staticp = 0; } ! friendp = specbits & RIDBIT (RID_FRIEND); ! specbits &= ~ (RIDBIT (RID_VIRTUAL) | RIDBIT (RID_FRIEND)); /* Warn if two storage classes are given. Default to `auto'. */ ! if (specbits) { ! if (specbits & RIDBIT (RID_STATIC)) nclasses++; ! if (specbits & RIDBIT (RID_EXTERN)) nclasses++; if (decl_context == PARM && nclasses > 0) error ("storage class specifiers invalid in parameter declarations"); ! if (specbits & RIDBIT (RID_TYPEDEF)) { if (decl_context == PARM) --- 7783,7832 ---- staticp = 0; } ! friendp = RIDBIT_SETP (RID_FRIEND, specbits); ! RIDBIT_RESET (RID_VIRTUAL, specbits); ! RIDBIT_RESET (RID_FRIEND, specbits); ! ! if (RIDBIT_SETP (RID_MUTABLE, specbits)) ! { ! if (decl_context == PARM) ! { ! error ("non-member `%s' cannot be declared mutable", name); ! RIDBIT_RESET (RID_MUTABLE, specbits); ! } ! else if (friendp || decl_context == TYPENAME) ! { ! error ("non-object member `%s' cannot be declared mutable", name); ! RIDBIT_RESET (RID_MUTABLE, specbits); ! } ! else if (staticp) ! { ! error ("static `%s' cannot be declared mutable", name); ! RIDBIT_RESET (RID_MUTABLE, specbits); ! } ! #if 0 ! if (RIDBIT_SETP (RID_TYPEDEF, specbits)) ! { ! error ("non-object member `%s' cannot be declared mutable", name); ! RIDBIT_RESET (RID_MUTABLE, specbits); ! } ! /* Because local typedefs are parsed twice, we don't want this ! message here. */ ! else if (decl_context != FIELD) ! { ! error ("non-member `%s' cannot be declared mutable", name); ! RIDBIT_RESET (RID_MUTABLE, specbits); ! } ! #endif ! } /* Warn if two storage classes are given. Default to `auto'. */ ! if (RIDBIT_ANY_SET (specbits)) { ! if (RIDBIT_SETP (RID_STATIC, specbits)) nclasses++; ! if (RIDBIT_SETP (RID_EXTERN, specbits)) nclasses++; if (decl_context == PARM && nclasses > 0) error ("storage class specifiers invalid in parameter declarations"); ! if (RIDBIT_SETP (RID_TYPEDEF, specbits)) { if (decl_context == PARM) *************** *** 7275,7280 **** nclasses++; } ! if (specbits & RIDBIT (RID_AUTO)) nclasses++; ! if (specbits & RIDBIT (RID_REGISTER)) nclasses++; } --- 7834,7839 ---- nclasses++; } ! if (RIDBIT_SETP (RID_AUTO, specbits)) nclasses++; ! if (RIDBIT_SETP (RID_REGISTER, specbits)) nclasses++; } *************** *** 7285,7289 **** --- 7844,7860 ---- virtualp = 0; } + if (current_class_name == NULL_TREE && RIDBIT_SETP (RID_MUTABLE, specbits)) + { + error ("only members can be declared mutable"); + RIDBIT_RESET (RID_MUTABLE, specbits); + } + /* Static anonymous unions are dealt with here. */ + if (staticp && decl_context == TYPENAME + && TREE_CODE (declspecs) == TREE_LIST + && TREE_CODE (TREE_VALUE (declspecs)) == UNION_TYPE + && ANON_AGGRNAME_P (TYPE_IDENTIFIER (TREE_VALUE (declspecs)))) + decl_context = FIELD; + /* Warn about storage classes that are invalid for certain kinds of declarations (parameters, typenames, etc.). */ *************** *** 7294,7351 **** { if (decl_context == PARM ! && ((specbits & RIDBIT (RID_REGISTER)) | RIDBIT (RID_AUTO))) ; ! else if ((decl_context == FIELD ! || decl_context == TYPENAME) ! && (specbits & RIDBIT (RID_TYPEDEF))) ! { ! /* A typedef which was made in a class's scope. */ ! tree loc_typedecl; ! register int i = sizeof (struct lang_decl_flags) / sizeof (int); ! register int *pi; ! struct binding_level *local_binding_level; ! ! /* keep `grokdeclarator' from thinking we are in PARM context. */ ! pushlevel (0); ! /* poplevel_class may be called by grokdeclarator which is called in ! start_decl which is called below. In this case, our pushed level ! may vanish and poplevel mustn't be called. So remember what we ! have pushed and pop only if that is matched by ! current_binding_level later. mnl@dtro.e-technik.th-darmstadt.de */ ! local_binding_level = current_binding_level; ! ! loc_typedecl = start_decl (declarator, declspecs, initialized, NULL_TREE); ! ! pi = (int *) permalloc (sizeof (struct lang_decl_flags)); ! while (i > 0) ! pi[--i] = 0; ! DECL_LANG_SPECIFIC (loc_typedecl) = (struct lang_decl *) pi; ! /* This poplevel conflicts with the popclass over in ! grokdeclarator. See ``This popclass conflicts'' */ ! if (current_binding_level == local_binding_level) ! poplevel (0, 0, 0); ! ! #if 0 ! if (TREE_CODE (TREE_TYPE (loc_typedecl)) == ENUMERAL_TYPE) ! { ! tree ref = lookup_tag (ENUMERAL_TYPE, DECL_NAME (loc_typedecl), current_binding_level, 0); ! if (! ref) ! pushtag (DECL_NAME (loc_typedecl), TREE_TYPE (loc_typedecl)); } ! #endif ! ! /* We used to check for a typedef hiding a previous decl in ! class scope, but delete_duplicate_fields_1 will now do ! that for us in the proper place. */ ! ! /* We reset loc_typedecl because the IDENTIFIER_CLASS_NAME is ! set by pushdecl_class_level. */ ! loc_typedecl = pushdecl_class_level (loc_typedecl); ! ! return loc_typedecl; } else if (decl_context == FIELD /* C++ allows static class elements */ ! && (specbits & RIDBIT (RID_STATIC))) /* C++ also allows inlines and signed and unsigned elements, but in those cases we don't come in here. */ --- 7865,7925 ---- { if (decl_context == PARM ! && (RIDBIT_SETP (RID_REGISTER, specbits) ! || RIDBIT_SETP (RID_AUTO, specbits))) ; ! else if (decl_context == FIELD ! && RIDBIT_SETP (RID_TYPEDEF, specbits)) ! { ! /* Processing a typedef declaration nested within a class type ! definition. */ ! register tree scanner; ! register tree previous_declspec; ! tree loc_typedecl; ! ! if (initialized) ! error ("typedef declaration includes an initializer"); ! ! /* To process a class-local typedef declaration, we descend down ! the chain of declspecs looking for the `typedef' spec. When we ! find it, we splice it out of the chain of declspecs, and then ! recursively call `grokdeclarator' with the original declarator ! and with the newly adjusted declspecs. This call should return ! a FIELD_DECL node with the TREE_TYPE (and other parts) set ! appropriately. We can then just change the TREE_CODE on that ! from FIELD_DECL to TYPE_DECL and we're done. */ ! ! for (previous_declspec = NULL_TREE, scanner = declspecs; ! scanner; ! previous_declspec = scanner, scanner = TREE_CHAIN (scanner)) ! { ! if (TREE_VALUE (scanner) == ridpointers[(int) RID_TYPEDEF]) ! break; ! } ! if (previous_declspec) ! TREE_CHAIN (previous_declspec) = TREE_CHAIN (scanner); ! else ! declspecs = TREE_CHAIN (scanner); ! ! loc_typedecl = ! grokdeclarator (declarator, declspecs, FIELD, 0, NULL_TREE); ! ! if (loc_typedecl != error_mark_node) ! { ! register int i = sizeof (struct lang_decl_flags) / sizeof (int); ! register int *pi; ! ! TREE_SET_CODE (loc_typedecl, TYPE_DECL); ! ! pi = (int *) permalloc (sizeof (struct lang_decl_flags)); ! while (i > 0) ! pi[--i] = 0; ! DECL_LANG_SPECIFIC (loc_typedecl) = (struct lang_decl *) pi; } ! ! return loc_typedecl; } else if (decl_context == FIELD /* C++ allows static class elements */ ! && RIDBIT_SETP (RID_STATIC, specbits)) /* C++ also allows inlines and signed and unsigned elements, but in those cases we don't come in here. */ *************** *** 7365,7373 **** ? "storage class specified for parameter `%s'" : "storage class specified for typename"), name); ! specbits &= ~ (RIDBIT (RID_REGISTER) | RIDBIT (RID_AUTO) ! | RIDBIT (RID_EXTERN)); } } ! else if ((specbits & RIDBIT (RID_EXTERN)) && initialized && !funcdef_flag) { if (current_binding_level == global_binding_level) --- 7939,7948 ---- ? "storage class specified for parameter `%s'" : "storage class specified for typename"), name); ! RIDBIT_RESET (RID_REGISTER, specbits); ! RIDBIT_RESET (RID_AUTO, specbits); ! RIDBIT_RESET (RID_EXTERN, specbits); } } ! else if (RIDBIT_SETP (RID_EXTERN, specbits) && initialized && !funcdef_flag) { if (current_binding_level == global_binding_level) *************** *** 7381,7385 **** error ("`%s' has both `extern' and initializer", name); } ! else if ((specbits & RIDBIT (RID_EXTERN)) && funcdef_flag && current_binding_level != global_binding_level) error ("nested function `%s' declared `extern'", name); --- 7956,7960 ---- error ("`%s' has both `extern' and initializer", name); } ! else if (RIDBIT_SETP (RID_EXTERN, specbits) && funcdef_flag && current_binding_level != global_binding_level) error ("nested function `%s' declared `extern'", name); *************** *** 7386,7393 **** else if (current_binding_level == global_binding_level) { ! if (specbits & RIDBIT (RID_AUTO)) error ("top-level declaration of `%s' specifies `auto'", name); #if 0 ! if (specbits & RIDBIT (RID_REGISTER)) error ("top-level declaration of `%s' specifies `register'", name); #endif --- 7961,7968 ---- else if (current_binding_level == global_binding_level) { ! if (RIDBIT_SETP (RID_AUTO, specbits)) error ("top-level declaration of `%s' specifies `auto'", name); #if 0 ! if (RIDBIT_SETP (RID_REGISTER, specbits)) error ("top-level declaration of `%s' specifies `register'", name); #endif *************** *** 7397,7404 **** warn if other bits are turned on. */ if (decl_context == NORMAL ! && ! (specbits & RIDBIT (RID_EXTERN)) && ! root_lang_context_p ()) { ! specbits |= RIDBIT (RID_EXTERN); } #endif --- 7972,7979 ---- warn if other bits are turned on. */ if (decl_context == NORMAL ! && RIDBIT_NOSETP (RID_EXTERN, specbits) && ! root_lang_context_p ()) { ! RIDBIT_SET (RID_EXTERN, specbits); } #endif *************** *** 7488,7492 **** then you'd have to ask: what does `*(x + i)' mean? */ if (TREE_CODE (type) == REFERENCE_TYPE) ! error ("declaration of `%s' as array of references", name); if (size == error_mark_node) --- 8063,8083 ---- then you'd have to ask: what does `*(x + i)' mean? */ if (TREE_CODE (type) == REFERENCE_TYPE) ! { ! error ("declaration of `%s' as array of references", name); ! type = error_mark_node; ! } ! ! if (TREE_CODE (type) == OFFSET_TYPE) ! { ! error ("declaration of `%s' as array of data members", name); ! type = error_mark_node; ! } ! ! if (TREE_CODE (type) == METHOD_TYPE) ! { ! error ("declaration of `%s' as array of function members", ! name); ! type = error_mark_node; ! } if (size == error_mark_node) *************** *** 7527,7530 **** --- 8118,8122 ---- if (TREE_CONSTANT (size)) { + constant_expression_warning (size); if (INT_CST_LT (size, integer_zero_node)) { *************** *** 7551,7561 **** } ! /* Build the array type itself. ! Merge any constancy or volatility into the target type. */ if (constp || volatilep) type = build_type_variant (type, constp, volatilep); - type = build_cplus_array_type (type, itype); ctype = NULL_TREE; } --- 8143,8155 ---- } ! /* Build the array type itself, then merge any constancy or ! volatility into the target type. We must do it in this order ! to ensure that the TYPE_MAIN_VARIANT field of the array type ! is set correctly. */ + type = build_cplus_array_type (type, itype); if (constp || volatilep) type = build_type_variant (type, constp, volatilep); ctype = NULL_TREE; } *************** *** 7660,7665 **** return void_type_node; } ! if (specbits & ~(RIDBIT (RID_INLINE)|RIDBIT (RID_STATIC))) ! error ("return value type specifier for constructor ignored"); type = TYPE_POINTER_TO (ctype); if (decl_context == FIELD) --- 8254,8270 ---- return void_type_node; } ! { ! int inlinep, staticp; ! inlinep = RIDBIT_SETP (RID_INLINE, specbits); ! staticp = RIDBIT_SETP (RID_STATIC, specbits); ! RIDBIT_RESET (RID_INLINE, specbits); ! RIDBIT_RESET (RID_STATIC, specbits); ! if (RIDBIT_ANY_SET (specbits)) ! error ("return value type specifier for constructor ignored"); ! if (inlinep) ! RIDBIT_SET (RID_INLINE, specbits); ! if (staticp) ! RIDBIT_SET (RID_STATIC, specbits); ! } type = TYPE_POINTER_TO (ctype); if (decl_context == FIELD) *************** *** 7680,7684 **** /* Cannot be both friend and virtual. */ error ("virtual functions cannot be friends"); ! specbits &= ~ RIDBIT (RID_FRIEND); } --- 8285,8289 ---- /* Cannot be both friend and virtual. */ error ("virtual functions cannot be friends"); ! RIDBIT_RESET (RID_FRIEND, specbits); } *************** *** 7719,7722 **** --- 8324,8329 ---- || TREE_CODE (inner_decl) == TYPE_EXPR)) ? funcdef_flag : 0; + /* FIXME: This is where default args should be fully processed. */ + arg_types = grokparms (inner_parms, funcdef_p); } *************** *** 7805,7808 **** --- 8412,8419 ---- } } + else if (TREE_CODE (type) == METHOD_TYPE) + { + type = build_ptrmemfunc_type (build_pointer_type (type)); + } else type = build_pointer_type (type); *************** *** 7859,7862 **** --- 8470,8482 ---- else if (TREE_COMPLEXITY (declarator) == current_class_depth) { + /* I'm not really sure what pushclass calls this popclass + corresponds to. One is in build_push_scope and that has + been changed to a push_nested_class call, that's why I + try to use pop_nested_class here instead. + -niklas@appli.se */ + #if NEW_CLASS_SCOPING + pop_nested_class (1); + TREE_COMPLEXITY (declarator) = current_class_depth; + #else TREE_COMPLEXITY (declarator) -= 1; /* This popclass conflicts with the poplevel over in *************** *** 7863,7866 **** --- 8483,8487 ---- grokdeclarator. See ``This poplevel conflicts'' */ popclass (1); + #endif } else *************** *** 7886,7892 **** basetype :: member . */ ! if (TYPE_MAIN_VARIANT (ctype) == current_class_type || friendp) { ! if (TREE_CODE (type) == FUNCTION_TYPE) type = build_cplus_method_type (build_type_variant (ctype, constp, volatilep), TREE_TYPE (type), TYPE_ARG_TYPES (type)); --- 8507,8515 ---- basetype :: member . */ ! if (TREE_CODE (type) == FUNCTION_TYPE) { ! if (current_class_type == NULL_TREE ! || TYPE_MAIN_VARIANT (ctype) == current_class_type ! || friendp) type = build_cplus_method_type (build_type_variant (ctype, constp, volatilep), TREE_TYPE (type), TYPE_ARG_TYPES (type)); *************** *** 7893,7910 **** else { ! if (TYPE_MAIN_VARIANT (ctype) != current_class_type) ! { ! error ("cannot declare member `%s::%s' within this class", ! TYPE_NAME_STRING (ctype), name); ! return void_type_node; ! } ! else if (extra_warnings) ! warning ("extra qualification `%s' on member `%s' ignored", ! TYPE_NAME_STRING (ctype), name); ! type = build_offset_type (ctype, type); } } else if (TYPE_SIZE (ctype) != NULL_TREE ! || (specbits & RIDBIT (RID_TYPEDEF))) { tree t; --- 8516,8533 ---- else { ! error ("cannot declare member function `%s::%s' within this class", ! TYPE_NAME_STRING (ctype), name); ! return void_type_node; } } + else if (TYPE_MAIN_VARIANT (ctype) == current_class_type) + { + if (extra_warnings) + warning ("extra qualification `%s' on member `%s' ignored", + TYPE_NAME_STRING (ctype), name); + type = build_offset_type (ctype, type); + } else if (TYPE_SIZE (ctype) != NULL_TREE ! || (RIDBIT_SETP (RID_TYPEDEF, specbits))) { tree t; *************** *** 7945,7973 **** if (flags == TYPENAME_FLAG) ! error_with_aggr_type (ctype, "type conversion is not a member of structure `%s'"); else ! error ("field `%s' is not a member of structure `%s'", ! IDENTIFIER_POINTER (sname), ! TYPE_NAME_STRING (ctype)); } ! if (TREE_CODE (type) == FUNCTION_TYPE) ! type = build_cplus_method_type (build_type_variant (ctype, constp, volatilep), ! TREE_TYPE (type), TYPE_ARG_TYPES (type)); ! else { ! if (current_class_type) { ! if (TYPE_MAIN_VARIANT (ctype) != current_class_type) ! { ! error ("cannot declare member `%s::%s' within this class", ! TYPE_NAME_STRING (ctype), name); ! return void_type_node; ! } ! else if (extra_warnings) ! warning ("extra qualification `%s' on member `%s' ignored", ! TYPE_NAME_STRING (ctype), name); } ! type = build_offset_type (ctype, type); } } else if (uses_template_parms (ctype)) --- 8568,8591 ---- if (flags == TYPENAME_FLAG) ! cp_error ("type conversion is not a member of structure `%T'", ctype); else ! cp_error ! ("field `%D' is not a member of structure `%T'", ! sname, ctype); } ! ! if (current_class_type) { ! if (TYPE_MAIN_VARIANT (ctype) != current_class_type) { ! cp_error ("cannot declare member `%T::%s' within this class", ! ctype, name); ! return void_type_node; } ! else if (extra_warnings) ! cp_warning ("extra qualification `%T' on member `%s' ignored", ! ctype, name); } + type = build_offset_type (ctype, type); } else if (uses_template_parms (ctype)) *************** *** 7983,7988 **** } else ! sorry ("structure `%s' not yet defined", ! TYPE_NAME_STRING (ctype)); declarator = sname; } --- 8601,8609 ---- } else ! { ! cp_error ("structure `%T' not yet defined", ctype); ! return error_mark_node; ! } ! declarator = sname; } *************** *** 8036,8045 **** declarator = grokoptypename (declarator, 0); if (explicit_int != -1) ! if (comp_target_types (type, ! TREE_TYPE (TREE_OPERAND (declarator, 0)), ! 1) == 0) ! error ("type conversion function declared to return incongruent type"); ! else ! pedwarn ("return type specified for type conversion function"); type = TREE_TYPE (TREE_OPERAND (declarator, 0)); maybe_globalize_type (type); --- 8657,8668 ---- declarator = grokoptypename (declarator, 0); if (explicit_int != -1) ! { ! if (comp_target_types (type, ! TREE_TYPE (TREE_OPERAND (declarator, 0)), ! 1) == 0) ! error ("type conversion function declared to return incongruent type"); ! else ! pedwarn ("return type specified for type conversion function"); ! } type = TREE_TYPE (TREE_OPERAND (declarator, 0)); maybe_globalize_type (type); *************** *** 8065,8069 **** /* If this is declaring a typedef name, return a TYPE_DECL. */ ! if (specbits & RIDBIT (RID_TYPEDEF)) { tree decl; --- 8688,8692 ---- /* If this is declaring a typedef name, return a TYPE_DECL. */ ! if (RIDBIT_SETP (RID_TYPEDEF, specbits)) { tree decl; *************** *** 8078,8082 **** refer to it, so nothing needs know about the name change. The TYPE_NAME field was filled in by build_struct_xref. */ ! if (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL && ANON_AGGRNAME_P (TYPE_IDENTIFIER (type))) --- 8701,8706 ---- refer to it, so nothing needs know about the name change. The TYPE_NAME field was filled in by build_struct_xref. */ ! if (type != error_mark_node ! && TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL && ANON_AGGRNAME_P (TYPE_IDENTIFIER (type))) *************** *** 8092,8101 **** decl = build_decl (TYPE_DECL, declarator, type); #endif ! if (quals) { if (ctype == NULL_TREE) { if (TREE_CODE (type) != METHOD_TYPE) ! error_with_decl (decl, "invalid type qualifier for non-method type"); else ctype = TYPE_METHOD_BASETYPE (type); --- 8716,8730 ---- decl = build_decl (TYPE_DECL, declarator, type); #endif ! if (TREE_CODE (type) == OFFSET_TYPE || TREE_CODE (type) == METHOD_TYPE) { + cp_error_at ("typedef name may not be class-qualified", decl); + TREE_TYPE (decl) = error_mark_node; + } + else if (quals) + { if (ctype == NULL_TREE) { if (TREE_CODE (type) != METHOD_TYPE) ! cp_error_at ("invalid type qualifier for non-method type", decl); else ctype = TYPE_METHOD_BASETYPE (type); *************** *** 8105,8112 **** } ! if ((specbits & RIDBIT (RID_SIGNED)) || (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl))) C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1; return decl; } --- 8734,8746 ---- } ! if (RIDBIT_SETP (RID_SIGNED, specbits) || (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl))) C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1; + if (RIDBIT_SETP (RID_MUTABLE, specbits)) + { + error ("non-object member `%s' cannot be declared mutable", name); + } + return decl; } *************** *** 8197,8202 **** if (ctype) error ("cannot use `::' in parameter declaration"); - bad_specifiers ("parameter", virtualp, quals != NULL_TREE, - friendp, raises != NULL_TREE); /* A parameter declared as an array of T is really a pointer to T. --- 8831,8834 ---- *************** *** 8236,8239 **** --- 8868,8874 ---- decl = build_decl (PARM_DECL, declarator, type); + bad_specifiers (decl, "parameter", virtualp, quals != NULL_TREE, + inlinep, friendp, raises != NULL_TREE); + /* Compute the type actually passed in the parmlist, for the case where there is no prototype. *************** *** 8309,8313 **** /* Tell grokfndecl if it needs to set TREE_PUBLIC on the node. */ ! publicp = ((specbits & RIDBIT (RID_EXTERN)) || (ctype != NULL_TREE && funcdef_flag >= 0) #if 0 --- 8944,8948 ---- /* Tell grokfndecl if it needs to set TREE_PUBLIC on the node. */ ! publicp = (RIDBIT_SETP (RID_EXTERN, specbits) || (ctype != NULL_TREE && funcdef_flag >= 0) #if 0 *************** *** 8315,8320 **** set TREE_PUBLIC. */ || (friendp ! && !(specbits & RIDBIT (RID_STATIC)) ! && !(specbits & RIDBIT (RID_INLINE))) #endif ); --- 8950,8955 ---- set TREE_PUBLIC. */ || (friendp ! && RIDBIT_NOTSETP (RID_STATIC, specbits) ! && RIDBIT_NOTSETP (RID_INLINE, specbits)) #endif ); *************** *** 8356,8360 **** instantiation made the field's type be incomplete. */ if (current_class_type ! && IDENTIFIER_TEMPLATE (current_class_type) && declspecs && TREE_VALUE (declspecs) && TREE_TYPE (TREE_VALUE (declspecs)) == type) --- 8991,8996 ---- instantiation made the field's type be incomplete. */ if (current_class_type ! && TYPE_NAME (current_class_type) ! && IDENTIFIER_TEMPLATE (DECL_NAME (TYPE_NAME (current_class_type))) && declspecs && TREE_VALUE (declspecs) && TREE_TYPE (TREE_VALUE (declspecs)) == type) *************** *** 8398,8402 **** last_function_parms, flags, quals); } ! else return void_type_node; } --- 9034,9039 ---- last_function_parms, flags, quals); } ! else ! return void_type_node; } *************** *** 8405,8411 **** if (decl == NULL_TREE) { - bad_specifiers ("field", virtualp, quals != NULL_TREE, - friendp, raises != NULL_TREE); - /* ANSI C++ June 5 1992 WP 9.2.2 and 9.4.2. A member-declarator cannot have an initializer, and a static member declaration must --- 9042,9045 ---- *************** *** 8443,8447 **** } else ! decl = build_lang_field_decl (FIELD_DECL, declarator, type); } } --- 9077,9091 ---- } else ! { ! decl = build_lang_field_decl (FIELD_DECL, declarator, type); ! if (RIDBIT_SETP (RID_MUTABLE, specbits)) ! { ! DECL_MUTABLE_P (decl) = 1; ! RIDBIT_RESET (RID_MUTABLE, specbits); ! } ! } ! ! bad_specifiers (decl, "field", virtualp, quals != NULL_TREE, ! inlinep, friendp, raises != NULL_TREE); } } *************** *** 8452,8459 **** int publicp = 0; ! if (! declarator) return NULL_TREE; ! if (specbits & (RIDBIT (RID_AUTO) | RIDBIT (RID_REGISTER))) error ("invalid storage class for function `%s'", name); /* Function declaration not at top level. Storage classes other than `extern' are not allowed --- 9096,9106 ---- int publicp = 0; ! if (! declarator) ! return NULL_TREE; ! if (RIDBIT_SETP (RID_AUTO, specbits) ! || RIDBIT_SETP (RID_REGISTER, specbits)) error ("invalid storage class for function `%s'", name); + /* Function declaration not at top level. Storage classes other than `extern' are not allowed *************** *** 8460,8464 **** and `extern' makes no difference. */ if (current_binding_level != global_binding_level ! && (specbits & (RIDBIT (RID_STATIC) | RIDBIT (RID_INLINE))) && pedantic) pedwarn ("invalid storage class for function `%s'", name); --- 9107,9111 ---- and `extern' makes no difference. */ if (current_binding_level != global_binding_level ! && (RIDBIT_SETP (RID_STATIC, specbits) || RIDBIT_SETP (RID_INLINE, specbits)) && pedantic) pedwarn ("invalid storage class for function `%s'", name); *************** *** 8472,8479 **** } ! /* ARM $13.4.3 */ ! /* XXX: It's likely others should also be forbidden. (bpk) */ ! if (declarator == ansi_opname[(int) MODIFY_EXPR]) ! warning ("operator `=' must be a member function"); if (current_lang_name == lang_name_cplusplus --- 9119,9132 ---- } ! /* ARM $13.4.3: operator= must be a nonstatic member fn. ! ARM $13.4.4: operator() must be a nonstatic member fn. ! ARM $13.4.5: operator[] must be a nonstatic member fn. ! ARM $13.4.6: operator-> must be a nonstatic member fn. */ ! if (declarator == ansi_opname[(int) MODIFY_EXPR] ! || declarator == ansi_opname[(int) CALL_EXPR] ! || declarator == ansi_opname[(int) ARRAY_REF] ! || declarator == ansi_opname[(int) COMPONENT_REF]) ! pedwarn ("`operator %s' must be a member function", ! operator_name_string (declarator)); if (current_lang_name == lang_name_cplusplus *************** *** 8500,8507 **** publicp = ((ctype ! && ! CLASSTYPE_INTERFACE_UNKNOWN (ctype) && ! CLASSTYPE_INTERFACE_ONLY (ctype)) ! || !(specbits & (RIDBIT (RID_STATIC) ! | RIDBIT (RID_INLINE)))); decl = grokfndecl (ctype, type, original_name, --- 9153,9160 ---- publicp = ((ctype ! && CLASSTYPE_INTERFACE_KNOWN (ctype) && ! CLASSTYPE_INTERFACE_ONLY (ctype)) ! || !(RIDBIT_SETP (RID_STATIC, specbits) ! || RIDBIT_SETP (RID_INLINE, specbits))); decl = grokfndecl (ctype, type, original_name, *************** *** 8511,8515 **** publicp); ! if (ctype == NULL_TREE) DECL_ASSEMBLER_NAME (decl) = declarator; --- 9164,9168 ---- publicp); ! if (ctype == NULL_TREE && DECL_LANGUAGE (decl) != lang_c) DECL_ASSEMBLER_NAME (decl) = declarator; *************** *** 8522,8527 **** if (TREE_CODE (type) == METHOD_TYPE) { ! error_with_decl (decl, ! "cannot declare member function `%s' to have static linkage"); illegal_static = 1; } --- 9175,9179 ---- if (TREE_CODE (type) == METHOD_TYPE) { ! cp_error_at ("cannot declare member function `%D' to have static linkage", decl); illegal_static = 1; } *************** *** 8539,8543 **** { staticp = 0; ! specbits &= ~ RIDBIT (RID_STATIC); } } --- 9191,9195 ---- { staticp = 0; ! RIDBIT_RESET (RID_STATIC, specbits); } } *************** *** 8553,8557 **** warning ("cannot inline function `main'"); else if (last && last != void_list_node) ! warning ("inline declaration ignored for function with `...'"); else /* Assume that otherwise the function can be inlined. */ --- 9205,9209 ---- warning ("cannot inline function `main'"); else if (last && last != void_list_node) ! cp_warning ("cannot inline function `%D' which takes `...'", original_name); else /* Assume that otherwise the function can be inlined. */ *************** *** 8558,8568 **** DECL_INLINE (decl) = 1; ! if (specbits & RIDBIT (RID_EXTERN)) { current_extern_inline = 1; ! if (pedantic) ! error ("ANSI C++ does not permit `extern inline'"); ! else if (flag_ansi) ! warning ("ANSI C++ does not permit `extern inline'"); } } --- 9210,9218 ---- DECL_INLINE (decl) = 1; ! if (RIDBIT_SETP (RID_EXTERN, specbits)) { current_extern_inline = 1; ! if (flag_ansi || pedantic || flag_pedantic_errors) ! pedwarn ("ANSI C++ does not permit `extern inline'"); } } *************** *** 8574,8584 **** /* It's a variable. */ - bad_specifiers ("variable", virtualp, quals != NULL_TREE, - friendp, raises != NULL_TREE); - if (inlinep) - warning ("variable declared `inline'"); - /* An uninitialized decl with `extern' is a reference. */ decl = grokvardecl (type, declarator, specbits, initialized); if (ctype) { --- 9224,9232 ---- /* It's a variable. */ /* An uninitialized decl with `extern' is a reference. */ decl = grokvardecl (type, declarator, specbits, initialized); + bad_specifiers (decl, "variable", virtualp, quals != NULL_TREE, + inlinep, friendp, raises != NULL_TREE); + if (ctype) { *************** *** 8588,8598 **** lang_printable_name (decl)); staticp = 0; ! specbits &= ~ RIDBIT (RID_STATIC); } ! if (specbits & RIDBIT (RID_EXTERN)) { error ("cannot explicitly declare member `%s' to have extern linkage", lang_printable_name (decl)); ! specbits &= ~ RIDBIT (RID_EXTERN); } } --- 9236,9246 ---- lang_printable_name (decl)); staticp = 0; ! RIDBIT_RESET (RID_STATIC, specbits); } ! if (RIDBIT_SETP (RID_EXTERN, specbits)) { error ("cannot explicitly declare member `%s' to have extern linkage", lang_printable_name (decl)); ! RIDBIT_RESET (RID_EXTERN, specbits); } } *************** *** 8599,8606 **** } /* Record `register' declaration for warnings on & and in case doing stupid register allocation. */ ! if (specbits & RIDBIT (RID_REGISTER)) DECL_REGISTER (decl) = 1; --- 9247,9259 ---- } + if (RIDBIT_SETP (RID_MUTABLE, specbits)) + { + error ("`%s' cannot be declared mutable", name); + } + /* Record `register' declaration for warnings on & and in case doing stupid register allocation. */ ! if (RIDBIT_SETP (RID_REGISTER, specbits)) DECL_REGISTER (decl) = 1; *************** *** 8871,8875 **** DECL_ARG_TYPE (decl) = TREE_TYPE (decl); #ifdef PROMOTE_PROTOTYPES ! if (C_PROMOTING_INTEGER_TYPE_P (type)) DECL_ARG_TYPE (decl) = integer_type_node; #endif --- 9524,9530 ---- DECL_ARG_TYPE (decl) = TREE_TYPE (decl); #ifdef PROMOTE_PROTOTYPES ! if ((TREE_CODE (type) == INTEGER_TYPE ! || TREE_CODE (type) == ENUMERAL_TYPE) ! && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)) DECL_ARG_TYPE (decl) = integer_type_node; #endif *************** *** 8890,8894 **** considered a local variable, then this code is wrong. */ ! error_with_decl (init, "local variable `%s' may not be used as a default argument"); any_error = 1; } --- 9545,9549 ---- considered a local variable, then this code is wrong. */ ! cp_error ("local variable `%D' may not be used as a default argument", init); any_error = 1; } *************** *** 8957,8961 **** /* These memoizing functions keep track of special properties which a class may have. `grok_ctor_properties' notices whether a class ! has a constructor of the for X(X&), and also complains if the class has a constructor of the form X(X). `grok_op_properties' takes notice of the various forms of --- 9612,9616 ---- /* These memoizing functions keep track of special properties which a class may have. `grok_ctor_properties' notices whether a class ! has a constructor of the form X(X&), and also complains if the class has a constructor of the form X(X). `grok_op_properties' takes notice of the various forms of *************** *** 8969,8975 **** tree parmtype = parmtypes ? TREE_VALUE (parmtypes) : void_type_node; ! if (parmtypes && TREE_CHAIN (parmtypes) ! && TREE_CODE (TREE_VALUE (TREE_CHAIN (parmtypes))) == REFERENCE_TYPE ! && TYPE_USES_VIRTUAL_BASECLASSES (TREE_TYPE (TREE_VALUE (TREE_CHAIN (parmtypes))))) { parmtypes = TREE_CHAIN (parmtypes); --- 9624,9634 ---- tree parmtype = parmtypes ? TREE_VALUE (parmtypes) : void_type_node; ! /* When a type has virtual baseclasses, a magical first int argument is ! added to any ctor so we can tell if the class has been initialized ! yet. This could screw things up in this function, so we deliberately ! ignore the leading int if we're in that situation. */ ! if (parmtypes ! && TREE_VALUE (parmtypes) == integer_type_node ! && TYPE_USES_VIRTUAL_BASECLASSES (ctype)) { parmtypes = TREE_CHAIN (parmtypes); *************** *** 9045,9049 **** } else ! error_with_decl (decl, "`%s' cannot be a static member function"); } else if (DECL_NAME (decl) == ansi_opname[(int) MODIFY_EXPR]) --- 9704,9708 ---- } else ! cp_error ("`%D' cannot be a static member function", decl); } else if (DECL_NAME (decl) == ansi_opname[(int) MODIFY_EXPR]) *************** *** 9054,9058 **** if (argtypes == NULL_TREE) { ! error_with_decl (decl, "too few arguments to `%s'"); return; } --- 9713,9717 ---- if (argtypes == NULL_TREE) { ! cp_error ("too few arguments to `%D'", decl); return; } *************** *** 9119,9123 **** #endif rv = xref_tag (code_type_node, name, binfo); ! pushdecl_top_level (build_lang_decl (TYPE_DECL, ncp, rv)); } else --- 9778,9792 ---- #endif rv = xref_tag (code_type_node, name, binfo); ! { ! register tree type_decl = build_lang_decl (TYPE_DECL, ncp, rv); ! #ifdef DWARF_DEBUGGING_INFO ! /* Mark the TYPE_DECL node created just above as a gratuitous one ! so that dwarfout.c will know not to generate a TAG_typedef DIE ! for it. */ ! if (write_symbols == DWARF_DEBUG) ! DECL_IGNORED_P (type_decl) = 1; ! #endif /* DWARF_DEBUGGING_INFO */ ! pushdecl_top_level (type_decl); ! } } else *************** *** 9262,9267 **** break; case 3: ! needs_writing ! = ! (CLASSTYPE_INTERFACE_ONLY (ref) || CLASSTYPE_INTERFACE_UNKNOWN (ref)); break; default: --- 9931,9936 ---- break; case 3: ! needs_writing = ! CLASSTYPE_INTERFACE_ONLY (ref) ! && CLASSTYPE_INTERFACE_KNOWN (ref); break; default: *************** *** 9364,9368 **** else if (TYPE_SIZE (basetype) == NULL_TREE) { ! error_with_aggr_type (basetype, "base class `%s' has incomplete type"); continue; } --- 10033,10037 ---- else if (TYPE_SIZE (basetype) == NULL_TREE) { ! cp_error ("base class `%T' has incomplete type", basetype); continue; } *************** *** 9373,9379 **** { if (basetype == ref) ! error_with_aggr_type (basetype, "recursive type `%s' undefined"); else ! error_with_aggr_type (basetype, "duplicate base type `%s' invalid"); continue; } --- 10042,10048 ---- { if (basetype == ref) ! cp_error ("recursive type `%T' undefined", basetype); else ! cp_error ("duplicate base type `%T' invalid", basetype); continue; } *************** *** 9532,9536 **** register tree enumtype, values; { ! register tree pair; register HOST_WIDE_INT maxvalue = 0; register HOST_WIDE_INT minvalue = 0; --- 10201,10205 ---- register tree enumtype, values; { ! register tree pair, tem; register HOST_WIDE_INT maxvalue = 0; register HOST_WIDE_INT minvalue = 0; *************** *** 9589,9592 **** --- 10258,10274 ---- cadillac_finish_enum (enumtype); + /* Fix up all variant types of this enum type. */ + for (tem = TYPE_MAIN_VARIANT (enumtype); tem; tem = TYPE_NEXT_VARIANT (tem)) + { + TYPE_VALUES (tem) = TYPE_VALUES (enumtype); + TYPE_MIN_VALUE (tem) = TYPE_MIN_VALUE (enumtype); + TYPE_MAX_VALUE (tem) = TYPE_MAX_VALUE (enumtype); + TYPE_SIZE (tem) = TYPE_SIZE (enumtype); + TYPE_MODE (tem) = TYPE_MODE (enumtype); + TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype); + TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype); + TREE_UNSIGNED (tem) = TREE_UNSIGNED (enumtype); + } + /* Finish debugging output for this type. */ #if 0 *************** *** 9626,9630 **** } ! if (TREE_CODE (value) != INTEGER_CST) { error ("enumerator value for `%s' not integer constant", --- 10308,10314 ---- } ! if (TREE_CODE (value) == INTEGER_CST) ! constant_expression_warning (value); ! else { error ("enumerator value for `%s' not integer constant", *************** *** 9633,9636 **** --- 10317,10321 ---- } } + /* The order of things is reversed here so that we can check for possible sharing of enum values, *************** *** 9670,9675 **** GNU_xref_decl (current_function_decl, decl); } ! if (current_class_type) { /* class-local enum declaration */ --- 10355,10363 ---- GNU_xref_decl (current_function_decl, decl); } ! #if NEW_CLASS_SCOPING ! else if (current_class_type) ! #else if (current_class_type) + #endif { /* class-local enum declaration */ *************** *** 9783,9786 **** --- 10471,10488 ---- { decl1 = declarator; + + if (! DECL_ARGUMENTS (decl1) + && !DECL_STATIC_FUNCTION_P (decl1) + && DECL_CONTEXT (decl1) + && DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl1))) + && IDENTIFIER_TEMPLATE (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl1))))) + { + cp_error ("redeclaration of `%#D'", decl1); + if (IDENTIFIER_CLASS_VALUE (DECL_NAME (decl1))) + cp_error_at ("previous declaration here", IDENTIFIER_CLASS_VALUE (DECL_NAME (decl1))); + else if (IDENTIFIER_GLOBAL_VALUE (DECL_NAME (decl1))) + cp_error_at ("previous declaration here", IDENTIFIER_GLOBAL_VALUE (DECL_NAME (decl1))); + } + last_function_parms = DECL_ARGUMENTS (decl1); last_function_parm_tags = NULL_TREE; *************** *** 9825,9832 **** restype = TREE_TYPE (fntype); ! if (IS_AGGR_TYPE (restype) && ! CLASSTYPE_GOT_SEMICOLON (restype)) { ! error_with_aggr_type (restype, "semicolon missing after declaration of `%s'"); shadow_tag (build_tree_list (NULL_TREE, restype)); CLASSTYPE_GOT_SEMICOLON (restype) = 1; --- 10527,10534 ---- restype = TREE_TYPE (fntype); ! if (IS_AGGR_TYPE (restype) && ! TYPE_PTRMEMFUNC_P (restype) && ! CLASSTYPE_GOT_SEMICOLON (restype)) { ! cp_error ("semicolon missing after declaration of `%#T'", restype); shadow_tag (build_tree_list (NULL_TREE, restype)); CLASSTYPE_GOT_SEMICOLON (restype) = 1; *************** *** 9861,9866 **** if (! warn_implicit && IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1)) != NULL_TREE) ! warning_with_decl (IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1)), ! "`%s' implicitly declared before its definition"); current_function_decl = decl1; --- 10563,10567 ---- if (! warn_implicit && IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1)) != NULL_TREE) ! cp_warning_at ("`%D' implicitly declared before its definition", IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1))); current_function_decl = decl1; *************** *** 9926,9931 **** DECL_EXTERNAL (decl1) = current_extern_inline; ! /* Now see if this is the implementation of a function ! declared with "C" linkage. */ if (ctype == NULL_TREE && current_lang_name == lang_name_cplusplus && !DECL_CONTEXT (decl1)) --- 10627,10631 ---- DECL_EXTERNAL (decl1) = current_extern_inline; ! /* Now see if this is the implementation of a declared function. */ if (ctype == NULL_TREE && current_lang_name == lang_name_cplusplus && !DECL_CONTEXT (decl1)) *************** *** 9952,9960 **** DECL_ASSEMBLER_NAME (decl1) = DECL_ASSEMBLER_NAME (olddecl); DECL_OVERLOADED (decl1) = DECL_OVERLOADED (olddecl); ! if (DECL_INITIAL (olddecl)) redeclaration_error_message (decl1, olddecl); ! if (! duplicate_decls (decl1, olddecl)) ! my_friendly_abort (19); ! decl1 = olddecl; } else --- 10652,10661 ---- DECL_ASSEMBLER_NAME (decl1) = DECL_ASSEMBLER_NAME (olddecl); DECL_OVERLOADED (decl1) = DECL_OVERLOADED (olddecl); ! if (! DECL_BUILT_IN (olddecl) && DECL_INITIAL (olddecl)) redeclaration_error_message (decl1, olddecl); ! if (duplicate_decls (decl1, olddecl)) ! decl1 = olddecl; ! else ! olddecl = NULL_TREE; } else *************** *** 10017,10021 **** --- 10718,10726 ---- if (ctype) { + #if NEW_CLASS_SCOPING + push_nested_class (ctype, 1); + #else pushclass (ctype, 1); + #endif /* If we're compiling a friend function, neither of the variables *************** *** 10059,10063 **** --- 10764,10772 ---- { if (DECL_STATIC_FUNCTION_P (decl1)) + #if NEW_CLASS_SCOPING + push_nested_class (DECL_CONTEXT (decl1), 2); + #else pushclass (DECL_CONTEXT (decl1), 2); + #endif else push_memoized_context (0, 1); *************** *** 10174,10178 **** { #if 0 ! error_with_decl (parm, "parameter name omitted"); #else /* for C++, this is not an error. */ --- 10883,10887 ---- { #if 0 ! cp_error_at ("parameter name omitted", parm); #else /* for C++, this is not an error. */ *************** *** 10181,10185 **** } else if (TYPE_MAIN_VARIANT (TREE_TYPE (parm)) == void_type_node) ! error_with_decl (parm, "parameter `%s' declared void"); else { --- 10890,10894 ---- } else if (TYPE_MAIN_VARIANT (TREE_TYPE (parm)) == void_type_node) ! cp_error ("parameter `%D' declared void", parm); else { *************** *** 10379,10393 **** init = build (COMPONENT_REF, TREE_TYPE (fields), parm, fields); ! ! if (TREE_ANON_UNION_ELEM (fields)) ! name = build (COMPONENT_REF, TREE_TYPE (fields), C_C_D, fields); ! else ! { ! name = DECL_NAME (fields); ! init = build_tree_list (NULL_TREE, init); ! } current_member_init_list ! = tree_cons (name, init, current_member_init_list); } } --- 11088,11095 ---- init = build (COMPONENT_REF, TREE_TYPE (fields), parm, fields); ! init = build_tree_list (NULL_TREE, init); current_member_init_list ! = tree_cons (DECL_NAME (fields), init, current_member_init_list); } } *************** *** 10394,10397 **** --- 11096,11113 ---- + /* Get the binfo associated with the vfield. */ + + tree + get_binfo_from_vfield (vfield) + tree vfield; + { + if (VF_BINFO_VALUE (vfield)) + return VF_BINFO_VALUE (vfield); + /* Not sure where it is. maybe get_binfo on + VF_BASETYPE_VALUE (vfield), VF_DERIVED_VALUE (vfield)... */ + my_friendly_abort (350); + return NULL_TREE; + } + /* Finish up a function declaration and compile that function all the way to assembler language output. The free the storage *************** *** 10490,10493 **** --- 11206,11210 ---- the binding level of the parms. */ pushlevel (0); + expand_start_bindings (0); if (current_function_assigns_this) *************** *** 10510,10517 **** || TREE_GETS_DELETE (current_class_type)) exprstmt = build_delete (current_class_type, C_C_D, integer_zero_node, ! LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0, 0); else exprstmt = build_delete (current_class_type, C_C_D, in_charge_node, ! LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0, 0); /* If we did not assign to this, then `this' is non-zero at --- 11227,11234 ---- || TREE_GETS_DELETE (current_class_type)) exprstmt = build_delete (current_class_type, C_C_D, integer_zero_node, ! LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0); else exprstmt = build_delete (current_class_type, C_C_D, in_charge_node, ! LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0); /* If we did not assign to this, then `this' is non-zero at *************** *** 10547,10551 **** expand_expr_stmt (build_delete (TYPE_POINTER_TO (BINFO_TYPE (vbases)), ptr, integer_zero_node, ! LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR|LOOKUP_HAS_IN_CHARGE, 0, 0)); } vbases = TREE_CHAIN (vbases); --- 11264,11268 ---- expand_expr_stmt (build_delete (TYPE_POINTER_TO (BINFO_TYPE (vbases)), ptr, integer_zero_node, ! LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR|LOOKUP_HAS_IN_CHARGE, 0)); } vbases = TREE_CHAIN (vbases); *************** *** 10590,10594 **** /* End of destructor. */ ! poplevel (2, 0, 0); /* Back to the top of destructor. */ --- 11307,11312 ---- /* End of destructor. */ ! expand_end_bindings (NULL_TREE, 1, 0); ! poplevel (2, 0, 0); /* XXX change to 1 */ /* Back to the top of destructor. */ *************** *** 10616,10629 **** if (vf_decl != error_mark_node) { - /* It is one of these two, or a combination... */ - /* basically speaking, I want to get down to the right - VF_BASETYPE_VALUE (vfields) */ - #if 0 - if (VF_NORMAL_VALUE (vfields) != VF_DERIVED_VALUE (vfields)) - warning ("hum, wonder if I am doing the right thing"); - #endif expand_expr_stmt (build_virtual_init (binfo, ! get_binfo (VF_BASETYPE_VALUE (vfields), ! get_binfo (VF_DERIVED_VALUE (vfields), binfo, 0), 0), vf_decl)); } --- 11334,11339 ---- if (vf_decl != error_mark_node) { expand_expr_stmt (build_virtual_init (binfo, ! get_binfo_from_vfield (vfields), vf_decl)); } *************** *** 10715,10719 **** : build_delete (TREE_TYPE (allocated_this), allocated_this, integer_three_node, ! LOOKUP_NORMAL|LOOKUP_HAS_IN_CHARGE, 1, 0); cleanup_deallocate = build_modify_expr (current_class_decl, NOP_EXPR, integer_zero_node); --- 11425,11429 ---- : build_delete (TREE_TYPE (allocated_this), allocated_this, integer_three_node, ! LOOKUP_NORMAL|LOOKUP_HAS_IN_CHARGE, 1); cleanup_deallocate = build_modify_expr (current_class_decl, NOP_EXPR, integer_zero_node); *************** *** 10769,10774 **** we don't hold on to it (across emit_base_init). */ last_parm_insn = get_first_nonparm_insn (); ! if (last_parm_insn == NULL_RTX) last_parm_insn = mark; ! else last_parm_insn = previous_insn (last_parm_insn); if (mark != get_last_insn ()) --- 11479,11486 ---- we don't hold on to it (across emit_base_init). */ last_parm_insn = get_first_nonparm_insn (); ! if (last_parm_insn == NULL_RTX) ! last_parm_insn = mark; ! else ! last_parm_insn = previous_insn (last_parm_insn); if (mark != get_last_insn ()) *************** *** 10875,10879 **** expand_end_except (); } - expand_end_bindings (0, 0, 0); /* Get return value into register if that's where it's supposed to be. */ --- 11587,11590 ---- *************** *** 10901,10905 **** --- 11612,11620 ---- { ctype = current_class_type; + #if NEW_CLASS_SCOPING + pop_nested_class (1); + #else popclass (1); + #endif } else *************** *** 10917,10920 **** --- 11632,11636 ---- /* Generate rtl for function exit. */ expand_function_end (input_filename, lineno); + expand_end_bindings (0, 0, 0); /* This must come after expand_function_end because cleanups might *************** *** 11071,11075 **** { if (DECL_CONTEXT (fndecl)) ! error_with_decl (fndecl, "`%s' is already defined in class %s", TYPE_NAME_STRING (DECL_CONTEXT (fndecl))); } --- 11787,11791 ---- { if (DECL_CONTEXT (fndecl)) ! cp_error ("`%D' is already defined in class %s", fndecl, TYPE_NAME_STRING (DECL_CONTEXT (fndecl))); } *************** *** 11146,11155 **** return decl; - #ifdef DEBUG_CP_BINDING_LEVELS - indent_to (stderr, debug_bindings_indentation); - fprintf (stderr, "finish_method"); - debug_bindings_indentation += 4; - #endif - old_initial = DECL_INITIAL (fndecl); --- 11862,11865 ---- *************** *** 11190,11202 **** current_binding_level->tag_transparent); ! pop_binding_level (); DECL_INITIAL (fndecl) = old_initial; ! #if 0 ! /* tiemann would like this, but is causes String.cc to not compile. */ ! if (DECL_FRIEND_P (fndecl) || DECL_CONTEXT (fndecl) != current_class_type) ! #else if (DECL_FRIEND_P (fndecl)) - #endif { CLASSTYPE_INLINE_FRIENDS (current_class_type) --- 11900,11911 ---- current_binding_level->tag_transparent); ! poplevel (0, 0, 0); DECL_INITIAL (fndecl) = old_initial; ! ! /* We used to check if the context of FNDECL was different from ! current_class_type as another way to get inside here. This didn't work ! for String.cc in libg++. */ if (DECL_FRIEND_P (fndecl)) { CLASSTYPE_INLINE_FRIENDS (current_class_type) *************** *** 11204,11243 **** decl = void_type_node; } - #if 0 - /* Work in progress, 9/17/92. */ - else if (context != current_class_type - && TREE_CHAIN (context) != NULL_TREE - && !DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl))) - { - /* Don't allow them to declare a function like this: - class A { - public: - class B { - public: - int f(); - }; - int B::f() {} - }; - - Note we can get in here if it's a friend (in which case we'll - avoid lots of nasty cruft), or it's a destructor. Compensate. - */ - tree tmp = DECL_ARGUMENTS (TREE_CHAIN (context)); - if (tmp - && TREE_CODE (tmp) == IDENTIFIER_NODE - && TREE_CHAIN (IDENTIFIER_GLOBAL_VALUE (tmp)) - && TREE_CODE (TREE_CHAIN (IDENTIFIER_GLOBAL_VALUE (tmp))) == TYPE_DECL) - { - error_with_decl (decl, - "qualified name used in declaration of `%s'"); - /* Make this node virtually unusable in the end. */ - TREE_CHAIN (decl) = NULL_TREE; - } - } - #endif - - #ifdef DEBUG_CP_BINDING_LEVELS - debug_bindings_indentation -= 4; - #endif return decl; --- 11913,11916 ---- *************** *** 11336,11340 **** rval = build1 (NOP_EXPR, TYPE_POINTER_TO (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (rval)))), rval); ! rval = build_delete (TREE_TYPE (rval), rval, integer_two_node, flags, 0, 0); if (TYPE_USES_VIRTUAL_BASECLASSES (type) --- 12009,12013 ---- rval = build1 (NOP_EXPR, TYPE_POINTER_TO (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (rval)))), rval); ! rval = build_delete (TREE_TYPE (rval), rval, integer_two_node, flags, 0); if (TYPE_USES_VIRTUAL_BASECLASSES (type) *************** *** 11382,11386 **** if (TREE_CODE (exp) == FUNCTION_DECL) { ! warning_with_decl (exp, "reference, not call, to function `%s'"); warning ("at this point in file"); } --- 12055,12059 ---- if (TREE_CODE (exp) == FUNCTION_DECL) { ! cp_warning ("reference, not call, to function `%D'", exp); warning ("at this point in file"); } *************** *** 11503,11507 **** build_delete (TREE_TYPE (addr), decl, lookup_name (in_charge_identifier, 0), ! LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0, 0), integer_zero_node); expand_decl_cleanup (decl, cleanup); --- 12176,12180 ---- build_delete (TREE_TYPE (addr), decl, lookup_name (in_charge_identifier, 0), ! LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0), integer_zero_node); expand_decl_cleanup (decl, cleanup); diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/cp-decl2.c gcc-2.5.0/cp-decl2.c *** gcc-2.4.5/cp-decl2.c Tue Apr 27 01:33:05 1993 --- gcc-2.5.0/cp-decl2.c Fri Oct 8 15:00:37 1993 *************** *** 37,40 **** --- 37,41 ---- extern tree grokdeclarator (); + extern tree get_file_function_name (); static void grok_function_init (); *************** *** 58,64 **** static int global_temp_name_counter; - /* The (assembler) name of the first globally-visible object output. */ - extern char * first_global_object_name; - /* Flag used when debugging cp-spew.c */ --- 59,62 ---- *************** *** 102,105 **** --- 100,108 ---- int flag_ansi = 0; + /* Nonzero means do argument matching for overloading according to the + ANSI rules, rather than what g++ used to believe to be correct. */ + + int flag_ansi_overloading = 0; + /* Nonzero means do emit exported implementations of functions even if they can be inlined. */ *************** *** 107,110 **** --- 110,118 ---- int flag_implement_inlines = 1; + /* Nonzero means do emit exported implementations of templates, instead of + multiple static copies in each file that needs a definition. */ + + int flag_external_templates = 0; + /* Nonzero means warn about implicit declarations. */ *************** *** 111,114 **** --- 119,127 ---- int warn_implicit = 1; + /* Nonzero means warn when all ctors or dtors are private, and the class + has no friends. */ + + int warn_ctor_dtor_privacy = 1; + /* Like `warn_return_type', but this is set by users, whereas `warn_return_type' is set by the compiler. */ *************** *** 155,158 **** --- 168,175 ---- int warn_redundant_decls; + /* Warn if initializer is not completely bracketed. */ + + int warn_missing_braces; + /* Warn about *printf or *scanf format/argument anomalies. */ *************** *** 161,165 **** /* Warn about a subscript that has type char. */ ! int warn_char_subscripts = 0; /* Warn if a type conversion is done that might have confusing results. */ --- 178,182 ---- /* Warn about a subscript that has type char. */ ! int warn_char_subscripts; /* Warn if a type conversion is done that might have confusing results. */ *************** *** 239,247 **** int flag_elide_constructors; - /* Same, but for inline functions: nonzero means write out debug info - for inlines. Zero means do not. */ - - int flag_inline_debug; - /* Nonzero means recognize and handle exception handling constructs. 2 means handle exceptions the way Spring wants them handled. */ --- 256,259 ---- *************** *** 318,322 **** {"memoize-lookups", &flag_memoize_lookups, 1}, {"elide-constructors", &flag_elide_constructors, 1}, - {"inline-debug", &flag_inline_debug, 0}, {"handle-exceptions", &flag_handle_exceptions, 1}, {"ansi-exceptions", &flag_ansi_exceptions, 1}, --- 330,333 ---- *************** *** 330,333 **** --- 341,346 ---- {"nonnull-objects", &flag_assume_nonnull_objects, 1}, {"implement-inlines", &flag_implement_inlines, 1}, + {"external-templates", &flag_external_templates, 1}, + {"ansi-overloading", &flag_ansi_overloading, 1}, }; *************** *** 439,442 **** --- 452,457 ---- else if (!strcmp (p, "return-type")) explicit_warn_return_type = setting; + else if (!strcmp (p, "ctor-dtor-privacy")) + warn_ctor_dtor_privacy = setting; else if (!strcmp (p, "write-strings")) warn_write_strings = setting; *************** *** 455,458 **** --- 470,475 ---- else if (!strcmp (p, "redundant-decls")) warn_redundant_decls = setting; + else if (!strcmp (p, "missing-braces")) + warn_missing_braces = setting; else if (!strcmp (p, "format")) warn_format = setting; *************** *** 475,479 **** --- 492,498 ---- warn_unused = setting; warn_implicit = setting; + warn_ctor_dtor_privacy = setting; warn_switch = setting; + warn_missing_braces = setting; /* We save the value of warn_uninitialized, since if they put -Wuninitialized on the command line, we need to generate a *************** *** 568,572 **** if (DECL_NAME (decl) && TREE_CODE (DECL_NAME (decl)) == IDENTIFIER_NODE) { ! char *n = decl_as_string (DECL_NAME (decl)); if (n[strlen (n) - 1] == ' ') n[strlen (n) - 1] = 0; --- 587,591 ---- if (DECL_NAME (decl) && TREE_CODE (DECL_NAME (decl)) == IDENTIFIER_NODE) { ! char *n = decl_as_string (DECL_NAME (decl), 1); if (n[strlen (n) - 1] == ' ') n[strlen (n) - 1] = 0; *************** *** 575,578 **** --- 594,681 ---- } + /* Warn when -fexternal-templates is used and #pragma + interface/implementation is not used all the times it should be, + inform the user. */ + void + warn_if_unknown_interface () + { + static int already_warned = 0; + if (++already_warned == 1) + warning ("templates that are built with -fexternal-templates should be in files that have #pragma interface/implementation"); + } + + /* A subroutine of the parser, to handle a component list. */ + tree + grok_x_components (specs, components) + tree specs, components; + { + register tree t, x; + + /* We just got some friends. They have been recorded elsewhere. */ + if (components == void_type_node) + return NULL_TREE; + + if (components == NULL_TREE) + { + t = groktypename (build_decl_list (specs, NULL_TREE)); + + if (t == NULL_TREE) + { + error ("error in component specification"); + return NULL_TREE; + } + + switch (TREE_CODE (t)) + { + case VAR_DECL: + /* Static anonymous unions come out as VAR_DECLs. */ + if (TREE_CODE (TREE_TYPE (t)) == UNION_TYPE + && ANON_AGGRNAME_P (TYPE_IDENTIFIER (TREE_TYPE (t)))) + return t; + + /* We return SPECS here, because in the parser it was ending + up with not doing anything to $$, which is what SPECS + represents. */ + return specs; + break; + + case RECORD_TYPE: + /* This code may be needed for UNION_TYPEs as + well. */ + if (TYPE_LANG_SPECIFIC (t) + && CLASSTYPE_DECLARED_EXCEPTION (t)) + shadow_tag (specs); + return NULL_TREE; + break; + + case UNION_TYPE: + case ENUMERAL_TYPE: + if (TREE_CODE (t) == UNION_TYPE + && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))) + x = build_lang_field_decl (FIELD_DECL, + NULL_TREE, t); + else if (TREE_CODE (t) == ENUMERAL_TYPE) + x = grok_enum_decls (t, NULL_TREE); + else + x = NULL_TREE; + return x; + break; + + default: + if (t != void_type_node) + error ("empty component declaration"); + return NULL_TREE; + } + } + else + { + t = TREE_TYPE (components); + if (TREE_CODE (t) == ENUMERAL_TYPE && TREE_NONLOCAL_FLAG (t)) + return grok_enum_decls (t, components); + else + return components; + } + } + /* Classes overload their constituent function names automatically. When a function name is declared in a record structure, *************** *** 634,637 **** --- 737,742 ---- of virtual baseclasses or not. */ parm = build_decl (PARM_DECL, in_charge_identifier, integer_type_node); + /* Mark the artificial `__in_chrg' parameter as "artificial". */ + DECL_SOURCE_LINE (parm) = 0; DECL_ARG_TYPE (parm) = integer_type_node; DECL_REGISTER (parm) = 1; *************** *** 668,672 **** arg_types = hash_tree_chain (const_integer_type, void_list_node); ! /* Build the overload name. It will look like e.g. 7Example. */ if (IDENTIFIER_TYPE_VALUE (cname)) dbuf = build_overload_name (IDENTIFIER_TYPE_VALUE (cname), 1, 1); --- 773,778 ---- arg_types = hash_tree_chain (const_integer_type, void_list_node); ! TREE_SIDE_EFFECTS (arg_types) = 1; ! /* Build the overload name. It will look like `7Example'. */ if (IDENTIFIER_TYPE_VALUE (cname)) dbuf = build_overload_name (IDENTIFIER_TYPE_VALUE (cname), 1, 1); *************** *** 674,686 **** dbuf = build_overload_name (TREE_TYPE (IDENTIFIER_LOCAL_VALUE (cname)), 1, 1); else - #if 0 - my_friendly_abort (346); - #else /* Using ctype fixes the `X::Y::~Y()' crash. The cname has no type when it's defined out of the class definition, since poplevel_class wipes ! it out. */ dbuf = build_overload_name (ctype, 1, 1); ! #endif ! buf = (char *)alloca (strlen (dbuf) + sizeof (DESTRUCTOR_DECL_PREFIX)); bcopy (DESTRUCTOR_DECL_PREFIX, buf, len); buf[len] = '\0'; --- 780,788 ---- dbuf = build_overload_name (TREE_TYPE (IDENTIFIER_LOCAL_VALUE (cname)), 1, 1); else /* Using ctype fixes the `X::Y::~Y()' crash. The cname has no type when it's defined out of the class definition, since poplevel_class wipes ! it out. This used to be internal error 346. */ dbuf = build_overload_name (ctype, 1, 1); ! buf = (char *) alloca (strlen (dbuf) + sizeof (DESTRUCTOR_DECL_PREFIX)); bcopy (DESTRUCTOR_DECL_PREFIX, buf, len); buf[len] = '\0'; *************** *** 688,693 **** --- 790,803 ---- DECL_ASSEMBLER_NAME (function) = get_identifier (buf); parm = build_decl (PARM_DECL, in_charge_identifier, const_integer_type); + /* Mark the artificial `__in_chrg' parameter as "artificial". */ + DECL_SOURCE_LINE (parm) = 0; TREE_USED (parm) = 1; + #if 0 + /* We don't need to mark the __in_chrg parameter itself as `const' + since its type is already `const int'. In fact we MUST NOT mark + it as `const' cuz that will screw up the debug info (causing it + to say that the type of __in_chrg is `const const int'). */ TREE_READONLY (parm) = 1; + #endif DECL_ARG_TYPE (parm) = const_integer_type; /* This is the same chain as DECL_ARGUMENTS (...). */ *************** *** 694,698 **** TREE_CHAIN (last_function_parms) = parm; ! TREE_TYPE (function) = build_cplus_method_type (ctype, void_type_node, arg_types); TYPE_HAS_DESTRUCTOR (ctype) = 1; } --- 804,809 ---- TREE_CHAIN (last_function_parms) = parm; ! TREE_TYPE (function) = build_cplus_method_type (ctype, void_type_node, ! arg_types); TYPE_HAS_DESTRUCTOR (ctype) = 1; } *************** *** 703,709 **** if (DECL_CONSTRUCTOR_FOR_VBASE_P (function)) { ! arg_types = hash_tree_chain (integer_type_node, TREE_CHAIN (arg_types)); TREE_TYPE (function) ! = build_cplus_method_type (ctype, TREE_TYPE (TREE_TYPE (function)), arg_types); arg_types = TYPE_ARG_TYPES (TREE_TYPE (function)); } --- 814,823 ---- if (DECL_CONSTRUCTOR_FOR_VBASE_P (function)) { ! arg_types = hash_tree_chain (integer_type_node, ! TREE_CHAIN (arg_types)); TREE_TYPE (function) ! = build_cplus_method_type (ctype, ! TREE_TYPE (TREE_TYPE (function)), ! arg_types); arg_types = TYPE_ARG_TYPES (TREE_TYPE (function)); } *************** *** 726,735 **** substitute_nice_name (function); #endif - - #if 0 - if (flags == TYPENAME_FLAG) - /* Not exactly an IDENTIFIER_TYPE_VALUE. */ - TREE_TYPE (DECL_ASSEMBLER_NAME (function)) = TREE_TYPE (fn_name); - #endif } --- 840,843 ---- *************** *** 740,757 **** } ! /* Generate errors possibly applicable for a given set of specifiers. */ ! void ! bad_specifiers (object, virtualp, quals, friendp, raises) ! char *object; ! int virtualp, quals, friendp, raises; { ! if (virtualp) ! error ("%s declared `virtual'", object); ! if (quals) ! error ("`const' and `volatile' function specifiers invalid in %s declaration"); ! if (friendp) ! error ("invalid friend declaration"); ! if (raises) ! error ("invalid raises declaration"); } --- 848,1015 ---- } ! /* Work on the expr used by alignof (this is only called by the parser). */ ! tree ! grok_alignof (expr) ! tree expr; { ! tree best, t; ! int bestalign; ! ! if (TREE_CODE (expr) == COMPONENT_REF ! && DECL_BIT_FIELD (TREE_OPERAND (expr, 1))) ! error ("`__alignof__' applied to a bit-field"); ! ! if (TREE_CODE (expr) == INDIRECT_REF) ! { ! best = t = TREE_OPERAND (expr, 0); ! 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; ! } ! return c_alignof (TREE_TYPE (TREE_TYPE (best))); ! } ! else ! { ! /* ANSI says arrays and fns are converted inside comma. ! But we can't convert them in build_compound_expr ! because that would break commas in lvalues. ! So do the conversion here if operand was a comma. */ ! if (TREE_CODE (expr) == COMPOUND_EXPR ! && (TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE ! || TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE)) ! expr = default_conversion (expr); ! return c_alignof (TREE_TYPE (expr)); ! } ! } ! ! /* Create an ARRAY_REF, checking for the user doing things backwards ! along the way. */ ! tree ! grok_array_decl (array_expr, index_exp) ! tree array_expr, index_exp; ! { ! tree type = TREE_TYPE (array_expr); ! ! if (type == error_mark_node || index_exp == error_mark_node) ! return error_mark_node; ! if (type == NULL_TREE) ! { ! /* Something has gone very wrong. Assume we are mistakenly reducing ! an expression instead of a declaration. */ ! error ("parser may be lost: is there a '{' missing somewhere?"); ! return NULL_TREE; ! } ! ! if (TREE_CODE (type) == OFFSET_TYPE ! || TREE_CODE (type) == REFERENCE_TYPE) ! type = TREE_TYPE (type); ! ! /* If they have an `operator[]', use that. */ ! if (TYPE_LANG_SPECIFIC (type) ! && TYPE_OVERLOADS_ARRAY_REF (type)) ! return build_opfncall (ARRAY_REF, LOOKUP_NORMAL, ! array_expr, index_exp, NULL_TREE); ! ! /* Otherwise, create an ARRAY_REF for a pointer or array type. */ ! if (TREE_CODE (type) == POINTER_TYPE ! || TREE_CODE (type) == ARRAY_TYPE) ! return build_array_ref (array_expr, index_exp); ! ! /* Woops, looks like they did something like `5[a]' instead of `a[5]'. ! We don't emit a warning or error for this, since it's allowed ! by ARM $8.2.4. */ ! ! type = TREE_TYPE (index_exp); ! ! if (TREE_CODE (type) == OFFSET_TYPE ! || TREE_CODE (type) == REFERENCE_TYPE) ! type = TREE_TYPE (type); ! ! if (TYPE_LANG_SPECIFIC (type) ! && TYPE_OVERLOADS_ARRAY_REF (type)) ! error ("array expression backwards"); ! else if (TREE_CODE (type) == POINTER_TYPE ! || TREE_CODE (type) == ARRAY_TYPE) ! return build_array_ref (index_exp, array_expr); ! else ! error("`[]' applied to non-pointer type"); ! ! /* We gave an error, so give an error. Huh? */ ! return error_mark_node; ! } ! ! /* Given the cast expression EXP, checking out its validity. Either return ! an error_mark_node if there was an unavoidable error, return a cast to ! void for trying to delete a pointer w/ the value 0, or return the ! call to delete. If DOING_VEC is 1, we handle things differently ! for doing an array delete. If DOING_VEC is 2, they gave us the ! array size as an argument to delete. ! Implements ARM $5.3.4. This is called from the parser. */ ! tree ! delete_sanity (exp, size, doing_vec) ! tree exp, size; ! int doing_vec; ! { ! tree t = stabilize_reference (convert_from_reference (exp)); ! tree type = TREE_TYPE (t); ! enum tree_code code = TREE_CODE (type); ! /* For a regular vector delete (aka, no size argument) we will pass ! this down as a NULL_TREE into build_vec_delete. */ ! tree maxindex = NULL_TREE; ! /* This is used for deleting arrays. */ ! tree elt_size; ! ! switch (doing_vec) ! { ! case 2: ! maxindex = build_binary_op (MINUS_EXPR, size, integer_one_node, 1); ! if (! flag_traditional) ! pedwarn ("ANSI C++ forbids array size in vector delete"); ! /* Fall through. */ ! case 1: ! elt_size = c_sizeof (type); ! break; ! default: ! if (code != POINTER_TYPE) ! { ! error ("non-pointer type to `delete'"); ! return error_mark_node; ! } ! ! /* Deleting a pointer with the value zero is legal and has no effect. */ ! if (integer_zerop (t)) ! return build1 (NOP_EXPR, void_type_node, t); ! } ! ! /* You can't delete a pointer to constant. */ ! if (code == POINTER_TYPE && TREE_READONLY (TREE_TYPE (type))) ! { ! error ("`const *' cannot be deleted"); ! return error_mark_node; ! } ! ! /* If the type has no destructor, then we should build a regular ! delete, instead of a vector delete. Otherwise, we would end ! up passing a bogus offset into __builtin_delete, which is ! not expecting it. */ ! if (doing_vec ! && TREE_CODE (type) == POINTER_TYPE ! && !TYPE_HAS_DESTRUCTOR (TREE_TYPE (type))) ! doing_vec = 0; ! ! if (doing_vec) ! return build_vec_delete (t, maxindex, elt_size, NULL_TREE, ! integer_one_node, integer_two_node); ! else ! return build_delete (type, t, integer_three_node, ! LOOKUP_NORMAL|LOOKUP_HAS_IN_CHARGE, ! TYPE_HAS_DESTRUCTOR (TREE_TYPE (type))); } *************** *** 893,897 **** && IDENTIFIER_POINTER (DECL_NAME (value))[0] == '_' && ! strcmp (IDENTIFIER_POINTER (DECL_NAME (value)), "_vptr")) ! error_with_decl (value, "member `%s' conflicts with virtual function table field name"); /* Stash away type declarations. */ --- 1151,1155 ---- && IDENTIFIER_POINTER (DECL_NAME (value))[0] == '_' && ! strcmp (IDENTIFIER_POINTER (DECL_NAME (value)), "_vptr")) ! cp_error ("member `%D' conflicts with virtual function table field name", value); /* Stash away type declarations. */ *************** *** 900,904 **** --- 1158,1164 ---- DECL_NONLOCAL (value) = 1; CLASSTYPE_LOCAL_TYPEDECLS (current_class_type) = 1; + #if !NEW_CLASS_SCOPING set_identifier_type_value (DECL_NAME (value), TREE_TYPE (value)); + #endif pushdecl_class_level (value); return value; *************** *** 907,912 **** if (DECL_IN_AGGR_P (value)) { ! error_with_decl (value, "`%s' is already defined in the class %s", ! TYPE_NAME_STRING (DECL_CONTEXT (value))); return void_type_node; } --- 1167,1172 ---- if (DECL_IN_AGGR_P (value)) { ! cp_error ("`%D' is already defined in the class %T", value, ! DECL_CONTEXT (value)); return void_type_node; } *************** *** 918,922 **** asmspec = TREE_STRING_POINTER (asmspec_tree); ! if (init != 0) { if (TREE_CODE (value) == FUNCTION_DECL) --- 1178,1182 ---- asmspec = TREE_STRING_POINTER (asmspec_tree); ! if (init) { if (TREE_CODE (value) == FUNCTION_DECL) *************** *** 927,931 **** else if (pedantic) { ! error ("fields cannot have initializers"); init = NULL_TREE; } --- 1187,1196 ---- else if (pedantic) { ! if (DECL_NAME (value)) ! pedwarn ("ANSI C++ forbids initialization of member `%s'", ! IDENTIFIER_POINTER (DECL_NAME (value))); ! else ! pedwarn ("ANSI C++ forbids initialization of fields"); ! init = NULL_TREE; } *************** *** 940,944 **** init = digest_init (TREE_TYPE (value), init, (tree *)0); } ! if (TREE_CODE (init) == CONST_DECL) init = DECL_INITIAL (init); --- 1205,1209 ---- init = digest_init (TREE_TYPE (value), init, (tree *)0); } ! if (TREE_CODE (init) == CONST_DECL) init = DECL_INITIAL (init); *************** *** 1075,1079 **** if (TREE_CODE (value) == TYPE_DECL) { ! error_with_decl (value, "cannot declare `%s' to be a bitfield type"); return NULL_TREE; } --- 1340,1344 ---- if (TREE_CODE (value) == TYPE_DECL) { ! cp_error ("cannot declare `%D' to be a bitfield type", value); return NULL_TREE; } *************** *** 1081,1086 **** if (DECL_IN_AGGR_P (value)) { ! error_with_decl (value, "`%s' is already defined in the class %s", ! TYPE_NAME_STRING (DECL_CONTEXT (value))); return void_type_node; } --- 1346,1351 ---- if (DECL_IN_AGGR_P (value)) { ! cp_error ("`%D' is already defined in the class %T", value, ! DECL_CONTEXT (value)); return void_type_node; } *************** *** 1090,1094 **** if (TREE_STATIC (value)) { ! error_with_decl (value, "static member `%s' cannot be a bitfield"); return NULL_TREE; } --- 1355,1359 ---- if (TREE_STATIC (value)) { ! cp_error ("static member `%D' cannot be a bitfield", value); return NULL_TREE; } *************** *** 1104,1108 **** if (TREE_CODE (width) != INTEGER_CST) { ! error_with_decl (value, "structure field `%s' width not an integer constant"); DECL_INITIAL (value) = NULL_TREE; } --- 1369,1374 ---- if (TREE_CODE (width) != INTEGER_CST) { ! cp_error ("structure field `%D' width not an integer constant", ! value); DECL_INITIAL (value) = NULL_TREE; } *************** *** 1109,1112 **** --- 1375,1379 ---- else { + constant_expression_warning (width); DECL_INITIAL (value) = width; DECL_BIT_FIELD (value) = 1; *************** *** 1278,1282 **** if (DECL_IN_AGGR_P (decl)) { ! error_with_decl (decl, "`%s' already defined in the class "); return void_type_node; } --- 1545,1549 ---- if (DECL_IN_AGGR_P (decl)) { ! cp_error ("`%D' already defined in the class ", decl); return void_type_node; } *************** *** 1289,1294 **** if (DECL_CHAIN (decl)) { ! error_with_decl (decl, "function `%s' declared twice in class %s", ! TYPE_NAME_STRING (DECL_CONTEXT (decl))); return NULL_TREE; } --- 1556,1561 ---- if (DECL_CHAIN (decl)) { ! cp_error ("function `%D' declared twice in class %T", decl, ! DECL_CONTEXT (decl)); return NULL_TREE; } *************** *** 1442,1448 **** if (TREE_CODE (type) == FUNCTION_TYPE) ! error_with_decl (decl, "initializer specified for non-member function `%s'"); else if (DECL_VINDEX (decl) == NULL_TREE) ! error_with_decl (decl, "initializer specified for non-virtual method `%s'"); else if (integer_zerop (init)) { --- 1709,1715 ---- if (TREE_CODE (type) == FUNCTION_TYPE) ! cp_error ("initializer specified for non-member function `%D'", decl); else if (DECL_VINDEX (decl) == NULL_TREE) ! cp_error ("initializer specified for non-virtual method `%D'", decl); else if (integer_zerop (init)) { *************** *** 1464,1468 **** tree basefn = TREE_OPERAND (init, 1); if (TREE_CODE (basefn) != FUNCTION_DECL) ! error_with_decl (decl, "non-method initializer invalid for method `%s'"); else if (! BINFO_OFFSET_ZEROP (TYPE_BINFO (DECL_CLASS_CONTEXT (basefn)))) sorry ("base member function from other than first base class"); --- 1731,1735 ---- tree basefn = TREE_OPERAND (init, 1); if (TREE_CODE (basefn) != FUNCTION_DECL) ! cp_error ("non-method initializer invalid for method `%D'", decl); else if (! BINFO_OFFSET_ZEROP (TYPE_BINFO (DECL_CLASS_CONTEXT (basefn)))) sorry ("base member function from other than first base class"); *************** *** 1485,1489 **** } else ! error_with_decl (decl, "invalid initializer for virtual method `%s'"); } --- 1752,1756 ---- } else ! cp_error ("invalid initializer for virtual method `%D'", decl); } *************** *** 1523,1527 **** --- 1790,1798 ---- return rval; + #if NEW_CLASS_SCOPING + push_nested_class (ctype, 3); + #else pushclass (ctype, 3); + #endif TREE_COMPLEXITY (rval) = current_class_depth; return rval; *************** *** 1618,1622 **** more base class then we ascribe CURRENT_VTABLE_DECL to be. */ finish_decl (current_vtable_decl, convert_force (TREE_TYPE (current_vtable_decl), vfield), 0, 0); ! current_vtable_decl = build_indirect_ref (current_vtable_decl, 0); } else --- 1889,1893 ---- more base class then we ascribe CURRENT_VTABLE_DECL to be. */ finish_decl (current_vtable_decl, convert_force (TREE_TYPE (current_vtable_decl), vfield), 0, 0); ! current_vtable_decl = build_indirect_ref (current_vtable_decl, NULL_PTR); } else *************** *** 1762,1767 **** return; ! if (public_p && (static_p || external_p)) ! error ("optimizer cannot handle global anonymous unions"); while (field) --- 2033,2041 ---- return; ! if (public_p) ! { ! error ("global anonymous unions must be declared static"); ! return; ! } while (field) *************** *** 1778,1782 **** can hold them all. */ if (main_decl == NULL_TREE ! && DECL_SIZE (decl) == DECL_SIZE (anon_union_decl)) { main_decl = decl; --- 2052,2056 ---- can hold them all. */ if (main_decl == NULL_TREE ! && simple_cst_equal (DECL_SIZE (decl), DECL_SIZE (anon_union_decl))) { main_decl = decl; *************** *** 1885,1889 **** /* Finish processing a builtin type TYPE. It's name is NAME, its fields are in the array FIELDS. LEN is the number of elements ! in FIELDS. It is given the same alignment as ALIGN_TYPE. */ --- 2159,2164 ---- /* Finish processing a builtin type TYPE. It's name is NAME, its fields are in the array FIELDS. LEN is the number of elements ! in FIELDS minus one, or put another way, it is the maximum subscript ! used in FIELDS. It is given the same alignment as ALIGN_TYPE. */ *************** *** 2021,2025 **** --- 2296,2302 ---- TREE_PUBLIC (fn) = 1; TREE_ADDRESSABLE (fn) = 1; + temporary_allocation (); output_inline_function (fn); + permanent_allocation (); } else *************** *** 2073,2076 **** --- 2350,2382 ---- if (TREE_TYPE (DECL_INITIAL (vars)) == 0) store_init_value (vars, DECL_INITIAL (vars)); + + #ifdef DWARF_DEBUGGING_INFO + if (write_symbols == DWARF_DEBUG) + { + /* Mark the VAR_DECL node representing the vtable itself as a + "gratuitous" one, thereby forcing dwarfout.c to ignore it. + It is rather important that such things be ignored because + any effort to actually generate DWARF for them will run + into trouble when/if we encounter code like: + + #pragma interface + struct S { virtual void member (); }; + + because the artificial declaration of the vtable itself (as + manufactured by the g++ front end) will say that the vtable + is a static member of `S' but only *after* the debug output + for the definition of `S' has already been output. This causes + grief because the DWARF entry for the definition of the vtable + will try to refer back to an earlier *declaration* of the + vtable as a static member of `S' and there won't be one. + We might be able to arrange to have the "vtable static member" + attached to the member list for `S' before the debug info for + `S' get written (which would solve the problem) but that would + require more intrusive changes to the g++ front end. */ + + DECL_IGNORED_P (vars) = 1; + } + #endif /* DWARF_DEBUGGING_INFO */ + rest_of_decl_compilation (vars, 0, 1, 1); } *************** *** 2088,2094 **** for (prev = 0, vars = getdecls (); vars; vars = TREE_CHAIN (vars)) { if (TREE_CODE (vars) == TYPE_DECL ! && TYPE_LANG_SPECIFIC (TREE_TYPE (vars)) ! && CLASSTYPE_VSIZE (TREE_TYPE (vars))) { if (typedecl_fn) (*typedecl_fn) (prev, vars); --- 2394,2403 ---- for (prev = 0, vars = getdecls (); vars; vars = TREE_CHAIN (vars)) { + register tree type = TREE_TYPE (vars); + if (TREE_CODE (vars) == TYPE_DECL ! && type != error_mark_node ! && TYPE_LANG_SPECIFIC (type) ! && CLASSTYPE_VSIZE (type)) { if (typedecl_fn) (*typedecl_fn) (prev, vars); *************** *** 2119,2124 **** int start_time, this_time; - char *buf; - char *p; tree fnname; tree vars = static_aggregates; --- 2428,2431 ---- *************** *** 2125,2136 **** int needs_cleaning = 0, needs_messing_up = 0; - if (main_input_filename == 0) - main_input_filename = input_filename; - if (!first_global_object_name) - first_global_object_name = main_input_filename; - - buf = (char *) alloca (sizeof (FILE_FUNCTION_FORMAT) - + strlen (first_global_object_name)); - if (flag_detailed_statistics) dump_tree_statistics (); --- 2432,2435 ---- *************** *** 2150,2175 **** the program) rather than the file name (which imposes extra constraints). -- Raeburn@MIT.EDU, 10 Jan 1990. */ - sprintf (buf, FILE_FUNCTION_FORMAT, first_global_object_name); - - /* Don't need to pull wierd characters out of global names. */ - if (first_global_object_name == main_input_filename) - { - for (p = buf+11; *p; p++) - if (! ((*p >= '0' && *p <= '9') - #if 0 /* we always want labels, which are valid C++ identifiers (+ `$') */ - #ifndef ASM_IDENTIFY_GCC /* this is required if `.' is invalid -- k. raeburn */ - || *p == '.' - #endif - #endif - #ifndef NO_DOLLAR_IN_LABEL /* this for `$'; unlikely, but... -- kr */ - || *p == '$' - #endif - #ifndef NO_DOT_IN_LABEL /* this for `.'; unlikely, but... */ - || *p == '.' - #endif - || (*p >= 'A' && *p <= 'Z') - || (*p >= 'a' && *p <= 'z'))) - *p = '_'; - } /* See if we really need the hassle. */ --- 2449,2452 ---- *************** *** 2195,2199 **** lineno -= 1; ! fnname = get_identifier (buf); start_function (void_list_node, build_parse_node (CALL_EXPR, fnname, void_list_node, NULL_TREE), 0, 0); fnname = DECL_ASSEMBLER_NAME (current_function_decl); --- 2472,2476 ---- lineno -= 1; ! fnname = get_file_function_name ('D'); start_function (void_list_node, build_parse_node (CALL_EXPR, fnname, void_list_node, NULL_TREE), 0, 0); fnname = DECL_ASSEMBLER_NAME (current_function_decl); *************** *** 2225,2229 **** } temp = build_delete (TREE_TYPE (temp), temp, ! integer_two_node, LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0, 0); expand_expr_stmt (temp); --- 2502,2506 ---- } temp = build_delete (TREE_TYPE (temp), temp, ! integer_two_node, LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0); expand_expr_stmt (temp); *************** *** 2249,2255 **** if (vars != NULL_TREE) { ! buf[FILE_FUNCTION_PREFIX_LEN] = 'I'; ! ! fnname = get_identifier (buf); start_function (void_list_node, build_parse_node (CALL_EXPR, fnname, void_list_node, NULL_TREE), 0, 0); fnname = DECL_ASSEMBLER_NAME (current_function_decl); --- 2526,2530 ---- if (vars != NULL_TREE) { ! fnname = get_file_function_name ('I'); start_function (void_list_node, build_parse_node (CALL_EXPR, fnname, void_list_node, NULL_TREE), 0, 0); fnname = DECL_ASSEMBLER_NAME (current_function_decl); *************** *** 2348,2352 **** expand_expr (decl, const0_rtx, VOIDmode, 0); free_temp_slots (); ! expand_aggr_init (build_indirect_ref (decl, 0), init, 0); } } --- 2623,2627 ---- expand_expr (decl, const0_rtx, VOIDmode, 0); free_temp_slots (); ! expand_aggr_init (build_indirect_ref (decl, NULL_PTR), init, 0); } } *************** *** 2393,2397 **** && ! DECL_EXTERNAL (decl) && DECL_SAVED_INSNS (decl)) ! output_inline_function (decl); pending_addressable_inlines = TREE_CHAIN (pending_addressable_inlines); } --- 2668,2676 ---- && ! DECL_EXTERNAL (decl) && DECL_SAVED_INSNS (decl)) ! { ! temporary_allocation (); ! output_inline_function (decl); ! permanent_allocation (); ! } pending_addressable_inlines = TREE_CHAIN (pending_addressable_inlines); } Only in gcc-2.4.5: cp-dem.c diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/cp-errfn.c gcc-2.5.0/cp-errfn.c *** gcc-2.4.5/cp-errfn.c --- gcc-2.5.0/cp-errfn.c Fri Oct 8 15:05:07 1993 *************** *** 0 **** --- 1,199 ---- + /* Provide a call-back mechanism for handling error output. + Copyright (C) 1993 Free Software Foundation, Inc. + Contributed by Jason Merrill (jason@cygnus.com) + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + #include "config.h" + #include "tree.h" + #include + #include + + /* cp_printer is the type of a function which converts an argument into + a string for digestion by printf. The cp_printer function should deal + with all memory management; the functions in this file will not free + the char*s returned. See cp-error.c for an example use of this code. */ + + typedef char* cp_printer PROTO((HOST_WIDE_INT, int)); + extern cp_printer * cp_printers[256]; + + typedef void errorfn (); /* deliberately vague */ + + extern char* cp_file_of PROTO((tree)); + extern int cp_line_of PROTO((tree)); + + #define STRDUP(f) strcpy ((char *) alloca (strlen (f)+1), (f)) + + #define NARGS 3 + #define arglist a1, a2, a3 + #define arglist_dcl HOST_WIDE_INT a1, a2, a3; + #define ARGSINIT args[0] = a1; args[1] = a2; args[2] = a3; + #define ARGSLIST args[0], args[1], args[2] + + static void + cp_thing (errfn, atarg1, format, arglist) + errorfn *errfn; + int atarg1; + char *format; + arglist_dcl + { + char *fmt = STRDUP(format); + char *f; + int arg; + HOST_WIDE_INT args[NARGS]; + ARGSINIT + + for (f = fmt, arg = 0; *f; ++f) + { + cp_printer * function; + int alternate; + + /* ignore text */ + if (*f != '%') continue; + + ++f; + + alternate = 0; + + /* ignore most flags */ + while (*f == ' ' || *f == '-' || *f == '+' || *f == '#') + { + if (*f == '#') + alternate = 1; + ++f; + } + + /* ignore field width */ + if (*f == '*') + { + ++f; + ++arg; + } + else + while (isdigit (*f)) + ++f; + + /* ignore precision */ + if (*f == '.') + { + ++f; + if (*f == '*') + { + ++f; + ++arg; + } + else + while (isdigit (*f)) + ++f; + } + + /* ignore "long" */ + if (*f == 'l') + ++f; + + function = cp_printers[*f]; + + if (function) + { + char *p; + + if (arg >= NARGS) abort (); + + /* Must use a temporary to avoid calling *function twice */ + p = (*function) (args[arg], alternate); + args[arg] = (HOST_WIDE_INT) STRDUP(p); + *f = 's'; + } + + ++f; + ++arg; /* Assume valid format string */ + + } + + if (atarg1) + { + char *file = cp_file_of ((tree) a1); + int line = cp_line_of ((tree) a1); + (*errfn) (file, line, fmt, ARGSLIST); + } + else + (*errfn) (fmt, ARGSLIST); + + } + + void + cp_error (format, arglist) + char *format; + arglist_dcl + { + extern errorfn error; + cp_thing (error, 0, format, arglist); + } + + void + cp_warning (format, arglist) + char *format; + arglist_dcl + { + extern errorfn warning; + cp_thing (warning, 0, format, arglist); + } + + void + cp_pedwarn (format, arglist) + char *format; + arglist_dcl + { + extern errorfn pedwarn; + cp_thing (pedwarn, 0, format, arglist); + } + + void + cp_compiler_error (format, arglist) + char *format; + arglist_dcl + { + extern errorfn compiler_error; + cp_thing (compiler_error, 0, format, arglist); + } + + void + cp_error_at (format, arglist) + char *format; + arglist_dcl + { + extern errorfn error_with_file_and_line; + cp_thing (error_with_file_and_line, 1, format, arglist); + } + + void + cp_warning_at (format, arglist) + char *format; + arglist_dcl + { + extern errorfn warning_with_file_and_line; + cp_thing (warning_with_file_and_line, 1, format, arglist); + } + + void + cp_pedwarn_at (format, arglist) + char *format; + arglist_dcl + { + extern errorfn pedwarn_with_file_and_line; + cp_thing (pedwarn_with_file_and_line, 1, format, arglist); + } diff -rc2P -x gcc.??s -x cpp.??s -x c-parse.[chy] -x objc-parse.[chy] -x cp-parse.c gcc-2.4.5/cp-error.c gcc-2.5.0/cp-error.c *** gcc-2.4.5/cp-error.c --- gcc-2.5.0/cp-error.c Fri Oct 8 20:43:56 1993 *************** *** 0 **** --- 1,1185 ---- + /* Call-backs for C++ error reporting. + This code is non-reentrant. + Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + #include "config.h" + #include "tree.h" + #include "cp-tree.h" + #include "obstack.h" + #include + + typedef char* cp_printer PROTO((tree, int)); + + #define D decl_as_string + #define E expr_as_string + #define T type_as_string + + #define _ (cp_printer *) 0 + cp_printer * cp_printers[256] = + { + /*0 1 2 3 4 5 6 7 8 9 A B C D E F */ + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x00 */ + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x10 */ + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x20 */ + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x30 */ + _, _, _, _, D, E, _, _, _, _, _, _, _, _, _, _, /* 0x40 */ + _, _, _, _, T, _, _, _, _, _, _, _, _, _, _, _, /* 0x50 */ + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x60 */ + _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x70 */ + }; + #undef D + #undef E + #undef T + #undef _ + + #define obstack_chunk_alloc xmalloc + #define obstack_chunk_free free + + /* Obstack where we build text strings for overloading, etc. */ + static struct obstack scratch_obstack; + static char *scratch_firstobj; + + /* This points to a safe place to resume processing in case an expression + generates an error while we're trying to format it. */ + static int scratch_error_offset; + + # define OB_INIT() (scratch_firstobj ? (obstack_free (&scratch_obstack, scratch_firstobj), 0) : 0) + # define OB_PUTC(C) (obstack_1grow (&scratch_obstack, (C))) + # define OB_PUTC2(C1,C2) \ + (obstack_1grow (&scratch_obstack, (C1)), obstack_1grow (&scratch_obstack, (C2))) + # define OB_PUTS(S) (obstack_grow (&scratch_obstack, (S), sizeof (S) - 1)) + # define OB_PUTID(ID) \ + (obstack_grow (&scratch_obstack, IDENTIFIER_POINTER (ID), \ + IDENTIFIER_LENGTH (ID))) + # define OB_PUTCP(S) (obstack_grow (&scratch_obstack, (S), strlen (S))) + # define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0')) + # define OB_PUTI(CST) do { sprintf (digit_buffer, "%d", (CST)); \ + OB_PUTCP (digit_buffer); } while (0) + + # define NEXT_CODE(t) (TREE_CODE (TREE_TYPE (t))) + + static void dump_type (), dump_decl (), dump_function_decl (); + static void dump_expr (), dump_unary_op (), dump_binary_op (); + static void dump_aggr_type (), dump_type_prefix (), dump_type_suffix (); + static void dump_function_name (); + + void + init_error () + { + gcc_obstack_init (&scratch_obstack); + scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0); + } + + /* Counter to help build parameter names in case they were omitted. */ + static int dummy_name; + + tree + make_anon_parm_name () + { + char buf[32]; + + sprintf (buf, ANON_PARMNAME_FORMAT, dummy_name++); + return get_identifier (buf); + } + + void + clear_anon_parm_name () + { + /* recycle these names. */ + dummy_name = 0; + } + + enum pad { none, before, after }; + + static void + dump_readonly_or_volatile (t, p) + tree t; + enum pad p; + { + if (TYPE_READONLY (t) || TYPE_VOLATILE (t)) + { + if (p == before) OB_PUTC (' '); + if (TYPE_READONLY (t)) + OB_PUTS ("const"); + if (TYPE_VOLATILE (t)) + OB_PUTS ("volatile"); + if (p == after) OB_PUTC (' '); + } + } + + /* This must be large enough to hold any anonymous parm name. */ + static char anon_buffer[sizeof (ANON_PARMNAME_FORMAT) + 20]; + + /* This must be large enough to hold any printed integer or floating-point + value. */ + static char digit_buffer[128]; + + /* Dump into the obstack a human-readable equivalent of TYPE. */ + static void + dump_type (t, v) + tree t; + int v; /* verbose? */ + { + if (t == NULL_TREE) + return; + + if (TYPE_PTRMEMFUNC_P (t)) + goto offset_type; + + switch (TREE_CODE (t)) + { + case ERROR_MARK: + sprintf (anon_buffer, ANON_PARMNAME_FORMAT, dummy_name++); + OB_PUTCP (anon_buffer); + break; + + case UNKNOWN_TYPE: + OB_PUTS (""); + break; + + case TREE_LIST: + /* i.e. function taking no arguments */ + if (t != void_list_node) + { + dump_type (TREE_VALUE (t), v); + /* Can this happen other than for default arguments? */ + if (TREE_PURPOSE (t)) + { + OB_PUTS (" = "); + dump_expr (TREE_PURPOSE (t)); + } + if (TREE_CHAIN (t)) + { + if (TREE_CHAIN (t) != void_list_node) + { + OB_PUTC2 (',', ' '); + dump_type (TREE_CHAIN (t), v); + } + } + else OB_PUTS (" ..."); + } + break; + + case IDENTIFIER_NODE: + OB_PUTID (t); + break; + + case TREE_VEC: + dump_type (BINFO_TYPE (t), v); + break; + + case RECORD_TYPE: + case UNION_TYPE: + case ENUMERAL_TYPE: + dump_aggr_type (t, v); + break; + + case TYPE_DECL: + dump_readonly_or_volatile (t, after); + OB_PUTID (DECL_NAME (t)); + break; + + case INTEGER_TYPE: + if (!TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && TREE_UNSIGNED (t)) + OB_PUTS ("unsigned "); + else if (TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && !TREE_UNSIGNED (t)) + OB_PUTS ("signed "); + + /* fall through. */ + case REAL_TYPE: + case VOID_TYPE: + dump_readonly_or_volatile (t, after); + OB_PUTID (TYPE_IDENTIFIER (t)); + break; + + case TEMPLATE_TYPE_PARM: + OB_PUTS ("