diff -u -r -N gcc-3.3.6-core-orig/ChangeLog.M68HC11 gcc-3.3.6/ChangeLog.M68HC11 --- gcc-3.3.6-core-orig/ChangeLog.M68HC11 1970-01-01 01:00:00.000000000 +0100 +++ gcc-3.3.6/ChangeLog.M68HC11 2010-11-09 20:47:16.000000000 +0000 @@ -0,0 +1,4 @@ +2003-05-18 Stephane Carrez + + * configure.in (m68hc11): Configure libstdcxx_version. + diff -u -r -N gcc-3.3.6-core-orig/config.sub gcc-3.3.6/config.sub --- gcc-3.3.6-core-orig/config.sub 2003-01-30 23:25:36.000000000 +0000 +++ gcc-3.3.6/config.sub 2010-11-09 20:47:16.000000000 +0000 @@ -268,7 +268,7 @@ | z8k) basic_machine=$basic_machine-unknown ;; - m6811 | m68hc11 | m6812 | m68hc12) + m6811 | m68hc11 | m6812 | m68hc12 | m9s12x) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none diff -u -r -N gcc-3.3.6-core-orig/configure.in gcc-3.3.6/configure.in --- gcc-3.3.6-core-orig/configure.in 2004-01-02 14:09:48.000000000 +0000 +++ gcc-3.3.6/configure.in 2010-11-09 20:47:16.000000000 +0000 @@ -487,7 +487,7 @@ i[3456]86-*-beos*) noconfigdirs="$noconfigdirs gdb target-newlib target-libgloss ${libgcj}" ;; - m68hc11-*-*|m6811-*-*|m68hc12-*-*|m6812-*-*) + m68hc11-*-*|m6811-*-*|m68hc12-*-*|m6812-*-*|m9s12x-*-*) noconfigdirs="$noconfigdirs target-libiberty ${libstdcxx_version} ${libgcj}" ;; m68k-*-elf*) diff -u -r -N gcc-3.3.6-core-orig/gcc/ChangeLog.M68HC11 gcc-3.3.6/gcc/ChangeLog.M68HC11 --- gcc-3.3.6-core-orig/gcc/ChangeLog.M68HC11 1970-01-01 01:00:00.000000000 +0100 +++ gcc-3.3.6/gcc/ChangeLog.M68HC11 2010-11-09 20:47:16.000000000 +0000 @@ -0,0 +1,384 @@ +2010-10-28 James Murray + More work on 9s12x target building + S12X optimisations in larith.asm + +2010-10-26 James Murray + Bump version + Include A.E.Smith S12X ldivmod.asm assembler long division + Port ldivmod.asm to S12 + (Earlier work) + Support building as 9S12X target to match binutils + +2006-01-22 Stephane Carrez + + * version.c: Bump to 2006-01-22 + +2006-01-22 Stephane Carrez + + PR savannah/13917 + * config/m68hc11/m68hc11.c (nonimmediate_noinc_operand): New predicate. + * config/m68hc11/m68hc11-protos.h (nonimmediate_noinc_operand): Declare. + * config/m68hc11/m68hc11.h (PREDICATE_CODES): Register it. + * config/m68hc11/m68hc11.md ("addqi3"): Use it for operand 0, 1. + ("uminqi3"): Likewise. + ("umaxqi3"): Likewise. + ("uminhi3"): Likewise. + ("umaxhi3"): Likewise. + ("negqi2"): Likewise. + ("*ashlqi3_const1", "*ashrqi3_const1"): Likewise. + ("lshrhi3_const", "*lshrqi3_const1"): Likewise. + +2006-01-20 Stephane Carrez + + savannah/15493 + * config/m68hc11/m68hc11.c (m68hc11_gen_movqi): Must save register + A and copy X or Y in it for a move when both operands refer to X or Y. + +2005-11-05 Stephane Carrez + + PR savannah/13879 + * expmed.c (make_tree): If we have a constant for SIGN_EXTEND or + ZERO_EXTEND, use the mode from the extend node; the constant is VOIDmode + and it will crash. + +2005-11-05 Stephane Carrez + + * expmed.c (store_bit_field): Must apply a correction for big-endian + target when the bitfield contains less word than the source constant. + +2005-05-15 Stephane Carrez + + * config/m68hc11/m68hc11.h (REG_VALID_P): The macro can be used with + signed numbers passed as argument. + * version.c: Bump to 20050515 + +2005-05-08 Stephane Carrez + + PR savannah/12572 + * config/m68hc11/m68hc11.md ("movhi"): Sign extend the constants in + the range 32768..65535 so that the generated set is recognized. + +2005-05-08 Stephane Carrez + + * config/m68hc11/m68hc11.md ("mulqi3"): Use general_operand for operand + 1 and fix constraints. + ("mulqihi3")" Use general_operand for operand 2. + * config/m68hc11/m68hc11.c (m68hc11_gen_movqi): Use pula and pulb + instead of lda and ldb for 68HC12. + +2005-05-08 Stephane Carrez + + * config/m68hc11/m68hc11-protos.h (m68hc11_hard_regno_rename_ok): Pass + the mode. + * config/m68hc11/m68hc11.h (HARD_REGNO_RENAME_OK): Likewise. + * config/m68hc11/m68hc11.c (m68hc11_hard_regno_rename_ok): Likewise. + * regrename.c (regrename_optimize): Pass the mode in which the register + is used. + +2005-04-03 Stephane Carrez + + PR savannah/12297 + * config/m68hc11/m68hc11.c (m68hc11_z_replacement): Use emit_insn_after + when adding the save Z instruction so that it is part of the good BB. + +2005-02-13 Stephane Carrez + + PR target/17551 + * gcse.c (handle_avail_expr): Use gen_move_insn() instead of + gen_rtx_SET() + +2005-02-13 Stephane Carrez + + PR target/16925 + * config/m68hc11/m68hc11.c (m68hc11_gen_highpart): Handle split of + 64-bit constants on 64-bit hosts. + (m68hc11_split_logical): Simplify. + (m68hc11_split_move): Likewise. + +2005-02-12 Stephane Carrez + + PR savannah/11813 + * config/m68hc11/m68hc11.c (reg_or_some_mem_operand): Do not allow + the 68HC12 address indirect addressing mode as it is not supported + by bset and bclr. + +2005-01-29 Stephane Carrez + + * version.c (version_string): Bump to 2005-01-29. + * config/udivmodsi4.c (__udivmodsi4): Rewrite ediv as it didn't + passed the gcc validation. + +2005-01-28 Stephane Carrez + + From philipljohnson@comcast.net: + + Patch savannah/3626 + * config/udivmodsi4.c (__udivmodsi4): Use 68HC12 ediv instruction to + compute division and modulus. + +2004-08-30 Stephane Carrez + + * config/m68hc11/m68hc11.c (m68hc11_gen_movhi): Fix invalid generation + of indexed indirect addressing with movw + +2004-08-29 Stephane Carrez + + * version.c (version_string): Bump to 2004-08-29. + +2004-08-29 Stephane Carrez + + * final.c (alter_subreg): Adjust the offset of paradoxical subreg + so that we load the correct value. + +2004-08-06 Stephane Carrez + + * config/m68hc11/m68hc11.md ("movhi_const0"): Use this pattern only + for 68HC11. + +2004-08-01 Stephane Carrez + + * version.c (version_string): Bump to 2004-08-01 and use gcc 3.3.4. + +2004-06-06 Stephane Carrez + + PR target/14542 + * config/m68hc11/m68hc11.md (move peephole2): Emit a use note to avoid + a live change of a register after peephole replacement. + +2004-06-06 Stephane Carrez + + PR target/14457 + * config/m68hc11/m68hc11.c (splitable_operand): New predicate. + * config/m68hc11/m68hc11-protos.h (splitable_operand): Declare. + * config/m68hc11/m68hc11.h (PREDICATE_CODES): Register it. + (inhibit_libc): Must define. + * config/m68hc11/m68hc11.md ("movhi_const0"): Use splitable_operand. + ("*andhi3_gen", "iorhi3", "*iorhi3_gen"): Likewise. + ("xorhi3"): Likewise. + +2004-04-25 Stephane Carrez + + * config/m68hc11/m68hc11.md ("iorqi3_gen"): Use general_operand for + first operand. + ("*andqi3_gen", "xorqi3"): Likewise. + ("subqi3", "*subhi3"): Likewise. + ("*addhi3_zext"): Likewise. + +2004-04-25 Stephane Carrez + + * config/m68hc11/m68hc11.h (ASM_OUTPUT_LABELREF): Redefine to strip + any name encoding. + +2004-03-07 Stephane Carrez + + * config/m68hc11/m68hc11.md ("*lshrsi3_const"): Disable for 68HC12. + ("*lshrsi3"): Also accept an immediate for 68HC12. + ("*ashrsi3_const"): Likewise. + ("*ashrsi3"): Likewise. + ("*ashlsi3_const"): Likewise. + ("*ashlsi3"): Likewise. + ("cmphi_1_hc12"): Compare two hard register by pushing them and + comparing with a pop; don't use a split for that. + ("cmphi split"): Disable compare split for 68HC12. + +2004-03-06 Stephane Carrez + + * config/m68hc11/m68hc11.md ("*lshrsi3_const1"): Allow a memory for + operand 1 when operand 0 is a soft register. + ("*ashlsi3_const1"): Likewise. + +2004-03-06 Stephane Carrez + + * config/m68hc11/m68hc11.c (m68hc11_gen_movhi): Use 2,-sp to push + the stack register. + +2004-03-06 Stephane Carrez + + * doc/extend.texi (Function Attributes): Document page0, trap and + update far documentation. + +2004-03-06 Stephane Carrez + + PR savannah/4987: + * doc/invoke.texi (M68hc1x Options): Document -mrelax + +2004-03-06 Stephane Carrez + + PR savannah/8028: + * config/m68hc11/m68hc11.c (expand_prologue): Don't make an interrupt + or a trap handler a far symbol. + (m68hc11_initial_elimination_offset): Likewise. + +2004-03-06 Stephane Carrez + + * config/m68hc11/m68hc11.md ("*lshrsi3_const1"): Tune constraints + to optimize more case where we don't need a scratch register. + ("*ashlsi3_const1"): Likewise. + ("*pushdi_internal"): New insn and split + to separate push from moves. + ("*pushdf_internal"): Likewise. + ("*pushsf_internal"): Likewise. + ("*pushsi_internal"): Likewise. + ("movdi_internal"): Use define_insn_and_split; non push operand. + ("movdf_internal"): Likewise. + ("movsf_internal"): Likewise. + ("movsi_internal"): Likewise. + +2004-03-02 Stephane Carrez + + * config/m68hc11/m68hc11.c (m68hc11_addr_mode): New variable. + (m68hc11_mov_addr_mode): Likewise. + (m68hc11_override_options): Initialize them based on target. + (register_indirect_p): Allow a MEM for indirect addressing modes and + use flags to control what is allowed. + (m68hc11_small_indexed_indirect_p): Use m68hc11_mov_addr_mode for + supported addressing modes. + (m68hc11_register_indirect_p): Use m68hc11_addr_mode. + (go_if_legitimate_address_internal): Likewise. + (m68hc11_indirect_p): Likewise and check the mode. + (print_operand): Allow a (MEM (MEM)) and generate indirect addressing. + +2004-02-22 Stephane Carrez + + * version.c: Bump to 20040222 and use gcc 3.3.3. + +2003-11-16 Stephane Carrez + + * version.c: Bump to 200311116. + +2003-11-10 Stephane Carrez + + * config/m68hc11/m68hc11-protos.h (m68hc11_page0_symbol_p): Declare. + * config/m68hc11/m68hc11.c (m68hc11_page0_symbol_p): New predicate. + (m68hc11_indirect_p): Use it. + (print_operand): Likewise. + (m68hc11_handle_page0_attribute): New function to handle page0 + attribute + (m68hc11_attribute_table): New attribute page0 + (m68hc11_encode_section_info): Check page0 attribute. + * config/m68hc11/m68hc11.md: Use define_insn_and_split + (peephole2): New peephole to generate bset/bclr. + (peephole): New peephole to optimize compare in few cases and + setting of 2 registers from memory. + +2003-10-04 Stephane Carrez + + * version.c: Bump to 20031004. + +2003-10-04 Stephane Carrez + + PR savannah/3432: + * config/m68hc11/t-m68hc11-gas (MULTILIB_MATCHES): m68hcs12 is + identical to m68hc12 for libraries. + +2003-10-01 Stephane Carrez + + * version.c: Bump to 20031001. + +2003-09-30 Stephane Carrez + + * config/m68hc11/m68hc11.md ("*ashldi3_const32"): Adjust first operand + if it uses stack pointer register. + +2003-09-30 Stephane Carrez + + * config/m68hc11/m68hc11.md (peephole2 "remove one load"): Make sure + that register operand 3 does not appear in operand 2. + +2003-08-08 Stephane Carrez + + * version.c: Bump to 20030808 + +2003-08-02 Stephane Carrez + + * config/m68hc11/m68hc11.md (peephole2 "leas 2,sp"): Enable it + and add a use rtx. + (peephole2): New peephole to optimize moves on stack. + +2003-07-19 Stephane Carrez + + * config/m68hc11/m68hc11.md (peephole2 abx): Use m68hc11_gen_lowpart + to make sure the constant has the appropriate QImode. + +2003-07-08 Stephane Carrez + + * config/m68hc11/m68hc11.h (HAVE_AS_DWARF2_DEBUG_LINE): Don't define + as .file/.loc directives are incompatible with linker relaxation. + +2003-05-19 Stephane Carrez + + * config/m68hc11/m68hc11.md ("*movqi" split): Don't split when source + or destination is d, b or a register. + +2003-05-18 Stephane Carrez + + * config/m68hc11/m68hc11.md ("*logicalhi3_zexthi_ashift8): Allow + address registers for operand 1 and 2. + +2003-05-18 Stephane Carrez + + * reload.c (find_reloads_toplev): Do not reload the paradoxical + subreg with its wider mode but the register itself. + +2003-05-18 Stephane Carrez + + Merge 3.0.4-20030501 patchs in 3.3 + + 2003-03-12 Stephane Carrez + + * config/m68hc11/m68hc11.md + ("movdi_internal", "movdf_internal"): Fix constraints. + ("movsi_internal", "movsf_internal"): Likewise. + (peephole2): New peephole2 to optimize the address computations + by using 'abx' and 'aby'. + (peephole2): New peephole2 to optimize 32-bit shift and use only + one hard register instead of two. + (peephole2): New peephole2 to avoid loading the same value in two + different registers. + + 2003-03-12 Stephane Carrez + + * config/m68hc11/m68hc11.md (split "logicalsi3_silshl16_zext"): Split + after reload but reject the particular case that generates a xgdx + pattern, it must be handled after Z register replacement. + + 2003-03-10 Stephane Carrez + + * config/m68hc11/m68hc11.md ("*addhi3_68hc12"): Accept any constant + when adding to X and Y since leax/leay are fast. + ("*addhi3"): Accept 'I' constraint when adding to address register. + + 2003-02-27 Stephane Carrez + + * config/m68hc11/m68hc11.md ("*logicalsi3_silshr16"): Accept D reg + on all operands. + + 2003-01-10 Stephane Carrez + + * config/m68hc11/m68hc11.md ("*logicalsi3_silshl16_zext"): New split. + ("*logicalsi3_silshr16"): Fix constraints. + + 2002-02-27 Stephane Carrez + + * reload.c (find_reloads): Change to RELOAD_FOR_OTHER_ADDRESS any + RELOAD_FOR_OPERAND_ADDRESS reloads which is used by a RELOAD_FOR_OTHER + reload (ensures correct order of reload insns). + + 2001-07-09 Stephane Carrez + + * reload1.c (merge_assigned_reloads): After a RELOAD_OTHER merge, + fix setting of the reloads of that reload to RELOAD_FOR_OTHER_ADDRESS. + + 2001-06-22 Stephane Carrez + + * config/m68hc11/m68hc11.h (MAX_BITS_PER_WORD): Define to 32. + + 2001-03-01 Stephane Carrez + + * reload1.c (merge_assigned_reloads): Change the type of the + reload to emit it at the good place after the merge. + + 2001-02-24 Stephane Carrez + + * reload.c (find_reloads_subreg_address): Call find_reloads_address + with the same reload type. diff -u -r -N gcc-3.3.6-core-orig/gcc/collect2.c gcc-3.3.6/gcc/collect2.c --- gcc-3.3.6-core-orig/gcc/collect2.c 2003-12-08 19:02:39.000000000 +0000 +++ gcc-3.3.6/gcc/collect2.c 2010-11-09 20:47:16.000000000 +0000 @@ -74,6 +74,10 @@ #undef REAL_STRIP_FILE_NAME #endif +#ifdef WIN32 +# define USE_POPEN +#endif + /* If we cannot use a special method, use the ordinary one: run nm to find what symbols are present. In a cross-compiler, this means you need a cross nm, @@ -444,7 +448,11 @@ #endif signal (signo, SIG_DFL); +#ifndef WIN32 kill (getpid (), signo); +#else + exit(3); +#endif } @@ -2081,6 +2089,31 @@ if (nm_file_name == 0) fatal ("cannot find `nm'"); +#ifdef USE_POPEN + p = (char*) xmalloc (strlen (nm_file_name) + + strlen (NM_FLAGS) + + strlen (prog_name) + + 10); + strcpy (p, nm_file_name); + strcat (p, " "); + if (NM_FLAGS[0] != '\0') + { + strcat (p, NM_FLAGS); + strcat (p, " "); + } + strcat (p, prog_name); + inf = popen (p, "r"); + if (inf == NULL) + fatal_perror ("can't popen `%s'", p); + + /* Trace if needed. */ + if (vflag) + fprintf (stderr, " %s\n", p); + + free (p); + fflush (stdout); + fflush (stderr); +#else nm_argv[argc++] = nm_file_name; if (NM_FLAGS[0] != '\0') nm_argv[argc++] = NM_FLAGS; @@ -2142,6 +2175,7 @@ if (debug) fprintf (stderr, "\nnm output with constructors/destructors.\n"); +#endif /* Read each line of nm output. */ while (fgets (buf, sizeof buf, inf) != (char *) 0) @@ -2215,7 +2249,11 @@ if (fclose (inf) != 0) fatal_perror ("fclose"); +#ifdef USE_POPEN + pclose (inf); +#else do_wait (nm_file_name); +#endif signal (SIGINT, int_handler); #ifdef SIGQUIT diff -u -r -N gcc-3.3.6-core-orig/gcc/combine.c gcc-3.3.6/gcc/combine.c --- gcc-3.3.6-core-orig/gcc/combine.c 2005-01-18 08:39:05.000000000 +0000 +++ gcc-3.3.6/gcc/combine.c 2010-11-09 20:47:16.000000000 +0000 @@ -6553,7 +6553,7 @@ address, we stay there. If we have a comparison, set to COMPARE, but once inside, go back to our default of SET. */ - next_code = (code == MEM || code == PLUS || code == MINUS ? MEM + next_code = (code == MEM /* SCz: || code == PLUS || code == MINUS */ ? MEM : ((code == COMPARE || GET_RTX_CLASS (code) == '<') && XEXP (x, 1) == const0_rtx) ? COMPARE : in_code == COMPARE ? SET : in_code); diff -u -r -N gcc-3.3.6-core-orig/gcc/config/divmod.c gcc-3.3.6/gcc/config/divmod.c --- gcc-3.3.6-core-orig/gcc/config/divmod.c 2000-11-30 08:25:58.000000000 +0000 +++ gcc-3.3.6/gcc/config/divmod.c 2010-11-09 20:47:16.000000000 +0000 @@ -1,4 +1,21 @@ -long udivmodsi4 (); +/* cover the root directory case */ +#if !defined(mc68hc11) && !defined(mc68hc12) && !defined(m9s12x) +#if defined(target11) +#define mc68hc11 +#endif +#if defined(target12) +#define mc68hc12 +#endif +#if defined(targets12x) +#define m9s12x +#define mc68hc12 +#endif +#endif + +#ifndef mc68hc12 + +extern unsigned long __udivmodsi4 (unsigned long num, unsigned long den, + unsigned long *mod); long __divsi3 (long a, long b) @@ -18,7 +35,7 @@ neg = !neg; } - res = udivmodsi4 (a, b, 0); + res = __udivmodsi4 (a, b, 0); if (neg) res = -res; @@ -41,10 +58,13 @@ if (b < 0) b = -b; - res = udivmodsi4 (a, b, 1); + __udivmodsi4 (a, b, (unsigned long*) &res); if (neg) res = -res; return res; } + + +#endif /* !mc68hc12 */ diff -u -r -N gcc-3.3.6-core-orig/gcc/config/larith.asm gcc-3.3.6/gcc/config/larith.asm --- gcc-3.3.6-core-orig/gcc/config/larith.asm 1970-01-01 01:00:00.000000000 +0100 +++ gcc-3.3.6/gcc/config/larith.asm 2010-11-09 20:47:16.000000000 +0000 @@ -0,0 +1,1348 @@ +/* libgcc routines for M68HC11 & M68HC12. + Copyright (C) 1999, 2000, 2001, 2002, 2003 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. + +In addition to the permissions in the GNU General Public License, the +Free Software Foundation gives you unlimited permission to link the +compiled version of this file with other programs, and to distribute +those programs without any restriction coming from the use of this +file. (The General Public License restrictions do apply in other +respects; for example, they cover modification of the file, and +distribution when not linked into another program.) + +This file 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; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* As a special exception, if you link this library with other files, + some of which are compiled with GCC, to produce an executable, + this library does not by itself cause the resulting executable + to be covered by the GNU General Public License. + This exception does not however invalidate any other reasons why + the executable file might be covered by the GNU General Public License. */ + + .file "larith.asm" + +#ifdef __HAVE_SHORT_INT__ + .mode mshort +#else + .mode mlong +#endif + + .macro declare_near name + .globl \name + .type \name,@function + .size \name,.Lend-\name +\name: + .endm + +#if defined(__USE_RTC__) +# define ARG(N) N+1 + + .macro ret +#if defined(mc68hc12) + rtc +#else + jmp __return_32 +#endif + .endm + + .macro declare name + .globl \name + .type \name,@function + .size \name,.Lend-\name + .far \name +\name: + .endm + + .macro farsym name + .far NAME + .endm + +#else +# define ARG(N) N + + .macro ret + rts + .endm + + .macro farsym name + .endm + + .macro declare name + .globl \name + .type \name,@function + .size \name,.Lend-\name +\name: + .endm + +#endif + + .sect .text + + +#define REG(NAME) \ +NAME: .dc.w 1; \ + .type NAME,@object ; \ + .size NAME,2 + +#ifdef L_regs_min +/* Pseudo hard registers used by gcc. + They should be located in page0. */ + + .sect .softregs + .globl _.tmp + .globl _.z,_.xy +REG(_.tmp) +REG(_.z) +REG(_.xy) + +#endif + +#ifdef L_regs_frame + .sect .softregs + .globl _.frame +REG(_.frame) +#endif + +#ifdef L_regs_d1_2 + .sect .softregs + .globl _.d1,_.d2 +REG(_.d1) +REG(_.d2) +#endif + +#ifdef L_regs_d3_4 + .sect .softregs + .globl _.d3,_.d4 +REG(_.d3) +REG(_.d4) +#endif + +#ifdef L_regs_d5_6 + .sect .softregs + .globl _.d5,_.d6 +REG(_.d5) +REG(_.d6) +#endif + +#ifdef L_regs_d7_8 + .sect .softregs + .globl _.d7,_.d8 +REG(_.d7) +REG(_.d8) +#endif + +#ifdef L_regs_d9_16 +/* Pseudo hard registers used by gcc. + They should be located in page0. */ + .sect .softregs + .globl _.d9,_.d10,_.d11,_.d12,_.d13,_.d14 + .globl _.d15,_.d16 +REG(_.d9) +REG(_.d10) +REG(_.d11) +REG(_.d12) +REG(_.d13) +REG(_.d14) +REG(_.d15) +REG(_.d16) + +#endif + +#ifdef L_regs_d17_32 +/* Pseudo hard registers used by gcc. + They should be located in page0. */ + .sect .softregs + .globl _.d17,_.d18,_.d19,_.d20,_.d21,_.d22 + .globl _.d23,_.d24,_.d25,_.d26,_.d27,_.d28 + .globl _.d29,_.d30,_.d31,_.d32 +REG(_.d17) +REG(_.d18) +REG(_.d19) +REG(_.d20) +REG(_.d21) +REG(_.d22) +REG(_.d23) +REG(_.d24) +REG(_.d25) +REG(_.d26) +REG(_.d27) +REG(_.d28) +REG(_.d29) +REG(_.d30) +REG(_.d31) +REG(_.d32) +#endif + +#ifdef L_premain +;; +;; Specific initialization for 68hc11 before the main. +;; Nothing special for a generic routine; Just enable interrupts. +;; + declare_near __premain + clra + tap ; Clear both I and X. + rts +#endif + +#ifdef L__exit +;; +;; Exit operation. Just loop forever and wait for interrupts. +;; (no other place to go) +;; This operation is split in several pieces collected together by +;; the linker script. This allows to support destructors at the +;; exit stage while not impacting program sizes when there is no +;; destructors. +;; +;; _exit: +;; *(.fini0) /* Beginning of finish code (_exit symbol). */ +;; *(.fini1) /* Place holder for applications. */ +;; *(.fini2) /* C++ destructors. */ +;; *(.fini3) /* Place holder for applications. */ +;; *(.fini4) /* Runtime exit. */ +;; + .sect .fini0,"ax",@progbits + .globl _exit + .globl exit + .weak exit + farsym exit + farsym _exit +exit: +_exit: + + .sect .fini4,"ax",@progbits +fatal: + cli + wai + bra fatal +#endif + +#ifdef L_abort +;; +;; Abort operation. This is defined for the GCC testsuite. +;; + declare abort + + ldd #255 ; +#ifdef mc68hc12 + trap #0x30 +#else + .byte 0xCD ; Generate an illegal instruction trap + .byte 0x03 ; The simulator catches this and stops. +#endif + jmp _exit +#endif + +#ifdef L_cleanup +;; +;; Cleanup operation used by exit(). +;; + declare _cleanup + + ret +#endif + +;----------------------------------------- +; required gcclib code +;----------------------------------------- +#ifdef L_memcpy + declare memcpy + declare __memcpy + + .weak memcpy +;;; +;;; void* memcpy(void*, const void*, size_t) +;;; +;;; D = dst Pmode +;;; 2,sp = src Pmode +;;; 4,sp = size HImode (size_t) +;;; +#ifdef mc68hc12 + ldx ARG(2),sp + ldy ARG(4),sp + pshd + xgdy + lsrd + bcc Start + movb 1,x+,1,y+ +Start: + beq Done +Loop: + movw 2,x+,2,y+ + dbne d,Loop +Done: + puld + ret +#else + xgdy + tsx + ldd ARG(4),x + ldx ARG(2),x ; SRC = X, DST = Y + cpd #0 + beq End + pshy + inca ; Correction for the deca below +L0: + psha ; Save high-counter part +L1: + ldaa 0,x ; Copy up to 256 bytes + staa 0,y + inx + iny + decb + bne L1 + pula + deca + bne L0 + puly ; Restore Y to return the DST +End: + xgdy + ret +#endif +#endif + +#ifdef L_memset + declare memset + declare __memset +;;; +;;; void* memset(void*, int value, size_t) +;;; +#ifndef __HAVE_SHORT_INT__ +;;; D = dst Pmode +;;; 2,sp = src SImode +;;; 6,sp = size HImode (size_t) + val = ARG(5) + size = ARG(6) +#else +;;; D = dst Pmode +;;; 2,sp = src SImode +;;; 6,sp = size HImode (size_t) + val = ARG(3) + size = ARG(4) +#endif +#ifdef mc68hc12 + xgdx + ldab val,sp + ldy size,sp + pshx + beq End +Loop: + stab 1,x+ + dbne y,Loop +End: + puld + ret +#else + xgdx + tsy + ldab val,y + ldy size,y ; DST = X, CNT = Y + beq End + pshx +L0: + stab 0,x ; Fill up to 256 bytes + inx + dey + bne L0 + pulx ; Restore X to return the DST +End: + xgdx + ret +#endif +#endif + +#ifdef L_adddi3 + declare ___adddi3 + + tsx + xgdy + ldd ARG(8),x ; Add LSB + addd ARG(16),x + std 6,y ; Save (carry preserved) + + ldd ARG(6),x + adcb ARG(15),x + adca ARG(14),x + std 4,y + + ldd ARG(4),x + adcb ARG(13),x + adca ARG(12),x + std 2,y + + ldd ARG(2),x + adcb ARG(11),x ; Add MSB + adca ARG(10),x + std 0,y + + xgdy + ret +#endif + +#ifdef L_subdi3 + declare ___subdi3 + + tsx + xgdy + ldd ARG(8),x ; Subtract LSB + subd ARG(16),x + std 6,y ; Save, borrow preserved + + ldd ARG(6),x + sbcb ARG(15),x + sbca ARG(14),x + std 4,y + + ldd ARG(4),x + sbcb ARG(13),x + sbca ARG(12),x + std 2,y + + ldd ARG(2),x ; Subtract MSB + sbcb ARG(11),x + sbca ARG(10),x + std 0,y + + xgdy ; + ret +#endif + +#ifdef L_notdi2 + declare ___notdi2 + + tsy + xgdx + ldd ARG(8),y + coma + comb + std 6,x + + ldd ARG(6),y + coma + comb + std 4,x + + ldd ARG(4),y + coma + comb + std 2,x + + ldd ARG(2),y + coma + comb + std 0,x + xgdx + ret +#endif + +#ifdef L_negsi2 + declare_near ___negsi2 + + comb + coma + xgdx + comb + coma + inx + xgdx + bne done + inx +done: + rts +#endif + +#ifdef L_one_cmplsi2 + declare_near ___one_cmplsi2 + + comb + coma + xgdx + comb + coma + xgdx + rts +#endif + +#ifdef L_ashlsi3 + declare_near ___ashlsi3 + + xgdy + clra + andb #0x1f + xgdy + beq Return +Loop: + lsld + xgdx + rolb + rola + xgdx + dey + bne Loop +Return: + rts +#endif + +#ifdef L_ashrsi3 + declare_near ___ashrsi3 + + xgdy + clra + andb #0x1f + xgdy + beq Return +Loop: + xgdx + asra + rorb + xgdx + rora + rorb + dey + bne Loop +Return: + rts +#endif + +#ifdef L_lshrsi3 + declare_near ___lshrsi3 + + xgdy + clra + andb #0x1f + xgdy + beq Return +Loop: + xgdx + lsrd + xgdx + rora + rorb + dey + bne Loop +Return: + rts +#endif + +#ifdef L_lshrhi3 + declare_near ___lshrhi3 + + cpx #16 + bge Return_zero + cpx #0 + beq Return +Loop: + lsrd + dex + bne Loop +Return: + rts +Return_zero: + clra + clrb + rts +#endif + +#ifdef L_lshlhi3 + declare_near ___lshlhi3 + + cpx #16 + bge Return_zero + cpx #0 + beq Return +Loop: + lsld + dex + bne Loop +Return: + rts +Return_zero: + clra + clrb + rts +#endif + +#ifdef L_rotrhi3 + declare_near ___rotrhi3 + +___rotrhi3: + xgdx + clra + andb #0x0f + xgdx + beq Return +Loop: + tap + rorb + rora + dex + bne Loop +Return: + rts +#endif + +#ifdef L_rotlhi3 + declare_near ___rotlhi3 + +___rotlhi3: + xgdx + clra + andb #0x0f + xgdx + beq Return +Loop: + asrb + rolb + rola + rolb + dex + bne Loop +Return: + rts +#endif + +#ifdef L_ashrhi3 + declare_near ___ashrhi3 + + cpx #16 + bge Return_minus_1_or_zero + cpx #0 + beq Return +Loop: + asra + rorb + dex + bne Loop +Return: + rts +Return_minus_1_or_zero: + clrb + tsta + bpl Return_zero + comb +Return_zero: + tba + rts +#endif + +#ifdef L_ashrqi3 + declare_near ___ashrqi3 + + cmpa #8 + bge Return_minus_1_or_zero + tsta + beq Return +Loop: + asrb + deca + bne Loop +Return: + rts +Return_minus_1_or_zero: + clrb + tstb + bpl Return_zero + coma +Return_zero: + tab + rts +#endif + +#ifdef L_lshlqi3 + declare_near ___lshlqi3 + + cmpa #8 + bge Return_zero + tsta + beq Return +Loop: + lslb + deca + bne Loop +Return: + rts +Return_zero: + clrb + rts +#endif + +#ifdef L_divmodhi4 +#ifndef mc68hc12 +/* 68HC12 signed divisions are generated inline (idivs). */ + + declare_near __divmodhi4 + +; +;; D = numerator +;; X = denominator +;; +;; Result: D = D / X +;; X = D % X +;; + tsta + bpl Numerator_pos + comb ; D = -D <=> D = (~D) + 1 + coma + xgdx + inx + tsta + bpl Numerator_neg_denominator_pos +Numerator_neg_denominator_neg: + comb ; X = -X + coma + addd #1 + xgdx + idiv + coma + comb + xgdx ; Remainder <= 0 and result >= 0 + inx + rts + +Numerator_pos_denominator_pos: + xgdx + idiv + xgdx ; Both values are >= 0 + rts + +Numerator_pos: + xgdx + tsta + bpl Numerator_pos_denominator_pos +Numerator_pos_denominator_neg: + coma ; X = -X + comb + xgdx + inx + idiv + xgdx ; Remainder >= 0 but result <= 0 + coma + comb + addd #1 + rts + +Numerator_neg_denominator_pos: + xgdx + idiv + coma ; One value is > 0 and the other < 0 + comb ; Change the sign of result and remainder + xgdx + inx + coma + comb + addd #1 + rts +#endif /* !mc68hc12 */ +#endif + +#ifdef L_mulqi3 + declare_near ___mulqi3 + +; +; short __mulqi3(signed char a, signed char b); +; +; signed char a -> register A +; signed char b -> register B +; +; returns the signed result of A * B in register D. +; + tsta + bmi A_neg + tstb + bmi B_neg + mul + rts +B_neg: + negb + bra A_or_B_neg +A_neg: + nega + tstb + bmi AB_neg +A_or_B_neg: + mul + coma + comb + addd #1 + rts +AB_neg: + negb + mul + rts +#endif + +#ifdef L_mulhi3 + declare_near ___mulhi3 + +; +; +; unsigned short ___mulhi3(unsigned short a, unsigned short b) +; +; a = register D +; b = register X +; +#ifdef mc68hc12 + pshx ; Preserve X + exg x,y + emul + exg x,y + pulx + rts +#else +#ifdef NO_TMP + ; + ; 16 bit multiplication without temp memory location. + ; (smaller but slower) + ; + pshx ; (4) + ins ; (3) + pshb ; (3) + psha ; (3) + pshx ; (4) + pula ; (4) + pulx ; (5) + mul ; (10) B.high * A.low + xgdx ; (3) + mul ; (10) B.low * A.high + abx ; (3) + pula ; (4) + pulb ; (4) + mul ; (10) B.low * A.low + pshx ; (4) + tsx ; (3) + adda 1,x ; (4) + pulx ; (5) + rts ; (5) 20 bytes + ; --- + ; 91 cycles +#else + stx *_.tmp ; (4) + pshb ; (3) + ldab *_.tmp+1 ; (3) + mul ; (10) A.high * B.low + ldaa *_.tmp ; (3) + stab *_.tmp ; (3) + pulb ; (4) + pshb ; (4) + mul ; (10) A.low * B.high + addb *_.tmp ; (4) + stab *_.tmp ; (3) + ldaa *_.tmp+1 ; (3) + pulb ; (4) + mul ; (10) A.low * B.low + adda *_.tmp ; (4) + rts ; (5) 24/32 bytes + ; 77/85 cycles +#endif +#endif +#endif + +#ifdef L_mulhi32 + +; +; +; unsigned long __mulhi32(unsigned short a, unsigned short b) +; +; a = register D +; b = value on stack +; +; +---------------+ +; | B low | <- 7,x +; +---------------+ +; | B high | <- 6,x +; +---------------+ +; | PC low | +; +---------------+ +; | PC high | +; +---------------+ +; | Tmp low | +; +---------------+ +; | Tmp high | +; +---------------+ +; | A low | +; +---------------+ +; | A high | +; +---------------+ <- 0,x +; +; +; 5,x +; 4,x +; 2,x +; 1,x +; 0,x +; + declare_near __mulhi32 + +#ifdef mc68hc12 + ldy 2,sp + emul + exg x,y + rts +#else + pshx ; Room for temp value + pshb + psha + tsx + ldab 6,x + mul + xgdy ; A.high * B.high + ldab 7,x + pula + mul ; A.high * B.low + std 2,x + ldaa 1,x + ldab 6,x + mul ; A.low * B.high + addd 2,x + stab 2,x + tab + aby + bcc N + ldab #0xff + aby + iny +N: + ldab 7,x + pula + mul ; A.low * B.low + adda 2,x + pulx ; Drop temp location + pshy ; Put high part in X + pulx + bcc Ret + inx +Ret: + rts +#endif +#endif + +#ifdef L_mulsi3 + +; +; 8,y +; 6,y +; 4,y +; 2,y +; 0,y +; +; D,X -> A +; Stack -> B +; +; The result is: +; +; (((A.low * B.high) + (A.high * B.low)) << 16) + (A.low * B.low) +; +; +; + + declare __mulsi3 + +#ifdef mc68hc12 + + + + pshd ; Save A.low + ldy ARG(4),sp + emul ; A.low * B.high + ldy ARG(6),sp + exg x,d + emul ; A.high * B.low + leax d,x + ldy ARG(6),sp + puld + emul ; A.low * B.low + exg d,y + leax d,x + exg d,y + ret +#else +B_low = ARG(8) +B_high = ARG(6) +A_low = 0 +A_high = 2 + pshx + pshb + psha + tsy +; +; If B.low is 0, optimize into: (A.low * B.high) << 16 +; + ldd B_low,y + beq B_low_zero +; +; If A.high is 0, optimize into: (A.low * B.high) << 16 + (A.low * B.low) +; + cpx #0 + beq A_high_zero + bsr ___mulhi3 ; A.high * B.low +; +; If A.low is 0, optimize into: (A.high * B.low) << 16 +; + ldx A_low,y + beq A_low_zero ; X = 0, D = A.high * B.low + std 2,y +; +; If B.high is 0, we can avoid the (A.low * B.high) << 16 term. +; + ldd B_high,y + beq B_high_zero + bsr ___mulhi3 ; A.low * B.high + addd 2,y + std 2,y +; +; Here, we know that A.low and B.low are not 0. +; +B_high_zero: + ldd B_low,y ; A.low is on the stack + bsr __mulhi32 ; A.low * B.low + xgdx + tsy ; Y was clobbered, get it back + addd 2,y +A_low_zero: ; See A_low_zero_non_optimized below + xgdx +Return: + ins + ins + ins + ins + ret +; +; +; A_low_zero_non_optimized: +; +; At this step, X = 0 and D = (A.high * B.low) +; Optimize into: (A.high * B.low) << 16 +; +; xgdx +; clra ; Since X was 0, clearing D is superfuous. +; clrb +; bra Return +; ---------------- +; B.low == 0, the result is: (A.low * B.high) << 16 +; +; At this step: +; D = B.low = 0 +; X = A.high ? +; A.low is at A_low,y ? +; B.low is at B_low,y ? +; +B_low_zero: + ldd A_low,y + beq Zero1 + ldx B_high,y + beq Zero2 + bsr ___mulhi3 +Zero1: + xgdx +Zero2: + clra + clrb + bra Return +; ---------------- +; A.high is 0, optimize into: (A.low * B.high) << 16 + (A.low * B.low) +; +; At this step: +; D = B.low != 0 +; X = A.high = 0 +; A.low is at A_low,y ? +; B.low is at B_low,y ? +; +A_high_zero: + ldd A_low,y ; A.low + beq Zero1 + ldx B_high,y ; B.high + beq A_low_B_low + bsr ___mulhi3 + std 2,y + bra B_high_zero ; Do the (A.low * B.low) and the add. + +; ---------------- +; A.high and B.high are 0 optimize into: (A.low * B.low) +; +; At this step: +; D = B.high = 0 +; X = A.low != 0 +; A.low is at A_low,y != 0 +; B.high is at B_high,y = 0 +; +A_low_B_low: + ldd B_low,y ; A.low is on the stack + bsr __mulhi32 + bra Return +#endif +#endif + +#ifdef L_map_data + + .sect .install2,"ax",@progbits + .globl __map_data_section + .globl __data_image +#ifdef mc68hc12 + .globl __data_section_size +#endif +__map_data_section: +#ifdef mc68hc12 + ldx #__data_image + ldy #__data_section_start + ldd #__data_section_size + beq Done +Loop: + movb 1,x+,1,y+ + dbne d,Loop +#else + ldx #__data_image + ldy #__data_section_start + bra Start_map +Loop: + ldaa 0,x + staa 0,y + inx + iny +Start_map: + cpx #__data_image_end + blo Loop +#endif +Done: + +#endif + +#ifdef L_init_bss + + .sect .install2,"ax",@progbits + .globl __init_bss_section + +__init_bss_section: + ldd #__bss_size + beq Done + ldx #__bss_start +Loop: +#ifdef mc68hc12 + clr 1,x+ + dbne d,Loop +#else + clr 0,x + inx + subd #1 + bne Loop +#endif +Done: + +#endif + +#ifdef L_ctor + +; End of constructor table + .sect .install3,"ax",@progbits + .globl __do_global_ctors + +__do_global_ctors: + ; Start from the end - sizeof(void*) + ldx #__CTOR_END__-2 +ctors_loop: + cpx #__CTOR_LIST__ + blo ctors_done + pshx + ldx 0,x + jsr 0,x + pulx + dex + dex + bra ctors_loop +ctors_done: + +#endif + +#ifdef L_dtor + + .sect .fini3,"ax",@progbits + .globl __do_global_dtors + +;; +;; This piece of code is inserted in the _exit() code by the linker. +;; +__do_global_dtors: + pshb ; Save exit code + psha + ldx #__DTOR_LIST__ +dtors_loop: + cpx #__DTOR_END__ + bhs dtors_done + pshx + ldx 0,x + jsr 0,x + pulx + inx + inx + bra dtors_loop +dtors_done: + pula ; Restore exit code + pulb + +#endif + +#ifdef L_far_tramp +#ifdef mc68hc12 + .sect .tramp,"ax",@progbits + .globl __far_trampoline + +;; This is a trampoline used by the linker to invoke a function +;; using rtc to return and being called with jsr/bsr. +;; The trampoline generated is: +;; +;; foo_tramp: +;; ldy #foo +;; call __far_trampoline,page(foo) +;; +;; The linker transforms: +;; +;; jsr foo +;; +;; into +;; jsr foo_tramp +;; +;; The linker generated trampoline and _far_trampoline must be in +;; non-banked memory. +;; +__far_trampoline: + movb 0,sp, 2,sp ; Copy page register below the caller's return + leas 2,sp ; address. + jmp 0,y ; We have a 'call/rtc' stack layout now + ; and can jump to the far handler + ; (whose memory bank is mapped due to the + ; call to the trampoline). +#endif + +#ifdef mc68hc11 + .sect .tramp,"ax",@progbits + .globl __far_trampoline + +;; Trampoline generated by gcc for 68HC11: +;; +;; pshb +;; ldab #%page(func) +;; ldy #%addr(func) +;; jmp __far_trampoline +;; +__far_trampoline: + psha ; (2) Save function parameter (high) + ;; + psha ; (2) + ;; + pshx ; (4) + tsx ; (3) + ldab 4,x ; (4) Restore function parameter (low) + ldaa 2,x ; (4) Get saved page number + staa 4,x ; (4) Save it below return PC + pulx ; (5) + pula ; (3) + pula ; (3) Restore function parameter (high) + jmp 0,y ; (4) +#endif +#endif + +#ifdef L_call_far +#ifdef mc68hc11 + .sect .tramp,"ax",@progbits + .globl __call_a16 + .globl __call_a32 +;; +;; The call methods are used for 68HC11 to support memory bank switching. +;; Every far call is redirected to these call methods. Its purpose is to: +;; +;; 1/ Save the current page on the stack (1 byte to follow 68HC12 call frame) +;; 2/ Install the new page +;; 3/ Jump to the real function +;; +;; The page switching (get/save) is board dependent. The default provided +;; here does nothing (just create the appropriate call frame). +;; +;; Call sequence (10 bytes, 13 cycles): +;; +;; ldx #page ; (3) +;; ldy #func ; (4) +;; jsr __call_a16 ; (6) +;; +;; Call trampoline (11 bytes, 19 cycles): +;; +__call_a16: + ;; xgdx ; (3) + ;; ; (3) ldaa _current_page + psha ; (2) + ;; ; (4) staa _current_page + ;; xgdx ; (3) + jmp 0,y ; (4) + +;; +;; Call sequence (10 bytes, 14 cycles): +;; +;; pshb ; (2) +;; ldab #page ; (2) +;; ldy #func ; (4) +;; jsr __call_a32 ; (6) +;; +;; Call trampoline (87 bytes, 57 cycles): +;; +__call_a32: + pshx ; (4) + psha ; (2) + ;; ; (3) ldaa _current_page + psha ; (2) + ;; ; (4) staa _current_page + tsx ; (3) + ldab 6,x ; (4) Restore function parameter + ldaa 5,x ; (4) Move PC return at good place + staa 6,x ; (4) + ldaa 4,x ; (4) + staa 5,x ; (4) + pula ; (3) + staa 4,x ; (4) + pula ; (3) + pulx ; (5) + jmp 0,y ; (4) +#endif +#endif + +#ifdef L_return_far +#ifdef mc68hc11 + .sect .tramp,"ax",@progbits + .globl __return_void + .globl __return_16 + .globl __return_32 + +__return_void: + ;; pulb + ;; (Board specific) + ;; rts +__return_16: + ;; xgdx + ;; pulb + ;; (Board specific) + ;; xgdx + ;; rts +__return_32: + ;; xgdy + ;; pulb + ;; (Board specific) + ;; xgdy + ;; rts + ins + rts +#endif +#endif +.Lend: +;----------------------------------------- +; end required gcclib code +;----------------------------------------- diff -u -r -N gcc-3.3.6-core-orig/gcc/config/m68hc11/larith.asm gcc-3.3.6/gcc/config/m68hc11/larith.asm --- gcc-3.3.6-core-orig/gcc/config/m68hc11/larith.asm 2003-04-12 15:53:47.000000000 +0100 +++ gcc-3.3.6/gcc/config/m68hc11/larith.asm 2010-11-09 20:47:16.000000000 +0000 @@ -35,6 +35,20 @@ .file "larith.asm" +/* cover the root directory case */ +#if !defined(mc68hc11) && !defined(mc68hc12) && !defined(m9s12x) +#if defined(target11) +#define mc68hc11 +#endif +#if defined(target12) +#define mc68hc12 +#endif +#if defined(targets12x) +#define m9s12x +#define mc68hc12 +#endif +#endif + #ifdef __HAVE_SHORT_INT__ .mode mshort #else @@ -402,18 +416,30 @@ std 6,y ; Save, borrow preserved ldd ARG(6),x +#if defined(m9s12x) + sbed ARG(14),x +#else sbcb ARG(15),x sbca ARG(14),x +#endif std 4,y ldd ARG(4),x +#if defined(m9s12x) + sbed ARG(12),x +#else sbcb ARG(13),x sbca ARG(12),x +#endif std 2,y ldd ARG(2),x ; Subtract MSB +#if defined(m9s12x) + sbed ARG(10),x +#else sbcb ARG(11),x sbca ARG(10),x +#endif std 0,y xgdy ; @@ -469,10 +495,14 @@ comb coma +#if defined(m9s12x) + comx +#else xgdx comb coma xgdx +#endif rts #endif @@ -486,10 +516,14 @@ beq Return Loop: lsld +#if defined(m9s12x) + rolx +#else xgdx rolb rola xgdx +#endif dey bne Loop Return: @@ -505,10 +539,14 @@ xgdy beq Return Loop: +#if defined(m9s12x) + asrx +#else xgdx asra rorb xgdx +#endif rora rorb dey @@ -526,9 +564,13 @@ xgdy beq Return Loop: +#if defined(m9s12x) + lsrx +#else xgdx lsrd xgdx +#endif rora rorb dey @@ -579,10 +621,14 @@ declare_near ___rotrhi3 ___rotrhi3: +#if defined(m9s12x) + andx #0x000f +#else xgdx clra andb #0x0f xgdx +#endif beq Return Loop: tap @@ -598,10 +644,14 @@ declare_near ___rotlhi3 ___rotlhi3: +#if defined(m9s12x) + andx #0x000f +#else xgdx clra andb #0x0f xgdx +#endif beq Return Loop: asrb @@ -951,6 +1001,9 @@ declare __mulsi3 #ifdef mc68hc12 + + + pshd ; Save A.low ldy ARG(4),sp emul ; A.low * B.high diff -u -r -N gcc-3.3.6-core-orig/gcc/config/m68hc11/ldivmod.asm gcc-3.3.6/gcc/config/m68hc11/ldivmod.asm --- gcc-3.3.6-core-orig/gcc/config/m68hc11/ldivmod.asm 1970-01-01 01:00:00.000000000 +0100 +++ gcc-3.3.6/gcc/config/m68hc11/ldivmod.asm 2010-11-09 20:47:16.000000000 +0000 @@ -0,0 +1,598 @@ +;;;----------------------------------------- + +;;; Hand coded div and mod functions. +;;; AES 2009 +;;; for S12X platform +;;;----------------------------------------- + +; Re-coded for m68hc12 as well - James Murray October 2010 + + .file "ldivmod.asm" + + +/* cover the root directory case */ +#if !defined(mc68hc11) && !defined(mc68hc12) && !defined(m9s12x) +#if defined(target11) +#define mc68hc11 +#endif +#if defined(target12) +#define mc68hc12 +#endif +#if defined(targets12x) +#define m9s12x +#define mc68hc12 +#endif +#endif + +#if !defined(mc68hc11) +; not for 68hc11 + +#ifdef __HAVE_SHORT_INT__ + .mode mshort +#else + .mode mlong +#endif + + .macro declare_near name + .globl \name + .type \name,@function + .size \name,.Lend-\name +\name: + .endm + +#if defined(__USE_RTC__) +# define ARG(N) N+1 + + .macro ret +#if defined(mc68hc12) + rtc +#else + jmp __return_32 +#endif + .endm + + .macro declare name + .globl \name + .type \name,@function + .size \name,.Lend-\name + .far \name +\name: + .endm + + .macro farsym name + .far NAME + .endm + +#else +# define ARG(N) N + + .macro ret + rts + .endm + + .macro farsym name + .endm + + .macro declare name + .globl \name + .type \name,@function + .size \name,.Lend-\name +\name: + .endm + +#endif + + .sect .text + + +#define REG(NAME) \ +NAME: .dc.w 1; \ + .type NAME,@object ; \ + .size NAME,2 + +#ifdef L_regs_min +/* Pseudo hard registers used by gcc. + They should be located in page0. */ + + .sect .softregs + .globl _.tmp + +REG(_.tmp) +#endif + + + +/* ok, guessing that we get called with a in D and X and B on stack */ + +;;; +;;; long __divsi3 ( long num, long den ) +;;; + +;;; d == num_low +;;; x == num_high + +;;; sp, ARG(4) == den_high +;;; sp, ARG(6) == den_low +;;; return result in XD + +;;; calling here we have also pushed 4 extra bytes on stack +;;; and we dont use a frame pointer + + +udivmodsi: + pshy ; preserve y + pshd ; save numerator in case ediv fails + pshx +#ifndef m9s12x + tst ARG(10), sp ; does denominator fit in uint16 ? + bne go_soft_udivmodsi + tst ARG(11), sp ; does denominator fit in uint16 ? + bne go_soft_udivmodsi +#else + tstw ARG(10), sp ; does denominator fit in uint16 ? + bne go_soft_udivmodsi +#endif + tfr x,y ; load num_high into y + ldx ARG(12), sp ; load denominator into x + ediv + bvs go_soft_udivmodsi ; overflow ?? + + ;; overwrite denominator on stack with modulus + ;; this is ok since c copies args onto stack (???CHECKME) + + std ARG(12), sp +#ifndef m9s12x + clr ARG(10), sp + clr ARG(11), sp +#else + clrw ARG(10), sp +#endif + + ;; return division results in X:D +#ifndef m9s12x + ldx #0 +#else + clrx +#endif + tfr y,d + + leas 4, sp ; deallocate stack for numerator save + puly ; retrieve y + rts + +go_soft_udivmodsi: +#ifndef m9s12x + ldy #0 +#else + clry +#endif + bra soft_udivmodsi + + +divmodsi: + + pshy ; preserve y + pshd ; save numerator in case edivs fails + pshx + ldy ARG(10),sp ; denominator fits in signed int16 ?? + beq test_pos +#ifndef m9s12x + xgdy + coma + comb + xgdy +#else + comy +#endif + beq test_neg + bra soft_divmodsi +test_pos: + ldy ARG(12),sp + bpl hard_divmodsi + bra soft_divmodsi + +test_neg: + ldy ARG(12),sp + bpl soft_divmodsi + +hard_divmodsi: + + exg x,y + edivs ; attempt a divide by hardware + bvs soft_divmodsi ; an overflow happened ... do soft divide + +#ifndef m9s12x + clr ARG(10),sp + clr ARG(11),sp +#else + clrw ARG(10),sp +#endif + std ARG(12), sp + bpl skip_hdsx_mod ; sign extend modulus + movw #0xFFFF, ARG(10), sp +skip_hdsx_mod: + + + ;; returned division results in X:D +#ifndef m9s12x + ldx #0 + xgdy + tsta + xgdy +#else + clrx + tsty +#endif + bpl skip_hdsx_div ; sign extend result + ldx #0xFFFF + +skip_hdsx_div: + tfr y,d + leas 4,sp ; deallocate stack + puly ; retrieve y + rts + +soft_divmodsi: + ;; numerator in sp and sp+1 ; den in ARG(10) and ARG(12) +#ifndef m9s12x + ldy #0 +#else + clry ; use y to evaluate sign of result +#endif + tst 0, sp ; was tstw + bpl sd_skip_neg_num + +#ifndef m9s12x + xgdy + orab #3 + xgdy + com 3, sp + com 2, sp + com 1, sp + com 0, sp + inc 3, sp + bne sd_skip_neg_num + inc 2, sp + bne sd_skip_neg_num + inc 1, sp + bne sd_skip_neg_num + inc 0, sp +#else + ory #3 + comw 2, sp + comw 0, sp + incw 2, sp + bne sd_skip_neg_num + incw 0, sp +#endif + +sd_skip_neg_num: + + tst ARG(10), sp + bpl sd_skip_neg_den ; was tstw + +#ifndef m9s12x + xgdy + eorb #1 + xgdy + com ARG(13), sp + com ARG(12), sp + com ARG(11), sp + com ARG(10), sp + inc ARG(13), sp + bne sd_skip_neg_den + inc ARG(12), sp + bne sd_skip_neg_den + inc ARG(11), sp + bne sd_skip_neg_den + inc ARG(10), sp +#else + eory #1 + comw ARG(12), sp + comw ARG(10), sp + incw ARG(12), sp + bne sd_skip_neg_den + incw ARG(10), sp +#endif + +sd_skip_neg_den: +soft_udivmodsi: ; if called from udivmodsi + ; make sure y=0 + leas -8,sp ; allocate for 'bit' and 'res' + + ;; stack should look like this on entry if ARG(N)=N: + + ;; + ;; + ;; + ;; denominator (SI) --- sp+18 + ;; + ;; return address for calling function (HI) sp+16 + ;; + ;; return address for frontend function (HI) sp+14 + ;; + ;; preserve y ---- sp+12 + ;; + ;; + ;; + ;; numerator (SI) ---- sp+8 + ;; + ;; + ;; + ;; bit (SI) ---- sp+4 + ;; + ;; + ;; + ;; res (SI) ---- sp + +#ifndef m9s12x + clr 0, sp ; res = 0 + clr 1, sp + clr 2, sp + clr 3, sp + tst ARG(18),sp + bne checked_den + tst ARG(19),sp + bne checked_den + tst ARG(20),sp + bne checked_den + tst ARG(21),sp + beq while_end +#else + clrw 0, sp ; res = 0 + clrw 2, sp + tstw ARG(18),sp + bne checked_den + tstw ARG(20),sp + beq while_end +#endif + +checked_den: + + movw #1, 6, sp +#ifndef m9s12x + clr 4,sp ; bit = 1 + clr 5,sp ; bit = 1 +#else + clrw 4,sp ; bit = 1 +#endif + +while_den: ; while ((den < num) && !(den.bit31)) + tst ARG(18), sp ; was tstw + bmi while_bit + ldd 10,sp + ldx 8,sp + + subd ARG(20), sp +#ifndef m9s12x + xgdx + sbcb ARG(19), sp + sbca ARG(18), sp + xgdx +#else + sbex ARG(18), sp +#endif + bcs while_bit + +#ifndef m9s12x + asl ARG(21), sp ; den <<= 1 + rol ARG(20), sp + rol ARG(19), sp + rol ARG(18), sp + + asl 7,sp ; bit <<= 1 + rol 6,sp + rol 5,sp + rol 4,sp +#else + aslw ARG(20), sp ; den <<= 1 + rolw ARG(18), sp + + aslw 6,sp ; bit <<= 1 + rolw 4,sp +#endif + + bra while_den + + +while_bit: ; while (bit!=0) +#ifndef m9s12x + tst 4, sp + bne while_bit_ok + tst 5, sp + bne while_bit_ok + tst 6, sp + bne while_bit_ok + tst 7,sp + beq while_end +#else + tstw 4, sp + bne while_bit_ok + tstw 6,sp + beq while_end +#endif + +while_bit_ok: + + ldd 10, sp ; if (num >= den) + ldx 8, sp + subd ARG(20),sp +#ifndef m9s12x + xgdx + sbcb ARG(19),sp + sbca ARG(18),sp + xgdx +#else + sbex ARG(18),sp +#endif + bcs skip_restore ; here was bmi + + std 10,sp ; num-=den + stx 8,sp + +#ifndef m9s12x + ldd 0,sp ; res|= bit + oraa 4,sp + orab 5,sp + std 0,sp + ldd 2,sp + oraa 6,sp + orab 7,sp + std 2,sp +#else + ldx 0,sp ; res|= bit + orx 4,sp + stx 0,sp + ldx 2,sp + orx 6,sp + stx 2,sp +#endif + +skip_restore: + +#ifndef m9s12x + lsr 4,sp ; bit >>=1 + ror 5,sp + ror 6,sp + ror 7,sp + + lsr ARG(18),sp ; den >>=1 + ror ARG(19),sp + ror ARG(20),sp + ror ARG(21),sp +#else + lsrw 4,sp ; bit >>=1 + rorw 6,sp + + lsrw ARG(18),sp ; den >>=1 + rorw ARG(20),sp +#endif + + bra while_bit + +while_end: + ;; numerator contains mod + ;; overwrite denominator with it on stack for return +// movw 8,sp,ARG(18), sp +// movw 10,sp, ARG(20), sp + leax ARG(18), sp + movw 8,sp, 0,x + movw 10,sp, 2,x + + ldx 0,sp + ldd 2,sp + + leas 12,sp ; deallocate locals +#ifndef m9s12x + xgdy ; do we need to negate result ? + tsta + bne no_end + tstb + bne no_end + xgdy + bra end_division +no_end: + xgdy +#else + tsty ; do we need to negate result ? + beq end_division +#endif + + ;; if y&1 then negate result + ;; if y&2 then negate modulus + + pshy +#ifndef m9s12x + xgdy + andb #1 + xgdy +#else + andy #1 +#endif + puly + beq skip_end_res_neg + + coma + comb +#ifndef m9s12x + xgdx + coma + comb + xgdx +#else + comx +#endif + incb + bne end_division + inca + bne end_division + inx + +skip_end_res_neg: +#ifndef m9s12x + xgdy + andb #2 + xgdy +#else + andy #2 +#endif + beq end_division + +#ifndef m9s12x + com ARG(6), sp + com ARG(7), sp + com ARG(8), sp + com ARG(9), sp + inc ARG(9), sp + bne end_division + inc ARG(8), sp + bne end_division + inc ARG(7), sp + bne end_division + inc ARG(6), sp +#else + comw ARG(6), sp + comw ARG(8), sp + incw ARG(8), sp + bne end_division + incw ARG(6), sp +#endif + +end_division: + puly + rts + + + +;;; si3 frontends for divmodsi3 + + declare __divsi3 + bsr divmodsi + ret + + declare __modsi3 + + bsr divmodsi + ldx ARG(2), sp ; stack has two less on it now + ldd ARG(4), sp + ret + + declare __umodsi3 + bsr udivmodsi + ldx ARG(2), sp + ldd ARG(4), sp + ret + + + declare __udivsi3 + bsr udivmodsi + ret + +#endif + ; defined(m68hc12) || defined(m9s12x) + + +.Lend: +;----------------------------------------- +; end required gcclib code +;----------------------------------------- diff -u -r -N gcc-3.3.6-core-orig/gcc/config/m68hc11/ldivmod.asm-s12x_only gcc-3.3.6/gcc/config/m68hc11/ldivmod.asm-s12x_only --- gcc-3.3.6-core-orig/gcc/config/m68hc11/ldivmod.asm-s12x_only 1970-01-01 01:00:00.000000000 +0100 +++ gcc-3.3.6/gcc/config/m68hc11/ldivmod.asm-s12x_only 2010-11-09 20:47:16.000000000 +0000 @@ -0,0 +1,380 @@ +;;;----------------------------------------- + +;;; Hand coded div and mod functions. +;;; AES 2009 + +;;;----------------------------------------- + + + + + .file "ldivmod.asm" + +#ifdef __HAVE_SHORT_INT__ + .mode mshort +#else + .mode mlong +#endif + + .macro declare_near name + .globl \name + .type \name,@function + .size \name,.Lend-\name +\name: + .endm + +#if defined(__USE_RTC__) +# define ARG(N) N+1 + + .macro ret +#if defined(mc68hc12) + rtc +#else + jmp __return_32 +#endif + .endm + + .macro declare name + .globl \name + .type \name,@function + .size \name,.Lend-\name + .far \name +\name: + .endm + + .macro farsym name + .far NAME + .endm + +#else +# define ARG(N) N + + .macro ret + rts + .endm + + .macro farsym name + .endm + + .macro declare name + .globl \name + .type \name,@function + .size \name,.Lend-\name +\name: + .endm + +#endif + + .sect .text + + +#define REG(NAME) \ +NAME: .dc.w 1; \ + .type NAME,@object ; \ + .size NAME,2 + +#ifdef L_regs_min +/* Pseudo hard registers used by gcc. + They should be located in page0. */ + + .sect .softregs + .globl _.tmp + +REG(_.tmp) +#endif + + + +/* ok, guessing that we get called with a in D and X and B on stack */ + +;;; +;;; long __divsi3 ( long num, long den ) +;;; + +;;; d == num_low +;;; x == num_high + +;;; sp, ARG(4) == den_high +;;; sp, ARG(6) == den_low +;;; return result in XD + +;;; calling here we have also pushed 4 extra bytes on stack +;;; and we dont use a frame pointer + + +udivmodsi: + pshy ; preserve y + pshd ; save numerator in case ediv fails + pshx + tstw ARG(10), sp ; does denominator fit in uint16 ? + bne go_soft_udivmodsi + tfr x,y ; load num_high into y + ldx ARG(12), sp ; load denominator into x + ediv + bvs go_soft_udivmodsi ; overflow ?? + + ;; overwrite denominator on stack with modulus + ;; this is ok since c copies args onto stack (???CHECKME) + + std ARG(12), sp + clrw ARG(10), sp + + ;; return division results in X:D + clrx + tfr y,d + + leas 4, sp ; deallocate stack for numerator save + puly ; retrieve y + rts + +go_soft_udivmodsi: + clry + bra soft_udivmodsi + + +divmodsi: + + pshy ; preserve y + pshd ; save numerator in case edivs fails + pshx + ldy ARG(10),sp ; denominator fits in signed int16 ?? + beq test_pos + comy + beq test_neg + bra soft_divmodsi +test_pos: + ldy ARG(12),sp + bpl hard_divmodsi + bra soft_divmodsi + +test_neg: + ldy ARG(12),sp + bpl soft_divmodsi + +hard_divmodsi: + + exg x,y + edivs ; attempt a divide by hardware + bvs soft_divmodsi ; an overflow happened ... do soft divide + + clrw ARG(10),sp + std ARG(12), sp + bpl skip_hdsx_mod ; sign extend modulus + movw #0xFFFF, ARG(10), sp +skip_hdsx_mod: + + + ;; returned division results in X:D + clrx + tsty + bpl skip_hdsx_div ; sign extend result + ldx #0xFFFF + +skip_hdsx_div: + tfr y,d + leas 4,sp ; deallocate stack + puly ; retrieve y + rts + +soft_divmodsi: + ;; numerator in sp and sp+1 ; den in ARG(10) and ARG(12) + clry ; use y to evaluate sign of result + tstw 0, sp + bpl sd_skip_neg_num + + ory #3 + comw 2, sp + comw 0, sp + incw 2, sp + bne sd_skip_neg_num + incw 0, sp + + +sd_skip_neg_num: + + tstw ARG(10), sp + bpl sd_skip_neg_den + + eory #1 + comw ARG(12), sp + comw ARG(10), sp + incw ARG(12), sp + bne sd_skip_neg_den + incw ARG(10), sp + + +sd_skip_neg_den: +soft_udivmodsi: ; if called from udivmodsi + ; make sure y=0 + leas -8,sp ; allocate for 'bit' and 'res' + + ;; stack should look like this on entry if ARG(N)=N: + + ;; + ;; + ;; + ;; denominator (SI) --- sp+18 + ;; + ;; return address for calling function (HI) sp+16 + ;; + ;; return address for frontend function (HI) sp+14 + ;; + ;; preserve y ---- sp+12 + ;; + ;; + ;; + ;; numerator (SI) ---- sp+8 + ;; + ;; + ;; + ;; bit (SI) ---- sp+4 + ;; + ;; + ;; + ;; res (SI) ---- sp + + clrw 0, sp ; res = 0 + clrw 2, sp + + tstw ARG(18),sp + bne checked_den + tstw ARG(20),sp + beq while_end + +checked_den: + + movw #1, 6, sp + clrw 4,sp ; bit = 1 + +while_den: ; while ((den < num) && !(den.bit31)) + tstw ARG(18), sp + bmi while_bit + ldd 10,sp + ldx 8,sp + + subd ARG(20), sp + sbex ARG(18), sp + bcs while_bit + + aslw ARG(20), sp ; den <<= 1 + rolw ARG(18), sp + + aslw 6,sp ; bit <<= 1 + rolw 4,sp + + bra while_den + + +while_bit: ; while (bit!=0) + tstw 4, sp + bne while_bit_ok + tstw 6,sp + beq while_end + +while_bit_ok: + + ldd 10, sp ; if (num >= den) + ldx 8, sp + subd ARG(20),sp + sbex ARG(18),sp + bcs skip_restore ; here was bmi + + std 10,sp ; num-=den + stx 8,sp + + ldx 0,sp ; res|= bit + orx 4,sp + stx 0,sp + ldx 2,sp + orx 6,sp + stx 2,sp + +skip_restore: + + lsrw 4,sp ; bit >>=1 + rorw 6,sp + + lsrw ARG(18),sp ; den >>=1 + rorw ARG(20),sp + + bra while_bit + +while_end: + ;; numerator contains mod + ;; overwrite denominator with it on stack for return +// movw 8,sp,ARG(18), sp +// movw 10,sp, ARG(20), sp + leax ARG(18), sp + movw 8,sp, 0,x + movw 10,sp, 2,x + + ldx 0,sp + ldd 2,sp + + leas 12,sp ; deallocate locals + tsty ; do we need to negate result ? + beq end_division + + ;; if y&1 then negate result + ;; if y&2 then negate modulus + + pshy + andy #1 + puly + beq skip_end_res_neg + + coma + comb + comx + incb + bne end_division + inca + bne end_division + incx + +skip_end_res_neg: + andy #2 + beq end_division + + comw ARG(6), sp + comw ARG(8), sp + incw ARG(8), sp + bne end_division + incw ARG(6), sp + + +end_division: + puly + rts + + + +;;; si3 frontends for divmodsi3 + + declare __divsi3 + bsr divmodsi + ret + + declare __modsi3 + + bsr divmodsi + ldx ARG(2), sp ; stack has two less on it now + ldd ARG(4), sp + ret + + declare __umodsi3 + bsr udivmodsi + ldx ARG(2), sp + ldd ARG(4), sp + ret + + + declare __udivsi3 + bsr udivmodsi + ret + + +.Lend: +;----------------------------------------- +; end required gcclib code +;----------------------------------------- diff -u -r -N gcc-3.3.6-core-orig/gcc/config/m68hc11/m68hc11.c gcc-3.3.6/gcc/config/m68hc11/m68hc11.c --- gcc-3.3.6-core-orig/gcc/config/m68hc11/m68hc11.c 2003-04-12 22:53:41.000000000 +0100 +++ gcc-3.3.6/gcc/config/m68hc11/m68hc11.c 2010-11-09 20:47:16.000000000 +0000 @@ -1,21 +1,22 @@ /* Subroutines for code generation on Motorola 68HC11 and 68HC12. - Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. Contributed by Stephane Carrez (stcarrez@nerim.fr) -This file is part of GNU CC. +This file is part of GCC. -GNU CC is free software; you can redistribute it and/or modify +GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. -GNU CC is distributed in the hope that it will be useful, +GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to +along with GCC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. @@ -70,6 +71,7 @@ static int m68hc11_make_autoinc_notes PARAMS ((rtx*, void*)); static int m68hc11_auto_inc_p PARAMS ((rtx)); static tree m68hc11_handle_fntype_attribute PARAMS ((tree *, tree, tree, int, bool *)); +static tree m68hc11_handle_page0_attribute PARAMS ((tree *, tree, tree, int, bool *)); const struct attribute_spec m68hc11_attribute_table[]; void create_regs_rtx PARAMS ((void)); @@ -79,6 +81,7 @@ static void m68hc11_asm_out_constructor PARAMS ((rtx, int)); static void m68hc11_asm_out_destructor PARAMS ((rtx, int)); static void m68hc11_encode_section_info PARAMS((tree, int)); +static const char *m68hc11_strip_name_encoding (const char* str); /* Must be set to 1 to produce debug messages. */ int debug_m6811 = 0; @@ -129,6 +132,16 @@ This is 1 for 68HC11 and 0 for 68HC12. */ int m68hc11_sp_correction; +#define ADDR_STRICT 0x01 /* Accept only registers in class A_REGS */ +#define ADDR_INCDEC 0x02 /* Post/Pre inc/dec */ +#define ADDR_INDEXED 0x04 /* D-reg index */ +#define ADDR_OFFSET 0x08 +#define ADDR_INDIRECT 0x10 /* Accept (mem (mem ...)) for [n,X] */ +#define ADDR_CONST 0x20 /* Accept const and symbol_ref */ + +int m68hc11_addr_mode; +int m68hc11_mov_addr_mode; + /* Comparison operands saved by the "tstxx" and "cmpxx" expand patterns. */ rtx m68hc11_compare_op0; rtx m68hc11_compare_op1; @@ -227,6 +240,9 @@ #undef TARGET_ENCODE_SECTION_INFO #define TARGET_ENCODE_SECTION_INFO m68hc11_encode_section_info +#undef TARGET_STRIP_NAME_ENCODING +#define TARGET_STRIP_NAME_ENCODING m68hc11_strip_name_encoding + struct gcc_target targetm = TARGET_INITIALIZER; int @@ -264,6 +280,8 @@ m68hc11_reg_valid_for_base[HARD_Z_REGNUM] = 1; m68hc11_sp_correction = 1; m68hc11_tmp_regs_class = D_REGS; + m68hc11_addr_mode = ADDR_OFFSET; + m68hc11_mov_addr_mode = 0; if (m68hc11_soft_reg_count == 0 && !TARGET_M6812) m68hc11_soft_reg_count = "4"; } @@ -283,6 +301,10 @@ m68hc11_reg_valid_for_index[HARD_D_REGNUM] = 1; m68hc11_sp_correction = 0; m68hc11_tmp_regs_class = TMP_REGS; + m68hc11_addr_mode = ADDR_INDIRECT | ADDR_OFFSET | ADDR_CONST + | (TARGET_AUTO_INC_DEC ? ADDR_INCDEC : 0); + m68hc11_mov_addr_mode = ADDR_OFFSET | ADDR_CONST + | (TARGET_AUTO_INC_DEC ? ADDR_INCDEC : 0); target_flags &= ~MASK_M6811; target_flags |= MASK_NO_DIRECT_MODE; if (m68hc11_soft_reg_count == 0) @@ -316,7 +338,7 @@ /* For 68HC12, the Z register emulation is not necessary when the frame pointer is not used. The frame pointer is eliminated and replaced by the stack register (which is a BASE_REG_CLASS). */ - if (TARGET_M6812 && flag_omit_frame_pointer && optimize) + if (TARGET_M6812 && flag_omit_frame_pointer && optimize && 0) { fixed_regs[HARD_Z_REGNUM] = 1; } @@ -385,8 +407,9 @@ } int -m68hc11_hard_regno_rename_ok (reg1, reg2) +m68hc11_hard_regno_rename_ok (reg1, reg2, mode) int reg1, reg2; + int mode; { /* Don't accept renaming to Z register. We will replace it to X,Y or D during machine reorg pass. */ @@ -398,6 +421,11 @@ && (D_REGNO_P (reg1) || X_REGNO_P (reg1))) return 0; + /* Don't rename D as if it holds a 8-bit value, the code will be + bigger. */ + if (mode == QImode && D_REGNO_P (reg1)) + return 0; + return 1; } @@ -522,21 +550,25 @@ For 68hc11: n,r with n in [0..255] and r in A_REGS class For 68hc12: n,r no constraint on the constant, r in A_REGS class. */ static int -register_indirect_p (operand, mode, strict) - rtx operand; - enum machine_mode mode; - int strict; +register_indirect_p (rtx operand, enum machine_mode mode, int addr_mode) { rtx base, offset; switch (GET_CODE (operand)) { + case MEM: + if ((addr_mode & ADDR_INDIRECT) && GET_MODE_SIZE (mode) <= 2) + return register_indirect_p (XEXP (operand, 0), mode, + addr_mode & (ADDR_STRICT | ADDR_OFFSET)); + return 0; + case POST_INC: case PRE_INC: case POST_DEC: case PRE_DEC: - if (TARGET_M6812 && TARGET_AUTO_INC_DEC) - return register_indirect_p (XEXP (operand, 0), mode, strict); + if (addr_mode & ADDR_INCDEC) + return register_indirect_p (XEXP (operand, 0), mode, + addr_mode & ADDR_STRICT); return 0; case PLUS: @@ -548,36 +580,57 @@ if (GET_CODE (offset) == MEM) return 0; + /* Indexed addressing mode with 2 registers. */ + if (GET_CODE (base) == REG && GET_CODE (offset) == REG) + { + if (!(addr_mode & ADDR_INDEXED)) + return 0; + + addr_mode &= ADDR_STRICT; + if (REGNO_OK_FOR_BASE_P2 (REGNO (base), addr_mode) + && REGNO_OK_FOR_INDEX_P2 (REGNO (offset), addr_mode)) + return 1; + + if (REGNO_OK_FOR_BASE_P2 (REGNO (offset), addr_mode) + && REGNO_OK_FOR_INDEX_P2 (REGNO (base), addr_mode)) + return 1; + + return 0; + } + + if (!(addr_mode & ADDR_OFFSET)) + return 0; + if (GET_CODE (base) == REG) { - if (!VALID_CONSTANT_OFFSET_P (offset, mode)) + if (!VALID_CONSTANT_OFFSET_P (offset, mode)) return 0; - if (strict == 0) + if (!(addr_mode & ADDR_STRICT)) return 1; - return REGNO_OK_FOR_BASE_P2 (REGNO (base), strict); + return REGNO_OK_FOR_BASE_P2 (REGNO (base), 1); } + if (GET_CODE (offset) == REG) { if (!VALID_CONSTANT_OFFSET_P (base, mode)) return 0; - if (strict == 0) + if (!(addr_mode & ADDR_STRICT)) return 1; - return REGNO_OK_FOR_BASE_P2 (REGNO (offset), strict); + return REGNO_OK_FOR_BASE_P2 (REGNO (offset), 1); } return 0; case REG: - return REGNO_OK_FOR_BASE_P2 (REGNO (operand), strict); + return REGNO_OK_FOR_BASE_P2 (REGNO (operand), addr_mode & ADDR_STRICT); case CONST_INT: - if (TARGET_M6811) - return 0; - - return VALID_CONSTANT_OFFSET_P (operand, mode); + if (addr_mode & ADDR_CONST) + return VALID_CONSTANT_OFFSET_P (operand, mode); + return 0; default: return 0; @@ -592,6 +645,7 @@ enum machine_mode mode; { rtx base, offset; + int addr_mode; if (GET_CODE (operand) == REG && reload_in_progress && REGNO (operand) >= FIRST_PSEUDO_REGISTER @@ -611,7 +665,8 @@ if (PUSH_POP_ADDRESS_P (operand)) return 1; - if (!register_indirect_p (operand, mode, reload_completed)) + addr_mode = m68hc11_mov_addr_mode | (reload_completed ? ADDR_STRICT : 0); + if (!register_indirect_p (operand, mode, addr_mode)) return 0; if (TARGET_M6812 && GET_CODE (operand) == PLUS @@ -654,12 +709,21 @@ rtx operand; enum machine_mode mode; { + int addr_mode; + + if (GET_CODE (operand) == REG && reload_in_progress + && REGNO (operand) >= FIRST_PSEUDO_REGISTER + && reg_equiv_memory_loc[REGNO (operand)]) + { + operand = reg_equiv_memory_loc[REGNO (operand)]; + operand = eliminate_regs (operand, 0, NULL_RTX); + } if (GET_CODE (operand) != MEM) return 0; operand = XEXP (operand, 0); - return register_indirect_p (operand, mode, - (reload_completed | reload_in_progress)); + addr_mode = m68hc11_addr_mode | (reload_completed ? ADDR_STRICT : 0); + return register_indirect_p (operand, mode, addr_mode); } static int @@ -668,6 +732,8 @@ enum machine_mode mode; int strict; { + int addr_mode; + if (CONSTANT_ADDRESS_P (operand) && TARGET_M6812) { /* Reject the global variables if they are too wide. This forces @@ -677,7 +743,8 @@ return 1; } - if (register_indirect_p (operand, mode, strict)) + addr_mode = m68hc11_addr_mode | (strict ? ADDR_STRICT : 0); + if (register_indirect_p (operand, mode, addr_mode)) { return 1; } @@ -930,6 +997,27 @@ return general_operand (operand, mode); } +/* Predicate for nonimmediate operands but which rejects the + auto-increment/decrement modes. We must use this predicate + for operand 0 (and sometimes operand 1) when an insn can have + an operand that would create a RELOAD_OTHER in which a reload + part (RELOAD_FOR_OUTPUT_ADDRESS) could be created. When this + happens, the RELOAD_FOR_OUTPUT_ADDRESS is emitted after the RELOAD_OTHER + and this will not be valid. */ +int +nonimmediate_noinc_operand (operand, mode) + rtx operand; + enum machine_mode mode; +{ + if (GET_CODE (operand) == MEM) + { + rtx addr = XEXP (operand, 0); + if (m68hc11_auto_inc_p (addr)) + return 0; + } + return nonimmediate_operand (operand, mode); +} + int non_push_operand (operand, mode) rtx operand; @@ -944,6 +1032,43 @@ } int +splitable_operand (operand, mode) + rtx operand; + enum machine_mode mode; +{ + if (general_operand (operand, mode) == 0) + return 0; + + if (push_operand (operand, mode) == 1) + return 0; + + /* Reject a (MEM (MEM X)) because the patterns that use non_push_operand + need to split such addresses to access the low and high part but it + is not possible to express a valid address for the low part. */ + if (mode != QImode && GET_CODE (operand) == MEM + && GET_CODE (XEXP (operand, 0)) == MEM) + return 0; + return 1; +} + +int +push_or_splitable_operand (operand, mode) + rtx operand; + enum machine_mode mode; +{ + if (general_operand (operand, mode) == 0) + return 0; + + /* Reject a (MEM (MEM X)) because the patterns that use non_push_operand + need to split such addresses to access the low and high part but it + is not possible to express a valid address for the low part. */ + if (mode != QImode && GET_CODE (operand) == MEM + && GET_CODE (XEXP (operand, 0)) == MEM) + return 0; + return 1; +} + +int reg_or_some_mem_operand (operand, mode) rtx operand; enum machine_mode mode; @@ -951,6 +1076,7 @@ if (GET_CODE (operand) == MEM) { rtx op = XEXP (operand, 0); + int addr_mode; if (symbolic_memory_operand (op, mode)) return 1; @@ -958,10 +1084,20 @@ if (IS_STACK_PUSH (operand)) return 1; - if (m68hc11_register_indirect_p (operand, mode)) - return 1; + if (GET_CODE (operand) == REG && reload_in_progress + && REGNO (operand) >= FIRST_PSEUDO_REGISTER + && reg_equiv_memory_loc[REGNO (operand)]) + { + operand = reg_equiv_memory_loc[REGNO (operand)]; + operand = eliminate_regs (operand, 0, NULL_RTX); + } + if (GET_CODE (operand) != MEM) + return 0; - return 0; + operand = XEXP (operand, 0); + addr_mode = m68hc11_addr_mode | (reload_completed ? ADDR_STRICT : 0); + addr_mode &= ~ADDR_INDIRECT; + return register_indirect_p (operand, mode, addr_mode); } return register_operand (operand, mode); @@ -987,18 +1123,23 @@ rtx operand; enum machine_mode mode; { - if (GET_CODE (operand) == MEM) + if (GET_CODE (operand) == MEM && GET_MODE (operand) == mode) { rtx op = XEXP (operand, 0); + int addr_mode; + + if (m68hc11_page0_symbol_p (op)) + return 1; if (symbolic_memory_operand (op, mode)) - return 0; + return TARGET_M6812; if (reload_in_progress) return 1; operand = XEXP (operand, 0); - return register_indirect_p (operand, mode, reload_completed); + addr_mode = m68hc11_addr_mode | (reload_completed ? ADDR_STRICT : 0); + return register_indirect_p (operand, mode, addr_mode); } return 0; } @@ -1234,6 +1375,31 @@ /* Declaration of types. */ +/* Handle an "tiny_data" attribute; arguments as in + struct attribute_spec.handler. */ +static tree +m68hc11_handle_page0_attribute (node, name, args, flags, no_add_attrs) + tree *node; + tree name; + tree args ATTRIBUTE_UNUSED; + int flags ATTRIBUTE_UNUSED; + bool *no_add_attrs; +{ + tree decl = *node; + + if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)) + { + DECL_SECTION_NAME (decl) = build_string (6, ".page0"); + } + else + { + warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } + + return NULL_TREE; +} + const struct attribute_spec m68hc11_attribute_table[] = { /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ @@ -1241,6 +1407,7 @@ { "trap", 0, 0, false, true, true, m68hc11_handle_fntype_attribute }, { "far", 0, 0, false, true, true, m68hc11_handle_fntype_attribute }, { "near", 0, 0, false, true, true, m68hc11_handle_fntype_attribute }, + { "page0", 0, 0, false, false, false, m68hc11_handle_page0_attribute }, { NULL, 0, 0, false, false, false, NULL } }; @@ -1271,6 +1438,52 @@ return NULL_TREE; } +/* Undo the effects of the above. */ + +static const char * +m68hc11_strip_name_encoding (str) + const char *str; +{ + return str + (*str == '*' || *str == '@' || *str == '&'); +} + +static void +m68hc11_encode_label (tree decl) +{ + const char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0); + int len = strlen (str); + char *newstr = alloca (len + 2); + + newstr[0] = '@'; + strcpy (&newstr[1], str); + + XSTR (XEXP (DECL_RTL (decl), 0), 0) = ggc_alloc_string (newstr, len + 1); +} + +/* Return 1 if this is a symbol in page0 */ +int +m68hc11_page0_symbol_p (rtx x) +{ + switch (GET_CODE (x)) + { + case SYMBOL_REF: + return XSTR (x, 0) != 0 && XSTR (x, 0)[0] == '@'; + + case CONST: + return m68hc11_page0_symbol_p (XEXP (x, 0)); + + case PLUS: + if (!m68hc11_page0_symbol_p (XEXP (x, 0))) + return 0; + + return GET_CODE (XEXP (x, 1)) == CONST_INT + && INTVAL (XEXP (x, 1)) < 256 + && INTVAL (XEXP (x, 1)) >= 0; + + default: + return 0; + } +} /* We want to recognize trap handlers so that we handle calls to traps in a special manner (by issuing the trap). This information is stored @@ -1286,6 +1499,13 @@ int is_far = 0; rtx rtl; + if (TREE_CODE (decl) == VAR_DECL) + { + if (lookup_attribute ("page0", DECL_ATTRIBUTES (decl)) != 0) + m68hc11_encode_label (decl); + return; + } + if (TREE_CODE (decl) != FUNCTION_DECL) return; @@ -1372,15 +1592,19 @@ /* For a trap handler, we must take into account the registers which are pushed on the stack during the trap (except the PC). */ func_attr = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)); + current_function_interrupt = lookup_attribute ("interrupt", + func_attr) != NULL_TREE; + trap_handler = lookup_attribute ("trap", func_attr) != NULL_TREE; if (lookup_attribute ("far", func_attr) != 0) current_function_far = 1; else if (lookup_attribute ("near", func_attr) != 0) current_function_far = 0; else - current_function_far = TARGET_LONG_CALLS != 0; + current_function_far = (TARGET_LONG_CALLS != 0 + && !current_function_interrupt + && !trap_handler); - trap_handler = lookup_attribute ("trap", func_attr) != NULL_TREE; if (trap_handler && from == ARG_POINTER_REGNUM) size = 7; @@ -1679,7 +1903,9 @@ else if (lookup_attribute ("near", func_attr) != NULL_TREE) current_function_far = 0; else - current_function_far = TARGET_LONG_CALLS != 0; + current_function_far = (TARGET_LONG_CALLS != 0 + && !current_function_interrupt + && !current_function_trap); /* Get the scratch register to build the frame and push registers. If the first argument is a 32-bit quantity, the D+X registers @@ -2014,6 +2240,14 @@ { return gen_int_mode (val >> 16, HImode); } + else if (mode == SImode) + { +#if HOST_BITS_PER_WIDE_INT > 32 + return gen_int_mode (val >> 32, SImode); +#else + return (val >= 0) ? const0_rtx : constm1_rtx; +#endif + } } if (mode == QImode && D_REG_P (x)) return gen_rtx (REG, mode, HARD_A_REGNUM); @@ -2307,7 +2541,21 @@ abort (); break; + case MEM: + if (TARGET_M6812) + { + fprintf (file, "["); + print_operand_address (file, XEXP (base, 0)); + fprintf (file, "]"); + } + else + abort (); + break; + default: + if (m68hc11_page0_symbol_p (base)) + fprintf (file, "*"); + output_address (base); break; } @@ -2349,7 +2597,7 @@ } /* Returns true if the operand 'op' must be printed with parenthesis - arround it. This must be done only if there is a symbol whose name + around it. This must be done only if there is a symbol whose name is a processor register. */ static int must_parenthesize (op) @@ -2903,15 +3151,7 @@ high_to = m68hc11_gen_highpart (mode, to); low_from = m68hc11_gen_lowpart (mode, from); - if (mode == SImode && GET_CODE (from) == CONST_INT) - { - if (INTVAL (from) >= 0) - high_from = const0_rtx; - else - high_from = constm1_rtx; - } - else - high_from = m68hc11_gen_highpart (mode, from); + high_from = m68hc11_gen_highpart (mode, from); if (offset) { @@ -3104,26 +3344,8 @@ low[2] = m68hc11_gen_lowpart (mode, operands[2]); high[0] = m68hc11_gen_highpart (mode, operands[0]); - - if (mode == SImode && GET_CODE (operands[1]) == CONST_INT) - { - if (INTVAL (operands[1]) >= 0) - high[1] = const0_rtx; - else - high[1] = constm1_rtx; - } - else - high[1] = m68hc11_gen_highpart (mode, operands[1]); - - if (mode == SImode && GET_CODE (operands[2]) == CONST_INT) - { - if (INTVAL (operands[2]) >= 0) - high[2] = const0_rtx; - else - high[2] = constm1_rtx; - } - else - high[2] = m68hc11_gen_highpart (mode, operands[2]); + high[1] = m68hc11_gen_highpart (mode, operands[1]); + high[2] = m68hc11_gen_highpart (mode, operands[2]); low[3] = operands[3]; high[3] = operands[3]; @@ -3236,10 +3458,13 @@ if (TARGET_M6812) { - if (IS_STACK_PUSH (operands[0]) && H_REG_P (operands[1])) + rtx from = operands[1]; + rtx to = operands[0]; + + if (IS_STACK_PUSH (to) && H_REG_P (from)) { cc_status = cc_prev_status; - switch (REGNO (operands[1])) + switch (REGNO (from)) { case HARD_X_REGNUM: case HARD_Y_REGNUM: @@ -3247,17 +3472,17 @@ output_asm_insn ("psh%1", operands); break; case HARD_SP_REGNUM: - output_asm_insn ("sts\t-2,sp", operands); + output_asm_insn ("sts\t2,-sp", operands); break; default: abort (); } return; } - if (IS_STACK_POP (operands[1]) && H_REG_P (operands[0])) + if (IS_STACK_POP (from) && H_REG_P (to)) { cc_status = cc_prev_status; - switch (REGNO (operands[0])) + switch (REGNO (to)) { case HARD_X_REGNUM: case HARD_Y_REGNUM: @@ -3278,17 +3503,6 @@ { if (SP_REG_P (operands[0])) output_asm_insn ("lds\t%1", operands); - else if (0 /* REG_WAS_0 note is boggus; don't rely on it. */ - && !D_REG_P (operands[0]) - && GET_CODE (operands[1]) == CONST_INT - && (INTVAL (operands[1]) == 1 || INTVAL (operands[1]) == -1) - && find_reg_note (insn, REG_WAS_0, 0)) - { - if (INTVAL (operands[1]) == 1) - output_asm_insn ("in%0", operands); - else - output_asm_insn ("de%0", operands); - } else output_asm_insn ("ld%0\t%1", operands); } @@ -3299,11 +3513,52 @@ else output_asm_insn ("st%1\t%0", operands); } + + /* The 68hc12 does not support (MEM:HI (MEM:HI)) with the movw + instruction. We have to use a scratch register as temporary location. + Trying to use a specific pattern or constrain failed. */ + else if (GET_CODE (to) == MEM && GET_CODE (XEXP (to, 0)) == MEM) + { + rtx ops[4]; + + ops[0] = to; + ops[2] = from; + ops[3] = 0; + if (dead_register_here (insn, d_reg)) + ops[1] = d_reg; + else if (dead_register_here (insn, ix_reg)) + ops[1] = ix_reg; + else if (dead_register_here (insn, iy_reg)) + ops[1] = iy_reg; + else + { + ops[1] = d_reg; + ops[3] = d_reg; + output_asm_insn ("psh%3", ops); + } + + ops[0] = to; + ops[2] = from; + output_asm_insn ("ld%1\t%2", ops); + output_asm_insn ("st%1\t%0", ops); + if (ops[3]) + output_asm_insn ("pul%3", ops); + } + + /* Use movw for non-null constants or when we are clearing + a volatile memory reference. However, this is possible + only if the memory reference has a small offset or is an + absolute address. */ + else if (GET_CODE (from) == CONST_INT + && INTVAL (from) == 0 + && (MEM_VOLATILE_P (to) == 0 + || m68hc11_small_indexed_indirect_p (to, HImode) == 0)) + { + output_asm_insn ("clr\t%h0", operands); + output_asm_insn ("clr\t%b0", operands); + } else { - rtx from = operands[1]; - rtx to = operands[0]; - if ((m68hc11_register_indirect_p (from, GET_MODE (from)) && !m68hc11_small_indexed_indirect_p (from, GET_MODE (from))) || (m68hc11_register_indirect_p (to, GET_MODE (to)) @@ -3320,6 +3575,7 @@ ops[0] = to; ops[1] = operands[2]; m68hc11_gen_movhi (insn, ops); + return; } else { @@ -3327,19 +3583,11 @@ fatal_insn ("move insn not handled", insn); } } - else - { - if (GET_CODE (from) == CONST_INT && INTVAL (from) == 0) - { - output_asm_insn ("clr\t%h0", operands); - output_asm_insn ("clr\t%b0", operands); - } - else - { - m68hc11_notice_keep_cc (operands[0]); - output_asm_insn ("movw\t%1,%0", operands); - } - } + else + { + m68hc11_notice_keep_cc (operands[0]); + output_asm_insn ("movw\t%1,%0", operands); + } } return; } @@ -3472,16 +3720,6 @@ cc_status = cc_prev_status; output_asm_insn ("tsx", operands); } - else if (0 /* REG_WAS_0 note is boggus; don't rely on it. */ - && GET_CODE (operands[1]) == CONST_INT - && (INTVAL (operands[1]) == 1 || INTVAL (operands[1]) == -1) - && find_reg_note (insn, REG_WAS_0, 0)) - { - if (INTVAL (operands[1]) == 1) - output_asm_insn ("in%0", operands); - else - output_asm_insn ("de%0", operands); - } else { output_asm_insn ("ldx\t%1", operands); @@ -3530,16 +3768,6 @@ cc_status = cc_prev_status; output_asm_insn ("tsy", operands); } - else if (0 /* REG_WAS_0 note is boggus; don't rely on it. */ - && GET_CODE (operands[1]) == CONST_INT - && (INTVAL (operands[1]) == 1 || INTVAL (operands[1]) == -1) - && find_reg_note (insn, REG_WAS_0, 0)) - { - if (INTVAL (operands[1]) == 1) - output_asm_insn ("in%0", operands); - else - output_asm_insn ("de%0", operands); - } else { output_asm_insn ("ldy\t%1", operands); @@ -3689,8 +3917,10 @@ } else if (H_REG_P (operands[0])) { - if (Q_REG_P (operands[0])) - output_asm_insn ("lda%0\t%b1", operands); + if (IS_STACK_POP (operands[1])) + output_asm_insn ("pul%b0", operands); + else if (Q_REG_P (operands[0])) + output_asm_insn ("lda%0\t%b1", operands); else if (D_REG_P (operands[0])) output_asm_insn ("ldab\t%b1", operands); else @@ -3780,16 +4010,6 @@ output_asm_insn ("ldab\t%T0", operands); } } - else if (0 /* REG_WAS_0 note is boggus; don't rely on it. */ - && GET_CODE (operands[1]) == CONST_INT - && (INTVAL (operands[1]) == 1 || INTVAL (operands[1]) == -1) - && find_reg_note (insn, REG_WAS_0, 0)) - { - if (INTVAL (operands[1]) == 1) - output_asm_insn ("inc%b0", operands); - else - output_asm_insn ("dec%b0", operands); - } else if (!DB_REG_P (operands[1]) && !D_REG_P (operands[1]) && !DA_REG_P (operands[1])) { @@ -3935,11 +4155,34 @@ break; case HARD_X_REGNUM: - output_asm_insn ("xgdx\n\tstab\t%b0\n\txgdx", operands); - break; - - case HARD_Y_REGNUM: - output_asm_insn ("xgdy\n\tstab\t%b0\n\txgdy", operands); + case HARD_Y_REGNUM: + if (!reg_mentioned_p (operands[1], operands[0])) + { + output_asm_insn ("xgd%1\n\tstab\t%b0\n\txgd%1", operands); + } + else if (TARGET_M6811) + { + int dead = dead_register_here (insn, d_reg); + output_asm_insn ("st%1\t%t1", operands); + if (!dead) + output_asm_insn ("psha", operands); + output_asm_insn ("ldaa\t%T1", operands); + output_asm_insn ("staa\t%0", operands); + if (!dead) + output_asm_insn ("pula", operands); + CC_STATUS_INIT; + } + else + { + int dead = dead_register_here (insn, d_reg); + if (!dead) + output_asm_insn ("psha", operands); + output_asm_insn ("tfr\t%1,a", operands); + output_asm_insn ("staa\t%0", operands); + if (!dead) + output_asm_insn ("pulb", operands); + CC_STATUS_INIT; + } break; default: @@ -4136,6 +4379,12 @@ && cc_status.value2 && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2)) cc_status.value2 = 0; + + else if (cc_status.value1 && side_effects_p (cc_status.value1)) + cc_status.value1 = 0; + + else if (cc_status.value2 && side_effects_p (cc_status.value2)) + cc_status.value2 = 0; } /* The current instruction does not affect the flags but changes @@ -4306,8 +4555,10 @@ { if ((GET_CODE (src) == REG && REGNO (src) == HARD_Z_REGNUM) || (GET_CODE (src) == COMPARE && - (rtx_equal_p (XEXP (src, 0), z_reg) - || rtx_equal_p (XEXP (src, 1), z_reg)))) + ((rtx_equal_p (XEXP (src, 0), z_reg) + && H_REG_P (XEXP (src, 1))) + || (rtx_equal_p (XEXP (src, 1), z_reg) + && H_REG_P (XEXP (src, 0)))))) { if (insn == info->first) { @@ -4905,7 +5156,7 @@ /* The insn uses the Z register. Find a replacement register for it (either X or Y) and replace it in the insn and the next ones until the flow changes or the replacement register is used. Instructions - are emited before and after the Z-block to preserve the value of + are emitted before and after the Z-block to preserve the value of Z and of the replacement register. */ static void @@ -5067,9 +5318,11 @@ if (info.save_before_last) save_pos_insn = PREV_INSN (save_pos_insn); - emit_insn_before (gen_movhi (gen_rtx (REG, HImode, SOFT_Z_REGNUM), - gen_rtx (REG, HImode, info.regno)), - save_pos_insn); + /* Use emit_insn_after () to ensure the new insn is part of + the good basic block. */ + emit_insn_after (gen_movhi (gen_rtx (REG, HImode, SOFT_Z_REGNUM), + gen_rtx (REG, HImode, info.regno)), + PREV_INSN (save_pos_insn)); } if (info.must_push_reg && info.last) @@ -5108,8 +5361,8 @@ else dst = gen_rtx (REG, HImode, SOFT_SAVED_XY_REGNUM); - emit_insn_before (gen_movhi (gen_rtx (REG, HImode, info.regno), - dst), insn); + emit_insn_after (gen_movhi (gen_rtx (REG, HImode, info.regno), + dst), PREV_INSN (insn)); } } @@ -5176,6 +5429,13 @@ } +/* Machine-dependent reorg pass. + Specific optimizations are defined here: + - this pass changes the Z register into either X or Y + (it preserves X/Y previous values in a memory slot in page0). + + When this pass is finished, the global variable + 'z_replacement_completed' is set to 2. */ void m68hc11_reorg (first) rtx first; @@ -5204,7 +5464,7 @@ z_replacement_completed = 1; m68hc11_reassign_regs (first); - /* After some splitting, there are some oportunities for CSE pass. + /* After some splitting, there are some opportunities for CSE pass. This happens quite often when 32-bit or above patterns are split. */ if (optimize > 0 && split_done) { @@ -5355,7 +5615,7 @@ break; case SYMBOL_REF: - cost = 8; + cost = m68hc11_page0_symbol_p (addr) ? 0 : 8; break; case LABEL_REF: @@ -5388,7 +5648,7 @@ break; case SYMBOL_REF: - cost = 8; + cost = m68hc11_page0_symbol_p (addr) ? 0 : 8; break; case CONST: diff -u -r -N gcc-3.3.6-core-orig/gcc/config/m68hc11/m68hc11-crt0.S gcc-3.3.6/gcc/config/m68hc11/m68hc11-crt0.S --- gcc-3.3.6-core-orig/gcc/config/m68hc11/m68hc11-crt0.S 2002-08-14 08:32:52.000000000 +0100 +++ gcc-3.3.6/gcc/config/m68hc11/m68hc11-crt0.S 2010-11-09 20:47:16.000000000 +0000 @@ -79,7 +79,7 @@ ;; ;; int __premain(void); ;; - jsr __premain + bsr __premain ;; ;; diff -u -r -N gcc-3.3.6-core-orig/gcc/config/m68hc11/m68hc11.h gcc-3.3.6/gcc/config/m68hc11/m68hc11.h --- gcc-3.3.6-core-orig/gcc/config/m68hc11/m68hc11.h 2003-07-08 22:07:33.000000000 +0100 +++ gcc-3.3.6/gcc/config/m68hc11/m68hc11.h 2010-11-09 20:47:16.000000000 +0000 @@ -1,22 +1,23 @@ /* Definitions of target machine for GNU compiler. Motorola 68HC11 and 68HC12. - Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, + 2005, 2006 Free Software Foundation, Inc. Contributed by Stephane Carrez (stcarrez@nerim.fr) -This file is part of GNU CC. +This file is part of GCC. -GNU CC is free software; you can redistribute it and/or modify +GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. -GNU CC is distributed in the hope that it will be useful, +GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to +along with GCC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. @@ -41,24 +42,28 @@ #undef ENDFILE_SPEC -/* Compile and assemble for a 68hc11 unless there is a -m68hc12 option. */ +/* Default to compile and assemble for a 68hc11 */ +/* convert parameter style from 'cc1' to 'as' */ #ifndef ASM_SPEC #define ASM_SPEC \ "%{m68hc12:-m68hc12}" \ "%{m68hcs12:-m68hcs12}" \ -"%{!m68hc12:%{!m68hcs12:-m68hc11}} " \ +"%{m9s12x:-mm9s12x}" \ +"%{!m68hc12:%{!m68hcs12:%{!m9s12x:-m68hc11}}} " \ "%{mshort:-mshort}%{!mshort:-mlong} " \ "%{fshort-double:-mshort-double}%{!fshort-double:-mlong-double}" #endif /* We need to tell the linker the target elf format. Just pass an - emulation option. This can be overriden by -Wl option of gcc. */ + emulation option. This can be overridden by -Wl option of gcc. */ #ifndef LINK_SPEC #define LINK_SPEC \ "%{m68hc12:-m m68hc12elf}" \ "%{m68hcs12:-m m68hc12elf}" \ -"%{!m68hc12:%{!m68hcs12:-m m68hc11elf}} " \ -"%{!mnorelax:%{!m68hc12:%{!m68hcs12:-relax}}}" +"%{m9s12x:-m m9s12x}" \ +"%{!m68hc12:%{!m68hcs12:%{!m9s12x:-m m68hc11elf}}} " \ +"%{!mnorelax:%{!m68hc12:%{!m68hcs12:%{!m9s12x:-relax}}}}" + #endif #ifndef LIB_SPEC @@ -75,7 +80,8 @@ %{!mshort:-D__INT__=32}\ %{m68hc12:-Dmc6812 -DMC6812 -Dmc68hc12}\ %{m68hcs12:-Dmc6812 -DMC6812 -Dmc68hcs12}\ - %{!m68hc12:%{!m68hcs12:-Dmc6811 -DMC6811 -Dmc68hc11}}\ + %{m9s12x:-Dmc6812 -DMC6812 -Dmc68hcs12}\ + %{!m68hc12:%{!m68hcs12:%{!m9s12x:-Dmc6811 -DMC6811 -Dmc68hc11}}}\ %{fshort-double:-D__HAVE_SHORT_DOUBLE__}\ %{mlong-calls:-D__USE_RTC__}" #endif @@ -84,7 +90,9 @@ #define STARTFILE_SPEC "crt1%O%s" /* Names to predefine in the preprocessor for this target machine. */ -#define CPP_PREDEFINES "-Dmc68hc1x" +#ifndef CPP_PREDEFINES +#define CPP_PREDEFINES "-Dmc68hc1x -Dtarget11" +#endif /* As an embedded target, we have no libc. */ #define inhibit_libc @@ -125,20 +133,22 @@ * with -mauto-incdec. */ -#define MASK_SHORT 0002 /* Compile with 16-bit `int' */ -#define MASK_AUTO_INC_DEC 0004 -#define MASK_M6811 0010 -#define MASK_M6812 0020 -#define MASK_M68S12 0040 -#define MASK_NO_DIRECT_MODE 0100 -#define MASK_MIN_MAX 0200 -#define MASK_LONG_CALLS 0400 +#define MASK_SHORT 0x0002 /* Compile with 16-bit `int' */ +#define MASK_AUTO_INC_DEC 0x0004 /* FIXME - tidy M68XX flags order */ +#define MASK_M6811 0x0010 +#define MASK_M6812 0x0020 +#define MASK_M68S12 0x0040 +#define MASK_NO_DIRECT_MODE 0x0100 +#define MASK_MIN_MAX 0x0200 +#define MASK_LONG_CALLS 0x0400 +#define MASK_M68S12X 0x0800 #define TARGET_OP_TIME (optimize && optimize_size == 0) #define TARGET_SHORT (target_flags & MASK_SHORT) #define TARGET_M6811 (target_flags & MASK_M6811) #define TARGET_M6812 (target_flags & MASK_M6812) #define TARGET_M68S12 (target_flags & MASK_M68S12) +#define TARGET_M68S12X (!(target_flags & MASK_M6811) && (target_flags & MASK_M68S12X)) #define TARGET_AUTO_INC_DEC (target_flags & MASK_AUTO_INC_DEC) #define TARGET_MIN_MAX (target_flags & MASK_MIN_MAX) #define TARGET_NO_DIRECT_MODE (target_flags & MASK_NO_DIRECT_MODE) @@ -161,6 +171,7 @@ # define MULTILIB_DEFAULTS { "m68hc12" } # endif #endif +/* 9s12x in own .h */ /* 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 @@ -200,6 +211,10 @@ N_("Compile for a 68HC12")}, \ { "68S12", MASK_M6812 | MASK_M68S12, \ N_("Compile for a 68HCS12")}, \ + { "9s12x", MASK_M6812 | MASK_M68S12 | MASK_M68S12X, \ + N_("Compile for CPU12X")}, \ + { "m9s12x", MASK_M6812 | MASK_M68S12 | MASK_M68S12X, \ + N_("Compile for CPU12X")}, \ { "", TARGET_DEFAULT, 0 }} /* This macro is similar to `TARGET_SWITCHES' but defines names of @@ -232,7 +247,7 @@ #endif /* Print subsidiary information on the compiler version in use. */ -#define TARGET_VERSION fprintf (stderr, " (MC68HC11/MC68HC12/MC68HCS12)") +#define TARGET_VERSION fprintf (stderr, " (MC68HC11/MC68HC12/MC68HCS12/M9S12X)") /* Sometimes certain combinations of command options do not make sense on a particular target machine. You can define a macro @@ -277,6 +292,10 @@ /* Define this if most significant word of a multiword number is numbered. */ #define WORDS_BIG_ENDIAN 1 +/* Use a MAX_BITS_PER_WORD equivalent to SImode so that + several SI patterns can be used (mostly shift & add). */ +/* #define MAX_BITS_PER_WORD 32 */ + /* Width of a word, in units (bytes). */ #define UNITS_PER_WORD 2 @@ -804,8 +823,8 @@ /* A C expression that is nonzero if hard register number REGNO2 can be considered for use as a rename register for REGNO1 */ -#define HARD_REGNO_RENAME_OK(REGNO1,REGNO2) \ - m68hc11_hard_regno_rename_ok ((REGNO1), (REGNO2)) +#define HARD_REGNO_RENAME_OK(REGNO1,REGNO2,MODE) \ + m68hc11_hard_regno_rename_ok ((REGNO1), (REGNO2), (MODE)) /* A C expression whose value is nonzero if pseudos that have been assigned to registers of class CLASS would likely be spilled @@ -874,7 +893,9 @@ && VALUE == CONST0_RTX (GET_MODE (VALUE))) : 0) /* 'U' represents certain kind of memory indexed operand for 68HC12. - and any memory operand for 68HC11. */ + and any memory operand for 68HC11. + 'R' represents indexed addressing mode or access to page0 for 68HC11. + For 68HC12, it represents any memory operand. */ #define EXTRA_CONSTRAINT(OP, C) \ ((C) == 'U' ? m68hc11_small_indexed_indirect_p (OP, GET_MODE (OP)) \ : (C) == 'Q' ? m68hc11_symbolic_p (OP, GET_MODE (OP)) \ @@ -963,7 +984,7 @@ followed by "to". Eliminations of the same "from" register are listed in order of preference. - We have two registers that are eliminated on the 6811. The psuedo arg + We have two registers that are eliminated on the 6811. The pseudo arg pointer and pseudo frame pointer registers can always be eliminated; they are replaced with either the stack or the real frame pointer. */ @@ -1215,7 +1236,7 @@ /* Internal macro, return 1 if REGNO is a valid base register. */ -#define REG_VALID_P(REGNO) (1) /* ? */ +#define REG_VALID_P(REGNO) ((REGNO) >= 0) extern unsigned char m68hc11_reg_valid_for_base[FIRST_PSEUDO_REGISTER]; #define REG_VALID_FOR_BASE_P(REGNO) \ @@ -1489,7 +1510,7 @@ macro is used in only one place: `find_reloads_address' in reload.c. For M68HC11, we handle large displacements of a base register - by splitting the addend accors an addhi3 insn. + by splitting the addend across an addhi3 insn. For M68HC12, the 64K offset range is available. */ @@ -1690,7 +1711,7 @@ /* Assembler Commands for Exception Regions. */ -/* Default values provided by GCC should be ok. Assumming that DWARF-2 +/* Default values provided by GCC should be ok. Assuming that DWARF-2 frame unwind info is ok for this platform. */ #undef PREFERRED_DEBUGGING_TYPE @@ -1719,6 +1740,12 @@ #define IMMEDIATE_PREFIX "#" #define GLOBAL_ASM_OP "\t.globl\t" +/* This is how to output a reference to a user-level label named NAME. + `assemble_name' uses this. */ +#undef ASM_OUTPUT_LABELREF +#define ASM_OUTPUT_LABELREF(FILE, NAME) \ + asm_fprintf (FILE, "%U%s", (*targetm.strip_name_encoding) (NAME)) + /* Miscellaneous Parameters. */ @@ -1737,8 +1764,10 @@ {"m68hc11_shift_operator", {ASHIFT, ASHIFTRT, LSHIFTRT, ROTATE, ROTATERT}},\ {"m68hc11_eq_compare_operator", {EQ, NE}}, \ {"non_push_operand", {SUBREG, REG, MEM}}, \ +{"splitable_operand", {SUBREG, REG, MEM}}, \ {"reg_or_some_mem_operand", {SUBREG, REG, MEM}}, \ {"tst_operand", {SUBREG, REG, MEM}}, \ +{"nonimmediate_noinc_operand", {SUBREG, REG, MEM}}, \ {"cmp_operand", {SUBREG, REG, MEM, SYMBOL_REF, LABEL_REF, \ CONST_INT, CONST_DOUBLE}}, diff -u -r -N gcc-3.3.6-core-orig/gcc/config/m68hc11/m68hc11.md gcc-3.3.6/gcc/config/m68hc11/m68hc11.md --- gcc-3.3.6-core-orig/gcc/config/m68hc11/m68hc11.md 2003-04-12 22:25:37.000000000 +0100 +++ gcc-3.3.6/gcc/config/m68hc11/m68hc11.md 2010-11-09 20:47:16.000000000 +0000 @@ -1,21 +1,22 @@ ;;- Machine description file for Motorola 68HC11 and 68HC12. -;;- Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +;;- Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +;;- Free Software Foundation, Inc. ;;- Contributed by Stephane Carrez (stcarrez@nerim.fr) -;; This file is part of GNU CC. +;; This file is part of GCC. -;; GNU CC is free software; you can redistribute it and/or modify +;; GCC is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. -;; GNU CC is distributed in the hope that it will be useful, +;; GCC is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with GNU CC; see the file COPYING. If not, write to +;; along with GCC; see the file COPYING. If not, write to ;; the Free Software Foundation, 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. @@ -93,7 +94,7 @@ ;; Operands modifiers: ;; ;; %b Get the low part of the operand (to obtain a QImode) -;; This modified must always be used for QImode operations +;; This modifier must always be used for QImode operations ;; because a correction must be applied when the operand ;; is a soft register (ex: *ZD1). Otherwise, we generate ;; *ZD1 and this is the high part of the register. For other @@ -143,7 +144,9 @@ (A_REGNUM 5) ; A (high part of D) (B_REGNUM 6) ; B (low part of D) (CC_REGNUM 7) ; Condition code register - (SOFT_Z_REGNUM 11) ; Z soft register + (SOFT_TMP_REGNUM 10) ; TMP soft register + (SOFT_Z_REGNUM 11) ; Z soft register + (SOFT_XY_REGNUM 12) ; XY soft register ]) ;;-------------------------------------------------------------------- @@ -247,19 +250,13 @@ ;; avoid problems with the flow+cse register pass which are made ;; after Z register replacement. ;; -(define_insn "tstqi_z_used" +(define_insn_and_split "tstqi_z_used" [(set (cc0) (match_operand:QI 0 "tst_operand" "m")) (use (match_operand:HI 1 "hard_reg_operand" "dxy")) - (use (reg:HI 11))] - "" - "#") - -(define_split /* "tstqi_z_used" */ - [(set (cc0) - (match_operand:QI 0 "tst_operand" "")) - (use (match_operand:HI 1 "hard_reg_operand" "")) (use (reg:HI SOFT_Z_REGNUM))] + "" + "#" "z_replacement_completed == 2" [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 1)) (set (match_dup 1) (match_dup 2)) @@ -300,12 +297,24 @@ [(set (cc0) (compare (match_operand:HI 0 "hard_reg_operand" "") (match_operand:HI 1 "hard_reg_operand" "")))] - "reload_completed" + "TARGET_M6811 + && reload_completed && !(Z_REG_P (operands[0]) || Z_REG_P (operands[1]))" [(set (match_dup 2) (match_dup 1)) (set (cc0) (compare (match_dup 0) (match_dup 2)))] "operands[2] = gen_rtx (REG, HImode, SOFT_TMP_REGNUM);") +(define_split + [(set (cc0) + (compare (match_operand:HI 0 "hard_reg_operand" "") + (match_operand:HI 1 "hard_reg_operand" "")))] + "0 && TARGET_M6812 + && reload_completed && !(Z_REG_P (operands[0]) || Z_REG_P (operands[1]))" + [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 1)) + (set (cc0) + (compare (match_dup 0) (mem:HI (post_inc:HI (reg:HI SP_REGNUM)))))] + "") + (define_expand "cmphi" [(set (cc0) (compare (match_operand:HI 0 "tst_operand" "") @@ -325,7 +334,7 @@ [(set (cc0) (compare (match_operand:HI 0 "tst_operand" "d,?xy,xyd,?xy,d,m,!u,dxy,dxy") - (match_operand:HI 1 "cmp_operand" + (match_operand:HI 1 "general_operand" "i,i,!u,m,m,dxy,dxy,?*d*A,!*w")))] "TARGET_M6812" "* @@ -335,8 +344,10 @@ cc_status.flags |= CC_REVERSED; return \"cp%1\\t%0\"; } + else if (SP_REG_P (operands[1])) + return \"sts\\t2,-sp\n\\tcp%0\\t2,sp+\"; else if (H_REG_P (operands[1])) - return \"#\"; + return \"psh%1\n\\tcp%0\\t2,sp+\"; else return \"cp%0\\t%1\"; }") @@ -344,9 +355,9 @@ (define_insn "cmphi_1_hc11" [(set (cc0) (compare (match_operand:HI 0 "tst_operand" - "dx,y,xyd,?xy,d,m,!u,dxy,dxy") + "dx,y,xyd,?xy,d,m,m,dxy,dxy,?u*z,dxy,*z") (match_operand:HI 1 "cmp_operand" - "i,i,!u,m,m,dxy,dxy,?*d*A,!*w")))] + "i,i,!u,m,m,?xy,d,?*d*A,?u,dxy,!*w,i")))] "TARGET_M6811" "* { @@ -361,21 +372,14 @@ return \"cp%0\\t%1\"; }") -(define_insn "cmphi_z_used" +(define_insn_and_split "cmphi_z_used" [(set (cc0) (compare (match_operand:HI 0 "tst_operand" "dxy,m") - (match_operand:HI 1 "cmp_operand" "m,dxy"))) + (match_operand:HI 1 "cmp_operand" "mi,dxy"))) (use (match_operand:HI 2 "hard_reg_operand" "dxy,dxy")) (use (reg:HI SOFT_Z_REGNUM))] "" - "#") - -(define_split /* "cmphi_z_used" */ - [(set (cc0) - (compare (match_operand:HI 0 "tst_operand" "") - (match_operand:HI 1 "cmp_operand" ""))) - (use (match_operand:HI 2 "hard_reg_operand" "")) - (use (reg:HI SOFT_Z_REGNUM))] + "#" "z_replacement_completed == 2" [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 2)) (set (match_dup 2) (match_dup 3)) @@ -452,21 +456,14 @@ operands[3] = gen_rtx (REG, HImode, SOFT_TMP_REGNUM); operands[4] = gen_rtx (REG, QImode, SOFT_TMP_REGNUM);") -(define_insn "bitcmpqi_z_used" +(define_insn_and_split "bitcmpqi_z_used" [(set (cc0) (and:QI (match_operand:QI 0 "tst_operand" "d,m") (match_operand:QI 1 "cmp_operand" "m,d"))) (use (match_operand:HI 2 "hard_reg_operand" "xy,xy")) (use (reg:HI SOFT_Z_REGNUM))] "" - "#") - -(define_split /* "bitcmpqi_z_used" */ - [(set (cc0) - (and:QI (match_operand:QI 0 "tst_operand" "") - (match_operand:QI 1 "cmp_operand" ""))) - (use (match_operand:HI 2 "hard_reg_operand" "")) - (use (reg:HI SOFT_Z_REGNUM))] + "#" "z_replacement_completed == 2" [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 2)) (set (match_dup 2) (match_dup 3)) @@ -542,21 +539,14 @@ return \"cmpb\\t%b0\"; }") -(define_insn "cmpqi_z_used" +(define_insn_and_split "cmpqi_z_used" [(set (cc0) (compare (match_operand:QI 0 "tst_operand" "dxy,m") (match_operand:QI 1 "cmp_operand" "m,dxy"))) (use (match_operand:HI 2 "hard_reg_operand" "dxy,dxy")) (use (reg:HI SOFT_Z_REGNUM))] "" - "#") - -(define_split /* cmpqi_z_used */ - [(set (cc0) - (compare (match_operand:QI 0 "tst_operand" "") - (match_operand:QI 1 "cmp_operand" ""))) - (use (match_operand:HI 2 "hard_reg_operand" "")) - (use (reg:HI SOFT_Z_REGNUM))] + "#" "z_replacement_completed == 2" [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 2)) (set (match_dup 2) (match_dup 3)) @@ -573,41 +563,29 @@ ;; (strict_low_part ...) information. This is correct for our machine ;; description but not for GCC optimization passes. ;; -(define_insn "movstrictsi" +(define_insn_and_split "movstrictsi" [(set (strict_low_part (match_operand:SI 0 "non_push_operand" "+um,D,D")) (match_operand:SI 1 "general_operand" "D,Dim,uD"))] "" - "#") - -(define_split - [(set (strict_low_part (match_operand:SI 0 "non_push_operand" "")) - (match_operand:SI 1 "general_operand" ""))] + "#" "z_replacement_completed == 2" [(set (match_dup 0) (match_dup 1))] "") -(define_insn "movstricthi" +(define_insn_and_split "movstricthi" [(set (strict_low_part (match_operand:HI 0 "non_push_operand" "+um,dA,dA")) (match_operand:HI 1 "general_operand" "dA,dAim,u"))] "" - "#") - -(define_split - [(set (strict_low_part (match_operand:HI 0 "non_push_operand" "")) - (match_operand:HI 1 "general_operand" ""))] + "#" "z_replacement_completed == 2" [(set (match_dup 0) (match_dup 1))] "") -(define_insn "movstrictqi" +(define_insn_and_split "movstrictqi" [(set (strict_low_part (match_operand:QI 0 "non_push_operand" "+mu,!dA")) (match_operand:QI 1 "general_operand" "d,imudA"))] "" - "#") - -(define_split - [(set (strict_low_part (match_operand:QI 0 "non_push_operand" "")) - (match_operand:QI 1 "general_operand" ""))] + "#" "z_replacement_completed == 2" [(set (match_dup 0) (match_dup 1))] "") @@ -651,17 +629,26 @@ } ") -(define_insn "movdi_internal" - [(set (match_operand:DI 0 "nonimmediate_operand" "=ou,U,!u,U,m,m,!u") +;; Separate push from normal moves to avoid reloading problems +;; The 'clr' is not able to push on 68HC11 so we really need a scratch. +;; We can also accept more scratch registers. +(define_insn_and_split "*pushdi_internal" + [(set (match_operand:DI 0 "push_operand" "=<,<,<,<") + (match_operand:DI 1 "general_operand" "i,U,m,!u")) + (clobber (match_scratch:HI 2 "=&dA,&d,&d,&dA"))] + "" + "#" + "reload_completed" + [(const_int 0)] + "m68hc11_split_move (operands[0], operands[1], operands[2]); + DONE;") + +(define_insn_and_split "movdi_internal" + [(set (match_operand:DI 0 "non_push_operand" "=m!u,U,!u,U,m,m,!u") (match_operand:DI 1 "general_operand" "K,iU,iU,!u,mi,!u,!mu")) (clobber (match_scratch:HI 2 "=X,&d,&d,&d,&d,&d,&d"))] "" - "#") - -(define_split - [(set (match_operand:DI 0 "nonimmediate_operand" "") - (match_operand:DI 1 "general_operand" "")) - (clobber (match_scratch:HI 2 ""))] + "#" "reload_completed" [(const_int 0)] "m68hc11_split_move (operands[0], operands[1], operands[2]); @@ -687,17 +674,24 @@ } ") -(define_insn "movdf_internal" - [(set (match_operand:DF 0 "nonimmediate_operand" "=ou,U,!u,U,m,m,!u") +;; See pushdi_internal +(define_insn_and_split "*pushdf_internal" + [(set (match_operand:DF 0 "push_operand" "=<,<,<,<") + (match_operand:DF 1 "general_operand" "i,U,m,!u")) + (clobber (match_scratch:HI 2 "=&dA,&d,&d,&dA"))] + "" + "#" + "reload_completed" + [(const_int 0)] + "m68hc11_split_move (operands[0], operands[1], operands[2]); + DONE;") + +(define_insn_and_split "movdf_internal" + [(set (match_operand:DF 0 "non_push_operand" "=mu,U,!u,U,m,m,!u") (match_operand:DF 1 "general_operand" "G,iU,iU,!u,mi,!u,!mu")) (clobber (match_scratch:HI 2 "=X,&d,&d,&d,&d,&d,&d"))] "" - "#") - -(define_split - [(set (match_operand:DF 0 "nonimmediate_operand" "") - (match_operand:DF 1 "general_operand" "")) - (clobber (match_scratch:HI 2 ""))] + "#" "reload_completed" [(const_int 0)] "m68hc11_split_move (operands[0], operands[1], operands[2]); @@ -732,17 +726,23 @@ } ") -(define_insn "movsi_internal" - [(set (match_operand:SI 0 "nonimmediate_operand" "=ou,mu,?D,m,?D,?u,?u,!u,D") - (match_operand:SI 1 "general_operand" "K,imu,im,?D,!u,?D,mi,!u,!D")) - (clobber (match_scratch:HI 2 "=X,&d,X,X,X,X,&d,&d,X"))] +(define_insn_and_split "*pushsi_internal" + [(set (match_operand:SI 0 "push_operand" "=<,<,<,<,<") + (match_operand:SI 1 "general_operand" "!D,i,U,m,!u")) + (clobber (match_scratch:HI 2 "=X,&dA,&d,&d,&dA"))] "" - "#") + "#" + "reload_completed" + [(const_int 0)] + "m68hc11_split_move (operands[0], operands[1], operands[2]); + DONE;") -(define_split - [(set (match_operand:SI 0 "nonimmediate_operand" "") - (match_operand:SI 1 "general_operand" "")) - (clobber (match_scratch:HI 2 ""))] +(define_insn_and_split "movsi_internal" + [(set (match_operand:SI 0 "nonimmediate_operand" "=mu,mu,?D,m,?D,?u,?u,!u,D") + (match_operand:SI 1 "general_operand" "K,imu,im,?D,!u,?D,mi,!u,!D")) + (clobber (match_scratch:HI 2 "=X,&d,X,X,X,X,&d,&d,X"))] + "" + "#" "reload_completed" [(const_int 0)] "m68hc11_split_move (operands[0], operands[1], operands[2]); @@ -768,17 +768,23 @@ } ") -(define_insn "movsf_internal" - [(set (match_operand:SF 0 "nonimmediate_operand" "=o!u,m,D,m,D,!u,!u,!u,D") +(define_insn_and_split "*pushsf_internal" + [(set (match_operand:SF 0 "push_operand" "=<,<,<,<,<") + (match_operand:SF 1 "general_operand" "!D,i,U,m,!u")) + (clobber (match_scratch:HI 2 "=X,&dA,&d,&d,&dA"))] + "" + "#" + "reload_completed" + [(const_int 0)] + "m68hc11_split_move (operands[0], operands[1], operands[2]); + DONE;") + +(define_insn_and_split "movsf_internal" + [(set (match_operand:SF 0 "nonimmediate_operand" "=m!u,m,D,m,D,!u,!u,!u,D") (match_operand:SF 1 "general_operand" "G,im,im,D,!u,D,mi,!u,!D")) (clobber (match_scratch:HI 2 "=X,&d,X,X,X,X,&d,&d,X"))] "" - "#") - -(define_split - [(set (match_operand:SF 0 "nonimmediate_operand" "") - (match_operand:SF 1 "general_operand" "")) - (clobber (match_scratch:HI 2 ""))] + "#" "reload_completed" [(const_int 0)] "m68hc11_split_move (operands[0], operands[1], operands[2]); @@ -849,6 +855,18 @@ DONE; } } + + /* The doloop optimization can emit a move with a constant > 32767. + This will fail later on because the move instruction is not recognized + eg: (set (reg:HI 53) (const_int 0x8000)) + because for some reason gcc expects the constant to be sign extended + ie, it only recognize: (set (reg:HI 53) (const_int 0xffff8000)) + Do the sign extension here. */ + if (GET_CODE (operands[1]) == CONST_INT + && INTVAL (operands[1]) > 0x7fffL && INTVAL (operands[1]) <= 0x0ffffL) + { + operands[1] = GEN_INT ((INTVAL (operands[1])) | (-1L << 16)); + } if (TARGET_M6811 && (reload_in_progress | reload_completed) == 0) { if (GET_CODE (operands[0]) == MEM && @@ -878,18 +896,9 @@ } }") -(define_insn "movhi_const0" - [(set (match_operand:HI 0 "non_push_operand" "=d,A,um") - (const_int 0))] - "" - "@ - clra\\n\\tclrb - ld%0\\t#0 - clr\\t%b0\\n\\tclr\\t%h0") - (define_insn "*movhi_68hc12" - [(set (match_operand:HI 0 "nonimmediate_operand" "=U,dAw,U,U,m,!u") - (match_operand:HI 1 "general_operand" "U,rim,dAwi,!u,dAw,riU"))] + [(set (match_operand:HI 0 "nonimmediate_operand" "=U,dAw,dAw,m,U,U,m,!u") + (match_operand:HI 1 "general_operand" "U,dAwim,!u,K,dAwi,!u,dAw,riU"))] "TARGET_M6812" "* { @@ -897,6 +906,15 @@ return \"\"; }") +(define_insn "movhi_const0" + [(set (match_operand:HI 0 "nonimmediate_operand" "=d,A,um") + (const_int 0))] + "TARGET_M6811" + "@ + clra\\n\\tclrb + ld%0\\t#0 + clr\\t%b0\\n\\tclr\\t%h0") + (define_insn "*movhi_m68hc11" [(set (match_operand:HI 0 "nonimmediate_operand" "=dAw,!u,m,m,dAw,!*u") (match_operand:HI 1 "general_operand" "dAwim,dAw,dA,?Aw,!*u,dAw"))] @@ -936,9 +954,9 @@ (define_split [(set (match_operand:QI 0 "hard_addr_reg_operand" "") (match_operand:QI 1 "general_operand" ""))] - "z_replacement_completed == 2 && GET_MODE (operands[0]) == QImode + "z_replacement_completed == 2 && !reg_mentioned_p (operands[0], operands[1]) - && !D_REG_P (operands[1])" + && !(D_REG_P (operands[1]) || Q_REG_P (operands[1]))" [(parallel [(set (reg:HI D_REGNUM) (match_dup 2)) (set (match_dup 2) (reg:HI D_REGNUM))]) (set (reg:QI D_REGNUM) (match_dup 1)) @@ -952,9 +970,9 @@ (define_split [(set (match_operand:QI 0 "nonimmediate_operand" "") (match_operand:QI 1 "hard_addr_reg_operand" ""))] - "z_replacement_completed == 2 && GET_MODE (operands[1]) == QImode + "z_replacement_completed == 2 && !reg_mentioned_p (operands[1], operands[0]) - && !D_REG_P (operands[0])" + && !(D_REG_P (operands[0]) || Q_REG_P (operands[0]))" [(parallel [(set (reg:HI D_REGNUM) (match_dup 2)) (set (match_dup 2) (reg:HI D_REGNUM))]) (set (match_dup 0) (reg:QI D_REGNUM)) @@ -1664,8 +1682,8 @@ ;;- Min and Max instructions (68HC12). ;;-------------------------------------------------------------------- (define_insn "uminqi3" - [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m") - (umin:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") + [(set (match_operand:QI 0 "nonimmediate_noinc_operand" "=d,m") + (umin:QI (match_operand:QI 1 "nonimmediate_noinc_operand" "%0,0") (match_operand:QI 2 "general_operand" "m,d")))] "TARGET_M6812 && TARGET_MIN_MAX" "* @@ -1686,8 +1704,8 @@ }") (define_insn "umaxqi3" - [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m") - (umax:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") + [(set (match_operand:QI 0 "nonimmediate_noinc_operand" "=d,m") + (umax:QI (match_operand:QI 1 "nonimmediate_noinc_operand" "%0,0") (match_operand:QI 2 "general_operand" "m,d")))] "TARGET_M6812 && TARGET_MIN_MAX" "* @@ -1708,8 +1726,8 @@ }") (define_insn "uminhi3" - [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m") - (umin:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") + [(set (match_operand:HI 0 "nonimmediate_noinc_operand" "=d,m") + (umin:HI (match_operand:HI 1 "nonimmediate_noinc_operand" "%0,0") (match_operand:HI 2 "general_operand" "m,d")))] "TARGET_M6812 && TARGET_MIN_MAX" "* @@ -1727,8 +1745,8 @@ }") (define_insn "umaxhi3" - [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m") - (umax:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") + [(set (match_operand:HI 0 "nonimmediate_noinc_operand" "=d,m") + (umax:HI (match_operand:HI 1 "nonimmediate_noinc_operand" "%0,0") (match_operand:HI 2 "general_operand" "m,d")))] "TARGET_M6812 && TARGET_MIN_MAX" "* @@ -2090,8 +2108,8 @@ }") (define_insn "*addhi3_68hc12" - [(set (match_operand:HI 0 "register_operand" "=xyd,d,xy*z*w,xy*z*w,xy*z") - (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,xy*zw,0") + [(set (match_operand:HI 0 "register_operand" "=d*A,d,xy*A*w,xy*A*w,xy*A") + (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,xy*Aw,0") (match_operand:HI 2 "general_operand" "i,m*A*wu,id,id,!mu*A")))] "TARGET_M6812" "* @@ -2279,9 +2297,9 @@ }") (define_insn "*addhi3" - [(set (match_operand:HI 0 "hard_reg_operand" "=A,dA,d,!A,d*A,!d*A") - (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0,0,0") - (match_operand:HI 2 "general_operand" "N,I,i,I,mi*A*d,!u*d*w")))] + [(set (match_operand:HI 0 "hard_reg_operand" "=A,dA,d,!A,d*A,d,!d*A") + (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0,0,0,0") + (match_operand:HI 2 "general_operand" "N,I,i,I,mi*A*d,*u,!u*d*w")))] "TARGET_M6811" "* { @@ -2374,7 +2392,7 @@ [(set (match_operand:HI 0 "hard_reg_operand" "=A,d") (plus:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,um*A")) - (match_operand:HI 2 "hard_reg_operand" "0,0")))] + (match_operand:HI 2 "general_operand" "0,0")))] "" "* { @@ -2401,8 +2419,8 @@ "") (define_insn "addqi3" - [(set (match_operand:QI 0 "nonimmediate_operand" "=!d*rm,dq,!*A") - (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") + [(set (match_operand:QI 0 "nonimmediate_noinc_operand" "=!d*rm,dq,!*A") + (plus:QI (match_operand:QI 1 "nonimmediate_noinc_operand" "%0,0,0") (match_operand:QI 2 "general_operand" "N,ium*A*d,ium*A*d")))] "" "* @@ -2707,9 +2725,9 @@ (define_insn "*subhi3" - [(set (match_operand:HI 0 "register_operand" "=d,*A,d*A") - (minus:HI (match_operand:HI 1 "register_operand" "0,0,0") - (match_operand:HI 2 "general_operand" "im*A*d,im*d*A,!u")))] + [(set (match_operand:HI 0 "register_operand" "=d,*A,d,*A") + (minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0") + (match_operand:HI 2 "general_operand" "im*A*d,im*d*A,u,!u")))] "" "* { @@ -2723,7 +2741,7 @@ (define_insn "*subhi3_zext" [(set (match_operand:HI 0 "hard_reg_operand" "=d,d") - (minus:HI (match_operand:HI 1 "hard_reg_operand" "0,0") + (minus:HI (match_operand:HI 1 "general_operand" "0,0") (zero_extend:HI (match_operand:QI 2 "general_operand" "mi*A,!u"))))] "" "* @@ -2743,7 +2761,7 @@ (define_insn "subqi3" [(set (match_operand:QI 0 "hard_reg_operand" "=dq,!*x*y") - (minus:QI (match_operand:QI 1 "hard_reg_operand" "0,0") + (minus:QI (match_operand:QI 1 "general_operand" "0,0") (match_operand:QI 2 "general_operand" "uim*A*d,uim*A*d")))] "" "* @@ -2837,6 +2855,32 @@ return \"emul\\n\\texg\\tx,y\"; }") +(define_insn "umulhisi3_hc11" + [(set (match_operand:SI 0 "register_operand" "=D,D") + (mult:SI (zero_extend:SI + (match_operand:HI 1 "register_operand" "%d,Amu")) + (zero_extend:SI + (match_operand:HI 2 "register_operand" "Amu,d")))) + (clobber (match_scratch:HI 3 "=y,y"))] + "TARGET_M6811" + "* +{ + CC_STATUS_INIT; + if (!H_REG_P (operands[1])) + output_asm_insn (\"ldx\\t%1\", operands); + if (!H_REG_P (operands[2])) + output_asm_insn (\"ldx\\t%2\", operands); + + if (Y_REG_P (operands[1]) || Y_REG_P (operands[2])) + output_asm_insn (\"pshy\", operands); + else if (X_REG_P (operands[1]) || X_REG_P (operands[2]) + || !H_REG_P (operands[1]) || !H_REG_P (operands[2])) + output_asm_insn (\"pshx\", operands); + + output_asm_insn (\"bsr\\t__mulhi32\", operands); + return \"ins\\n\\tins\"; +}") + (define_insn "mulhisi3" [(set (match_operand:SI 0 "register_operand" "=D,D") (mult:SI (sign_extend:SI @@ -2896,8 +2940,8 @@ (define_insn "mulqi3" [(set (match_operand:QI 0 "register_operand" "=d,*x,*y") - (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%dum,0,0") - (match_operand:QI 2 "general_operand" "dium,*xium,*yium")))] + (mult:QI (match_operand:QI 1 "general_operand" "%di*um,0,0") + (match_operand:QI 2 "general_operand" "di*um,*xium,*yium")))] "" "* { @@ -2952,11 +2996,11 @@ ") (define_insn "mulqihi3" - [(set (match_operand:HI 0 "register_operand" "=d,d") + [(set (match_operand:HI 0 "register_operand" "=d,d,d") (mult:HI (sign_extend:HI - (match_operand:QI 1 "register_operand" "%0,0")) + (match_operand:QI 1 "register_operand" "%0,0,0")) (sign_extend:HI - (match_operand:QI 2 "nonimmediate_operand" "dm,*A"))))] + (match_operand:QI 2 "general_operand" "mi*u,*A,0"))))] "" "* { @@ -3054,21 +3098,29 @@ ;;- and instructions. ;;-------------------------------------------------------------------- -(define_insn "anddi3" +(define_insn_and_split "anddi3" [(set (match_operand:DI 0 "reg_or_some_mem_operand" "=m,u") (and:DI (match_operand:DI 1 "reg_or_some_mem_operand" "%imu,imu") (match_operand:DI 2 "general_operand" "imu,imu"))) (clobber (match_scratch:HI 3 "=d,d"))] "" - "#") + "#" + "reload_completed" + [(const_int 0)] + "m68hc11_split_logical (SImode, AND, operands); + DONE;") -(define_insn "andsi3" +(define_insn_and_split "andsi3" [(set (match_operand:SI 0 "register_operand" "=D,!u") (and:SI (match_operand:SI 1 "register_operand" "%0,0") (match_operand:SI 2 "general_operand" "Dimu,imu"))) (clobber (match_scratch:HI 3 "=X,d"))] "" - "#") + "#" + "reload_completed" + [(const_int 0)] + "m68hc11_split_logical (HImode, AND, operands); + DONE;") (define_expand "andhi3" [(set (match_operand:HI 0 "register_operand" "") @@ -3078,10 +3130,10 @@ "") (define_insn "*andhi3_mem" - [(set (match_operand:HI 0 "memory_operand" "=Q,R") + [(set (match_operand:HI 0 "memory_operand" "=R,Q") (and:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "i,i"))) - (clobber (match_scratch:HI 2 "=xy,X"))] + (clobber (match_scratch:HI 2 "=X,xy"))] "TARGET_RELAX && !TARGET_M6812" "* { @@ -3101,7 +3153,7 @@ /* When destination is a global variable, generate a .relax instruction and load the address in the clobber register. That load can be eliminated by the linker if the address is in page0. */ - if (which_alternative == 0) + if (which_alternative == 1) { rtx ops[3]; @@ -3216,8 +3268,8 @@ (define_insn "*andhi3_gen" [(set (match_operand:HI 0 "register_operand" "=d,d,!*A") - (and:HI (match_operand:HI 1 "register_operand" "%0,0,0") - (match_operand:HI 2 "general_operand" "mi,!u*A,!um*A")))] + (and:HI (match_operand:HI 1 "splitable_operand" "%0,0,0") + (match_operand:HI 2 "splitable_operand" "mi,!u*A,!um*Ai")))] "" "* { @@ -3236,10 +3288,10 @@ "") (define_insn "*andqi3_mem" - [(set (match_operand:QI 0 "memory_operand" "=Q,R") + [(set (match_operand:QI 0 "memory_operand" "=R,Q") (and:QI (match_dup 0) (match_operand:QI 1 "const_int_operand" "i,i"))) - (clobber (match_scratch:HI 2 "=xy,X"))] + (clobber (match_scratch:HI 2 "=X,xy"))] "TARGET_RELAX && !TARGET_M6812" "* { @@ -3257,7 +3309,7 @@ /* When destination is a global variable, generate a .relax instruction and load the address in the clobber register. That load can be eliminated by the linker if the address is in page0. */ - if (which_alternative == 0) + if (which_alternative == 1) { rtx ops[3]; @@ -3310,8 +3362,8 @@ (define_insn "*andqi3_gen" [(set (match_operand:QI 0 "register_operand" "=d,d,d,?*A,?*A,!*q") - (and:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0") - (match_operand:QI 2 "general_operand" "mi,!u,?*A,!um,?*A*d,!um*A")))] + (and:QI (match_operand:QI 1 "general_operand" "%0,0,0,0,0,0") + (match_operand:QI 2 "general_operand" "mi,!*u,?*A,!*um,?*A*d,!*um*A")))] "" "* { @@ -3330,34 +3382,42 @@ ;;- Bit set or instructions. ;;-------------------------------------------------------------------- -(define_insn "iordi3" +(define_insn_and_split "iordi3" [(set (match_operand:DI 0 "reg_or_some_mem_operand" "=m,u") (ior:DI (match_operand:DI 1 "reg_or_some_mem_operand" "%imu,imu") (match_operand:DI 2 "general_operand" "imu,imu"))) (clobber (match_scratch:HI 3 "=d,d"))] "" - "#") + "#" + "reload_completed" + [(const_int 0)] + "m68hc11_split_logical (SImode, IOR, operands); + DONE;") -(define_insn "iorsi3" +(define_insn_and_split "iorsi3" [(set (match_operand:SI 0 "register_operand" "=D,!u") (ior:SI (match_operand:SI 1 "register_operand" "%0,0") (match_operand:SI 2 "general_operand" "Dimu,imu"))) (clobber (match_scratch:HI 3 "=X,d"))] "" - "#") + "#" + "reload_completed" + [(const_int 0)] + "m68hc11_split_logical (HImode, IOR, operands); + DONE;") (define_expand "iorhi3" [(set (match_operand:HI 0 "register_operand" "") (ior:HI (match_operand:HI 1 "register_operand" "") - (match_operand:HI 2 "general_operand" "")))] + (match_operand:HI 2 "splitable_operand" "")))] "" "") (define_insn "*iorhi3_mem" - [(set (match_operand:HI 0 "memory_operand" "=Q,R") + [(set (match_operand:HI 0 "memory_operand" "=R,Q") (ior:HI (match_dup 0) (match_operand:HI 1 "const_int_operand" ""))) - (clobber (match_scratch:HI 2 "=xy,X"))] + (clobber (match_scratch:HI 2 "=X,xy"))] "TARGET_RELAX && !TARGET_M6812" "* { @@ -3369,7 +3429,7 @@ return \"\"; } CC_STATUS_INIT; - if (which_alternative == 0) + if (which_alternative == 1) { rtx ops[3]; @@ -3437,8 +3497,8 @@ (define_insn "*iorhi3_gen" [(set (match_operand:HI 0 "register_operand" "=d,d,!*A") - (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0") - (match_operand:HI 2 "general_operand" "mi,!u*A,!um*A")))] + (ior:HI (match_operand:HI 1 "splitable_operand" "%0,0,0") + (match_operand:HI 2 "splitable_operand" "mi,!u*A,!um*Ai")))] "" "* { @@ -3457,10 +3517,10 @@ "") (define_insn "*iorqi3_mem" - [(set (match_operand:QI 0 "memory_operand" "=Q,R") + [(set (match_operand:QI 0 "memory_operand" "=R,Q") (ior:QI (match_dup 0) (match_operand:QI 1 "const_int_operand" ""))) - (clobber (match_scratch:HI 2 "=xy,X"))] + (clobber (match_scratch:HI 2 "=X,xy"))] "TARGET_RELAX && !TARGET_M6812" "* { @@ -3471,7 +3531,7 @@ cc_status = cc_prev_status; return \"\"; } - if (which_alternative == 0) + if (which_alternative == 1) { rtx ops[3]; @@ -3520,8 +3580,8 @@ (define_insn "*iorqi3_gen" [(set (match_operand:QI 0 "register_operand" "=d,d,d,?*A,?*A,!*q") - (ior:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0") - (match_operand:QI 2 "general_operand" "mi,!u,!*A,!um,?*A*d,!um*A")))] + (ior:QI (match_operand:QI 1 "general_operand" "%0,0,0,0,0,0") + (match_operand:QI 2 "general_operand" "mi,!*u,!*A,!*um,?*A*d,!*um*A")))] "" "* { @@ -3541,26 +3601,34 @@ ;;- xor instructions. ;;-------------------------------------------------------------------- -(define_insn "xordi3" +(define_insn_and_split "xordi3" [(set (match_operand:DI 0 "reg_or_some_mem_operand" "=m,u") (xor:DI (match_operand:DI 1 "reg_or_some_mem_operand" "%imu,imu") (match_operand:DI 2 "general_operand" "imu,imu"))) (clobber (match_scratch:HI 3 "=d,d"))] "" - "#") + "#" + "reload_completed" + [(const_int 0)] + "m68hc11_split_logical (SImode, XOR, operands); + DONE;") -(define_insn "xorsi3" +(define_insn_and_split "xorsi3" [(set (match_operand:SI 0 "register_operand" "=D,!u") (xor:SI (match_operand:SI 1 "register_operand" "%0,0") (match_operand:SI 2 "general_operand" "Dimu,imu"))) (clobber (match_scratch:HI 3 "=X,d"))] "" - "#") + "#" + "reload_completed" + [(const_int 0)] + "m68hc11_split_logical (HImode, XOR, operands); + DONE;") (define_insn "xorhi3" [(set (match_operand:HI 0 "register_operand" "=d,d,!*A") - (xor:HI (match_operand:HI 1 "register_operand" "%0,0,0") - (match_operand:HI 2 "general_operand" "im,!u*A,!ium*A")))] + (xor:HI (match_operand:HI 1 "splitable_operand" "%0,0,0") + (match_operand:HI 2 "splitable_operand" "im,!u*A,!ium*A")))] "" "* { @@ -3604,8 +3672,8 @@ (define_insn "xorqi3" [(set (match_operand:QI 0 "register_operand" "=d,d,d,?*A,?*A,!*q") - (xor:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0") - (match_operand:QI 2 "general_operand" "im,!u,!*A,!ium,?*A*d,!ium*A")))] + (xor:QI (match_operand:QI 1 "general_operand" "%0,0,0,0,0,0") + (match_operand:QI 2 "general_operand" "im,!*u,!*A,!i*um,?*A*d,!i*um*A")))] "" "* { @@ -3641,30 +3709,47 @@ ;;- Bit set or instructions. ;;-------------------------------------------------------------------- -(define_insn "*logicalsi3_zexthi" +(define_insn_and_split "*logicalsi3_zexthi" [(set (match_operand:SI 0 "register_operand" "=D") (match_operator:SI 3 "m68hc11_logical_operator" [(zero_extend:SI (match_operand:HI 1 "general_operand" "imudA")) (match_operand:SI 2 "general_operand" "Dimu")]))] "" - "#") + "#" + "reload_completed" + [(set (reg:HI D_REGNUM) (match_dup 4)) + (set (reg:HI D_REGNUM) (match_op_dup 3 [(reg:HI D_REGNUM) (match_dup 5)])) + (set (reg:HI X_REGNUM) (match_dup 6))] + "PUT_MODE (operands[3], HImode); + if (X_REG_P (operands[2])) + { + operands[5] = operands[1]; + /* Make all the (set (REG:x) (REG:y)) a nop set. */ + operands[4] = gen_rtx (REG, HImode, HARD_D_REGNUM); + operands[6] = gen_rtx (REG, HImode, HARD_X_REGNUM); + } + else + { + operands[4] = operands[1]; + operands[5] = m68hc11_gen_lowpart (HImode, operands[2]); + operands[6] = m68hc11_gen_highpart (HImode, operands[2]); + } + /* For an AND, make sure the high 16-bit part is cleared. */ + if (GET_CODE (operands[3]) == AND) + { + operands[6] = const0_rtx; + } + ") -(define_insn "*logicalsi3_zextqi" +(define_insn_and_split "*logicalsi3_zextqi" [(set (match_operand:SI 0 "register_operand" "=D,D,D") (match_operator:SI 3 "m68hc11_logical_operator" [(zero_extend:SI (match_operand:QI 1 "general_operand" "d,*A,imu")) (match_operand:SI 2 "general_operand" "imu,imu,0")]))] "" - "#") - -(define_split /* logicalsi3_zextqi */ - [(set (match_operand:SI 0 "register_operand" "") - (match_operator:SI 3 "m68hc11_logical_operator" - [(zero_extend:SI - (match_operand:QI 1 "general_operand" "")) - (match_operand:SI 2 "general_operand" "")]))] + "#" "z_replacement_completed == 2" [(set (reg:QI A_REGNUM) (match_dup 4)) (set (reg:QI D_REGNUM) (match_dup 7)) @@ -3695,63 +3780,47 @@ } ") -(define_split /* logicalsi3_zexthi */ - [(set (match_operand:SI 0 "register_operand" "") - (match_operator:SI 3 "m68hc11_logical_operator" - [(zero_extend:SI - (match_operand:HI 1 "general_operand" "")) - (match_operand:SI 2 "general_operand" "")]))] - "reload_completed" - [(set (reg:HI D_REGNUM) (match_dup 4)) - (set (reg:HI D_REGNUM) (match_op_dup 3 [(reg:HI D_REGNUM) (match_dup 5)])) - (set (reg:HI X_REGNUM) (match_dup 6))] - "PUT_MODE (operands[3], HImode); - if (X_REG_P (operands[2])) - { - operands[5] = operands[1]; - /* Make all the (set (REG:x) (REG:y)) a nop set. */ - operands[4] = gen_rtx (REG, HImode, HARD_D_REGNUM); - operands[6] = gen_rtx (REG, HImode, HARD_X_REGNUM); - } - else - { - operands[4] = operands[1]; - operands[5] = m68hc11_gen_lowpart (HImode, operands[2]); - operands[6] = m68hc11_gen_highpart (HImode, operands[2]); - } - /* For an AND, make sure the high 16-bit part is cleared. */ - if (GET_CODE (operands[3]) == AND) - { - operands[6] = const0_rtx; - } - ") - -(define_insn "*logicalhi3_zexthi_ashift8" +(define_insn_and_split "*logicalhi3_zexthi_ashift8" [(set (match_operand:HI 0 "register_operand" "=d") (match_operator:HI 3 "m68hc11_logical_operator" [(zero_extend:HI - (match_operand:QI 1 "general_operand" "imud")) + (match_operand:QI 1 "general_operand" "imud*A")) (ashift:HI - (match_operand:HI 2 "general_operand" "dimu") + (match_operand:HI 2 "general_operand" "imud*A") (const_int 8))]))] "" - "#") + "#" + "z_replacement_completed == 2" + [(set (reg:QI A_REGNUM) (match_dup 4)) + (set (reg:QI B_REGNUM) (match_dup 5))] + " + if (GET_CODE (operands[3]) == AND) + { + emit_insn (gen_movhi (operands[0], const0_rtx)); + DONE; + } + else + { + operands[5] = operands[1]; + if (D_REG_P (operands[2])) + { + operands[4] = gen_rtx (REG, QImode, HARD_B_REGNUM); + } + else + { + operands[4] = m68hc11_gen_lowpart (QImode, operands[2]); + } + } + ") -(define_insn "*logicalhi3_zexthi" +(define_insn_and_split "*logicalhi3_zexthi" [(set (match_operand:HI 0 "register_operand" "=d,d") (match_operator:HI 3 "m68hc11_logical_operator" [(zero_extend:HI (match_operand:QI 1 "general_operand" "imd*A,?u")) (match_operand:HI 2 "general_operand" "dim,?dimu")]))] "" - "#") - -(define_split /* logicalhi3_zexthi */ - [(set (match_operand:HI 0 "register_operand" "") - (match_operator:HI 3 "m68hc11_logical_operator" - [(zero_extend:HI - (match_operand:QI 1 "general_operand" "")) - (match_operand:HI 2 "general_operand" "")]))] + "#" "z_replacement_completed == 2" [(set (reg:QI B_REGNUM) (match_dup 6)) (set (reg:QI A_REGNUM) (match_dup 4)) @@ -3780,63 +3849,25 @@ } ") -(define_split /* logicalhi3_zexthi_ashift8 */ - [(set (match_operand:HI 0 "register_operand" "") - (match_operator:HI 3 "m68hc11_logical_operator" - [(zero_extend:HI - (match_operand:QI 1 "general_operand" "")) - (ashift:HI - (match_operand:HI 2 "general_operand" "") - (const_int 8))]))] - "z_replacement_completed == 2" - [(set (reg:QI A_REGNUM) (match_dup 4)) - (set (reg:QI B_REGNUM) (match_dup 5))] - " - if (GET_CODE (operands[3]) == AND) + +(define_insn_and_split "*logicalsi3_silshr16" + [(set (match_operand:SI 0 "register_operand" "=D,D,D,?D") + (match_operator:SI 3 "m68hc11_logical_operator" + [(lshiftrt:SI + (match_operand:SI 1 "general_operand" "uim,uim,0,0") + (const_int 16)) + (match_operand:SI 2 "general_operand" "uim,0,uim,0")]))] + "" + "#" + "reload_completed" + [(set (reg:HI D_REGNUM) (match_dup 4)) + (set (reg:HI D_REGNUM) (match_op_dup 3 [(reg:HI D_REGNUM) (match_dup 5)])) + (set (reg:HI X_REGNUM) (match_dup 6))] + "operands[5] = m68hc11_gen_highpart (HImode, operands[1]); + if (X_REG_P (operands[2])) { - emit_insn (gen_movhi (operands[0], const0_rtx)); - DONE; - } - else - { - operands[5] = operands[1]; - if (D_REG_P (operands[2])) - { - operands[4] = gen_rtx (REG, QImode, HARD_B_REGNUM); - } - else - { - operands[4] = m68hc11_gen_lowpart (QImode, operands[2]); - } - } - ") - -(define_insn "*logicalsi3_silshr16" - [(set (match_operand:SI 0 "register_operand" "=D,D,D") - (match_operator:SI 3 "m68hc11_logical_operator" - [(lshiftrt:SI - (match_operand:SI 1 "general_operand" "uim,uim,?D") - (const_int 16)) - (match_operand:SI 2 "general_operand" "uim,0,0")]))] - "" - "#") - -(define_split /* logicalsi3_silshr16 */ - [(set (match_operand:SI 0 "register_operand" "") - (match_operator:SI 3 "m68hc11_logical_operator" - [(lshiftrt:SI - (match_operand:SI 1 "general_operand" "") - (const_int 16)) - (match_operand:SI 2 "general_operand" "")]))] - "reload_completed" - [(set (reg:HI D_REGNUM) (match_dup 4)) - (set (reg:HI D_REGNUM) (match_op_dup 3 [(reg:HI D_REGNUM) (match_dup 5)])) - (set (reg:HI X_REGNUM) (match_dup 6))] - "operands[5] = m68hc11_gen_highpart (HImode, operands[1]); - if (X_REG_P (operands[2])) - { - operands[4] = gen_rtx (REG, HImode, HARD_D_REGNUM); - operands[6] = gen_rtx (REG, HImode, HARD_X_REGNUM); + operands[4] = gen_rtx (REG, HImode, HARD_D_REGNUM); + operands[6] = gen_rtx (REG, HImode, HARD_X_REGNUM); } else { @@ -3852,7 +3883,7 @@ } ") -(define_insn "*logicalsi3_silshl16" +(define_insn_and_split "*logicalsi3_silshl16" [(set (match_operand:SI 0 "register_operand" "=D,D") (match_operator:SI 3 "m68hc11_logical_operator" [(ashift:SI @@ -3860,15 +3891,7 @@ (const_int 16)) (match_operand:SI 2 "general_operand" "0,0")]))] "" - "#") - -(define_split /* logicalsi3_silshl16 */ - [(set (match_operand:SI 0 "register_operand" "") - (match_operator:SI 3 "m68hc11_logical_operator" - [(ashift:SI - (match_operand:SI 1 "general_operand" "") - (const_int 16)) - (match_operand:SI 2 "general_operand" "")]))] + "#" "z_replacement_completed == 2" [(set (reg:HI X_REGNUM) (match_op_dup 3 [(reg:HI X_REGNUM) (match_dup 4)])) (set (reg:HI D_REGNUM) (match_dup 5))] @@ -3881,48 +3904,45 @@ operands[5] = gen_rtx (REG, HImode, HARD_D_REGNUM); ") - -;;-------------------------------------------------------------------- -;;- 64/32-bit Logical Operations. Patterns are defined so that GCC -;; can optimize correctly. These insns are split by the `final' -;; pass (# pattern). They are split to fall in the corresponding -;; 16-bit logical patterns. -;;-------------------------------------------------------------------- - -;; Split 64-bit logical operations: anddi3, iordi3, xordi3 -(define_split - [(set (match_operand:DI 0 "reg_or_some_mem_operand" "") - (match_operator:DI 4 "m68hc11_logical_operator" - [(match_operand:DI 1 "reg_or_some_mem_operand" "") - (match_operand:DI 2 "general_operand" "")])) - (clobber (match_scratch:HI 3 ""))] +(define_insn_and_split "*logicalsi3_silshl16_zext" + [(set (match_operand:SI 0 "register_operand" "=D,D,D") + (match_operator:SI 3 "m68hc11_logical_operator" + [(ashift:SI + (zero_extend:SI + (match_operand:HI 1 "general_operand" "uim,udA,!dA")) + (const_int 16)) + (zero_extend:SI (match_operand:HI 2 "general_operand" "uidA,um,!dA"))]))] + "" + "#" + ;; Must split before z register replacement "reload_completed" - [(const_int 0)] - "m68hc11_split_logical (SImode, GET_CODE (operands[4]), operands); - DONE;") - -;; Split 32-bit logical operations: andsi3, iorsi3, xorsi3 -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (match_operator:SI 3 "m68hc11_logical_operator" - [(match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "general_operand" "")]))] - "0 && reload_completed" - [(const_int 0)] - "m68hc11_split_logical (HImode, GET_CODE (operands[3]), operands); - DONE;") + [(set (match_dup 4) (match_dup 5)) + (set (match_dup 6) (match_dup 7))] + " + /* set (X_REGNUM) (d), set (D_REGNUM) (1) */ + if (GET_CODE (operands[1]) == HARD_D_REGNUM + && GET_CODE (operands[3]) != AND) + { + /* This particular case is too early to be split before + Z register replacement because the cse-reg pass we do + does not recognize the 'swap_areg'. It is ok to handle + this case after. */ + if (z_replacement_completed != 2) + { + FAIL; + } + emit_move_insn (gen_rtx (REG, HImode, HARD_X_REGNUM), operands[2]); + emit_insn (gen_swap_areg (gen_rtx (REG, HImode, HARD_D_REGNUM), + gen_rtx (REG, HImode, HARD_X_REGNUM))); + } + operands[4] = gen_rtx (REG, HImode, HARD_D_REGNUM); + operands[6] = gen_rtx (REG, HImode, HARD_X_REGNUM); + operands[5] = operands[2]; + operands[7] = operands[1]; -;; Split 32-bit logical operations: andsi3, iorsi3, xorsi3 -(define_split - [(set (match_operand:SI 0 "reg_or_some_mem_operand" "") - (match_operator:SI 4 "m68hc11_logical_operator" - [(match_operand:SI 1 "reg_or_some_mem_operand" "") - (match_operand:SI 2 "general_operand" "")])) - (clobber (match_scratch:HI 3 ""))] - "reload_completed" - [(const_int 0)] - "m68hc11_split_logical (HImode, GET_CODE (operands[4]), operands); - DONE;") + if (GET_CODE (operands[3]) == AND) + operands[5] = operands[7] = const0_rtx; + ") ;;-------------------------------------------------------------------- ;; 16-bit Arithmetic and logical operations on X and Y: @@ -4323,8 +4343,8 @@ xgd%0\\n\\tcoma\\n\\tcomb\\n\\txgd%0\\n\\tin%0") (define_insn "negqi2" - [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m,!u,!*A") - (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,0,0")))] + [(set (match_operand:QI 0 "nonimmediate_noinc_operand" "=d,m,!u,!*A") + (neg:QI (match_operand:QI 1 "nonimmediate_noinc_operand" "0,0,0,0")))] "" "@ negb @@ -4421,19 +4441,13 @@ } }") -(define_insn "*ashldi3_const32" +(define_insn_and_split "*ashldi3_const32" [(set (match_operand:DI 0 "nonimmediate_operand" "=<,m,u") (ashift:DI (match_operand:DI 1 "general_operand" "umi,umi,umi") (const_int 32))) (clobber (match_scratch:HI 2 "=&A,d,d"))] "" - "#") - -(define_split - [(set (match_operand:DI 0 "nonimmediate_operand" "") - (ashift:DI (match_operand:DI 1 "general_operand" "") - (const_int 32))) - (clobber (match_scratch:HI 2 ""))] + "#" "reload_completed" [(const_int 0)] "/* Move the lowpart in the highpart first in case the shift @@ -4442,6 +4456,13 @@ { m68hc11_split_move (m68hc11_gen_lowpart (SImode, operands[0]), const0_rtx, operands[2]); + + /* Adjust first operand if it uses SP so that we take into + account the above push. Can occur only for 68HC12. */ + if (reg_mentioned_p (gen_rtx (REG, HImode, HARD_SP_REGNUM), + operands[1])) + operands[1] = adjust_address (operands[1], + GET_MODE (operands[0]), 4); } m68hc11_split_move (m68hc11_gen_highpart (SImode, operands[0]), m68hc11_gen_lowpart (SImode, operands[1]), @@ -4453,19 +4474,13 @@ } DONE;") -(define_insn "*ashldi3_const1" +(define_insn_and_split "*ashldi3_const1" [(set (match_operand:DI 0 "non_push_operand" "=m,m,u") (ashift:DI (match_operand:DI 1 "general_operand" "mi,u,umi") (const_int 1))) (clobber (match_scratch:HI 2 "=d,d,d"))] "" - "#") - -(define_split - [(set (match_operand:DI 0 "non_push_operand" "") - (ashift:DI (match_operand:DI 1 "general_operand" "") - (const_int 1))) - (clobber (match_scratch:HI 2 ""))] + "#" "z_replacement_completed == 2" [(set (match_dup 2) (match_dup 3)) (set (match_dup 2) (ashift:HI (match_dup 2) (const_int 1))) @@ -4505,10 +4520,10 @@ operands[8] = m68hc11_gen_lowpart (HImode, operands[8]);") (define_insn "addsi_silshr16" - [(set (match_operand:SI 0 "register_operand" "=D,D") - (plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "!*uim,0") + [(set (match_operand:SI 0 "register_operand" "=D,D,!D") + (plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "!*uim,0,0") (const_int 16)) - (match_operand:SI 2 "general_operand" "0,m!*u")))] + (match_operand:SI 2 "general_operand" "0,m!*u,0")))] "" "#") @@ -4530,14 +4545,24 @@ (const_int 16)) (match_operand:SI 2 "general_operand" "")))] "z_replacement_completed == 2 && X_REG_P (operands[1])" - [(set (reg:HI D_REGNUM) (reg:HI X_REGNUM)) + [(set (reg:HI D_REGNUM) (match_dup 5)) (set (reg:HI X_REGNUM) (match_dup 3)) (set (reg:HI D_REGNUM) (plus:HI (reg:HI D_REGNUM) (match_dup 4))) (set (reg:HI X_REGNUM) (plus:HI (plus:HI (reg:HI X_REGNUM) (const_int 0)) (reg:HI CC_REGNUM)))] "operands[3] = m68hc11_gen_highpart (HImode, operands[2]); - operands[4] = m68hc11_gen_lowpart (HImode, operands[2]);") + if (X_REG_P (operands[2])) + { + operands[4] = gen_rtx (REG, HImode, HARD_X_REGNUM); + operands[5] = gen_rtx (REG, HImode, HARD_D_REGNUM); + } + else + { + operands[4] = m68hc11_gen_lowpart (HImode, operands[2]); + operands[5] = gen_rtx (REG, HImode, HARD_X_REGNUM); + } +") (define_insn "addsi_ashift16" [(set (match_operand:SI 0 "register_operand" "=D") @@ -4563,24 +4588,27 @@ operands[4] = m68hc11_gen_lowpart (HImode, operands[2]); }") -(define_insn "addsi_andshr16" +(define_insn_and_split "addsi_andshr16" [(set (match_operand:SI 0 "register_operand" "=D") (plus:SI (and:SI (match_operand:SI 1 "general_operand" "%uim") (const_int 65535)) (match_operand:SI 2 "general_operand" "0")))] "" - "#") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (and:SI (match_operand:SI 1 "general_operand" "") - (const_int 65535)) - (match_operand:SI 2 "general_operand" "")))] + "#" "z_replacement_completed == 2" [(set (reg:HI D_REGNUM) (plus:HI (reg:HI D_REGNUM) (match_dup 3))) (set (reg:HI X_REGNUM) (plus:HI (plus:HI (reg:HI X_REGNUM) (const_int 0)) (reg:HI CC_REGNUM)))] "operands[3] = m68hc11_gen_lowpart (HImode, operands[1]);") +(define_insn "subhi_ashlhi8" + [(set (match_operand:HI 0 "register_operand" "=d") + (minus:HI (match_operand:HI 1 "register_operand" "0") + (mult:HI (match_operand:HI 2 "register_operand" "0") + (const_int 256))))] + "0" + "@ + sba") + ;; ;; 32-bit shifts are made by a small library routine that uses ;; a specific passing convention for parameters (for efficiency reasons). @@ -4622,31 +4650,24 @@ "" "#") -(define_insn "*ashlsi3_const16_zexthi" +(define_insn_and_split "*ashlsi3_const16_zexthi" [(set (match_operand:SI 0 "nonimmediate_operand" "=D") (ashift:SI (zero_extend:HI (match_operand:HI 1 "general_operand" "duim*A")) (const_int 16))) (clobber (match_scratch:HI 2 "=X"))] "" - "#") - -(define_split /* "*ashlsi3_const16_zexthi"*/ - [(set (match_operand:SI 0 "nonimmediate_operand" "") - (ashift:SI (zero_extend:HI - (match_operand:HI 1 "general_operand" "")) - (const_int 16))) - (clobber (match_scratch:HI 2 "=X"))] + "#" "reload_completed" [(set (reg:HI X_REGNUM) (match_dup 1)) (set (reg:HI D_REGNUM) (const_int 0))] "") (define_insn "*ashlsi3_const1" - [(set (match_operand:SI 0 "non_push_operand" "=D,D,m,!*u,?*um") - (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,*um,0,0,*um") + [(set (match_operand:SI 0 "non_push_operand" "=D,D,D,m,*u,*u") + (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,*u,m,*u,m") (const_int 1))) - (clobber (match_scratch:HI 2 "=X,X,&d,&d,&d"))] + (clobber (match_scratch:HI 2 "=X,X,X,&d,&d,&d"))] "" "* { @@ -4702,7 +4723,7 @@ (ashift:SI (match_dup 0) (match_operand:HI 1 "const_int_operand" ""))) (clobber (match_scratch:HI 2 "=y"))] - "" + "TARGET_M6811 /* See *ashlsi3 note. */" "* { CC_STATUS_INIT; @@ -4712,7 +4733,7 @@ (define_insn "*ashlsi3" [(set (match_operand:SI 0 "register_operand" "+D,D") (ashift:SI (match_dup 0) - (match_operand:HI 1 "general_operand" "y,m"))) + (match_operand:HI 1 "general_operand" "y,mi"))) (clobber (match_scratch:HI 2 "=1,X"))] "" "* @@ -4725,7 +4746,12 @@ is not enough register in class A_REGS. Assuming that 'operands[1]' does not refer to the stack (which - is true for 68hc11 only, we save temporary the value of Y. */ + is true for 68hc11 only, we save temporary the value of Y. + + For 68HC12 we must also accept a constant because Z register is + disabled when compiling with -fomit-frame-pointer. We can come up + with a reload problem and the *lshrsi3_const pattern was disabled + for that reason. */ if (!Y_REG_P (operands[2])) { rtx ops[1]; @@ -4861,8 +4887,8 @@ "") (define_insn "*ashlqi3_const1" - [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m,!u,!*q,!*A") - (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,0,0,0") + [(set (match_operand:QI 0 "nonimmediate_noinc_operand" "=d,m,!u,!*q,!*A") + (ashift:QI (match_operand:QI 1 "nonimmediate_noinc_operand" "0,0,0,0,0") (const_int 1)))] "" "@ @@ -5112,7 +5138,7 @@ (ashiftrt:SI (match_dup 0) (match_operand:HI 1 "const_int_operand" ""))) (clobber (match_scratch:HI 2 "=y"))] - "" + "TARGET_M6811 /* See *ashrsi3 note. */" "* { CC_STATUS_INIT; @@ -5122,7 +5148,7 @@ (define_insn "*ashrsi3" [(set (match_operand:SI 0 "register_operand" "+D,D") (ashiftrt:SI (match_dup 0) - (match_operand:HI 1 "general_operand" "y,m"))) + (match_operand:HI 1 "general_operand" "y,mi"))) (clobber (match_scratch:HI 2 "=1,X"))] "" "* @@ -5134,7 +5160,12 @@ is not enough register in class A_REGS. Assuming that 'operands[1]' does not refer to the stack (which - is true for 68hc11 only, we save temporary the value of Y. */ + is true for 68hc11 only, we save temporary the value of Y. + + For 68HC12 we must also accept a constant because Z register is + disabled when compiling with -fomit-frame-pointer. We can come up + with a reload problem and the *lshrsi3_const pattern was disabled + for that reason. */ if (!Y_REG_P (operands[2])) { rtx ops[1]; @@ -5162,8 +5193,8 @@ "") (define_insn "*ashrqi3_const1" - [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m,!u,!*q,!*A") - (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,0,0,0") + [(set (match_operand:QI 0 "nonimmediate_noinc_operand" "=d,m,!u,!*q,!*A") + (ashiftrt:QI (match_operand:QI 1 "nonimmediate_noinc_operand" "0,0,0,0,0") (const_int 1)))] "" "@ @@ -5240,19 +5271,13 @@ } }") -(define_insn "*lshrdi3_const32" +(define_insn_and_split "*lshrdi3_const32" [(set (match_operand:DI 0 "nonimmediate_operand" "=<,m,u") (lshiftrt:DI (match_operand:DI 1 "general_operand" "umi,umi,umi") (const_int 32))) (clobber (match_scratch:HI 2 "=&A,d,d"))] "" - "#") - -(define_split - [(set (match_operand:DI 0 "nonimmediate_operand" "") - (lshiftrt:DI (match_operand:DI 1 "general_operand" "") - (const_int 32))) - (clobber (match_scratch:HI 2 "=&A,d"))] + "#" "reload_completed" [(const_int 0)] "m68hc11_split_move (m68hc11_gen_lowpart (SImode, operands[0]), @@ -5322,19 +5347,13 @@ operands[7] = m68hc11_gen_highpart (HImode, operands[6]); operands[6] = m68hc11_gen_lowpart (HImode, operands[6]);") -(define_insn "*lshrdi_const1" +(define_insn_and_split "*lshrdi_const1" [(set (match_operand:DI 0 "non_push_operand" "=m,u") (lshiftrt:DI (match_operand:DI 1 "general_operand" "umi,umi") (const_int 1))) (clobber (match_scratch:HI 2 "=d,d"))] "" - "#") - -(define_split - [(set (match_operand:DI 0 "non_push_operand" "") - (lshiftrt:DI (match_operand:DI 1 "general_operand" "") - (const_int 1))) - (clobber (match_scratch:HI 2 ""))] + "#" "z_replacement_completed == 2" [(set (match_dup 2) (match_dup 3)) (set (match_dup 2) (lshiftrt:HI (match_dup 2) (const_int 1))) @@ -5407,10 +5426,10 @@ #") (define_insn "*lshrsi3_const1" - [(set (match_operand:SI 0 "non_push_operand" "=D,m,*u") - (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "D*um,*um,*um") + [(set (match_operand:SI 0 "non_push_operand" "=D,D,D,m,*u,*u") + (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,*u,m,*u,m") (const_int 1))) - (clobber (match_scratch:HI 2 "=X,&d,&d"))] + (clobber (match_scratch:HI 2 "=X,X,X,&d,&d,&d"))] "" "* { @@ -5461,7 +5480,7 @@ (lshiftrt:SI (match_dup 0) (match_operand:HI 1 "const_int_operand" ""))) (clobber (match_scratch:HI 2 "=y"))] - "" + "TARGET_M6811 /* See *lshrsi3 note. */" "* { CC_STATUS_INIT; @@ -5471,7 +5490,7 @@ (define_insn "*lshrsi3" [(set (match_operand:SI 0 "register_operand" "+D,D") (lshiftrt:SI (match_dup 0) - (match_operand:HI 1 "general_operand" "y,m"))) + (match_operand:HI 1 "general_operand" "y,mi"))) (clobber (match_scratch:HI 2 "=1,X"))] "" "* @@ -5483,7 +5502,12 @@ is not enough register in class A_REGS. Assuming that 'operands[1]' does not refer to the stack (which - is true for 68hc11 only, we save temporary the value of Y. */ + is true for 68hc11 only, we save temporary the value of Y. + + For 68HC12 we must also accept a constant because Z register is + disabled when compiling with -fomit-frame-pointer. We can come up + with a reload problem and the *lshrsi3_const pattern was disabled + for that reason. */ if (!Y_REG_P (operands[2])) { rtx ops[1]; @@ -5544,8 +5568,8 @@ }") (define_insn "lshrhi3_const" - [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,!*A,!*A") - (lshiftrt:HI (match_operand:HI 1 "general_operand" "dm*A,!u,dm,!u") + [(set (match_operand:HI 0 "nonimmediate_noinc_operand" "=d,d,!*A,!*A") + (lshiftrt:HI (match_operand:HI 1 "nonimmediate_noinc_operand" "dm*A,!u,dm,!u") (match_operand:HI 2 "const_int_operand" "i,i,i,i")))] "" "* @@ -5649,8 +5673,8 @@ "") (define_insn "*lshrqi3_const1" - [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d,!u,!*q,!*A") - (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,0,0,0") + [(set (match_operand:QI 0 "nonimmediate_noinc_operand" "=m,d,!u,!*q,!*A") + (lshiftrt:QI (match_operand:QI 1 "nonimmediate_noinc_operand" "0,0,0,0,0") (const_int 1)))] "" "@ @@ -5937,6 +5961,98 @@ "") ;;-------------------------------------------------------------------- +;;- Bit test and branch +;;-------------------------------------------------------------------- +;; Logical and, test if zero and branch to use "brset/brclr" instruction +;; +(define_insn "brclr" + [(set (pc) + (if_then_else + (eq (and:QI (match_operand:QI 0 "memory_operand" "R,Q") + (match_operand:QI 1 "const_int_operand" "")) + (const_int 0)) + (label_ref (match_operand 2 "" "")) + (pc))) + (clobber (match_scratch:HI 3 "=X,xy"))] + "0" + "* +{ + cc_status = cc_prev_status; + if (which_alternative == 0 || TARGET_M6812) + { + return \"brclr\\t%0,%1,%l2\"; + } + else + { + rtx ops[3]; + + ops[0] = operands[3]; + ops[1] = XEXP (operands[0], 0); + ops[2] = gen_label_rtx (); + output_asm_insn (\".relax\\t%l2\", ops); + m68hc11_gen_movhi (insn, ops); + output_asm_insn (\"brclr\\t0,%3,%1,%l2\", operands); + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", + CODE_LABEL_NUMBER (ops[2])); + return \"\"; + } +}") + +(define_insn "brset" + [(set (pc) + (if_then_else + (eq (and:QI (not:QI (match_operand:QI 0 "memory_operand" "R,Q")) + (match_operand:QI 1 "const_int_operand" "")) + (const_int 0)) + (label_ref (match_operand 2 "" "")) + (pc))) + (clobber (match_scratch:HI 3 "=X,xy"))] + "0" + "* +{ + cc_status = cc_prev_status; + if (which_alternative == 0 || TARGET_M6812) + { + return \"brset\\t%0,%1,%l2\"; + } + else + { + rtx ops[3]; + + ops[0] = operands[3]; + ops[1] = XEXP (operands[0], 0); + ops[2] = gen_label_rtx (); + output_asm_insn (\".relax\\t%l2\", ops); + m68hc11_gen_movhi (insn, ops); + output_asm_insn (\"brset\\t0,%3,%1,%l2\", operands); + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", + CODE_LABEL_NUMBER (ops[2])); + return \"\"; + } +}") + +(define_peephole2 + [(set (match_operand:QI 0 "hard_reg_operand" "") + (match_operand:QI 1 "memory_operand" "m")) + (set (cc0) (and:HI (match_operand:HI 2 "hard_reg_operand" "") + (match_operand:HI 3 "const_int_operand" ""))) + (set (pc) + (if_then_else (eq (cc0) (const_int 0)) + (label_ref (match_operand 4 "" "")) + (pc)))] + "0 && REGNO (operands[0]) == REGNO (operands[2]) + && peep2_reg_dead_p (2, operands[0])" + [(parallel [ + (set (pc) + (if_then_else + (eq (and:QI (match_dup 1) (match_dup 3)) + (const_int 0)) + (label_ref (match_dup 4)) + (pc))) + (clobber (match_dup 5))])] + "operands[5] = gen_rtx_SCRATCH (HImode);") + +;;-------------------------------------------------------------------- ;;- 68HC12 Decrement/Increment and branch ;;-------------------------------------------------------------------- ;; These patterns are used by loop optimization as well as peephole2 @@ -5976,17 +6092,24 @@ { FAIL; } + + /* Note that for xxx_dbcc_dec_yy the gen_rtx_NE is only used to pass + the operator and its operands are not relevant. */ if (GET_MODE (operands[0]) == HImode) { emit_jump_insn (gen_m68hc12_dbcc_dec_hi (operands[0], - gen_rtx (NE, HImode), + gen_rtx (NE, HImode, + operands[0], + operands[1]), operands[4])); DONE; } if (GET_MODE (operands[0]) == QImode) { emit_jump_insn (gen_m68hc12_dbcc_dec_qi (operands[0], - gen_rtx (NE, QImode), + gen_rtx (NE, QImode, + operands[0], + operands[1]), operands[4])); DONE; } @@ -6928,18 +7051,81 @@ ;; ;; Replace "leas 2,sp" with a "pulx" or a "puly". ;; On 68HC12, this is one cycle slower but one byte smaller. -;; pr target/6899: This peephole is not valid because a register CSE -;; pass removes the pulx/puly. +;; pr target/6899: This peephole was not valid because a register CSE +;; pass removes the pulx/puly. The 'use' clause ensure that the pulx is +;; not removed. ;; (define_peephole2 [(set (reg:HI SP_REGNUM) (plus:HI (reg:HI SP_REGNUM) (const_int 2))) (match_scratch:HI 0 "xy")] - "0 && TARGET_M6812 && optimize_size" - [(set (match_dup 0) (match_dup 1))] + "TARGET_M6812 && optimize_size" + [(set (match_dup 0) (match_dup 1)) + (use (match_dup 0))] "operands[1] = gen_rtx (MEM, HImode, gen_rtx (POST_INC, HImode, gen_rtx_REG (HImode, HARD_SP_REGNUM)));") +;; Replace: "pshx; tfr d,x; stx 0,sp" into "pshd; tfr d,x" +;; +;; PR 14542: emit a use to pretend we need the value of initial register. +;; Otherwise verify_local_live_at_start will abort due to a live change +;; of that register. +;; +(define_peephole2 + [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) + (match_operand:HI 0 "hard_reg_operand" "")) + (set (match_dup 0) + (match_operand:HI 1 "hard_reg_operand" "")) + (set (mem:HI (reg:HI SP_REGNUM)) + (match_dup 0))] + "TARGET_M6812" + [(use (match_dup 0)) + (set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) + (match_dup 1)) + (set (match_dup 0) (match_dup 1))] + "") + +;; +;; Change: "ldd 0,sp; pulx" into "puld" +;; This sequence usually appears at end a functions. +(define_peephole2 + [(set (match_operand:HI 0 "hard_reg_operand" "") + (mem:HI (reg:HI SP_REGNUM))) + (use (match_dup 0)) + (set (match_operand:HI 1 "hard_reg_operand" "") + (mem:HI (post_inc:HI (reg:HI SP_REGNUM))))] + "peep2_reg_dead_p (2, operands[1])" + [(set (match_dup 0) (mem:HI (post_inc:HI (reg:HI SP_REGNUM)))) + (use (match_dup 0))] + "") + +;; Replace: "pshx; clr 0,sp; clr 1,sp" by "clr 1,-sp; clr 1,-sp" +;; Appears to allocate local variables. +(define_peephole2 + [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) + (match_operand:HI 0 "hard_reg_operand" "")) + (set (mem:QI (plus:HI (reg:HI SP_REGNUM) (const_int 1))) + (const_int 0)) + (set (mem:QI (reg:HI SP_REGNUM)) + (const_int 0))] + "TARGET_M6812" + [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) + (const_int 0))] + "") + +;; Likewise for HI mode +(define_peephole2 + [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) + (match_operand:HI 0 "hard_reg_operand" "")) + (set (mem:HI (reg:HI SP_REGNUM)) + (const_int 0))] + "TARGET_M6812" + [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) + (const_int 0))] + "") +;;-------------------------------------------------------------------- +;;- +;;-------------------------------------------------------------------- ;; ;; Optimize memory<->memory moves when the value is also loaded in ;; a register. @@ -6989,6 +7175,32 @@ (set (match_dup 0) (match_dup 2))] "") +;;-------------------------------------------------------------------- +;;- +;;-------------------------------------------------------------------- +;; SCz 2005-05-08: this peephole2 is not finished. I'm not sure it is +;; valid in all cases. Disabled but kept for documentation and futur fix. +;; (optimize 8-bit move to/from the X or Y registers; the issue with +;; the first (set) is that since operand 0 is either X or Y, we have to +;; use the scratch _.tmp memory location; the peephole uses a stack location +;; instead to save D and use D for the load) +;; +(define_peephole2 + [(set (match_operand:QI 0 "hard_reg_operand" "") + (match_operand:QI 1 "memory_operand" "")) + (set (match_operand:QI 2 "memory_operand" "") + (match_dup 0))] + "0 && A_REG_P (operands[0]) && peep2_reg_dead_p (2, operands[0]) + && !reg_mentioned_p (gen_rtx (REG, HImode, HARD_D_REGNUM), operands[1]) + && !reg_mentioned_p (gen_rtx (REG, HImode, HARD_D_REGNUM), operands[1]) + && !reg_mentioned_p (gen_rtx (REG, HImode, REGNO (operands[0])), operands[2])" + [(set (mem:QI (pre_dec:HI (reg:HI SP_REGNUM))) (reg:QI D_REGNUM)) + (set (reg:QI D_REGNUM) (match_dup 1)) + (set (match_dup 2) (reg:QI D_REGNUM)) + (set (reg:QI D_REGNUM) (mem:QI (post_inc:HI (reg:HI SP_REGNUM)))) + (use (reg:HI SP_REGNUM))] + "") + ;; ;; Reorganize to optimize address computations. ;; @@ -7004,6 +7216,36 @@ "") ;; +;; Replace: "ldx #N; xgdx; addd ; xgdx" by "ldab #N; ldx ; abx" +;; +(define_peephole2 + [(set (match_operand:HI 0 "hard_reg_operand" "") + (match_operand:HI 1 "const_int_operand" "")) + (set (match_dup 0) + (plus:HI (match_dup 0) + (match_operand:HI 2 "general_operand" ""))) + (match_scratch:QI 3 "d")] + "TARGET_M6811 && (INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 0x0ff)" + [(set (match_dup 3) (match_dup 4)) + (set (match_dup 0) (match_dup 2)) + (set (match_dup 0) (plus:HI (zero_extend:HI (match_dup 3)) (match_dup 0)))] + "operands[4] = m68hc11_gen_lowpart (QImode, operands[1]);") + +;; +;; Replace: "ldx #N; xgdx; addd ; xgdx" by "ldab #N; ldx ; abx" +;; +(define_peephole2 + [(set (match_operand:HI 0 "hard_reg_operand" "") + (match_operand:HI 1 "const_int_operand" "")) + (set (match_dup 0) + (plus:HI (match_dup 0) + (match_operand:HI 2 "general_operand" "")))] + "TARGET_M6812" + [(set (match_dup 0) (match_dup 2)) + (set (match_dup 0) (plus:HI (match_dup 0) (match_dup 1)))] + "") + +;; ;; Optimize an address register increment and a compare to use ;; a PRE_INC or PRE_DEC addressing mode (disabled on the tst insn ;; before reload, but can be enabled after). @@ -7095,6 +7337,31 @@ "") ;; +;; +;; +(define_peephole2 + [(parallel + [(set (match_operand:SI 0 "hard_reg_operand" "") + (ashift:SI (match_operand:SI 1 "general_operand" "") + (const_int 1))) + (clobber (match_scratch:HI 2 ""))]) + (set (match_operand:HI 3 "nonimmediate_operand" "") (reg:HI D_REGNUM)) + (set (match_operand:HI 4 "nonimmediate_operand" "") (reg:HI X_REGNUM))] + "!X_REG_P (operands[1]) + && peep2_reg_dead_p (2, gen_rtx (REG, HImode, D_REGNUM)) + && peep2_reg_dead_p (3, gen_rtx (REG, HImode, X_REGNUM))" + [(set (reg:HI D_REGNUM) (match_dup 5)) + (set (reg:HI D_REGNUM) (ashift:HI (reg:HI D_REGNUM) (const_int 1))) + (set (match_dup 3) (reg:HI D_REGNUM)) + (set (reg:HI D_REGNUM) (match_dup 6)) + (parallel [(set (reg:HI D_REGNUM) + (rotate:HI (reg:HI D_REGNUM) (const_int 1))) + (clobber (reg:HI CC_REGNUM))]) + (set (match_dup 4) (reg:HI D_REGNUM))] + "operands[5] = m68hc11_gen_lowpart (HImode, operands[1]); + operands[6] = m68hc11_gen_highpart (HImode, operands[1]);") + +;; ;; Replace a "ldd ; psha; pshb" with a "ldx ; pshx". ;; (define_peephole2 @@ -7109,6 +7376,25 @@ "") ;; +;; Remove one load when copying a value to/from memory and also +;; to a register. Take care not cloberring a possible register used +;; by operand 2. +;; Replace: "ldd 0,y; std 2,y; ldx 0,y" into "ldx 0,y; stx 2,y" +;; +(define_peephole2 + [(set (match_operand:HI 0 "hard_reg_operand" "") + (match_operand:HI 1 "general_operand" "")) + (set (match_operand:HI 2 "nonimmediate_operand" "") (match_dup 0)) + (set (match_operand:HI 3 "hard_reg_operand" "") (match_dup 1))] + "peep2_reg_dead_p (2, operands[0]) + && !side_effects_p (operands[1]) + && !side_effects_p (operands[2]) + && !reg_mentioned_p (operands[3], operands[2])" + [(set (match_dup 3) (match_dup 1)) + (set (match_dup 2) (match_dup 3))] + "") + +;; ;; Replace a "ldd ; addd #N; std " into a ;; "ldx ; leax; stx " if we have a free X/Y register ;; and the constant is small. @@ -7131,6 +7417,174 @@ "if (reg_mentioned_p (operands[4], operands[1])) FAIL; if (reg_mentioned_p (operands[4], operands[3])) FAIL;") +;;-------------------------------------------------------------------- +;;- Bset peephole2 +;;-------------------------------------------------------------------- +;; These peepholes try to replace some logical sequences by 'bset' and 'bclr'. +;; +;; Replace 'ldab ; orab #N; stab ' by 'bset #N'. +;; Register D must be dead and there must be no register side effects for mem. +;; The *can* be volatile this is why we must not use 'side_effects_p'. +;; The good side effect is that it makes the sequence atomic. +;; +(define_peephole2 + [(set (match_operand:QI 0 "hard_reg_operand" "") + (match_operand:QI 1 "nonimmediate_operand" "")) + (set (match_dup 0) (ior:QI (match_dup 0) + (match_operand:QI 2 "const_int_operand" ""))) + (set (match_dup 1) (match_dup 0))] + "(TARGET_M6812 || m68hc11_indirect_p (operands[1], QImode)) + && (GET_CODE (operands[1]) != MEM || !auto_inc_p (XEXP (operands[1], 0))) + && peep2_reg_dead_p (3, operands[0])" + [(set (match_dup 1) (ior:QI (match_dup 1) (match_dup 2)))] + "") + +(define_peephole2 + [(set (match_operand:HI 0 "hard_reg_operand" "") + (match_operand:HI 1 "nonimmediate_operand" "")) + (set (match_dup 0) (ior:HI (match_dup 0) + (match_operand:HI 2 "const_int_operand" ""))) + (set (match_dup 1) (match_dup 0))] + "(TARGET_M6812 || m68hc11_indirect_p (operands[1], HImode)) + && (GET_CODE (operands[1]) != MEM || !auto_inc_p (XEXP (operands[1], 0))) + && peep2_reg_dead_p (3, operands[0])" + [(set (match_dup 1) (ior:HI (match_dup 1) (match_dup 2)))] + "") + +;;-------------------------------------------------------------------- +;;- Bclr peephole2 +;;-------------------------------------------------------------------- +;; Replace 'ldab ; andab #N; stab ' by 'bclr #N'. +;; See Bset peephole2. +;; +(define_peephole2 + [(set (match_operand:QI 0 "hard_reg_operand" "") + (match_operand:QI 1 "nonimmediate_operand" "")) + (set (match_dup 0) (and:QI (match_dup 0) + (match_operand:QI 2 "const_int_operand" ""))) + (set (match_dup 1) (match_dup 0))] + "(TARGET_M6812 || m68hc11_indirect_p (operands[1], QImode)) + && (GET_CODE (operands[1]) != MEM || !auto_inc_p (XEXP (operands[1], 0))) + && peep2_reg_dead_p (3, operands[0])" + [(set (match_dup 1) (and:QI (match_dup 1) (match_dup 2)))] + "") + +(define_peephole2 + [(set (match_operand:HI 0 "hard_reg_operand" "") + (match_operand:HI 1 "nonimmediate_operand" "")) + (set (match_dup 0) (and:HI (match_dup 0) + (match_operand:HI 2 "const_int_operand" ""))) + (set (match_dup 1) (match_dup 0))] + "(TARGET_M6812 || m68hc11_indirect_p (operands[1], HImode)) + && (GET_CODE (operands[1]) != MEM || !auto_inc_p (XEXP (operands[1], 0))) + && peep2_reg_dead_p (3, operands[0])" + [(set (match_dup 1) (and:HI (match_dup 1) (match_dup 2)))] + "") + + +;;-------------------------------------------------------------------- +;;- Compare peephole2 +;;-------------------------------------------------------------------- +(define_peephole2 + [(set (match_operand:HI 0 "hard_reg_operand" "") + (match_operand:HI 1 "hard_reg_operand" "")) + (set (match_dup 1) (plus:HI (match_dup 1) + (match_operand:HI 2 "const_int_operand" ""))) + (set (cc0) (match_dup 0))] + "peep2_reg_dead_p (3, operands[0]) && !Z_REG_P (operands[1])" + [(set (match_dup 1) (plus:HI (match_dup 1) (match_dup 2))) + (set (cc0) (compare (match_dup 1) (match_dup 2)))] + "") + +(define_peephole2 + [(set (match_operand:HI 0 "hard_reg_operand" "") + (match_operand:HI 1 "hard_reg_operand" "")) + (set (match_operand:HI 2 "hard_reg_operand" "") + (plus:HI (match_dup 2) + (match_operand:HI 3 "const_int_operand" ""))) + (set (match_operand:HI 4 "memory_operand" "") (match_dup 2)) + (set (cc0) (match_operand:HI 5 "hard_reg_operand" ""))] + "peep2_reg_dead_p (4, operands[5]) && !Z_REG_P (operands[2]) + && !reg_mentioned_p (operands[2], operands[4]) + + && ((rtx_equal_p (operands[5], operands[0]) + && rtx_equal_p (operands[2], operands[1])) + + || (rtx_equal_p (operands[5], operands[1]) + && rtx_equal_p (operands[2], operands[0])))" + [(set (match_dup 2) (match_dup 1)) + (set (match_dup 2) (plus:HI (match_dup 2) (match_dup 3))) + (set (match_dup 4) (match_dup 2)) + (set (cc0) (compare (match_dup 2) (match_dup 3)))] + "") + + +;;-------------------------------------------------------------------- +;;- Load peephole2 +;;-------------------------------------------------------------------- +;; +;; Optimize initialization of 2 hard regs from the same memory location +;; Since we can't copy easily X, Y and D to each other, load the 2 registers +;; from the same memory location. +;; +(define_peephole2 + [(set (match_operand:HI 0 "hard_reg_operand" "") + (match_operand:HI 1 "memory_operand" "")) + (set (match_operand:HI 2 "hard_reg_operand" "") (match_dup 0))] + "TARGET_M6811 + && !side_effects_p (operands[1]) + && !reg_mentioned_p (operands[0], operands[1])" + [(set (match_dup 0) (match_dup 1)) + (set (match_dup 2) (match_dup 1))] + "") + +;; Replace "ldd #N; addd " with "ldd ; addd #N". +;; +(define_peephole2 + [(set (match_operand:HI 0 "nonimmediate_operand" "") (const_int 0)) + (set (match_operand:HI 1 "nonimmediate_operand" "") (const_int 0)) + (set (match_operand:HI 2 "nonimmediate_operand" "") (const_int 0)) + (set (match_operand:HI 3 "nonimmediate_operand" "") (const_int 0)) + (match_scratch:HI 4 "d")] + "" + [(set (match_dup 4) (const_int 0)) + (set (match_dup 0) (match_dup 4)) + (set (match_dup 1) (match_dup 4)) + (set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 4))] + "") + +;; +;; Replace "ldd #N; addd " with "ldd ; addd #N". +;; +(define_peephole2 + [(set (match_operand:HI 0 "nonimmediate_operand" "") (const_int 0)) + (set (match_operand:HI 1 "nonimmediate_operand" "") (const_int 0)) + (set (match_operand:HI 2 "nonimmediate_operand" "") (const_int 0)) + (match_scratch:HI 3 "d")] + "" + [(set (match_dup 3) (const_int 0)) + (set (match_dup 0) (match_dup 3)) + (set (match_dup 1) (match_dup 3)) + (set (match_dup 2) (match_dup 3))] + "") + +;; +;; Replace "ldd #N; addd " with "ldd ; addd #N". +;; +(define_peephole2 + [(set (match_operand:HI 0 "hard_reg_operand" "") (const_int 0)) + (set (match_operand:HI 1 "push_operand" "") (match_dup 0)) + (set (match_operand:HI 2 "push_operand" "") (match_dup 0)) + (set (match_operand:HI 3 "push_operand" "") (match_dup 0)) + (match_scratch:HI 4 "x")] + "TARGET_M6811 && D_REG_P (operands[0]) && peep2_reg_dead_p (4, operands[0])" + [(set (match_dup 4) (const_int 0)) + (set (match_dup 1) (match_dup 4)) + (set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 4))] + "") + ;; ;; This peephole catches the address computations generated by the reload ;; pass. @@ -7189,6 +7643,8 @@ } ") +;; SCz 2005-04-03: this peephole is not valid anymore because it appears +;; we can't rely on the REG_DEAD note (define_peephole [(set (match_operand:HI 0 "hard_reg_operand" "h") (match_operand:HI 1 "non_push_operand" "g")) @@ -7279,7 +7735,7 @@ ;;; ;;; Catch an xgdx/xgdy followed by a (set D X/Y). If X/Y is dead, we don't -;;; need to emit anything. Otherwise, we just need an copy of D to X/Y. +;;; need to emit anything. Otherwise, we just need a copy of D to X/Y. ;;; (define_peephole [(parallel [(set (reg:HI D_REGNUM) (match_operand:HI 0 "hard_reg_operand" "A")) @@ -7295,7 +7751,7 @@ ;;; ;;; Catch an xgdx/xgdy followed by a (set D X/Y). If X/Y is dead, we don't -;;; need to emit anything. Otherwise, we just need an copy of D to X/Y. +;;; need to emit anything. Otherwise, we just need a copy of D to X/Y. ;;; (define_peephole [(parallel [(set (reg:HI D_REGNUM) (match_operand:HI 0 "hard_reg_operand" "A")) @@ -7400,3 +7856,41 @@ return \"sts\\t%t0\\n\\tld%0\\t%t0\"; } ") + +(define_peephole + [(set (match_operand:HI 0 "hard_reg_operand" "") + (match_operand:HI 1 "memory_operand" "")) + (set (match_operand:HI 2 "hard_reg_operand" "") (match_dup 0))] + "TARGET_M6811 + && !side_effects_p (operands[1]) + && !reg_mentioned_p (operands[0], operands[1])" + "* +{ + rtx ops[2]; + + ops[0] = operands[0]; + ops[1] = operands[1]; + m68hc11_gen_movhi (insn, ops); + ops[0] = operands[2]; + m68hc11_gen_movhi (insn, ops); + return \"\"; +}") + +;; Peephole for Z register replacement. +;; Avoid to use _.tmp register when comparing D and X if we can compare +;; with soft register +(define_peephole + [(set (match_operand:HI 0 "hard_reg_operand" "") (reg:HI SOFT_XY_REGNUM)) + (set (reg:HI SOFT_TMP_REGNUM) (match_dup 0)) + (set (cc0) (compare (match_operand:HI 2 "hard_reg_operand" "") + (reg:HI SOFT_TMP_REGNUM)))] + "X_REG_P (operands[0]) || Y_REG_P (operands[0])" + "* +{ + rtx ops[2]; + + ops[0] = operands[0]; + ops[1] = operands[1]; + m68hc11_gen_movhi (insn, ops); + return \"cp%2\\t%1\"; +}") diff -u -r -N gcc-3.3.6-core-orig/gcc/config/m68hc11/m68hc11-protos.h gcc-3.3.6/gcc/config/m68hc11/m68hc11-protos.h --- gcc-3.3.6-core-orig/gcc/config/m68hc11/m68hc11-protos.h 2003-04-12 22:53:41.000000000 +0100 +++ gcc-3.3.6/gcc/config/m68hc11/m68hc11-protos.h 2010-11-09 20:47:16.000000000 +0000 @@ -1,5 +1,6 @@ /* Prototypes for exported functions defined in m68hc11.c - Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2003, + 2005, 2006 Free Software Foundation, Inc. Contributed by Stephane Carrez (stcarrez@nerim.fr) This file is part of GNU CC. @@ -24,7 +25,7 @@ extern int m68hc11_optimization_options PARAMS((int,int)); extern void m68hc11_conditional_register_usage PARAMS((void)); extern int hard_regno_mode_ok PARAMS((int, enum machine_mode)); -extern int m68hc11_hard_regno_rename_ok PARAMS((int, int)); +extern int m68hc11_hard_regno_rename_ok PARAMS((int, int, int)); extern int m68hc11_total_frame_size PARAMS((void)); extern int m68hc11_initial_frame_pointer_offset PARAMS((void)); @@ -105,6 +106,7 @@ extern int reg_or_indexed_operand PARAMS((rtx,enum machine_mode)); extern int tst_operand PARAMS((rtx,enum machine_mode)); extern int cmp_operand PARAMS((rtx,enum machine_mode)); +extern int nonimmediate_noinc_operand PARAMS((rtx,enum machine_mode)); extern int memory_indexed_operand PARAMS((rtx, enum machine_mode)); extern void m68hc11_split_logical PARAMS((enum machine_mode, int, rtx*)); @@ -147,6 +149,7 @@ extern int m68hc11_is_far_symbol PARAMS((rtx)); extern int m68hc11_is_trap_symbol PARAMS((rtx)); +extern int m68hc11_page0_symbol_p (rtx x); #endif /* TREE_CODE */ diff -u -r -N gcc-3.3.6-core-orig/gcc/config/m68hc11/m68hc12.h gcc-3.3.6/gcc/config/m68hc11/m68hc12.h --- gcc-3.3.6-core-orig/gcc/config/m68hc11/m68hc12.h 2003-01-15 23:00:12.000000000 +0000 +++ gcc-3.3.6/gcc/config/m68hc11/m68hc12.h 2010-11-09 20:47:16.000000000 +0000 @@ -19,11 +19,13 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* Compile and assemble for a 68hc12 unless there is a -m68hc11 option. */ +/* Default to compile and assemble for a 68hc12 */ #define ASM_SPEC \ "%{m68hc11:-m68hc11}" \ +"%{m6812:-m68hc12}" \ "%{m68hcs12:-m68hcs12}" \ -"%{!m68hc11:%{!m68hcs12:-m68hc12}}" +"%{m9s12x:-mm9s12x}" \ +"%{!m68hc11:%{!m68hcs12:%{!m9s12x:-m68hc12}}}" #define LIB_SPEC "" #define CC1_SPEC "" @@ -31,19 +33,23 @@ emulation option. This can be overriden by -Wl option of gcc. */ #define LINK_SPEC \ "%{m68hc11:-m m68hc11elf}" \ +"%{m9s12x:-m m9s12xelf}" \ "%{m68hcs12:-m m68hc12elf}" \ -"%{!m68hc11:%{!m68hcs12:-m m68hc11elf}} %{mrelax:-relax}" +"%{!m68hc11:%{!m68hcs12:%{!m9s12x:-m m68hc11elf}} %{mrelax:-relax}" #define CPP_SPEC \ "%{mshort:-D__HAVE_SHORT_INT__ -D__INT__=16}\ %{!mshort:-D__INT__=32}\ %{m68hc11:-Dmc6811 -DMC6811 -Dmc68hc11}\ - %{!m68hc11:%{!m68hc12:-Dmc6812 -DMC6812 -Dmc68hc12}}\ + %{m68hc12:-Dmc6812 -DMC6812 -Dmc68hc12}\ + %{m9s12x:-Dmc6812 -DMC6812 -Dmc68hcs12 -Dm9s12x}\ %{m68hcs12:-Dmc6812 -DMC6812 -Dmc68hcs12}\ - %{!m68hc11:-Dmc6812 -DMC6812 -Dmc68hc12}\ + %{!m68hc11:%{!m68hc12:%{!m9s12x:-Dmc6812 -DMC6812 -Dmc68hc12 -m68hc12}}}\ %{fshort-double:-D__HAVE_SHORT_DOUBLE__}" /* Default target_flags if no switches specified. */ #define TARGET_DEFAULT (MASK_M6812) #define TARGET_M68HC12 + +#define CPP_PREDEFINES "-Dmc68hc1x -Dtarget12" diff -u -r -N gcc-3.3.6-core-orig/gcc/config/m68hc11/m9s12x.h gcc-3.3.6/gcc/config/m68hc11/m9s12x.h --- gcc-3.3.6-core-orig/gcc/config/m68hc11/m9s12x.h 1970-01-01 01:00:00.000000000 +0100 +++ gcc-3.3.6/gcc/config/m68hc11/m9s12x.h 2010-11-09 20:47:16.000000000 +0000 @@ -0,0 +1,59 @@ +/* Definitions of target machine for GNU compiler, for m68hc12. + Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation, Inc. + Contributed by Stephane Carrez (stcarrez@nerim.fr). + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* Default to compile and assemble for a m9s12x */ +#define ASM_SPEC \ +"%{m68hc11:-m68hc11}" \ +"%{m6812:-m68hc12}" \ +"%{m9s12x:-mm9s12x}" \ +"%{m68hcs12:-m68hcs12}" \ +"%{!m68hc11:%{!m68hcs12:%{!m68hc12: -mm9s12x}}}" +/* last line was "%{!m68hc11:%{!m68hcs12:%{!m68hc12:%{!m9s12x:-mm9s12x}}}}" */ +#define LIB_SPEC "" +#define CC1_SPEC "" + +/* We need to tell the linker the target elf format. Just pass an + emulation option. This can be overriden by -Wl option of gcc. */ +#define LINK_SPEC \ +"%{m68hc11:-m m68hc11elf}" \ +"%{m9s12x:-m m68hc12elf}" \ +"%{m68hcs12:-m m68hc12elf}" \ +"%{!m68hc11:%{!m68hcs12:%{!m9s12x:-m m68hc11elf}}} %{mrelax:-relax}" + +#define CPP_SPEC \ +"%{mshort:-D__HAVE_SHORT_INT__ -D__INT__=16}\ + %{!mshort:-D__INT__=32}\ + %{m68hc11:-Dmc6811 -DMC6811 -Dmc68hc11}\ + %{m68hc12:-Dmc6812 -DMC6812 -Dmc68hc12}\ + %{m9s12x:-Dmc6812 -DMC6812 -Dmc68hc12 -Dmc68hcs12 -Dm9s12x -m9s12x}\ + %{m68hcs12:-Dmc6812 -DMC6812 -Dmc68hc12 -Dmc68hcs12}\ + %{!m68hc11:%{!m68hc12:%{!m68hcs12: -Dmc6812 -DMC6812 -Dmc68hc12 -Dmc68hcs12 -Dm9s12x -m9s12x}}}\ + %{fshort-double:-D__HAVE_SHORT_DOUBLE__}" +/* penultimate was %{!m68hc11:%{!m68hc12:%{!m68hcs12:%{!m9s12x:-Dmc6812 -DMC6812 -Dmc68hc12 -Dmc68hcs12 -Dm9s12x -m9s12x}}}} */ + +/* Default target_flags if no switches specified. */ +#define TARGET_DEFAULT (MASK_M68S12X) + +#define TARGET_M68HC12 + +#define MULTILIB_DEFAULTS { "m9s12x" } + +#define CPP_PREDEFINES "-Dmc68hc1x -Dtargets12x" diff -u -r -N gcc-3.3.6-core-orig/gcc/config/m68hc11/t-m68hc11-gas gcc-3.3.6/gcc/config/m68hc11/t-m68hc11-gas --- gcc-3.3.6-core-orig/gcc/config/m68hc11/t-m68hc11-gas 2005-01-28 22:21:39.000000000 +0000 +++ gcc-3.3.6/gcc/config/m68hc11/t-m68hc11-gas 2010-11-09 20:47:16.000000000 +0000 @@ -31,13 +31,14 @@ # C implementation of 32-bit div/mod. LIB2FUNCS_EXTRA = $(srcdir)/config/udivmodsi4.c \ - $(srcdir)/config/divmod.c $(srcdir)/config/udivmod.c + $(srcdir)/config/divmod.c $(srcdir)/config/udivmod.c \ + $(srcdir)/config/m68hc11/ldivmod.asm # Don't compile with -g1 this reduces the size of some sections (.eh_frame). LIBGCC2_DEBUG_CFLAGS =-g -LIBGCC2_CFLAGS = -Os -mrelax $(LIBGCC2_INCLUDES) $(TARGET_LIBGCC2_CFLAGS) $(LIBGCC2_DEBUG_CFLAGS) $(GTHREAD_FLAGS) -DIN_LIBGCC2 - -MULTILIB_OPTIONS = m68hc11/m68hc12 mshort fshort-double +LIBGCC2_CFLAGS = -O -mrelax $(LIBGCC2_INCLUDES) $(TARGET_LIBGCC2_CFLAGS) $(LIBGCC2_DEBUG_CFLAGS) $(GTHREAD_FLAGS) -DIN_LIBGCC2 +# -m9s12x +MULTILIB_OPTIONS = m68hc11/m68hc12/m9s12x mshort fshort-double mlong-calls MULTILIB_DIRNAMES = MULTILIB_MATCHES = m68hc11=m6811 m68hc12=m6812 m68hc12=m68hcs12 MULTILIB_EXCEPTIONS = -mnoshort -mno68hc11 diff -u -r -N gcc-3.3.6-core-orig/gcc/config/udivmod.c gcc-3.3.6/gcc/config/udivmod.c --- gcc-3.3.6-core-orig/gcc/config/udivmod.c 2000-11-30 08:25:58.000000000 +0000 +++ gcc-3.3.6/gcc/config/udivmod.c 2010-11-09 20:47:16.000000000 +0000 @@ -1,14 +1,36 @@ -long udivmodsi4 (); +/* cover the root directory case */ +#if !defined(mc68hc11) && !defined(mc68hc12) && !defined(m9s12x) +#if defined(target11) +#define mc68hc11 +#endif +#if defined(target12) +#define mc68hc12 +#endif +#if defined(targets12x) +#define m9s12x +#define mc68hc12 +#endif +#endif -long -__udivsi3 (long a, long b) +#ifndef mc68hc12 +extern unsigned long __udivmodsi4 (unsigned long num, unsigned long den, + unsigned long *mod); + +unsigned long +__inline __udivsi3 (unsigned long a, unsigned long b) { - return udivmodsi4 (a, b, 0); + return __udivmodsi4 (a, b, 0); } -long -__umodsi3 (long a, long b) +unsigned long +__inline __umodsi3 (unsigned long a, unsigned long b) { - return udivmodsi4 (a, b, 1); + unsigned long mod; + + __udivmodsi4 (a, b, &mod); + return mod; } + + +#endif /* !mc68hc12 */ diff -u -r -N gcc-3.3.6-core-orig/gcc/config/udivmodsi4.c gcc-3.3.6/gcc/config/udivmodsi4.c --- gcc-3.3.6-core-orig/gcc/config/udivmodsi4.c 2000-11-30 08:25:58.000000000 +0000 +++ gcc-3.3.6/gcc/config/udivmodsi4.c 2010-11-09 20:47:16.000000000 +0000 @@ -1,10 +1,72 @@ +/* cover the root directory case */ +#if !defined(mc68hc11) && !defined(mc68hc12) && !defined(m9s12x) +#if defined(target11) +#define mc68hc11 +#endif +#if defined(target12) +#define mc68hc12 +#endif +#if defined(targets12x) +#define m9s12x +#define mc68hc12 +#endif +#endif + +//#ifndef mc68hc12 unsigned long -udivmodsi4(unsigned long num, unsigned long den, int modwanted) +__udivmodsi4 (unsigned long num, unsigned long den, unsigned long* mod) { - unsigned long bit = 1; - unsigned long res = 0; + unsigned long bit; + unsigned long res; + + if ((unsigned short) (den >> 16) == 0) + { +#ifdef mc68hc11 + if ((unsigned short) (num >> 16) == 0) + { + /* Both numbers are 16-bit quantities, use 16-bit div/mod. */ + unsigned short sden = (unsigned short) den; + unsigned short snum = (unsigned short) num; + unsigned short sres = snum / sden; + unsigned short smod = snum % sden;; - while (den < num && bit && !(den & (1L<<31))) + if (mod) + *mod = (unsigned long) smod; + return (unsigned long) sres; + } +#endif +#ifdef mc68hc12 + { + /* To avoid to stress the gcc reload, use + operand modifier + and pass the input values in the same variables as the + outputs. */ + unsigned short status = (unsigned short) den; + unsigned short smod = (unsigned short) (num & 0x0ffff); + unsigned short sres = (unsigned short) (num >> 16); + + __asm__ __volatile__ ("ediv\n" + "tfr ccr,x" + : "+x" (status), "+y" (sres), + "+d" (smod)); + /* check for overflow */ + if (!(status & 0x03)) + { + if (mod) + *mod = (unsigned long) smod; + return (unsigned long) sres; + } + } +#endif + if ((unsigned short) den == 0) + { + if (mod) + *mod = 0; + return 0; + } + } + bit = 1; + res = 0; + while (den < num && !((unsigned short) (den >> 16) & (1L<<15))) { den <<=1; bit <<=1; @@ -19,6 +81,28 @@ bit >>=1; den >>=1; } - if (modwanted) return num; + if (mod) + *mod = num; return res; } + +#ifdef L_udivmodsi4 +unsigned long +udivmodsi4 (unsigned long num, unsigned long den, int modwanted) +{ + unsigned long mod; + + if (modwanted) + { + __udivmodsi4 (num, den, &mod); + return mod; + } + else + { + return __udivmodsi4 (num, den, 0); + } +} +#endif + +//#endif /*!mc68hc12 */ + diff -u -r -N gcc-3.3.6-core-orig/gcc/config.gcc gcc-3.3.6/gcc/config.gcc --- gcc-3.3.6-core-orig/gcc/config.gcc 2004-04-29 05:42:47.000000000 +0100 +++ gcc-3.3.6/gcc/config.gcc 2010-11-09 20:47:16.000000000 +0000 @@ -1516,6 +1516,13 @@ out_file="m68hc11/m68hc11.c" tmake_file="m68hc11/t-m68hc11-gas" ;; +m9s12x-*-*) + tm_file="m68hc11/m9s12x.h dbxelf.h elfos.h m68hc11/m68hc11.h" + tm_p_file="m68hc11/m68hc11-protos.h" + md_file="m68hc11/m68hc11.md" + out_file="m68hc11/m68hc11.c" + tmake_file="m68hc11/t-m68hc11-gas" + ;; m68000-hp-bsd*) # HP 9000/200 running BSD tm_file=m68k/hp2bsd.h use_collect2=yes diff -u -r -N gcc-3.3.6-core-orig/gcc/cppdefault.c gcc-3.3.6/gcc/cppdefault.c --- gcc-3.3.6-core-orig/gcc/cppdefault.c 2003-11-06 23:13:31.000000000 +0000 +++ gcc-3.3.6/gcc/cppdefault.c 2010-11-09 20:47:16.000000000 +0000 @@ -76,11 +76,15 @@ #ifdef GCC_INCLUDE_DIR const char cpp_GCC_INCLUDE_DIR[] = GCC_INCLUDE_DIR; +#if GNU_HC1X_DONT_PATCH const size_t cpp_GCC_INCLUDE_DIR_len = sizeof GCC_INCLUDE_DIR - 8; +#endif #else const char cpp_GCC_INCLUDE_DIR[] = ""; +#if GNU_HC1X_DONT_PATCH const size_t cpp_GCC_INCLUDE_DIR_len = 0; #endif +#endif #ifdef TARGET_SYSTEM_ROOT const char *cpp_SYSROOT = TARGET_SYSTEM_ROOT; diff -u -r -N gcc-3.3.6-core-orig/gcc/cppdefault.h gcc-3.3.6/gcc/cppdefault.h --- gcc-3.3.6-core-orig/gcc/cppdefault.h 2003-11-06 23:13:31.000000000 +0000 +++ gcc-3.3.6/gcc/cppdefault.h 2010-11-09 20:47:16.000000000 +0000 @@ -67,7 +67,17 @@ extern const struct default_include cpp_include_defaults[]; extern const char cpp_GCC_INCLUDE_DIR[]; + +/* Don't use sizeof GCC_INCLUDE_DIR because for Mingw32 we patch the + executable to replace this path with the good path. We must then + use strlen() to find the correct length. */ +#undef GNU_HC1X_DONT_PATCH +#if GNU_HC1X_DONT_PATCH extern const size_t cpp_GCC_INCLUDE_DIR_len; +#else +#define cpp_GCC_INCLUDE_DIR_len \ +(strlen (cpp_GCC_INCLUDE_DIR) > 7 ? strlen (cpp_GCC_INCLUDE_DIR) - 7 : 0) +#endif extern const char *cpp_SYSROOT; diff -u -r -N gcc-3.3.6-core-orig/gcc/doc/extend.texi gcc-3.3.6/gcc/doc/extend.texi --- gcc-3.3.6-core-orig/gcc/doc/extend.texi 2004-03-17 20:13:19.000000000 +0000 +++ gcc-3.3.6/gcc/doc/extend.texi 2010-11-09 20:47:16.000000000 +0000 @@ -2528,11 +2528,14 @@ On 68HC11 the compiler will generate a sequence of instructions to invoke a board-specific routine to switch the memory bank and call the -real function. The board-specific routine simulates a @code{call}. +real function. The board-specific routine simulates a @code{call}. At the end of a function, it will jump to a board-specific routine -instead of using @code{rts}. The board-specific return routine simulates +instead of using @code{rts}. The board-specific return routine simulates the @code{rtc}. +The @code{far} attribute must not be used when the @code{interrupt} or +@code{trap} attributes are used. + @item near @cindex functions which do not handle memory bank switching on 68HC11/68HC12 On 68HC11 and 68HC12 the @code{near} attribute causes the compiler to @@ -2540,6 +2543,21 @@ This attribute can be used to cancel the effect of the @option{-mlong-calls} option. +@item page0 +@cindex variables in page0 section for which direct addressing mode can be used +On 68HC11 and 68HC12, the @code{page0} attribute indicates that a global +or static variable is put in the @code{page0} section and the compiler can +use the direct addressing mode. On 68HC11 the compiler will be able to +use @code{bset} and @code{bclr} on these variables. Note that the @code{page0} +is limited to the absolute address range @code{0}..@code{0x0ff}. + +@item trap +@cindex functions which are used as trap handlers (@code{swi} or @code{trap}) +On 68HC11 and 68HC12, the @code{trap} attribute marks the function as being +a trap handler. It will use @code{rti} instead of @code{rts} to return +from the function. Offset of function parameters are also adjusted to take +into account the trap frame. + @item dllimport @cindex @code{__declspec(dllimport)} On Windows targets, the @code{dllimport} attribute causes the compiler diff -u -r -N gcc-3.3.6-core-orig/gcc/doc/gcc.1 gcc-3.3.6/gcc/doc/gcc.1 --- gcc-3.3.6-core-orig/gcc/doc/gcc.1 2005-05-03 13:41:29.000000000 +0100 +++ gcc-3.3.6/gcc/doc/gcc.1 2010-11-09 20:47:16.000000000 +0000 @@ -1,10282 +1 @@ -.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.14 -.\" -.\" Standard preamble: -.\" ======================================================================== -.de Sh \" Subsection heading -.br -.if t .Sp -.ne 5 -.PP -\fB\\$1\fR -.PP -.. -.de Sp \" Vertical space (when we can't use .PP) -.if t .sp .5v -.if n .sp -.. -.de Vb \" Begin verbatim text -.ft CW -.nf -.ne \\$1 -.. -.de Ve \" End verbatim text -.ft R -.fi -.. -.\" Set up some character translations and predefined strings. \*(-- will -.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left -.\" double quote, and \*(R" will give a right double quote. | will give a -.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to -.\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' -.\" expand to `' in nroff, nothing in troff, for use with C<>. -.tr \(*W-|\(bv\*(Tr -.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' -.ie n \{\ -. ds -- \(*W- -. ds PI pi -. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch -. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch -. ds L" "" -. ds R" "" -. ds C` "" -. ds C' "" -'br\} -.el\{\ -. ds -- \|\(em\| -. ds PI \(*p -. ds L" `` -. ds R" '' -'br\} -.\" -.\" If the F register is turned on, we'll generate index entries on stderr for -.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index -.\" entries marked with X<> in POD. Of course, you'll have to process the -.\" output yourself in some meaningful fashion. -.if \nF \{\ -. de IX -. tm Index:\\$1\t\\n%\t"\\$2" -.. -. nr % 0 -. rr F -.\} -.\" -.\" For nroff, turn off justification. Always turn off hyphenation; it makes -.\" way too many mistakes in technical documents. -.hy 0 -.if n .na -.\" -.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). -.\" Fear. Run. Save yourself. No user-serviceable parts. -. \" fudge factors for nroff and troff -.if n \{\ -. ds #H 0 -. ds #V .8m -. ds #F .3m -. ds #[ \f1 -. ds #] \fP -.\} -.if t \{\ -. ds #H ((1u-(\\\\n(.fu%2u))*.13m) -. ds #V .6m -. ds #F 0 -. ds #[ \& -. ds #] \& -.\} -. \" simple accents for nroff and troff -.if n \{\ -. ds ' \& -. ds ` \& -. ds ^ \& -. ds , \& -. ds ~ ~ -. ds / -.\} -.if t \{\ -. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" -. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' -. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' -. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' -. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' -. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' -.\} -. \" troff and (daisy-wheel) nroff accents -.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' -.ds 8 \h'\*(#H'\(*b\h'-\*(#H' -.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] -.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' -.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' -.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] -.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] -.ds ae a\h'-(\w'a'u*4/10)'e -.ds Ae A\h'-(\w'A'u*4/10)'E -. \" corrections for vroff -.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' -.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' -. \" for low resolution devices (crt and lpr) -.if \n(.H>23 .if \n(.V>19 \ -\{\ -. ds : e -. ds 8 ss -. ds o a -. ds d- d\h'-1'\(ga -. ds D- D\h'-1'\(hy -. ds th \o'bp' -. ds Th \o'LP' -. ds ae ae -. ds Ae AE -.\} -.rm #[ #] #H #V #F C -.\" ======================================================================== -.\" -.IX Title "GCC 1" -.TH GCC 1 "2005-05-03" "gcc-3.3.6" "GNU" -.SH "NAME" -gcc \- GNU project C and C++ compiler -.SH "SYNOPSIS" -.IX Header "SYNOPSIS" -gcc [\fB\-c\fR|\fB\-S\fR|\fB\-E\fR] [\fB\-std=\fR\fIstandard\fR] - [\fB\-g\fR] [\fB\-pg\fR] [\fB\-O\fR\fIlevel\fR] - [\fB\-W\fR\fIwarn\fR...] [\fB\-pedantic\fR] - [\fB\-I\fR\fIdir\fR...] [\fB\-L\fR\fIdir\fR...] - [\fB\-D\fR\fImacro\fR[=\fIdefn\fR]...] [\fB\-U\fR\fImacro\fR] - [\fB\-f\fR\fIoption\fR...] [\fB\-m\fR\fImachine-option\fR...] - [\fB\-o\fR \fIoutfile\fR] \fIinfile\fR... -.PP -Only the most useful options are listed here; see below for the -remainder. \fBg++\fR accepts mostly the same options as \fBgcc\fR. -.SH "DESCRIPTION" -.IX Header "DESCRIPTION" -When you invoke \s-1GCC\s0, it normally does preprocessing, compilation, -assembly and linking. The ``overall options'' allow you to stop this -process at an intermediate stage. For example, the \fB\-c\fR option -says not to run the linker. Then the output consists of object files -output by the assembler. -.PP -Other options are passed on to one stage of processing. Some options -control the preprocessor and others the compiler itself. Yet other -options control the assembler and linker; most of these are not -documented here, since you rarely need to use any of them. -.PP -Most of the command line options that you can use with \s-1GCC\s0 are useful -for C programs; when an option is only useful with another language -(usually \*(C+), the explanation says so explicitly. If the description -for a particular option does not mention a source language, you can use -that option with all supported languages. -.PP -The \fBgcc\fR program accepts options and file names as operands. Many -options have multi-letter names; therefore multiple single-letter options -may \fInot\fR be grouped: \fB\-dr\fR is very different from \fB\-d\ \-r\fR. -.PP -You can mix options and other arguments. For the most part, the order -you use doesn't matter. Order does matter when you use several options -of the same kind; for example, if you specify \fB\-L\fR more than once, -the directories are searched in the order specified. -.PP -Many options have long names starting with \fB\-f\fR or with -\&\fB\-W\fR\-\-\-for example, \fB\-fforce\-mem\fR, -\&\fB\-fstrength\-reduce\fR, \fB\-Wformat\fR and so on. Most of -these have both positive and negative forms; the negative form of -\&\fB\-ffoo\fR would be \fB\-fno\-foo\fR. This manual documents -only one of these two forms, whichever one is not the default. -.SH "OPTIONS" -.IX Header "OPTIONS" -.Sh "Option Summary" -.IX Subsection "Option Summary" -Here is a summary of all the options, grouped by type. Explanations are -in the following sections. -.IP "\fIOverall Options\fR" 4 -.IX Item "Overall Options" -\&\fB\-c \-S \-E \-o\fR \fIfile\fR \fB\-pipe \-pass\-exit\-codes -\&\-x\fR \fIlanguage\fR \fB\-v \-### \-\-help \-\-target\-help \-\-version\fR -.IP "\fIC Language Options\fR" 4 -.IX Item "C Language Options" -\&\fB\-ansi \-std=\fR\fIstandard\fR \fB\-aux\-info\fR \fIfilename\fR -\&\fB\-fno\-asm \-fno\-builtin \-fno\-builtin\-\fR\fIfunction\fR -\&\fB\-fhosted \-ffreestanding \-fms\-extensions -\&\-trigraphs \-no\-integrated\-cpp \-traditional \-traditional\-cpp -\&\-fallow\-single\-precision \-fcond\-mismatch -\&\-fsigned\-bitfields \-fsigned\-char -\&\-funsigned\-bitfields \-funsigned\-char -\&\-fwritable\-strings\fR -.IP "\fI\*(C+ Language Options\fR" 4 -.IX Item " Language Options" -\&\fB\-fabi\-version=\fR\fIn\fR \fB\-fno\-access\-control \-fcheck\-new -\&\-fconserve\-space \-fno\-const\-strings \-fdollars\-in\-identifiers -\&\-fno\-elide\-constructors -\&\-fno\-enforce\-eh\-specs \-fexternal\-templates -\&\-falt\-external\-templates -\&\-ffor\-scope \-fno\-for\-scope \-fno\-gnu\-keywords -\&\-fno\-implicit\-templates -\&\-fno\-implicit\-inline\-templates -\&\-fno\-implement\-inlines \-fms\-extensions -\&\-fno\-nonansi\-builtins \-fno\-operator\-names -\&\-fno\-optional\-diags \-fpermissive -\&\-frepo \-fno\-rtti \-fstats \-ftemplate\-depth\-\fR\fIn\fR -\&\fB\-fuse\-cxa\-atexit \-fvtable\-gc \-fno\-weak \-nostdinc++ -\&\-fno\-default\-inline \-Wabi \-Wctor\-dtor\-privacy -\&\-Wnon\-virtual\-dtor \-Wreorder -\&\-Weffc++ \-Wno\-deprecated -\&\-Wno\-non\-template\-friend \-Wold\-style\-cast -\&\-Woverloaded\-virtual \-Wno\-pmf\-conversions -\&\-Wsign\-promo\fR -.IP "\fIObjective-C Language Options\fR" 4 -.IX Item "Objective-C Language Options" -\&\fB\-fconstant\-string\-class=\fR\fIclass-name\fR -\&\fB\-fgnu\-runtime \-fnext\-runtime \-gen\-decls -\&\-Wno\-protocol \-Wselector \-Wundeclared\-selector\fR -.IP "\fILanguage Independent Options\fR" 4 -.IX Item "Language Independent Options" -\&\fB\-fmessage\-length=\fR\fIn\fR -\&\fB\-fdiagnostics\-show\-location=\fR[\fBonce\fR|\fBevery-line\fR] -.IP "\fIWarning Options\fR" 4 -.IX Item "Warning Options" -\&\fB\-fsyntax\-only \-pedantic \-pedantic\-errors -\&\-w \-W \-Wall \-Waggregate\-return -\&\-Wcast\-align \-Wcast\-qual \-Wchar\-subscripts \-Wcomment -\&\-Wconversion \-Wno\-deprecated\-declarations -\&\-Wdisabled\-optimization \-Wno\-div\-by\-zero \-Werror -\&\-Wfloat\-equal \-Wformat \-Wformat=2 -\&\-Wformat\-nonliteral \-Wformat\-security -\&\-Wimplicit \-Wimplicit\-int -\&\-Wimplicit\-function\-declaration -\&\-Werror\-implicit\-function\-declaration -\&\-Wimport \-Winline \-Wno\-endif\-labels -\&\-Wlarger\-than\-\fR\fIlen\fR \fB\-Wlong\-long -\&\-Wmain \-Wmissing\-braces -\&\-Wmissing\-format\-attribute \-Wmissing\-noreturn -\&\-Wno\-multichar \-Wno\-format\-extra\-args \-Wno\-format\-y2k -\&\-Wno\-import \-Wnonnull \-Wpacked \-Wpadded -\&\-Wparentheses \-Wpointer\-arith \-Wredundant\-decls -\&\-Wreturn\-type \-Wsequence\-point \-Wshadow -\&\-Wsign\-compare \-Wstrict\-aliasing -\&\-Wswitch \-Wswitch\-default \-Wswitch\-enum -\&\-Wsystem\-headers \-Wtrigraphs \-Wundef \-Wuninitialized -\&\-Wunknown\-pragmas \-Wunreachable\-code -\&\-Wunused \-Wunused\-function \-Wunused\-label \-Wunused\-parameter -\&\-Wunused\-value \-Wunused\-variable \-Wwrite\-strings\fR -.IP "\fIC\-only Warning Options\fR" 4 -.IX Item "C-only Warning Options" -\&\fB\-Wbad\-function\-cast \-Wmissing\-declarations -\&\-Wmissing\-prototypes \-Wnested\-externs -\&\-Wstrict\-prototypes \-Wtraditional\fR -.IP "\fIDebugging Options\fR" 4 -.IX Item "Debugging Options" -\&\fB\-d\fR\fIletters\fR \fB\-dumpspecs \-dumpmachine \-dumpversion -\&\-fdump\-unnumbered \-fdump\-translation\-unit\fR[\fB\-\fR\fIn\fR] -\&\fB\-fdump\-class\-hierarchy\fR[\fB\-\fR\fIn\fR] -\&\fB\-fdump\-tree\-original\fR[\fB\-\fR\fIn\fR] -\&\fB\-fdump\-tree\-optimized\fR[\fB\-\fR\fIn\fR] -\&\fB\-fdump\-tree\-inlined\fR[\fB\-\fR\fIn\fR] -\&\fB\-feliminate\-dwarf2\-dups \-fmem\-report -\&\-fprofile\-arcs \-frandom\-seed=\fR\fIn\fR -\&\fB\-fsched\-verbose=\fR\fIn\fR \fB\-ftest\-coverage \-ftime\-report -\&\-g \-g\fR\fIlevel\fR \fB\-gcoff \-gdwarf \-gdwarf\-1 \-gdwarf\-1+ \-gdwarf\-2 -\&\-ggdb \-gstabs \-gstabs+ \-gvms \-gxcoff \-gxcoff+ -\&\-p \-pg \-print\-file\-name=\fR\fIlibrary\fR \fB\-print\-libgcc\-file\-name -\&\-print\-multi\-directory \-print\-multi\-lib -\&\-print\-prog\-name=\fR\fIprogram\fR \fB\-print\-search\-dirs \-Q -\&\-save\-temps \-time\fR -.IP "\fIOptimization Options\fR" 4 -.IX Item "Optimization Options" -\&\fB\-falign\-functions=\fR\fIn\fR \fB\-falign\-jumps=\fR\fIn\fR -\&\fB\-falign\-labels=\fR\fIn\fR \fB\-falign\-loops=\fR\fIn\fR -\&\fB\-fbranch\-probabilities \-fcaller\-saves \-fcprop\-registers -\&\-fcse\-follow\-jumps \-fcse\-skip\-blocks \-fdata\-sections -\&\-fdelayed\-branch \-fdelete\-null\-pointer\-checks -\&\-fexpensive\-optimizations \-ffast\-math \-ffloat\-store -\&\-fforce\-addr \-fforce\-mem \-ffunction\-sections -\&\-fgcse \-fgcse\-lm \-fgcse\-sm \-floop\-optimize \-fcrossjumping -\&\-fif\-conversion \-fif\-conversion2 -\&\-finline\-functions \-finline\-limit=\fR\fIn\fR \fB\-fkeep\-inline\-functions -\&\-fkeep\-static\-consts \-fmerge\-constants \-fmerge\-all\-constants -\&\-fmove\-all\-movables \-fnew\-ra \-fno\-branch\-count\-reg -\&\-fno\-default\-inline \-fno\-defer\-pop -\&\-fno\-function\-cse \-fno\-guess\-branch\-probability -\&\-fno\-inline \-fno\-math\-errno \-fno\-peephole \-fno\-peephole2 -\&\-funsafe\-math\-optimizations \-ffinite\-math\-only -\&\-fno\-trapping\-math \-fno\-zero\-initialized\-in\-bss -\&\-fomit\-frame\-pointer \-foptimize\-register\-move -\&\-foptimize\-sibling\-calls \-fprefetch\-loop\-arrays -\&\-freduce\-all\-givs \-fregmove \-frename\-registers -\&\-freorder\-blocks \-freorder\-functions -\&\-frerun\-cse\-after\-loop \-frerun\-loop\-opt -\&\-fschedule\-insns \-fschedule\-insns2 -\&\-fno\-sched\-interblock \-fno\-sched\-spec \-fsched\-spec\-load -\&\-fsched\-spec\-load\-dangerous \-fsignaling\-nans -\&\-fsingle\-precision\-constant \-fssa \-fssa\-ccp \-fssa\-dce -\&\-fstrength\-reduce \-fstrict\-aliasing \-ftracer \-fthread\-jumps -\&\-funroll\-all\-loops \-funroll\-loops -\&\-\-param\fR \fIname\fR\fB=\fR\fIvalue\fR -\&\fB\-O \-O0 \-O1 \-O2 \-O3 \-Os\fR -.IP "\fIPreprocessor Options\fR" 4 -.IX Item "Preprocessor Options" -\&\fB\-$ \-A\fR\fIquestion\fR\fB=\fR\fIanswer\fR -\&\fB\-A\-\fR\fIquestion\fR[\fB=\fR\fIanswer\fR] -\&\fB\-C \-dD \-dI \-dM \-dN -\&\-D\fR\fImacro\fR[\fB=\fR\fIdefn\fR] \fB\-E \-H -\&\-idirafter\fR \fIdir\fR -\&\fB\-include\fR \fIfile\fR \fB\-imacros\fR \fIfile\fR -\&\fB\-iprefix\fR \fIfile\fR \fB\-iwithprefix\fR \fIdir\fR -\&\fB\-iwithprefixbefore\fR \fIdir\fR \fB\-isystem\fR \fIdir\fR -\&\fB\-M \-MM \-MF \-MG \-MP \-MQ \-MT \-nostdinc \-P \-remap -\&\-trigraphs \-undef \-U\fR\fImacro\fR \fB\-Wp,\fR\fIoption\fR -.IP "\fIAssembler Option\fR" 4 -.IX Item "Assembler Option" -\&\fB\-Wa,\fR\fIoption\fR -.IP "\fILinker Options\fR" 4 -.IX Item "Linker Options" -\&\fIobject-file-name\fR \fB\-l\fR\fIlibrary\fR -\&\fB\-nostartfiles \-nodefaultlibs \-nostdlib -\&\-s \-static \-static\-libgcc \-shared \-shared\-libgcc \-symbolic -\&\-Wl,\fR\fIoption\fR \fB\-Xlinker\fR \fIoption\fR -\&\fB\-u\fR \fIsymbol\fR -.IP "\fIDirectory Options\fR" 4 -.IX Item "Directory Options" -\&\fB\-B\fR\fIprefix\fR \fB\-I\fR\fIdir\fR \fB\-I\- \-L\fR\fIdir\fR \fB\-specs=\fR\fIfile\fR -.IP "\fITarget Options\fR" 4 -.IX Item "Target Options" -\&\fB\-V\fR \fIversion\fR \fB\-b\fR \fImachine\fR -.IP "\fIMachine Dependent Options\fR" 4 -.IX Item "Machine Dependent Options" -\&\fIM680x0 Options\fR -\&\fB\-m68000 \-m68020 \-m68020\-40 \-m68020\-60 \-m68030 \-m68040 -\&\-m68060 \-mcpu32 \-m5200 \-m68881 \-mbitfield \-mc68000 \-mc68020 -\&\-mfpa \-mnobitfield \-mrtd \-mshort \-msoft\-float \-mpcrel -\&\-malign\-int \-mstrict\-align\fR -.Sp -\&\fIM68hc1x Options\fR -\&\fB\-m6811 \-m6812 \-m68hc11 \-m68hc12 \-m68hcs12 -\&\-mauto\-incdec \-minmax \-mlong\-calls \-mshort -\&\-msoft\-reg\-count=\fR\fIcount\fR -.Sp -\&\fI\s-1VAX\s0 Options\fR -\&\fB\-mg \-mgnu \-munix\fR -.Sp -\&\fI\s-1SPARC\s0 Options\fR -\&\fB\-mcpu=\fR\fIcpu-type\fR -\&\fB\-mtune=\fR\fIcpu-type\fR -\&\fB\-mcmodel=\fR\fIcode-model\fR -\&\fB\-m32 \-m64 -\&\-mapp\-regs \-mbroken\-saverestore \-mcypress -\&\-mfaster\-structs \-mflat -\&\-mfpu \-mhard\-float \-mhard\-quad\-float -\&\-mimpure\-text \-mlittle\-endian \-mlive\-g0 \-mno\-app\-regs -\&\-mno\-faster\-structs \-mno\-flat \-mno\-fpu -\&\-mno\-impure\-text \-mno\-stack\-bias \-mno\-unaligned\-doubles -\&\-msoft\-float \-msoft\-quad\-float \-msparclite \-mstack\-bias -\&\-msupersparc \-munaligned\-doubles \-mv8 -\&\-threads \-pthreads\fR -.Sp -\&\fI\s-1ARM\s0 Options\fR -\&\fB\-mapcs\-frame \-mno\-apcs\-frame -\&\-mapcs\-26 \-mapcs\-32 -\&\-mapcs\-stack\-check \-mno\-apcs\-stack\-check -\&\-mapcs\-float \-mno\-apcs\-float -\&\-mapcs\-reentrant \-mno\-apcs\-reentrant -\&\-msched\-prolog \-mno\-sched\-prolog -\&\-mlittle\-endian \-mbig\-endian \-mwords\-little\-endian -\&\-malignment\-traps \-mno\-alignment\-traps -\&\-msoft\-float \-mhard\-float \-mfpe -\&\-mthumb\-interwork \-mno\-thumb\-interwork -\&\-mcpu=\fR\fIname\fR \fB\-march=\fR\fIname\fR \fB\-mfpe=\fR\fIname\fR -\&\fB\-mstructure\-size\-boundary=\fR\fIn\fR -\&\fB\-mabort\-on\-noreturn -\&\-mlong\-calls \-mno\-long\-calls -\&\-msingle\-pic\-base \-mno\-single\-pic\-base -\&\-mpic\-register=\fR\fIreg\fR -\&\fB\-mnop\-fun\-dllimport -\&\-mpoke\-function\-name -\&\-mthumb \-marm -\&\-mtpcs\-frame \-mtpcs\-leaf\-frame -\&\-mcaller\-super\-interworking \-mcallee\-super\-interworking\fR -.Sp -\&\fI\s-1MN10200\s0 Options\fR -\&\fB\-mrelax\fR -.Sp -\&\fI\s-1MN10300\s0 Options\fR -\&\fB\-mmult\-bug \-mno\-mult\-bug -\&\-mam33 \-mno\-am33 -\&\-mno\-crt0 \-mrelax\fR -.Sp -\&\fIM32R/D Options\fR -\&\fB\-m32rx \-m32r \-mcode\-model=\fR\fImodel-type\fR -\&\fB\-msdata=\fR\fIsdata-type\fR \fB\-G\fR \fInum\fR -.Sp -\&\fIM88K Options\fR -\&\fB\-m88000 \-m88100 \-m88110 \-mbig\-pic -\&\-mcheck\-zero\-division \-mhandle\-large\-shift -\&\-midentify\-revision \-mno\-check\-zero\-division -\&\-mno\-ocs\-debug\-info \-mno\-ocs\-frame\-position -\&\-mno\-optimize\-arg\-area \-mno\-serialize\-volatile -\&\-mno\-underscores \-mocs\-debug\-info -\&\-mocs\-frame\-position \-moptimize\-arg\-area -\&\-mserialize\-volatile \-mshort\-data\-\fR\fInum\fR \fB\-msvr3 -\&\-msvr4 \-mtrap\-large\-shift \-muse\-div\-instruction -\&\-mversion\-03.00 \-mwarn\-passed\-structs\fR -.Sp -\&\fI\s-1RS/6000\s0 and PowerPC Options\fR -\&\fB\-mcpu=\fR\fIcpu-type\fR -\&\fB\-mtune=\fR\fIcpu-type\fR -\&\fB\-mpower \-mno\-power \-mpower2 \-mno\-power2 -\&\-mpowerpc \-mpowerpc64 \-mno\-powerpc -\&\-maltivec \-mno\-altivec -\&\-mpowerpc\-gpopt \-mno\-powerpc\-gpopt -\&\-mpowerpc\-gfxopt \-mno\-powerpc\-gfxopt -\&\-mnew\-mnemonics \-mold\-mnemonics -\&\-mfull\-toc \-mminimal\-toc \-mno\-fp\-in\-toc \-mno\-sum\-in\-toc -\&\-m64 \-m32 \-mxl\-call \-mno\-xl\-call \-mpe -\&\-msoft\-float \-mhard\-float \-mmultiple \-mno\-multiple -\&\-mstring \-mno\-string \-mupdate \-mno\-update -\&\-mfused\-madd \-mno\-fused\-madd \-mbit\-align \-mno\-bit\-align -\&\-mstrict\-align \-mno\-strict\-align \-mrelocatable -\&\-mno\-relocatable \-mrelocatable\-lib \-mno\-relocatable\-lib -\&\-mtoc \-mno\-toc \-mlittle \-mlittle\-endian \-mbig \-mbig\-endian -\&\-mcall\-aix \-mcall\-sysv \-mcall\-netbsd -\&\-maix\-struct\-return \-msvr4\-struct\-return -\&\-mabi=altivec \-mabi=no\-altivec -\&\-mabi=spe \-mabi=no\-spe -\&\-misel=yes \-misel=no -\&\-mprototype \-mno\-prototype -\&\-msim \-mmvme \-mads \-myellowknife \-memb \-msdata -\&\-msdata=\fR\fIopt\fR \fB\-mvxworks \-mwindiss \-G\fR \fInum\fR \fB\-pthread\fR -.Sp -\&\fIDarwin Options\fR -.Sp -\&\fB\-all_load \-allowable_client \-arch \-arch_errors_fatal -\&\-arch_only \-bind_at_load \-bundle \-bundle_loader -\&\-client_name \-compatibility_version \-current_version -\&\-dependency\-file \-dylib_file \-dylinker_install_name -\&\-dynamic \-dynamiclib \-exported_symbols_list -\&\-filelist \-flat_namespace \-force_cpusubtype_ALL -\&\-force_flat_namespace \-headerpad_max_install_names -\&\-image_base \-init \-install_name \-keep_private_externs -\&\-multi_module \-multiply_defined \-multiply_defined_unused -\&\-noall_load \-nomultidefs \-noprebind \-noseglinkedit -\&\-pagezero_size \-prebind \-prebind_all_twolevel_modules -\&\-private_bundle \-read_only_relocs \-sectalign -\&\-sectobjectsymbols \-whyload \-seg1addr -\&\-sectcreate \-sectobjectsymbols \-sectorder -\&\-seg_addr_table \-seg_addr_table_filename \-seglinkedit -\&\-segprot \-segs_read_only_addr \-segs_read_write_addr -\&\-single_module \-static \-sub_library \-sub_umbrella -\&\-twolevel_namespace \-umbrella \-undefined -\&\-unexported_symbols_list \-weak_reference_mismatches \-whatsloaded\fR -.Sp -\&\fI\s-1RT\s0 Options\fR -\&\fB\-mcall\-lib\-mul \-mfp\-arg\-in\-fpregs \-mfp\-arg\-in\-gregs -\&\-mfull\-fp\-blocks \-mhc\-struct\-return \-min\-line\-mul -\&\-mminimum\-fp\-blocks \-mnohc\-struct\-return\fR -.Sp -\&\fI\s-1MIPS\s0 Options\fR -\&\fB\-mabicalls \-march=\fR\fIcpu-type\fR \fB\-mtune=\fR\fIcpu=type\fR -\&\fB\-mcpu=\fR\fIcpu-type\fR \fB\-membedded\-data \-muninit\-const\-in\-rodata -\&\-membedded\-pic \-mfp32 \-mfp64 \-mfused\-madd \-mno\-fused\-madd -\&\-mgas \-mgp32 \-mgp64 -\&\-mgpopt \-mhalf\-pic \-mhard\-float \-mint64 \-mips1 -\&\-mips2 \-mips3 \-mips4 \-mlong64 \-mlong32 \-mlong\-calls \-mmemcpy -\&\-mmips\-as \-mmips\-tfile \-mno\-abicalls -\&\-mno\-embedded\-data \-mno\-uninit\-const\-in\-rodata -\&\-mno\-embedded\-pic \-mno\-gpopt \-mno\-long\-calls -\&\-mno\-memcpy \-mno\-mips\-tfile \-mno\-rnames \-mno\-stats -\&\-mrnames \-msoft\-float -\&\-m4650 \-msingle\-float \-mmad -\&\-mstats \-EL \-EB \-G\fR \fInum\fR \fB\-nocpp -\&\-mabi=32 \-mabi=n32 \-mabi=64 \-mabi=eabi -\&\-mfix7000 \-mno\-crt0 \-mflush\-func=\fR\fIfunc\fR \fB\-mno\-flush\-func -\&\-mbranch\-likely \-mno\-branch\-likely\fR -.Sp -\&\fIi386 and x86\-64 Options\fR -\&\fB\-mcpu=\fR\fIcpu-type\fR \fB\-march=\fR\fIcpu-type\fR -\&\fB\-mfpmath=\fR\fIunit\fR \fB\-masm=\fR\fIdialect\fR \fB\-mno\-fancy\-math\-387 -\&\-mno\-fp\-ret\-in\-387 \-msoft\-float \-msvr3\-shlib -\&\-mno\-wide\-multiply \-mrtd \-malign\-double -\&\-mpreferred\-stack\-boundary=\fR\fInum\fR -\&\fB\-mmmx \-msse \-msse2 \-msse3 \-m3dnow -\&\-mthreads \-mno\-align\-stringops \-minline\-all\-stringops -\&\-mpush\-args \-maccumulate\-outgoing\-args \-m128bit\-long\-double -\&\-m96bit\-long\-double \-mregparm=\fR\fInum\fR \fB\-momit\-leaf\-frame\-pointer -\&\-mno\-red\-zone -\&\-mcmodel=\fR\fIcode-model\fR -\&\fB\-m32 \-m64\fR -.Sp -\&\fI\s-1HPPA\s0 Options\fR -\&\fB\-march=\fR\fIarchitecture-type\fR -\&\fB\-mbig\-switch \-mdisable\-fpregs \-mdisable\-indexing -\&\-mfast\-indirect\-calls \-mgas \-mgnu\-ld \-mhp\-ld -\&\-mjump\-in\-delay \-mlinker\-opt \-mlong\-calls -\&\-mlong\-load\-store \-mno\-big\-switch \-mno\-disable\-fpregs -\&\-mno\-disable\-indexing \-mno\-fast\-indirect\-calls \-mno\-gas -\&\-mno\-jump\-in\-delay \-mno\-long\-load\-store -\&\-mno\-portable\-runtime \-mno\-soft\-float -\&\-mno\-space\-regs \-msoft\-float \-mpa\-risc\-1\-0 -\&\-mpa\-risc\-1\-1 \-mpa\-risc\-2\-0 \-mportable\-runtime -\&\-mschedule=\fR\fIcpu-type\fR \fB\-mspace\-regs \-msio \-mwsio -\&\-nolibdld \-static \-threads\fR -.Sp -\&\fIIntel 960 Options\fR -\&\fB\-m\fR\fIcpu-type\fR \fB\-masm\-compat \-mclean\-linkage -\&\-mcode\-align \-mcomplex\-addr \-mleaf\-procedures -\&\-mic\-compat \-mic2.0\-compat \-mic3.0\-compat -\&\-mintel\-asm \-mno\-clean\-linkage \-mno\-code\-align -\&\-mno\-complex\-addr \-mno\-leaf\-procedures -\&\-mno\-old\-align \-mno\-strict\-align \-mno\-tail\-call -\&\-mnumerics \-mold\-align \-msoft\-float \-mstrict\-align -\&\-mtail\-call\fR -.Sp -\&\fI\s-1DEC\s0 Alpha Options\fR -\&\fB\-mno\-fp\-regs \-msoft\-float \-malpha\-as \-mgas -\&\-mieee \-mieee\-with\-inexact \-mieee\-conformant -\&\-mfp\-trap\-mode=\fR\fImode\fR \fB\-mfp\-rounding\-mode=\fR\fImode\fR -\&\fB\-mtrap\-precision=\fR\fImode\fR \fB\-mbuild\-constants -\&\-mcpu=\fR\fIcpu-type\fR \fB\-mtune=\fR\fIcpu-type\fR -\&\fB\-mbwx \-mmax \-mfix \-mcix -\&\-mfloat\-vax \-mfloat\-ieee -\&\-mexplicit\-relocs \-msmall\-data \-mlarge\-data -\&\-mmemory\-latency=\fR\fItime\fR -.Sp -\&\fI\s-1DEC\s0 Alpha/VMS Options\fR -\&\fB\-mvms\-return\-codes\fR -.Sp -\&\fIH8/300 Options\fR -\&\fB\-mrelax \-mh \-ms \-mn \-mint32 \-malign\-300\fR -.Sp -\&\fI\s-1SH\s0 Options\fR -\&\fB\-m1 \-m2 \-m3 \-m3e -\&\-m4\-nofpu \-m4\-single\-only \-m4\-single \-m4 -\&\-m5\-64media \-m5\-64media\-nofpu -\&\-m5\-32media \-m5\-32media\-nofpu -\&\-m5\-compact \-m5\-compact\-nofpu -\&\-mb \-ml \-mdalign \-mrelax -\&\-mbigtable \-mfmovd \-mhitachi \-mnomacsave -\&\-mieee \-misize \-mpadstruct \-mspace -\&\-mprefergot \-musermode\fR -.Sp -\&\fISystem V Options\fR -\&\fB\-Qy \-Qn \-YP,\fR\fIpaths\fR \fB\-Ym,\fR\fIdir\fR -.Sp -\&\fI\s-1ARC\s0 Options\fR -\&\fB\-EB \-EL -\&\-mmangle\-cpu \-mcpu=\fR\fIcpu\fR \fB\-mtext=\fR\fItext-section\fR -\&\fB\-mdata=\fR\fIdata-section\fR \fB\-mrodata=\fR\fIreadonly-data-section\fR -.Sp -\&\fITMS320C3x/C4x Options\fR -\&\fB\-mcpu=\fR\fIcpu\fR \fB\-mbig \-msmall \-mregparm \-mmemparm -\&\-mfast\-fix \-mmpyi \-mbk \-mti \-mdp\-isr\-reload -\&\-mrpts=\fR\fIcount\fR \fB\-mrptb \-mdb \-mloop\-unsigned -\&\-mparallel\-insns \-mparallel\-mpy \-mpreserve\-float\fR -.Sp -\&\fIV850 Options\fR -\&\fB\-mlong\-calls \-mno\-long\-calls \-mep \-mno\-ep -\&\-mprolog\-function \-mno\-prolog\-function \-mspace -\&\-mtda=\fR\fIn\fR \fB\-msda=\fR\fIn\fR \fB\-mzda=\fR\fIn\fR -\&\fB\-mapp\-regs \-mno\-app\-regs -\&\-mdisable\-callt \-mno\-disable\-callt -\&\-mv850e -\&\-mv850 \-mbig\-switch\fR -.Sp -\&\fI\s-1NS32K\s0 Options\fR -\&\fB\-m32032 \-m32332 \-m32532 \-m32081 \-m32381 -\&\-mmult\-add \-mnomult\-add \-msoft\-float \-mrtd \-mnortd -\&\-mregparam \-mnoregparam \-msb \-mnosb -\&\-mbitfield \-mnobitfield \-mhimem \-mnohimem\fR -.Sp -\&\fI\s-1AVR\s0 Options\fR -\&\fB\-mmcu=\fR\fImcu\fR \fB\-msize \-minit\-stack=\fR\fIn\fR \fB\-mno\-interrupts -\&\-mcall\-prologues \-mno\-tablejump \-mtiny\-stack\fR -.Sp -\&\fIMCore Options\fR -\&\fB\-mhardlit \-mno\-hardlit \-mdiv \-mno\-div \-mrelax\-immediates -\&\-mno\-relax\-immediates \-mwide\-bitfields \-mno\-wide\-bitfields -\&\-m4byte\-functions \-mno\-4byte\-functions \-mcallgraph\-data -\&\-mno\-callgraph\-data \-mslow\-bytes \-mno\-slow\-bytes \-mno\-lsim -\&\-mlittle\-endian \-mbig\-endian \-m210 \-m340 \-mstack\-increment\fR -.Sp -\&\fI\s-1MMIX\s0 Options\fR -\&\fB\-mlibfuncs \-mno\-libfuncs \-mepsilon \-mno\-epsilon \-mabi=gnu -\&\-mabi=mmixware \-mzero\-extend \-mknuthdiv \-mtoplevel\-symbols -\&\-melf \-mbranch\-predict \-mno\-branch\-predict \-mbase\-addresses -\&\-mno\-base\-addresses \-msingle\-exit \-mno\-single\-exit\fR -.Sp -\&\fI\s-1IA\-64\s0 Options\fR -\&\fB\-mbig\-endian \-mlittle\-endian \-mgnu\-as \-mgnu\-ld \-mno\-pic -\&\-mvolatile\-asm\-stop \-mb\-step \-mregister\-names \-mno\-sdata -\&\-mconstant\-gp \-mauto\-pic \-minline\-float\-divide\-min\-latency -\&\-minline\-float\-divide\-max\-throughput -\&\-minline\-int\-divide\-min\-latency -\&\-minline\-int\-divide\-max\-throughput \-mno\-dwarf2\-asm -\&\-mfixed\-range=\fR\fIregister-range\fR -.Sp -\&\fID30V Options\fR -\&\fB\-mextmem \-mextmemory \-monchip \-mno\-asm\-optimize -\&\-masm\-optimize \-mbranch\-cost=\fR\fIn\fR \fB\-mcond\-exec=\fR\fIn\fR -.Sp -\&\fIS/390 and zSeries Options\fR -\&\fB\-mhard\-float \-msoft\-float \-mbackchain \-mno\-backchain -\&\-msmall\-exec \-mno\-small\-exec \-mmvcle \-mno\-mvcle -\&\-m64 \-m31 \-mdebug \-mno\-debug\fR -.Sp -\&\fI\s-1CRIS\s0 Options\fR -\&\fB\-mcpu=\fR\fIcpu\fR \fB\-march=\fR\fIcpu\fR \fB\-mtune=\fR\fIcpu\fR -\&\fB\-mmax\-stack\-frame=\fR\fIn\fR \fB\-melinux\-stacksize=\fR\fIn\fR -\&\fB\-metrax4 \-metrax100 \-mpdebug \-mcc\-init \-mno\-side\-effects -\&\-mstack\-align \-mdata\-align \-mconst\-align -\&\-m32\-bit \-m16\-bit \-m8\-bit \-mno\-prologue\-epilogue \-mno\-gotplt -\&\-melf \-maout \-melinux \-mlinux \-sim \-sim2 -\&\-mmul\-bug\-workaround \-mno\-mul\-bug\-workaround\fR -.Sp -\&\fI\s-1PDP\-11\s0 Options\fR -\&\fB\-mfpu \-msoft\-float \-mac0 \-mno\-ac0 \-m40 \-m45 \-m10 -\&\-mbcopy \-mbcopy\-builtin \-mint32 \-mno\-int16 -\&\-mint16 \-mno\-int32 \-mfloat32 \-mno\-float64 -\&\-mfloat64 \-mno\-float32 \-mabshi \-mno\-abshi -\&\-mbranch\-expensive \-mbranch\-cheap -\&\-msplit \-mno\-split \-munix\-asm \-mdec\-asm\fR -.Sp -\&\fIXstormy16 Options\fR -\&\fB\-msim\fR -.Sp -\&\fIXtensa Options\fR -\&\fB\-mbig\-endian \-mlittle\-endian -\&\-mdensity \-mno\-density -\&\-mmac16 \-mno\-mac16 -\&\-mmul16 \-mno\-mul16 -\&\-mmul32 \-mno\-mul32 -\&\-mnsa \-mno\-nsa -\&\-mminmax \-mno\-minmax -\&\-msext \-mno\-sext -\&\-mbooleans \-mno\-booleans -\&\-mhard\-float \-msoft\-float -\&\-mfused\-madd \-mno\-fused\-madd -\&\-mserialize\-volatile \-mno\-serialize\-volatile -\&\-mtext\-section\-literals \-mno\-text\-section\-literals -\&\-mtarget\-align \-mno\-target\-align -\&\-mlongcalls \-mno\-longcalls\fR -.Sp -\&\fI\s-1FRV\s0 Options\fR -\&\fB\-mgpr\-32 \-mgpr\-64 \-mfpr\-32 \-mfpr\-64 -\&\-mhard\-float \-msoft\-float \-malloc\-cc \-mfixed\-cc -\&\-mdword \-mno\-dword \-mdouble \-mno\-double -\&\-mmedia \-mno\-media \-mmuladd \-mno\-muladd \-mlibrary\-pic -\&\-macc\-4 \-macc\-8 \-mpack \-mno\-pack \-mno\-eflags -\&\-mcond\-move \-mno\-cond\-move \-mscc \-mno\-scc -\&\-mcond\-exec \-mno\-cond\-exec \-mvliw\-branch \-mno\-vliw\-branch -\&\-mmulti\-cond\-exec \-mno\-multi\-cond\-exec \-mnested\-cond\-exec -\&\-mno\-nested\-cond\-exec \-mtomcat\-stats -\&\-mcpu=\fR\fIcpu\fR -.IP "\fICode Generation Options\fR" 4 -.IX Item "Code Generation Options" -\&\fB\-fcall\-saved\-\fR\fIreg\fR \fB\-fcall\-used\-\fR\fIreg\fR -\&\fB\-ffixed\-\fR\fIreg\fR \fB\-fexceptions -\&\-fnon\-call\-exceptions \-funwind\-tables -\&\-fasynchronous\-unwind\-tables -\&\-finhibit\-size\-directive \-finstrument\-functions -\&\-fno\-common \-fno\-ident \-fno\-gnu\-linker -\&\-fpcc\-struct\-return \-fpic \-fPIC -\&\-freg\-struct\-return \-fshared\-data \-fshort\-enums -\&\-fshort\-double \-fshort\-wchar \-fvolatile -\&\-fvolatile\-global \-fvolatile\-static -\&\-fverbose\-asm \-fpack\-struct \-fstack\-check -\&\-fstack\-limit\-register=\fR\fIreg\fR \fB\-fstack\-limit\-symbol=\fR\fIsym\fR -\&\fB\-fargument\-alias \-fargument\-noalias -\&\-fargument\-noalias\-global \-fleading\-underscore -\&\-ftls\-model=\fR\fImodel\fR -\&\fB\-ftrapv \-fbounds\-check\fR -.Sh "Options Controlling the Kind of Output" -.IX Subsection "Options Controlling the Kind of Output" -Compilation can involve up to four stages: preprocessing, compilation -proper, assembly and linking, always in that order. The first three -stages apply to an individual source file, and end by producing an -object file; linking combines all the object files (those newly -compiled, and those specified as input) into an executable file. -.PP -For any given input file, the file name suffix determines what kind of -compilation is done: -.IP "\fIfile\fR\fB.c\fR" 4 -.IX Item "file.c" -C source code which must be preprocessed. -.IP "\fIfile\fR\fB.i\fR" 4 -.IX Item "file.i" -C source code which should not be preprocessed. -.IP "\fIfile\fR\fB.ii\fR" 4 -.IX Item "file.ii" -\&\*(C+ source code which should not be preprocessed. -.IP "\fIfile\fR\fB.m\fR" 4 -.IX Item "file.m" -Objective-C source code. Note that you must link with the library -\&\fIlibobjc.a\fR to make an Objective-C program work. -.IP "\fIfile\fR\fB.mi\fR" 4 -.IX Item "file.mi" -Objective-C source code which should not be preprocessed. -.IP "\fIfile\fR\fB.h\fR" 4 -.IX Item "file.h" -C header file (not to be compiled or linked). -.IP "\fIfile\fR\fB.cc\fR" 4 -.IX Item "file.cc" -.PD 0 -.IP "\fIfile\fR\fB.cp\fR" 4 -.IX Item "file.cp" -.IP "\fIfile\fR\fB.cxx\fR" 4 -.IX Item "file.cxx" -.IP "\fIfile\fR\fB.cpp\fR" 4 -.IX Item "file.cpp" -.IP "\fIfile\fR\fB.c++\fR" 4 -.IX Item "file.c++" -.IP "\fIfile\fR\fB.C\fR" 4 -.IX Item "file.C" -.PD -\&\*(C+ source code which must be preprocessed. Note that in \fB.cxx\fR, -the last two letters must both be literally \fBx\fR. Likewise, -\&\fB.C\fR refers to a literal capital C. -.IP "\fIfile\fR\fB.f\fR" 4 -.IX Item "file.f" -.PD 0 -.IP "\fIfile\fR\fB.for\fR" 4 -.IX Item "file.for" -.IP "\fIfile\fR\fB.FOR\fR" 4 -.IX Item "file.FOR" -.PD -Fortran source code which should not be preprocessed. -.IP "\fIfile\fR\fB.F\fR" 4 -.IX Item "file.F" -.PD 0 -.IP "\fIfile\fR\fB.fpp\fR" 4 -.IX Item "file.fpp" -.IP "\fIfile\fR\fB.FPP\fR" 4 -.IX Item "file.FPP" -.PD -Fortran source code which must be preprocessed (with the traditional -preprocessor). -.IP "\fIfile\fR\fB.r\fR" 4 -.IX Item "file.r" -Fortran source code which must be preprocessed with a \s-1RATFOR\s0 -preprocessor (not included with \s-1GCC\s0). -.IP "\fIfile\fR\fB.ads\fR" 4 -.IX Item "file.ads" -Ada source code file which contains a library unit declaration (a -declaration of a package, subprogram, or generic, or a generic -instantiation), or a library unit renaming declaration (a package, -generic, or subprogram renaming declaration). Such files are also -called \fIspecs\fR. -.IP "\fIfile\fR\fB.adb\fR" 4 -.IX Item "file.adb" -Ada source code file containing a library unit body (a subprogram or -package body). Such files are also called \fIbodies\fR. -.IP "\fIfile\fR\fB.s\fR" 4 -.IX Item "file.s" -Assembler code. -.IP "\fIfile\fR\fB.S\fR" 4 -.IX Item "file.S" -Assembler code which must be preprocessed. -.IP "\fIother\fR" 4 -.IX Item "other" -An object file to be fed straight into linking. -Any file name with no recognized suffix is treated this way. -.PP -You can specify the input language explicitly with the \fB\-x\fR option: -.IP "\fB\-x\fR \fIlanguage\fR" 4 -.IX Item "-x language" -Specify explicitly the \fIlanguage\fR for the following input files -(rather than letting the compiler choose a default based on the file -name suffix). This option applies to all following input files until -the next \fB\-x\fR option. Possible values for \fIlanguage\fR are: -.Sp -.Vb 8 -\& c c-header cpp-output -\& c++ c++-cpp-output -\& objective-c objc-cpp-output -\& assembler assembler-with-cpp -\& ada -\& f77 f77-cpp-input ratfor -\& java -\& treelang -.Ve -.IP "\fB\-x none\fR" 4 -.IX Item "-x none" -Turn off any specification of a language, so that subsequent files are -handled according to their file name suffixes (as they are if \fB\-x\fR -has not been used at all). -.IP "\fB\-pass\-exit\-codes\fR" 4 -.IX Item "-pass-exit-codes" -Normally the \fBgcc\fR program will exit with the code of 1 if any -phase of the compiler returns a non-success return code. If you specify -\&\fB\-pass\-exit\-codes\fR, the \fBgcc\fR program will instead return with -numerically highest error produced by any phase that returned an error -indication. -.PP -If you only want some of the stages of compilation, you can use -\&\fB\-x\fR (or filename suffixes) to tell \fBgcc\fR where to start, and -one of the options \fB\-c\fR, \fB\-S\fR, or \fB\-E\fR to say where -\&\fBgcc\fR is to stop. Note that some combinations (for example, -\&\fB\-x cpp-output \-E\fR) instruct \fBgcc\fR to do nothing at all. -.IP "\fB\-c\fR" 4 -.IX Item "-c" -Compile or assemble the source files, but do not link. The linking -stage simply is not done. The ultimate output is in the form of an -object file for each source file. -.Sp -By default, the object file name for a source file is made by replacing -the suffix \fB.c\fR, \fB.i\fR, \fB.s\fR, etc., with \fB.o\fR. -.Sp -Unrecognized input files, not requiring compilation or assembly, are -ignored. -.IP "\fB\-S\fR" 4 -.IX Item "-S" -Stop after the stage of compilation proper; do not assemble. The output -is in the form of an assembler code file for each non-assembler input -file specified. -.Sp -By default, the assembler file name for a source file is made by -replacing the suffix \fB.c\fR, \fB.i\fR, etc., with \fB.s\fR. -.Sp -Input files that don't require compilation are ignored. -.IP "\fB\-E\fR" 4 -.IX Item "-E" -Stop after the preprocessing stage; do not run the compiler proper. The -output is in the form of preprocessed source code, which is sent to the -standard output. -.Sp -Input files which don't require preprocessing are ignored. -.IP "\fB\-o\fR \fIfile\fR" 4 -.IX Item "-o file" -Place output in file \fIfile\fR. This applies regardless to whatever -sort of output is being produced, whether it be an executable file, -an object file, an assembler file or preprocessed C code. -.Sp -Since only one output file can be specified, it does not make sense to -use \fB\-o\fR when compiling more than one input file, unless you are -producing an executable file as output. -.Sp -If \fB\-o\fR is not specified, the default is to put an executable file -in \fIa.out\fR, the object file for \fI\fIsource\fI.\fIsuffix\fI\fR in -\&\fI\fIsource\fI.o\fR, its assembler file in \fI\fIsource\fI.s\fR, and -all preprocessed C source on standard output. -.IP "\fB\-v\fR" 4 -.IX Item "-v" -Print (on standard error output) the commands executed to run the stages -of compilation. Also print the version number of the compiler driver -program and of the preprocessor and the compiler proper. -.IP "\fB\-###\fR" 4 -.IX Item "-###" -Like \fB\-v\fR except the commands are not executed and all command -arguments are quoted. This is useful for shell scripts to capture the -driver-generated command lines. -.IP "\fB\-pipe\fR" 4 -.IX Item "-pipe" -Use pipes rather than temporary files for communication between the -various stages of compilation. This fails to work on some systems where -the assembler is unable to read from a pipe; but the \s-1GNU\s0 assembler has -no trouble. -.IP "\fB\-\-help\fR" 4 -.IX Item "--help" -Print (on the standard output) a description of the command line options -understood by \fBgcc\fR. If the \fB\-v\fR option is also specified -then \fB\-\-help\fR will also be passed on to the various processes -invoked by \fBgcc\fR, so that they can display the command line options -they accept. If the \fB\-W\fR option is also specified then command -line options which have no documentation associated with them will also -be displayed. -.IP "\fB\-\-target\-help\fR" 4 -.IX Item "--target-help" -Print (on the standard output) a description of target specific command -line options for each tool. -.IP "\fB\-\-version\fR" 4 -.IX Item "--version" -Display the version number and copyrights of the invoked \s-1GCC\s0. -.Sh "Compiling \*(C+ Programs" -.IX Subsection "Compiling Programs" -\&\*(C+ source files conventionally use one of the suffixes \fB.C\fR, -\&\fB.cc\fR, \fB.cpp\fR, \fB.c++\fR, \fB.cp\fR, or \fB.cxx\fR; -preprocessed \*(C+ files use the suffix \fB.ii\fR. \s-1GCC\s0 recognizes -files with these names and compiles them as \*(C+ programs even if you -call the compiler the same way as for compiling C programs (usually with -the name \fBgcc\fR). -.PP -However, \*(C+ programs often require class libraries as well as a -compiler that understands the \*(C+ language\-\-\-and under some -circumstances, you might want to compile programs from standard input, -or otherwise without a suffix that flags them as \*(C+ programs. -\&\fBg++\fR is a program that calls \s-1GCC\s0 with the default language -set to \*(C+, and automatically specifies linking against the \*(C+ -library. On many systems, \fBg++\fR is also -installed with the name \fBc++\fR. -.PP -When you compile \*(C+ programs, you may specify many of the same -command-line options that you use for compiling programs in any -language; or command-line options meaningful for C and related -languages; or options that are meaningful only for \*(C+ programs. -.Sh "Options Controlling C Dialect" -.IX Subsection "Options Controlling C Dialect" -The following options control the dialect of C (or languages derived -from C, such as \*(C+ and Objective\-C) that the compiler accepts: -.IP "\fB\-ansi\fR" 4 -.IX Item "-ansi" -In C mode, support all \s-1ISO\s0 C90 programs. In \*(C+ mode, -remove \s-1GNU\s0 extensions that conflict with \s-1ISO\s0 \*(C+. -.Sp -This turns off certain features of \s-1GCC\s0 that are incompatible with \s-1ISO\s0 -C90 (when compiling C code), or of standard \*(C+ (when compiling \*(C+ code), -such as the \f(CW\*(C`asm\*(C'\fR and \f(CW\*(C`typeof\*(C'\fR keywords, and -predefined macros such as \f(CW\*(C`unix\*(C'\fR and \f(CW\*(C`vax\*(C'\fR that identify the -type of system you are using. It also enables the undesirable and -rarely used \s-1ISO\s0 trigraph feature. For the C compiler, -it disables recognition of \*(C+ style \fB//\fR comments as well as -the \f(CW\*(C`inline\*(C'\fR keyword. -.Sp -The alternate keywords \f(CW\*(C`_\|_asm_\|_\*(C'\fR, \f(CW\*(C`_\|_extension_\|_\*(C'\fR, -\&\f(CW\*(C`_\|_inline_\|_\*(C'\fR and \f(CW\*(C`_\|_typeof_\|_\*(C'\fR continue to work despite -\&\fB\-ansi\fR. You would not want to use them in an \s-1ISO\s0 C program, of -course, but it is useful to put them in header files that might be included -in compilations done with \fB\-ansi\fR. Alternate predefined macros -such as \f(CW\*(C`_\|_unix_\|_\*(C'\fR and \f(CW\*(C`_\|_vax_\|_\*(C'\fR are also available, with or -without \fB\-ansi\fR. -.Sp -The \fB\-ansi\fR option does not cause non-ISO programs to be -rejected gratuitously. For that, \fB\-pedantic\fR is required in -addition to \fB\-ansi\fR. -.Sp -The macro \f(CW\*(C`_\|_STRICT_ANSI_\|_\*(C'\fR is predefined when the \fB\-ansi\fR -option is used. Some header files may notice this macro and refrain -from declaring certain functions or defining certain macros that the -\&\s-1ISO\s0 standard doesn't call for; this is to avoid interfering with any -programs that might use these names for other things. -.Sp -Functions which would normally be built in but do not have semantics -defined by \s-1ISO\s0 C (such as \f(CW\*(C`alloca\*(C'\fR and \f(CW\*(C`ffs\*(C'\fR) are not built-in -functions with \fB\-ansi\fR is used. -.IP "\fB\-std=\fR" 4 -.IX Item "-std=" -Determine the language standard. This option is currently only -supported when compiling C or \*(C+. A value for this option must be -provided; possible values are -.RS 4 -.IP "\fBc89\fR" 4 -.IX Item "c89" -.PD 0 -.IP "\fBiso9899:1990\fR" 4 -.IX Item "iso9899:1990" -.PD -\&\s-1ISO\s0 C90 (same as \fB\-ansi\fR). -.IP "\fBiso9899:199409\fR" 4 -.IX Item "iso9899:199409" -\&\s-1ISO\s0 C90 as modified in amendment 1. -.IP "\fBc99\fR" 4 -.IX Item "c99" -.PD 0 -.IP "\fBc9x\fR" 4 -.IX Item "c9x" -.IP "\fBiso9899:1999\fR" 4 -.IX Item "iso9899:1999" -.IP "\fBiso9899:199x\fR" 4 -.IX Item "iso9899:199x" -.PD -\&\s-1ISO\s0 C99. Note that this standard is not yet fully supported; see -<\fBhttp://gcc.gnu.org/gcc\-3.3/c99status.html\fR> for more information. The -names \fBc9x\fR and \fBiso9899:199x\fR are deprecated. -.IP "\fBgnu89\fR" 4 -.IX Item "gnu89" -Default, \s-1ISO\s0 C90 plus \s-1GNU\s0 extensions (including some C99 features). -.IP "\fBgnu99\fR" 4 -.IX Item "gnu99" -.PD 0 -.IP "\fBgnu9x\fR" 4 -.IX Item "gnu9x" -.PD -\&\s-1ISO\s0 C99 plus \s-1GNU\s0 extensions. When \s-1ISO\s0 C99 is fully implemented in \s-1GCC\s0, -this will become the default. The name \fBgnu9x\fR is deprecated. -.IP "\fBc++98\fR" 4 -.IX Item "c++98" -The 1998 \s-1ISO\s0 \*(C+ standard plus amendments. -.IP "\fBgnu++98\fR" 4 -.IX Item "gnu++98" -The same as \fB\-std=c++98\fR plus \s-1GNU\s0 extensions. This is the -default for \*(C+ code. -.RE -.RS 4 -.Sp -Even when this option is not specified, you can still use some of the -features of newer standards in so far as they do not conflict with -previous C standards. For example, you may use \f(CW\*(C`_\|_restrict_\|_\*(C'\fR even -when \fB\-std=c99\fR is not specified. -.Sp -The \fB\-std\fR options specifying some version of \s-1ISO\s0 C have the same -effects as \fB\-ansi\fR, except that features that were not in \s-1ISO\s0 C90 -but are in the specified version (for example, \fB//\fR comments and -the \f(CW\*(C`inline\*(C'\fR keyword in \s-1ISO\s0 C99) are not disabled. -.RE -.IP "\fB\-aux\-info\fR \fIfilename\fR" 4 -.IX Item "-aux-info filename" -Output to the given filename prototyped declarations for all functions -declared and/or defined in a translation unit, including those in header -files. This option is silently ignored in any language other than C. -.Sp -Besides declarations, the file indicates, in comments, the origin of -each declaration (source file and line), whether the declaration was -implicit, prototyped or unprototyped (\fBI\fR, \fBN\fR for new or -\&\fBO\fR for old, respectively, in the first character after the line -number and the colon), and whether it came from a declaration or a -definition (\fBC\fR or \fBF\fR, respectively, in the following -character). In the case of function definitions, a K&R\-style list of -arguments followed by their declarations is also provided, inside -comments, after the declaration. -.IP "\fB\-fno\-asm\fR" 4 -.IX Item "-fno-asm" -Do not recognize \f(CW\*(C`asm\*(C'\fR, \f(CW\*(C`inline\*(C'\fR or \f(CW\*(C`typeof\*(C'\fR as a -keyword, so that code can use these words as identifiers. You can use -the keywords \f(CW\*(C`_\|_asm_\|_\*(C'\fR, \f(CW\*(C`_\|_inline_\|_\*(C'\fR and \f(CW\*(C`_\|_typeof_\|_\*(C'\fR -instead. \fB\-ansi\fR implies \fB\-fno\-asm\fR. -.Sp -In \*(C+, this switch only affects the \f(CW\*(C`typeof\*(C'\fR keyword, since -\&\f(CW\*(C`asm\*(C'\fR and \f(CW\*(C`inline\*(C'\fR are standard keywords. You may want to -use the \fB\-fno\-gnu\-keywords\fR flag instead, which has the same -effect. In C99 mode (\fB\-std=c99\fR or \fB\-std=gnu99\fR), this -switch only affects the \f(CW\*(C`asm\*(C'\fR and \f(CW\*(C`typeof\*(C'\fR keywords, since -\&\f(CW\*(C`inline\*(C'\fR is a standard keyword in \s-1ISO\s0 C99. -.IP "\fB\-fno\-builtin\fR" 4 -.IX Item "-fno-builtin" -.PD 0 -.IP "\fB\-fno\-builtin\-\fR\fIfunction\fR" 4 -.IX Item "-fno-builtin-function" -.PD -Don't recognize built-in functions that do not begin with -\&\fB_\|_builtin_\fR as prefix. -.Sp -\&\s-1GCC\s0 normally generates special code to handle certain built-in functions -more efficiently; for instance, calls to \f(CW\*(C`alloca\*(C'\fR may become single -instructions that adjust the stack directly, and calls to \f(CW\*(C`memcpy\*(C'\fR -may become inline copy loops. The resulting code is often both smaller -and faster, but since the function calls no longer appear as such, you -cannot set a breakpoint on those calls, nor can you change the behavior -of the functions by linking with a different library. -.Sp -With the \fB\-fno\-builtin\-\fR\fIfunction\fR option -only the built-in function \fIfunction\fR is -disabled. \fIfunction\fR must not begin with \fB_\|_builtin_\fR. If a -function is named this is not built-in in this version of \s-1GCC\s0, this -option is ignored. There is no corresponding -\&\fB\-fbuiltin\-\fR\fIfunction\fR option; if you wish to enable -built-in functions selectively when using \fB\-fno\-builtin\fR or -\&\fB\-ffreestanding\fR, you may define macros such as: -.Sp -.Vb 2 -\& #define abs(n) __builtin_abs ((n)) -\& #define strcpy(d, s) __builtin_strcpy ((d), (s)) -.Ve -.IP "\fB\-fhosted\fR" 4 -.IX Item "-fhosted" -Assert that compilation takes place in a hosted environment. This implies -\&\fB\-fbuiltin\fR. A hosted environment is one in which the -entire standard library is available, and in which \f(CW\*(C`main\*(C'\fR has a return -type of \f(CW\*(C`int\*(C'\fR. Examples are nearly everything except a kernel. -This is equivalent to \fB\-fno\-freestanding\fR. -.IP "\fB\-ffreestanding\fR" 4 -.IX Item "-ffreestanding" -Assert that compilation takes place in a freestanding environment. This -implies \fB\-fno\-builtin\fR. A freestanding environment -is one in which the standard library may not exist, and program startup may -not necessarily be at \f(CW\*(C`main\*(C'\fR. The most obvious example is an \s-1OS\s0 kernel. -This is equivalent to \fB\-fno\-hosted\fR. -.IP "\fB\-fms\-extensions\fR" 4 -.IX Item "-fms-extensions" -Accept some non-standard constructs used in Microsoft header files. -.IP "\fB\-trigraphs\fR" 4 -.IX Item "-trigraphs" -Support \s-1ISO\s0 C trigraphs. The \fB\-ansi\fR option (and \fB\-std\fR -options for strict \s-1ISO\s0 C conformance) implies \fB\-trigraphs\fR. -.IP "\fB\-no\-integrated\-cpp\fR" 4 -.IX Item "-no-integrated-cpp" -Performs a compilation in two passes: preprocessing and compiling. This -option allows a user supplied \*(L"cc1\*(R", \*(L"cc1plus\*(R", or \*(L"cc1obj\*(R" via the -\&\fB\-B\fR option. The user supplied compilation step can then add in -an additional preprocessing step after normal preprocessing but before -compiling. The default is to use the integrated cpp (internal cpp) -.Sp -The semantics of this option will change if \*(L"cc1\*(R", \*(L"cc1plus\*(R", and -\&\*(L"cc1obj\*(R" are merged. -.IP "\fB\-traditional\fR" 4 -.IX Item "-traditional" -.PD 0 -.IP "\fB\-traditional\-cpp\fR" 4 -.IX Item "-traditional-cpp" -.PD -Formerly, these options caused \s-1GCC\s0 to attempt to emulate a pre-standard -C compiler. They are now only supported with the \fB\-E\fR switch. -The preprocessor continues to support a pre-standard mode. See the \s-1GNU\s0 -\&\s-1CPP\s0 manual for details. -.IP "\fB\-fcond\-mismatch\fR" 4 -.IX Item "-fcond-mismatch" -Allow conditional expressions with mismatched types in the second and -third arguments. The value of such an expression is void. This option -is not supported for \*(C+. -.IP "\fB\-funsigned\-char\fR" 4 -.IX Item "-funsigned-char" -Let the type \f(CW\*(C`char\*(C'\fR be unsigned, like \f(CW\*(C`unsigned char\*(C'\fR. -.Sp -Each kind of machine has a default for what \f(CW\*(C`char\*(C'\fR should -be. It is either like \f(CW\*(C`unsigned char\*(C'\fR by default or like -\&\f(CW\*(C`signed char\*(C'\fR by default. -.Sp -Ideally, a portable program should always use \f(CW\*(C`signed char\*(C'\fR or -\&\f(CW\*(C`unsigned char\*(C'\fR when it depends on the signedness of an object. -But many programs have been written to use plain \f(CW\*(C`char\*(C'\fR and -expect it to be signed, or expect it to be unsigned, depending on the -machines they were written for. This option, and its inverse, let you -make such a program work with the opposite default. -.Sp -The type \f(CW\*(C`char\*(C'\fR is always a distinct type from each of -\&\f(CW\*(C`signed char\*(C'\fR or \f(CW\*(C`unsigned char\*(C'\fR, even though its behavior -is always just like one of those two. -.IP "\fB\-fsigned\-char\fR" 4 -.IX Item "-fsigned-char" -Let the type \f(CW\*(C`char\*(C'\fR be signed, like \f(CW\*(C`signed char\*(C'\fR. -.Sp -Note that this is equivalent to \fB\-fno\-unsigned\-char\fR, which is -the negative form of \fB\-funsigned\-char\fR. Likewise, the option -\&\fB\-fno\-signed\-char\fR is equivalent to \fB\-funsigned\-char\fR. -.IP "\fB\-fsigned\-bitfields\fR" 4 -.IX Item "-fsigned-bitfields" -.PD 0 -.IP "\fB\-funsigned\-bitfields\fR" 4 -.IX Item "-funsigned-bitfields" -.IP "\fB\-fno\-signed\-bitfields\fR" 4 -.IX Item "-fno-signed-bitfields" -.IP "\fB\-fno\-unsigned\-bitfields\fR" 4 -.IX Item "-fno-unsigned-bitfields" -.PD -These options control whether a bit-field is signed or unsigned, when the -declaration does not use either \f(CW\*(C`signed\*(C'\fR or \f(CW\*(C`unsigned\*(C'\fR. By -default, such a bit-field is signed, because this is consistent: the -basic integer types such as \f(CW\*(C`int\*(C'\fR are signed types. -.IP "\fB\-fwritable\-strings\fR" 4 -.IX Item "-fwritable-strings" -Store string constants in the writable data segment and don't uniquize -them. This is for compatibility with old programs which assume they can -write into string constants. -.Sp -Writing into string constants is a very bad idea; ``constants'' should -be constant. -.Sh "Options Controlling \*(C+ Dialect" -.IX Subsection "Options Controlling Dialect" -This section describes the command-line options that are only meaningful -for \*(C+ programs; but you can also use most of the \s-1GNU\s0 compiler options -regardless of what language your program is in. For example, you -might compile a file \f(CW\*(C`firstClass.C\*(C'\fR like this: -.PP -.Vb 1 -\& g++ -g -frepo -O -c firstClass.C -.Ve -.PP -In this example, only \fB\-frepo\fR is an option meant -only for \*(C+ programs; you can use the other options with any -language supported by \s-1GCC\s0. -.PP -Here is a list of options that are \fIonly\fR for compiling \*(C+ programs: -.IP "\fB\-fabi\-version=\fR\fIn\fR" 4 -.IX Item "-fabi-version=n" -Use version \fIn\fR of the \*(C+ \s-1ABI\s0. Version 1 is the version of the \*(C+ -\&\s-1ABI\s0 that first appeared in G++ 3.2. Version 0 will always be the -version that conforms most closely to the \*(C+ \s-1ABI\s0 specification. -Therefore, the \s-1ABI\s0 obtained using version 0 will change as \s-1ABI\s0 bugs are -fixed. -.Sp -The default is version 1. -.IP "\fB\-fno\-access\-control\fR" 4 -.IX Item "-fno-access-control" -Turn off all access checking. This switch is mainly useful for working -around bugs in the access control code. -.IP "\fB\-fcheck\-new\fR" 4 -.IX Item "-fcheck-new" -Check that the pointer returned by \f(CW\*(C`operator new\*(C'\fR is non-null -before attempting to modify the storage allocated. This check is -normally unnecessary because the \*(C+ standard specifies that -\&\f(CW\*(C`operator new\*(C'\fR will only return \f(CW0\fR if it is declared -\&\fB\f(BIthrow()\fB\fR, in which case the compiler will always check the -return value even without this option. In all other cases, when -\&\f(CW\*(C`operator new\*(C'\fR has a non-empty exception specification, memory -exhaustion is signalled by throwing \f(CW\*(C`std::bad_alloc\*(C'\fR. See also -\&\fBnew (nothrow)\fR. -.IP "\fB\-fconserve\-space\fR" 4 -.IX Item "-fconserve-space" -Put uninitialized or runtime-initialized global variables into the -common segment, as C does. This saves space in the executable at the -cost of not diagnosing duplicate definitions. If you compile with this -flag and your program mysteriously crashes after \f(CW\*(C`main()\*(C'\fR has -completed, you may have an object that is being destroyed twice because -two definitions were merged. -.Sp -This option is no longer useful on most targets, now that support has -been added for putting variables into \s-1BSS\s0 without making them common. -.IP "\fB\-fno\-const\-strings\fR" 4 -.IX Item "-fno-const-strings" -Give string constants type \f(CW\*(C`char *\*(C'\fR instead of type \f(CW\*(C`const -char *\*(C'\fR. By default, G++ uses type \f(CW\*(C`const char *\*(C'\fR as required by -the standard. Even if you use \fB\-fno\-const\-strings\fR, you cannot -actually modify the value of a string constant, unless you also use -\&\fB\-fwritable\-strings\fR. -.Sp -This option might be removed in a future release of G++. For maximum -portability, you should structure your code so that it works with -string constants that have type \f(CW\*(C`const char *\*(C'\fR. -.IP "\fB\-fdollars\-in\-identifiers\fR" 4 -.IX Item "-fdollars-in-identifiers" -Accept \fB$\fR in identifiers. You can also explicitly prohibit use of -\&\fB$\fR with the option \fB\-fno\-dollars\-in\-identifiers\fR. (\s-1GNU\s0 C allows -\&\fB$\fR by default on most target systems, but there are a few exceptions.) -Traditional C allowed the character \fB$\fR to form part of -identifiers. However, \s-1ISO\s0 C and \*(C+ forbid \fB$\fR in identifiers. -.IP "\fB\-fno\-elide\-constructors\fR" 4 -.IX Item "-fno-elide-constructors" -The \*(C+ standard allows an implementation to omit creating a temporary -which is only used to initialize another object of the same type. -Specifying this option disables that optimization, and forces G++ to -call the copy constructor in all cases. -.IP "\fB\-fno\-enforce\-eh\-specs\fR" 4 -.IX Item "-fno-enforce-eh-specs" -Don't check for violation of exception specifications at runtime. This -option violates the \*(C+ standard, but may be useful for reducing code -size in production builds, much like defining \fB\s-1NDEBUG\s0\fR. The compiler -will still optimize based on the exception specifications. -.IP "\fB\-fexternal\-templates\fR" 4 -.IX Item "-fexternal-templates" -Cause \fB#pragma interface\fR and \fBimplementation\fR to apply to -template instantiation; template instances are emitted or not according -to the location of the template definition. -.Sp -This option is deprecated. -.IP "\fB\-falt\-external\-templates\fR" 4 -.IX Item "-falt-external-templates" -Similar to \fB\-fexternal\-templates\fR, but template instances are -emitted or not according to the place where they are first instantiated. -.Sp -This option is deprecated. -.IP "\fB\-ffor\-scope\fR" 4 -.IX Item "-ffor-scope" -.PD 0 -.IP "\fB\-fno\-for\-scope\fR" 4 -.IX Item "-fno-for-scope" -.PD -If \fB\-ffor\-scope\fR is specified, the scope of variables declared in -a \fIfor-init-statement\fR is limited to the \fBfor\fR loop itself, -as specified by the \*(C+ standard. -If \fB\-fno\-for\-scope\fR is specified, the scope of variables declared in -a \fIfor-init-statement\fR extends to the end of the enclosing scope, -as was the case in old versions of G++, and other (traditional) -implementations of \*(C+. -.Sp -The default if neither flag is given to follow the standard, -but to allow and give a warning for old-style code that would -otherwise be invalid, or have different behavior. -.IP "\fB\-fno\-gnu\-keywords\fR" 4 -.IX Item "-fno-gnu-keywords" -Do not recognize \f(CW\*(C`typeof\*(C'\fR as a keyword, so that code can use this -word as an identifier. You can use the keyword \f(CW\*(C`_\|_typeof_\|_\*(C'\fR instead. -\&\fB\-ansi\fR implies \fB\-fno\-gnu\-keywords\fR. -.IP "\fB\-fno\-implicit\-templates\fR" 4 -.IX Item "-fno-implicit-templates" -Never emit code for non-inline templates which are instantiated -implicitly (i.e. by use); only emit code for explicit instantiations. -.IP "\fB\-fno\-implicit\-inline\-templates\fR" 4 -.IX Item "-fno-implicit-inline-templates" -Don't emit code for implicit instantiations of inline templates, either. -The default is to handle inlines differently so that compiles with and -without optimization will need the same set of explicit instantiations. -.IP "\fB\-fno\-implement\-inlines\fR" 4 -.IX Item "-fno-implement-inlines" -To save space, do not emit out-of-line copies of inline functions -controlled by \fB#pragma implementation\fR. This will cause linker -errors if these functions are not inlined everywhere they are called. -.IP "\fB\-fms\-extensions\fR" 4 -.IX Item "-fms-extensions" -Disable pedantic warnings about constructs used in \s-1MFC\s0, such as implicit -int and getting a pointer to member function via non-standard syntax. -.IP "\fB\-fno\-nonansi\-builtins\fR" 4 -.IX Item "-fno-nonansi-builtins" -Disable built-in declarations of functions that are not mandated by -\&\s-1ANSI/ISO\s0 C. These include \f(CW\*(C`ffs\*(C'\fR, \f(CW\*(C`alloca\*(C'\fR, \f(CW\*(C`_exit\*(C'\fR, -\&\f(CW\*(C`index\*(C'\fR, \f(CW\*(C`bzero\*(C'\fR, \f(CW\*(C`conjf\*(C'\fR, and other related functions. -.IP "\fB\-fno\-operator\-names\fR" 4 -.IX Item "-fno-operator-names" -Do not treat the operator name keywords \f(CW\*(C`and\*(C'\fR, \f(CW\*(C`bitand\*(C'\fR, -\&\f(CW\*(C`bitor\*(C'\fR, \f(CW\*(C`compl\*(C'\fR, \f(CW\*(C`not\*(C'\fR, \f(CW\*(C`or\*(C'\fR and \f(CW\*(C`xor\*(C'\fR as -synonyms as keywords. -.IP "\fB\-fno\-optional\-diags\fR" 4 -.IX Item "-fno-optional-diags" -Disable diagnostics that the standard says a compiler does not need to -issue. Currently, the only such diagnostic issued by G++ is the one for -a name having multiple meanings within a class. -.IP "\fB\-fpermissive\fR" 4 -.IX Item "-fpermissive" -Downgrade some diagnostics about nonconformant code from errors to -warnings. Thus, using \fB\-fpermissive\fR will allow some -nonconforming code to compile. -.IP "\fB\-frepo\fR" 4 -.IX Item "-frepo" -Enable automatic template instantiation at link time. This option also -implies \fB\-fno\-implicit\-templates\fR. -.IP "\fB\-fno\-rtti\fR" 4 -.IX Item "-fno-rtti" -Disable generation of information about every class with virtual -functions for use by the \*(C+ runtime type identification features -(\fBdynamic_cast\fR and \fBtypeid\fR). If you don't use those parts -of the language, you can save some space by using this flag. Note that -exception handling uses the same information, but it will generate it as -needed. -.IP "\fB\-fstats\fR" 4 -.IX Item "-fstats" -Emit statistics about front-end processing at the end of the compilation. -This information is generally only useful to the G++ development team. -.IP "\fB\-ftemplate\-depth\-\fR\fIn\fR" 4 -.IX Item "-ftemplate-depth-n" -Set the maximum instantiation depth for template classes to \fIn\fR. -A limit on the template instantiation depth is needed to detect -endless recursions during template class instantiation. \s-1ANSI/ISO\s0 \*(C+ -conforming programs must not rely on a maximum depth greater than 17. -.IP "\fB\-fuse\-cxa\-atexit\fR" 4 -.IX Item "-fuse-cxa-atexit" -Register destructors for objects with static storage duration with the -\&\f(CW\*(C`_\|_cxa_atexit\*(C'\fR function rather than the \f(CW\*(C`atexit\*(C'\fR function. -This option is required for fully standards-compliant handling of static -destructors, but will only work if your C library supports -\&\f(CW\*(C`_\|_cxa_atexit\*(C'\fR. -.IP "\fB\-fvtable\-gc\fR" 4 -.IX Item "-fvtable-gc" -Emit special relocations for vtables and virtual function references -so that the linker can identify unused virtual functions and zero out -vtable slots that refer to them. This is most useful with -\&\fB\-ffunction\-sections\fR and \fB\-Wl,\-\-gc\-sections\fR, in order to -also discard the functions themselves. -.Sp -This optimization requires \s-1GNU\s0 as and \s-1GNU\s0 ld. Not all systems support -this option. \fB\-Wl,\-\-gc\-sections\fR is ignored without \fB\-static\fR. -.IP "\fB\-fno\-weak\fR" 4 -.IX Item "-fno-weak" -Do not use weak symbol support, even if it is provided by the linker. -By default, G++ will use weak symbols if they are available. This -option exists only for testing, and should not be used by end\-users; -it will result in inferior code and has no benefits. This option may -be removed in a future release of G++. -.IP "\fB\-nostdinc++\fR" 4 -.IX Item "-nostdinc++" -Do not search for header files in the standard directories specific to -\&\*(C+, but do still search the other standard directories. (This option -is used when building the \*(C+ library.) -.PP -In addition, these optimization, warning, and code generation options -have meanings only for \*(C+ programs: -.IP "\fB\-fno\-default\-inline\fR" 4 -.IX Item "-fno-default-inline" -Do not assume \fBinline\fR for functions defined inside a class scope. - Note that these -functions will have linkage like inline functions; they just won't be -inlined by default. -.IP "\fB\-Wabi\fR (\*(C+ only)" 4 -.IX Item "-Wabi ( only)" -Warn when G++ generates code that is probably not compatible with the -vendor-neutral \*(C+ \s-1ABI\s0. Although an effort has been made to warn about -all such cases, there are probably some cases that are not warned about, -even though G++ is generating incompatible code. There may also be -cases where warnings are emitted even though the code that is generated -will be compatible. -.Sp -You should rewrite your code to avoid these warnings if you are -concerned about the fact that code generated by G++ may not be binary -compatible with code generated by other compilers. -.Sp -The known incompatibilities at this point include: -.RS 4 -.IP "*" 4 -Incorrect handling of tail-padding for bit\-fields. G++ may attempt to -pack data into the same byte as a base class. For example: -.Sp -.Vb 2 -\& struct A { virtual void f(); int f1 : 1; }; -\& struct B : public A { int f2 : 1; }; -.Ve -.Sp -In this case, G++ will place \f(CW\*(C`B::f2\*(C'\fR into the same byte -as\f(CW\*(C`A::f1\*(C'\fR; other compilers will not. You can avoid this problem -by explicitly padding \f(CW\*(C`A\*(C'\fR so that its size is a multiple of the -byte size on your platform; that will cause G++ and other compilers to -layout \f(CW\*(C`B\*(C'\fR identically. -.IP "*" 4 -Incorrect handling of tail-padding for virtual bases. G++ does not use -tail padding when laying out virtual bases. For example: -.Sp -.Vb 3 -\& struct A { virtual void f(); char c1; }; -\& struct B { B(); char c2; }; -\& struct C : public A, public virtual B {}; -.Ve -.Sp -In this case, G++ will not place \f(CW\*(C`B\*(C'\fR into the tail-padding for -\&\f(CW\*(C`A\*(C'\fR; other compilers will. You can avoid this problem by -explicitly padding \f(CW\*(C`A\*(C'\fR so that its size is a multiple of its -alignment (ignoring virtual base classes); that will cause G++ and other -compilers to layout \f(CW\*(C`C\*(C'\fR identically. -.IP "*" 4 -Incorrect handling of bit-fields with declared widths greater than that -of their underlying types, when the bit-fields appear in a union. For -example: -.Sp -.Vb 1 -\& union U { int i : 4096; }; -.Ve -.Sp -Assuming that an \f(CW\*(C`int\*(C'\fR does not have 4096 bits, G++ will make the -union too small by the number of bits in an \f(CW\*(C`int\*(C'\fR. -.IP "*" 4 -Empty classes can be placed at incorrect offsets. For example: -.Sp -.Vb 1 -\& struct A {}; -.Ve -.Sp -.Vb 4 -\& struct B { -\& A a; -\& virtual void f (); -\& }; -.Ve -.Sp -.Vb 1 -\& struct C : public B, public A {}; -.Ve -.Sp -G++ will place the \f(CW\*(C`A\*(C'\fR base class of \f(CW\*(C`C\*(C'\fR at a nonzero offset; -it should be placed at offset zero. G++ mistakenly believes that the -\&\f(CW\*(C`A\*(C'\fR data member of \f(CW\*(C`B\*(C'\fR is already at offset zero. -.IP "*" 4 -Names of template functions whose types involve \f(CW\*(C`typename\*(C'\fR or -template template parameters can be mangled incorrectly. -.Sp -.Vb 2 -\& template -\& void f(typename Q::X) {} -.Ve -.Sp -.Vb 2 -\& template