diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f25022bc2f8..1aa9d98ee61 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,41 @@ +2003-12-31 Kazuhiro Inaoka + + * config.gcc: Added m32r-linux m32rle-elf and m32le-linux targets. + * doc/invoke.texi: Document -mflush-func, -mflush-trap options. + Also add documentation for -mdebug, -malign-loops, -missue-rate, + and -mbranch-cost options. + * config/m32r/t-linux: New file: m32r-linux support. + * config/m32r/xm-linux.h: Likewise. + * config/m32r/xm-m32r.h: Likewise. + * config/m32r/linux.h: Likewise. + * config/m32r/little.h: New file: Little endian code generation + support. + * config/m32r/m32r-protos.h (m32r_legitimize_pic_address, + m32r_legitimate_pic_operand_p, load_pic_register): Add + prototypes. + * config/m32r/m32r.c (m32r_init): Add options for cache-flush. + (addr24_operand): Changes for PIC code generation. + * config/m32r/m32r.h (LABEL_ALIGN): Define to calculate PNOP + length at labels. + (ASM_SPEC): Add PIC support. + (FUNCTION_PROFILER): New define. + (TRAMPOLINE_SIZE, INITIALIZE_TRAMPOLINE): Changed to support + trampoline. + (CONDITIONAL_REGISTER_USAGE, CONSTANT_ADDRESS_P, + LEGITIMIZE_ADDRESS, JUMP_TABLES_IN_TEXT_SECTION, + PIC_OFFSET_TABLE_REGNUM, FINALIZE_PIC, LEGITIMATE_PIC_OPERAND_P, + ASM_OUTPUT_ADDR_DIFF_ELT, CASE_VECTOR_MODE): Define for PIC. + (move_src_operand, m32r_compute_frame_size, m32r_expand_prologue, + m32r_finalize_pic): Changes for PIC and profile support. + (global_offset_table, load_pic_register, m32r_legitimate_pic_operand_p, + m32r_legitimize_pic_address): Add for PIC support. + (m32r_file_start): Changed for little-endian-target. + * config/m32r/m32r.md (mvqi, movhi, movsi, movdi, movsf, movdf, + tablejump, tablejump_insn, call, call_value, call_value_via_label): + Changes for PIC. + (pic_load_addr, get_pc, builtin_setjmp_receiver): Added for PIC. + (flush_icache): Changes for cache-flush trap. + 2003-12-30 Kazu Hirata * config/i386/i386.h: Remove an unnecessary #undef. diff --git a/gcc/config.gcc b/gcc/config.gcc index 168a235f1f8..b4e750a5d0a 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -279,6 +279,9 @@ ia64-*-*) hppa*-*-* | parisc*-*-*) cpu_type=pa ;; +m32r*-*-*) + cpu_type=m32r + ;; m680[012]0-*-*) cpu_type=m68k extra_headers=math-68881.h @@ -1279,6 +1282,31 @@ m32r-*-elf*) extra_parts="crtinit.o crtfini.o" use_fixproto=yes ;; +m32rle-*-elf*) + tm_file="dbxelf.h elfos.h svr4.h m32r/little.h ${tm_file}" + extra_parts="crtinit.o crtfini.o m32rx/crtinit.o m32rx/crtfini.o" + use_fixproto=yes + ;; +m32r-*-linux*) + tm_file="dbxelf.h elfos.h svr4.h linux.h ${tm_file} m32r/linux.h" + extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" + tmake_file="m32r/t-linux" + gnu_ld=yes + use_fixproto=yes + if test x$enable_threads = xyes; then + thread_file='posix' + fi + ;; +m32rle-*-linux*) + tm_file="dbxelf.h elfos.h svr4.h linux.h m32r/little.h ${tm_file} m32r/linux.h" + extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" + tmake_file="m32r/t-linux" + gnu_ld=yes + use_fixproto=yes + if test x$enable_threads = xyes; then + thread_file='posix' + fi + ;; # m68hc11 and m68hc12 share the same machine description. m68hc11-*-*|m6811-*-*) tm_file="dbxelf.h elfos.h m68hc11/m68hc11.h" diff --git a/gcc/config/m32r/linux.h b/gcc/config/m32r/linux.h new file mode 100644 index 00000000000..b7da5bf8ce5 --- /dev/null +++ b/gcc/config/m32r/linux.h @@ -0,0 +1,104 @@ +/* Definitions for Renesas M32R running Linux-based GNU systems using ELF. + Copyright (C) 2003 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. */ + +#define LINUX_DEFAULT_ELF + +/* A lie, I guess, but the general idea behind linux/ELF is that we are + supposed to be outputting something that will assemble under SVr4. + This gets us pretty close. */ + +#define HANDLE_SYSV_PRAGMA + +#undef HANDLE_PRAGMA_PACK + +#undef TARGET_VERSION +#define TARGET_VERSION fprintf (stderr, " (M32R GNU/Linux with ELF)"); + +#undef SIZE_TYPE +#define SIZE_TYPE "unsigned int" + +#undef PTRDIFF_TYPE +#define PTRDIFF_TYPE "int" + +#undef WCHAR_TYPE +#define WCHAR_TYPE "long int" + +#undef WCHAR_TYPE_SIZE +#define WCHAR_TYPE_SIZE BITS_PER_WORD + +/* Provide a LINK_SPEC appropriate for Linux. Here we provide support + for the special GCC options -static and -shared, which allow us to + link things in one of these three modes by applying the appropriate + combinations of options at link-time. We like to support here for + as many of the other GNU linker options as possible. But I don't + have the time to search for those flags. I am sure how to add + support for -soname shared_object_name. H.J. + + I took out %{v:%{!V:-V}}. It is too much :-(. They can use + -Wl,-V. + + When the -shared link option is used a final link is not being + done. */ + +/* If ELF is the default format, we should not use /lib/elf. */ + +#undef LINK_SPEC +#if TARGET_LITTLE_ENDIAN +#define LINK_SPEC "%(link_cpu) -m m32rlelf_linux %{shared:-shared} \ + %{!shared: \ + %{!ibcs: \ + %{!static: \ + %{rdynamic:-export-dynamic} \ + %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \ + %{static:-static}}}" +#else +#define LINK_SPEC "%(link_cpu) -m m32relf_linux %{shared:-shared} \ + %{!shared: \ + %{!ibcs: \ + %{!static: \ + %{rdynamic:-export-dynamic} \ + %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \ + %{static:-static}}}" +#endif + +#undef LIB_SPEC +#define LIB_SPEC \ + "%{shared: -lc} \ + %{!shared: %{mieee-fp:-lieee} %{pthread:-lpthread} \ + %{profile:-lc_p} %{!profile: -lc}}" + +#undef STARTFILE_SPEC +#define STARTFILE_SPEC \ + "%{!shared: \ + %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}}\ + crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}" + +#undef ENDFILE_SPEC +#define ENDFILE_SPEC \ + "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s" + +#undef SUBTARGET_CPP_SPEC +#define SUBTARGET_CPP_SPEC "\ + %{posix:-D_POSIX_SOURCE} \ + %{pthread:-D_REENTRANT -D_PTHREADS} \ +" + +#define TARGET_OS_CPP_BUILTINS() LINUX_TARGET_OS_CPP_BUILTINS() + diff --git a/gcc/config/m32r/little.h b/gcc/config/m32r/little.h new file mode 100644 index 00000000000..793cf243863 --- /dev/null +++ b/gcc/config/m32r/little.h @@ -0,0 +1,34 @@ +/* Definitions for Renesas little endian M32R cpu. + Copyright (C) 2003 + Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. */ + +#define TARGET_LITTLE_ENDIAN (!TARGET_BIG_ENDIAN) + +#define CPP_ENDIAN_SPEC \ + " %{mbe:-D__BIG_ENDIAN__} %{mbig-endian:-D__BIG_ENDIAN__}" \ + " %{!mbe: %{!mbig-endian:-D__LITTLE_ENDIAN__}}" + +#define CC1_ENDIAN_SPEC " %{!mbe: %{!mbig-endian:-mle}}" + +#define ASM_ENDIAN_SPEC \ + " %{!mbe: %{!mbig-endian:-EL}} %{mbe:-EB} %{mbig-endian:-EB}" + +#define LINK_ENDIAN_SPEC " %{!mbe: %{!mbig-endian:-EL}}" + diff --git a/gcc/config/m32r/m32r-protos.h b/gcc/config/m32r/m32r-protos.h index cdd9db3296a..603c0bd51f8 100644 --- a/gcc/config/m32r/m32r-protos.h +++ b/gcc/config/m32r/m32r-protos.h @@ -1,22 +1,22 @@ /* Prototypes for m32r.c functions used in the md file & elsewhere. - Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. -This file is part of GCC. + This file is part of GCC. -GCC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. -GCC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ /* Function prototypes that cannot exist in v850.h due to dependency complications. */ @@ -31,6 +31,8 @@ extern int m32r_first_insn_address (void); extern void m32r_expand_prologue (void); extern void m32r_finalize_pic (void); extern int direct_return (void); +extern void m32r_load_pic_register (void); + #ifdef TREE_CODE extern enum m32r_function_type m32r_compute_function_type (tree); @@ -55,6 +57,8 @@ extern void m32r_print_operand (FILE *, rtx, int); extern void m32r_print_operand_address (FILE *, rtx); extern int m32r_not_same_reg (rtx, rtx); extern int m32r_hard_regno_rename_ok (unsigned int, unsigned int); +extern int m32r_legitimate_pic_operand_p (rtx); +extern rtx m32r_legitimize_pic_address (rtx, rtx); #ifdef HAVE_MACHINE_MODES extern int call_address_operand (rtx, Mmode); diff --git a/gcc/config/m32r/m32r.c b/gcc/config/m32r/m32r.c index a5a2b26cf09..244264b5a53 100644 --- a/gcc/config/m32r/m32r.c +++ b/gcc/config/m32r/m32r.c @@ -68,6 +68,19 @@ static int m32r_sched_odd_word_p; /* For string literals, etc. */ #define LIT_NAME_P(NAME) ((NAME)[0] == '*' && (NAME)[1] == '.') +/* Cache-flush support. Cache-flush is used at trampoline. + Default cache-flush is "trap 12". + default cache-flush function is "_flush_cache" (CACHE_FLUSH_FUNC) + default cache-flush trap-interrupt number is "12". (CACHE_FLUSH_TRAP) + You can change how to generate code of cache-flush with following options. + -flush-func=FLUSH-FUNC-NAME + -no-flush-func + -fluch-trap=TRAP-NUMBER + -no-flush-trap. */ +const char *m32r_cache_flush_func = CACHE_FLUSH_FUNC; +const char *m32r_cache_flush_trap_string = CACHE_FLUSH_TRAP; +int m32r_cache_flush_trap = 12; + /* Forward declaration. */ static void init_reg_tables (void); static void block_move_call (rtx, rtx, rtx); @@ -166,6 +179,15 @@ m32r_init (void) m32r_sdata = M32R_SDATA_USE; else error ("bad value (%s) for -msdata switch", m32r_sdata_string); + + if (m32r_cache_flush_trap_string) + { + /* Change trap-number (12) for cache-flush to the others (0 - 15). */ + m32r_cache_flush_trap = atoi (m32r_cache_flush_trap_string); + if (m32r_cache_flush_trap < 0 || m32r_cache_flush_trap > 15) + error ("bad value (%s) for -flush-trap=n (0== -0x80 && (X) <= 0x7f) -#define INT16_P(X) ((X) >= -0x8000 && (X) <= 0x7fff) -#define CMP_INT16_P(X) ((X) >= -0x7fff && (X) <= 0x8000) -#define UPPER16_P(X) (((X) & 0xffff) == 0 \ - && ((X) >> 16) >= -0x8000 \ - && ((X) >> 16) <= 0x7fff) -#define UINT16_P(X) (((unsigned HOST_WIDE_INT) (X)) <= 0x0000ffff) -#define UINT24_P(X) (((unsigned HOST_WIDE_INT) (X)) <= 0x00ffffff) -#define UINT32_P(X) (((unsigned HOST_WIDE_INT) (X)) <= 0xffffffff) -#define UINT5_P(X) ((X) >= 0 && (X) < 32) +#define INT8_P(X) ((X) >= - 0x80 && (X) <= 0x7f) +#define INT16_P(X) ((X) >= - 0x8000 && (X) <= 0x7fff) +#define CMP_INT16_P(X) ((X) >= - 0x7fff && (X) <= 0x8000) +#define UPPER16_P(X) (((X) & 0xffff) == 0 \ + && ((X) >> 16) >= - 0x8000 \ + && ((X) >> 16) <= 0x7fff) +#define UINT16_P(X) (((unsigned HOST_WIDE_INT) (X)) <= 0x0000ffff) +#define UINT24_P(X) (((unsigned HOST_WIDE_INT) (X)) <= 0x00ffffff) +#define UINT32_P(X) (((unsigned HOST_WIDE_INT) (X)) <= 0xffffffff) +#define UINT5_P(X) ((X) >= 0 && (X) < 32) #define INVERTED_SIGNED_8BIT(VAL) ((VAL) >= -127 && (VAL) <= 128) #define CONST_OK_FOR_LETTER_P(VALUE, C) \ -((C) == 'I' ? INT8_P (VALUE) \ - : (C) == 'J' ? INT16_P (VALUE) \ - : (C) == 'K' ? UINT16_P (VALUE) \ - : (C) == 'L' ? UPPER16_P (VALUE) \ - : (C) == 'M' ? UINT24_P (VALUE) \ - : (C) == 'N' ? INVERTED_SIGNED_8BIT (VALUE) \ - : (C) == 'O' ? UINT5_P (VALUE) \ - : (C) == 'P' ? CMP_INT16_P (VALUE) \ - : 0) + ( (C) == 'I' ? INT8_P (VALUE) \ + : (C) == 'J' ? INT16_P (VALUE) \ + : (C) == 'K' ? UINT16_P (VALUE) \ + : (C) == 'L' ? UPPER16_P (VALUE) \ + : (C) == 'M' ? UINT24_P (VALUE) \ + : (C) == 'N' ? INVERTED_SIGNED_8BIT (VALUE) \ + : (C) == 'O' ? UINT5_P (VALUE) \ + : (C) == 'P' ? CMP_INT16_P (VALUE) \ + : 0) /* Similar, but for floating constants, and defining letters G and H. Here VALUE is the CONST_DOUBLE rtx itself. For the m32r, handle a few constants inline. ??? We needn't treat DI and DF modes differently, but for now we do. */ -#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \ -((C) == 'G' ? easy_di_const (VALUE) \ - : (C) == 'H' ? easy_df_const (VALUE) \ - : 0) +#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \ + ( (C) == 'G' ? easy_di_const (VALUE) \ + : (C) == 'H' ? easy_df_const (VALUE) \ + : 0) /* A C expression that defines the optional machine-dependent constraint letters that can be used to segregate specific types of operands, @@ -839,19 +882,19 @@ extern enum reg_class m32r_regno_reg_class[FIRST_PSEUDO_REGISTER]; U is for loads with post increment. */ #define EXTRA_CONSTRAINT(VALUE, C) \ -( (C) == 'Q' ? ((TARGET_ADDR24 && GET_CODE (VALUE) == LABEL_REF) \ + ( (C) == 'Q' ? ((TARGET_ADDR24 && GET_CODE (VALUE) == LABEL_REF) \ || addr24_operand (VALUE, VOIDmode)) \ - : (C) == 'R' ? ((TARGET_ADDR32 && GET_CODE (VALUE) == LABEL_REF) \ + : (C) == 'R' ? ((TARGET_ADDR32 && GET_CODE (VALUE) == LABEL_REF) \ || addr32_operand (VALUE, VOIDmode)) \ - : (C) == 'S' ? (GET_CODE (VALUE) == MEM \ + : (C) == 'S' ? (GET_CODE (VALUE) == MEM \ && STORE_PREINC_PREDEC_P (GET_MODE (VALUE), \ XEXP (VALUE, 0))) \ - : (C) == 'T' ? (GET_CODE (VALUE) == MEM \ + : (C) == 'T' ? (GET_CODE (VALUE) == MEM \ && memreg_operand (VALUE, GET_MODE (VALUE))) \ - : (C) == 'U' ? (GET_CODE (VALUE) == MEM \ + : (C) == 'U' ? (GET_CODE (VALUE) == MEM \ && LOAD_POSTINC_P (GET_MODE (VALUE), \ XEXP (VALUE, 0))) \ - : 0) + : 0) /* Stack layout and stack pointer usage. */ @@ -859,12 +902,6 @@ extern enum reg_class m32r_regno_reg_class[FIRST_PSEUDO_REGISTER]; pointer to a smaller address. */ #define STACK_GROWS_DOWNWARD -/* Define this if the nominal address of the stack frame - is at the high-address end of the local variables; - that is, each additional local variable allocated - goes at a more negative offset from the frame pointer. */ -/*#define FRAME_GROWS_DOWNWARD*/ - /* Offset from frame pointer to start allocating local variables at. If FRAME_GROWS_DOWNWARD, this is the offset to the END of the first local allocated. Otherwise, it is the offset to the BEGINNING @@ -872,7 +909,7 @@ extern enum reg_class m32r_regno_reg_class[FIRST_PSEUDO_REGISTER]; /* The frame pointer points at the same place as the stack pointer, except if alloca has been called. */ #define STARTING_FRAME_OFFSET \ -M32R_STACK_ALIGN (current_function_outgoing_args_size) + M32R_STACK_ALIGN (current_function_outgoing_args_size) /* Offset from the stack pointer register to the first location at which outgoing arguments are placed. */ @@ -881,32 +918,6 @@ M32R_STACK_ALIGN (current_function_outgoing_args_size) /* Offset of first parameter from the argument pointer register value. */ #define FIRST_PARM_OFFSET(FNDECL) 0 -/* A C expression whose value is RTL representing the address in a - stack frame where the pointer to the caller's frame is stored. - Assume that FRAMEADDR is an RTL expression for the address of the - stack frame itself. - - If you don't define this macro, the default is to return the value - of FRAMEADDR--that is, the stack frame address is also the address - of the stack word that points to the previous frame. */ -/*define DYNAMIC_CHAIN_ADDRESS (FRAMEADDR)*/ - -/* A C expression whose value is RTL representing the value of the - return address for the frame COUNT steps up from the current frame. - FRAMEADDR is the frame pointer of the COUNT frame, or the frame - pointer of the COUNT - 1 frame if `RETURN_ADDR_IN_PREVIOUS_FRAME' - is defined. */ -/* The current return address is in r14. */ -#if 0 /* The default value should work. */ -#define RETURN_ADDR_RTX(COUNT, FRAME) \ -(((COUNT) == -1) \ - ? gen_rtx_REG (Pmode, 14) \ - : copy_to_reg (gen_rtx_MEM (Pmode, \ - memory_address (Pmode, \ - plus_constant ((FRAME), \ - UNITS_PER_WORD))))) -#endif - /* Register to use for pushing function arguments. */ #define STACK_POINTER_REGNUM 15 @@ -916,30 +927,17 @@ M32R_STACK_ALIGN (current_function_outgoing_args_size) /* Base register for access to arguments of the function. */ #define ARG_POINTER_REGNUM 16 -/* The register number of the return address pointer register, which - is used to access the current function's return address from the - stack. On some machines, the return address is not at a fixed - offset from the frame pointer or stack pointer or argument - pointer. This register can be defined to point to the return - address on the stack, and then be converted by `ELIMINABLE_REGS' - into either the frame pointer or stack pointer. - - Do not define this macro unless there is no other way to get the - return address from the stack. */ -/* ??? revisit */ -/* #define RETURN_ADDRESS_POINTER_REGNUM */ - -/* Register in which static-chain is passed to a function. This must - not be a register used by the prologue. */ -#define STATIC_CHAIN_REGNUM 7 +/* Register in which static-chain is passed to a function. + This must not be a register used by the prologue. */ +#define STATIC_CHAIN_REGNUM 7 /* These aren't official macros. */ -#define PROLOGUE_TMP_REGNUM 4 -#define RETURN_ADDR_REGNUM 14 -/* #define GP_REGNUM 12 */ -#define CARRY_REGNUM 17 -#define ACCUM_REGNUM 18 -#define M32R_MAX_INT_REGS 16 +#define PROLOGUE_TMP_REGNUM 4 +#define RETURN_ADDR_REGNUM 14 +/* #define GP_REGNUM 12 */ +#define CARRY_REGNUM 17 +#define ACCUM_REGNUM 18 +#define M32R_MAX_INT_REGS 16 #ifndef SUBTARGET_GPR_P #define SUBTARGET_GPR_P(REGNO) 0 @@ -1004,19 +1002,21 @@ M32R_STACK_ALIGN (current_function_outgoing_args_size) registers. This macro must be defined if `ELIMINABLE_REGS' is defined. */ -#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ -{ \ - int size = m32r_compute_frame_size (get_frame_size ()); \ - \ - if ((FROM) == FRAME_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \ - (OFFSET) = 0; \ - else if ((FROM) == ARG_POINTER_REGNUM && (TO) == FRAME_POINTER_REGNUM) \ - (OFFSET) = size - current_function_pretend_args_size; \ - else if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \ - (OFFSET) = size - current_function_pretend_args_size; \ - else \ - abort (); \ -} +#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ + do \ + { \ + int size = m32r_compute_frame_size (get_frame_size ()); \ + \ + if ((FROM) == FRAME_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \ + (OFFSET) = 0; \ + else if ((FROM) == ARG_POINTER_REGNUM && (TO) == FRAME_POINTER_REGNUM) \ + (OFFSET) = size - current_function_pretend_args_size; \ + else if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \ + (OFFSET) = size - current_function_pretend_args_size; \ + else \ + abort (); \ + } \ + while (0) /* Function argument passing. */ @@ -1030,22 +1030,6 @@ M32R_STACK_ALIGN (current_function_outgoing_args_size) increase the stack frame size by this amount. */ #define ACCUMULATE_OUTGOING_ARGS 1 -/* Define this macro if functions should assume that stack space has - been allocated for arguments even when their values are passed in - registers. - - The value of this macro is the size, in bytes, of the area - reserved for arguments passed in registers for the function - represented by FNDECL. - - This space can be allocated by the caller, or be a part of the - machine-dependent stack frame: `OUTGOING_REG_PARM_STACK_SPACE' says - which. */ -#if 0 -#define REG_PARM_STACK_SPACE(FNDECL) \ - (M32R_MAX_PARM_REGS * UNITS_PER_WORD) -#endif - /* Value is the number of bytes of arguments automatically popped when returning from a subroutine call. FUNDECL is the declaration node of the function (as a tree), @@ -1159,9 +1143,8 @@ M32R_STACK_ALIGN (current_function_outgoing_args_size) #if 0 /* We assume PARM_BOUNDARY == UNITS_PER_WORD here. */ #define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \ -(((TYPE) ? TYPE_ALIGN (TYPE) : GET_MODE_BITSIZE (MODE)) <= PARM_BOUNDARY \ - ? PARM_BOUNDARY \ - : 2 * PARM_BOUNDARY) + (((TYPE) ? TYPE_ALIGN (TYPE) : GET_MODE_BITSIZE (MODE)) <= PARM_BOUNDARY \ + ? PARM_BOUNDARY : 2 * PARM_BOUNDARY) #endif /* This macro offers an alternative @@ -1192,7 +1175,7 @@ M32R_STACK_ALIGN (current_function_outgoing_args_size) this case. */ #define SETUP_INCOMING_VARARGS(ARGS_SO_FAR, MODE, TYPE, PRETEND_SIZE, NO_RTL) \ - m32r_setup_incoming_varargs (&ARGS_SO_FAR, MODE, TYPE, &PRETEND_SIZE, NO_RTL) + m32r_setup_incoming_varargs (& ARGS_SO_FAR, MODE, TYPE, & PRETEND_SIZE, NO_RTL) /* Implement `va_arg'. */ #define EXPAND_BUILTIN_VA_ARG(valist, type) \ @@ -1243,19 +1226,49 @@ M32R_STACK_ALIGN (current_function_outgoing_args_size) /* Output assembler code to FILE to increment profiler label # LABELNO for profiling a function entry. */ -#define FUNCTION_PROFILER(FILE, LABELNO) abort () +#undef FUNCTION_PROFILER +#define FUNCTION_PROFILER(FILE, LABELNO) \ + do \ + { \ + if (flag_pic) \ + { \ + fprintf (FILE, "\tld24 r14,#mcount\n"); \ + fprintf (FILE, "\tadd r14,r12\n"); \ + fprintf (FILE, "\tld r14,@r14\n"); \ + fprintf (FILE, "\tjl r14\n"); \ + } \ + else \ + { \ + if (TARGET_ADDR24) \ + fprintf (FILE, "\tbl mcount\n"); \ + else \ + { \ + fprintf (FILE, "\tseth r14,#high(mcount)\n"); \ + fprintf (FILE, "\tor3 r14,r14,#low(mcount)\n"); \ + fprintf (FILE, "\tjl r14\n"); \ + } \ + } \ + fprintf (FILE, "\taddi sp,#4\n"); \ + } \ + while (0) /* Trampolines. */ -/* On the M32R, the trampoline is +/* On the M32R, the trampoline is: - ld24 r7,STATIC - ld24 r6,FUNCTION - jmp r6 - nop + mv r7, lr -> bl L1 ; 178e 7e01 +L1: add3 r6, lr, #L2-L1 ; 86ae 000c (L2 - L1 = 12) + mv lr, r7 -> ld r7,@r6+ ; 1e87 27e6 + ld r6, @r6 -> jmp r6 ; 26c6 1fc6 +L2: .word STATIC + .word FUNCTION */ - ??? Need addr32 support. -*/ +#ifndef CACHE_FLUSH_FUNC +#define CACHE_FLUSH_FUNC "_flush_cache" +#endif +#ifndef CACHE_FLUSH_TRAP +#define CACHE_FLUSH_TRAP "12" +#endif /* Length in bytes of the trampoline for entering a nested function. */ #define TRAMPOLINE_SIZE 12 @@ -1263,16 +1276,35 @@ M32R_STACK_ALIGN (current_function_outgoing_args_size) /* Emit RTL insns to initialize the variable parts of a trampoline. FNADDR is an RTX for the address of the function's pure code. CXT is an RTX for the static chain value for the function. */ -#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ -do { \ - emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 0)), \ - plus_constant ((CXT), 0xe7000000)); \ - emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 4)), \ - plus_constant ((FNADDR), 0xe6000000)); \ - emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 8)), \ - GEN_INT (0x1fc67000)); \ - emit_insn (gen_flush_icache (validize_mem (gen_rtx_MEM (SImode, TRAMP)))); \ -} while (0) +#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ + do \ + { \ + emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 0)), \ + GEN_INT \ + (TARGET_LITTLE_ENDIAN ? 0x017e8e17 : 0x178e7e01)); \ + emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 4)), \ + GEN_INT \ + (TARGET_LITTLE_ENDIAN ? 0x0c00ae86 : 0x86ae000c)); \ + emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 8)), \ + GEN_INT \ + (TARGET_LITTLE_ENDIAN ? 0xe627871e : 0x1e8727e6)); \ + emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 12)), \ + GEN_INT \ + (TARGET_LITTLE_ENDIAN ? 0xc616c626 : 0x26c61fc6)); \ + emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 16)), \ + (CXT)); \ + emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 20)), \ + (FNADDR)); \ + if (m32r_cache_flush_trap_string && m32r_cache_flush_trap_string[0]) \ + emit_insn (gen_flush_icache (validize_mem (gen_rtx_MEM (SImode, TRAMP)),\ + GEN_INT (m32r_cache_flush_trap) )); \ + else if (m32r_cache_flush_func && m32r_cache_flush_func[0]) \ + emit_library_call (gen_rtx_SYMBOL_REF (Pmode, m32r_cache_flush_func), \ + 0, VOIDmode, 3, TRAMP, Pmode, \ + GEN_INT (TRAMPOLINE_SIZE), SImode, \ + GEN_INT (3), SImode); \ + } \ + while (0) /* Library calls. */ @@ -1286,14 +1318,17 @@ do { \ /* We have post-inc load and pre-dec,pre-inc store, but only for 4 byte vals. */ -#define HAVE_PRE_DECREMENT 1 -#define HAVE_PRE_INCREMENT 1 +#define HAVE_PRE_DECREMENT 1 +#define HAVE_PRE_INCREMENT 1 #define HAVE_POST_INCREMENT 1 /* Recognize any constant value that is a valid address. */ -#define CONSTANT_ADDRESS_P(X) \ -(GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ - || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST) +#define CONSTANT_ADDRESS_P(X) \ + ( GET_CODE (X) == LABEL_REF \ + || GET_CODE (X) == SYMBOL_REF \ + || GET_CODE (X) == CONST_INT \ + || (GET_CODE (X) == CONST \ + && ! (flag_pic && ! m32r_legitimate_pic_operand_p (X)))) /* Nonzero if the constant value X is a legitimate general operand. We don't allow (plus symbol large-constant) as the relocations can't @@ -1302,11 +1337,11 @@ do { \ constant to memory if they can't handle them. */ #define LEGITIMATE_CONSTANT_P(X) \ -(! (GET_CODE (X) == CONST \ - && GET_CODE (XEXP (X, 0)) == PLUS \ - && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF \ - && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \ - && (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (X, 0), 1)) > 32767)) + (! (GET_CODE (X) == CONST \ + && GET_CODE (XEXP (X, 0)) == PLUS \ + && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF \ + && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \ + && (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (X, 0), 1)) > 32767)) /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx and check its validity for a certain class. @@ -1333,9 +1368,9 @@ do { \ /* Nonzero if X is a hard reg that can be used as a base reg or if it is a pseudo reg. */ #define REG_OK_FOR_BASE_P(X) \ -(GPR_P (REGNO (X)) \ - || (REGNO (X)) == ARG_POINTER_REGNUM \ - || REGNO (X) >= FIRST_PSEUDO_REGISTER) + (GPR_P (REGNO (X)) \ + || (REGNO (X)) == ARG_POINTER_REGNUM \ + || REGNO (X) >= FIRST_PSEUDO_REGISTER) /* Nonzero if X is a hard reg that can be used as an index or if it is a pseudo reg. */ #define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_BASE_P (X) @@ -1352,51 +1387,54 @@ do { \ /* Local to this file. */ #define RTX_OK_FOR_OFFSET_P(X) \ -(GET_CODE (X) == CONST_INT && INT16_P (INTVAL (X))) + (GET_CODE (X) == CONST_INT && INT16_P (INTVAL (X))) /* Local to this file. */ -#define LEGITIMATE_OFFSET_ADDRESS_P(MODE, X) \ -(GET_CODE (X) == PLUS \ - && RTX_OK_FOR_BASE_P (XEXP (X, 0)) \ - && RTX_OK_FOR_OFFSET_P (XEXP (X, 1))) +#define LEGITIMATE_OFFSET_ADDRESS_P(MODE, X) \ + (GET_CODE (X) == PLUS \ + && RTX_OK_FOR_BASE_P (XEXP (X, 0)) \ + && RTX_OK_FOR_OFFSET_P (XEXP (X, 1))) /* Local to this file. */ /* For LO_SUM addresses, do not allow them if the MODE is > 1 word, since more than one instruction will be required. */ -#define LEGITIMATE_LO_SUM_ADDRESS_P(MODE, X) \ -(GET_CODE (X) == LO_SUM \ - && (MODE != BLKmode && GET_MODE_SIZE (MODE) <= UNITS_PER_WORD) \ - && RTX_OK_FOR_BASE_P (XEXP (X, 0)) \ - && CONSTANT_P (XEXP (X, 1))) +#define LEGITIMATE_LO_SUM_ADDRESS_P(MODE, X) \ + (GET_CODE (X) == LO_SUM \ + && (MODE != BLKmode && GET_MODE_SIZE (MODE) <= UNITS_PER_WORD)\ + && RTX_OK_FOR_BASE_P (XEXP (X, 0)) \ + && CONSTANT_P (XEXP (X, 1))) /* Local to this file. */ /* Is this a load and increment operation. */ -#define LOAD_POSTINC_P(MODE, X) \ -(((MODE) == SImode || (MODE) == SFmode) \ - && GET_CODE (X) == POST_INC \ - && GET_CODE (XEXP (X, 0)) == REG \ - && RTX_OK_FOR_BASE_P (XEXP (X, 0))) +#define LOAD_POSTINC_P(MODE, X) \ + (((MODE) == SImode || (MODE) == SFmode) \ + && GET_CODE (X) == POST_INC \ + && GET_CODE (XEXP (X, 0)) == REG \ + && RTX_OK_FOR_BASE_P (XEXP (X, 0))) /* Local to this file. */ /* Is this an increment/decrement and store operation. */ -#define STORE_PREINC_PREDEC_P(MODE, X) \ -(((MODE) == SImode || (MODE) == SFmode) \ - && (GET_CODE (X) == PRE_INC || GET_CODE (X) == PRE_DEC) \ - && GET_CODE (XEXP (X, 0)) == REG \ - && RTX_OK_FOR_BASE_P (XEXP (X, 0))) +#define STORE_PREINC_PREDEC_P(MODE, X) \ + (((MODE) == SImode || (MODE) == SFmode) \ + && (GET_CODE (X) == PRE_INC || GET_CODE (X) == PRE_DEC) \ + && GET_CODE (XEXP (X, 0)) == REG \ + && RTX_OK_FOR_BASE_P (XEXP (X, 0))) -#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ -{ if (RTX_OK_FOR_BASE_P (X)) \ - goto ADDR; \ - if (LEGITIMATE_OFFSET_ADDRESS_P ((MODE), (X))) \ - goto ADDR; \ - if (LEGITIMATE_LO_SUM_ADDRESS_P ((MODE), (X))) \ - goto ADDR; \ - if (LOAD_POSTINC_P ((MODE), (X))) \ - goto ADDR; \ - if (STORE_PREINC_PREDEC_P ((MODE), (X))) \ - goto ADDR; \ -} +#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ + do \ + { \ + if (RTX_OK_FOR_BASE_P (X)) \ + goto ADDR; \ + if (LEGITIMATE_OFFSET_ADDRESS_P ((MODE), (X))) \ + goto ADDR; \ + if (LEGITIMATE_LO_SUM_ADDRESS_P ((MODE), (X))) \ + goto ADDR; \ + if (LOAD_POSTINC_P ((MODE), (X))) \ + goto ADDR; \ + if (STORE_PREINC_PREDEC_P ((MODE), (X))) \ + goto ADDR; \ + } \ + while (0) /* Try machine-dependent ways of modifying an illegitimate address to be legitimate. If we find one, return the new, valid address. @@ -1409,22 +1447,30 @@ do { \ GO_IF_LEGITIMATE_ADDRESS. It is always safe for this macro to do nothing. It exists to recognize - opportunities to optimize the output. + opportunities to optimize the output. */ - ??? Is there anything useful we can do here for the M32R? */ - -#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) +#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \ + do \ + { \ + if (flag_pic) \ + (X) = m32r_legitimize_pic_address (X, NULL_RTX); \ + if (memory_address_p (MODE, X)) \ + goto WIN; \ + } \ + while (0) /* Go to LABEL if ADDR (a legitimate address expression) has an effect that depends on the machine mode it is used for. */ -#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \ -do { \ - if (GET_CODE (ADDR) == PRE_DEC \ - || GET_CODE (ADDR) == PRE_INC \ - || GET_CODE (ADDR) == POST_INC \ - || GET_CODE (ADDR) == LO_SUM) \ - goto LABEL; \ -} while (0) +#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \ + do \ + { \ + if ( GET_CODE (ADDR) == PRE_DEC \ + || GET_CODE (ADDR) == PRE_INC \ + || GET_CODE (ADDR) == POST_INC \ + || GET_CODE (ADDR) == LO_SUM) \ + goto LABEL; \ + } \ + while (0) /* Condition code usage. */ @@ -1481,9 +1527,9 @@ do { \ output in the text section, along with the assembler instructions. Otherwise, the readonly data section is used. This macro is irrelevant if there is no separate readonly data section. */ -/*#define JUMP_TABLES_IN_TEXT_SECTION*/ +#define JUMP_TABLES_IN_TEXT_SECTION (flag_pic) -/* PIC */ +/* Position Independent Code. */ /* The register number of the register used to address a table of static data addresses in memory. In some cases this register is defined by a @@ -1492,7 +1538,7 @@ do { \ pointer and frame pointer registers. If this macro is not defined, it is up to the machine-dependent files to allocate such a register (if necessary). */ -/*#define PIC_OFFSET_TABLE_REGNUM 12*/ +#define PIC_OFFSET_TABLE_REGNUM 12 /* Define this macro if the register defined by PIC_OFFSET_TABLE_REGNUM is clobbered by calls. Do not define this macro if PIC_OFFSET_TABLE_REGNUM @@ -1514,7 +1560,7 @@ do { \ included in functions which used inline functions and were compiled to assembly language.) */ -/*#define FINALIZE_PIC m32r_finalize_pic ()*/ +#define FINALIZE_PIC m32r_finalize_pic () /* A C expression that is nonzero if X is a legitimate immediate operand on the target machine when generating position independent code. @@ -1523,7 +1569,7 @@ do { \ check it either. You need not define this macro if all constants (including SYMBOL_REF) can be immediate operands when generating position independent code. */ -/*#define LEGITIMATE_PIC_OPERAND_P(X)*/ +#define LEGITIMATE_PIC_OPERAND_P(X) m32r_legitimate_pic_operand_p (X) /* Control the assembler format that we output. */ @@ -1620,10 +1666,10 @@ extern char m32r_punct_chars[256]; are useful when a single `md' file must support multiple assembler formats. In that case, the various `tm.h' files can define these macros differently. */ -#define REGISTER_PREFIX "" -#define LOCAL_LABEL_PREFIX ".L" -#define USER_LABEL_PREFIX "" -#define IMMEDIATE_PREFIX "#" +#define REGISTER_PREFIX "" +#define LOCAL_LABEL_PREFIX ".L" +#define USER_LABEL_PREFIX "" +#define IMMEDIATE_PREFIX "#" /* This is how to output an element of a case-vector that is absolute. */ #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ @@ -1648,7 +1694,7 @@ extern char m32r_punct_chars[256]; fprintf (FILE, "-"); \ ASM_GENERATE_INTERNAL_LABEL (label, "L", REL); \ assemble_name (FILE, label); \ - fprintf (FILE, ")\n"); \ + fprintf (FILE, "\n"); \ } \ while (0) @@ -1720,7 +1766,7 @@ extern char m32r_punct_chars[256]; /* Debugging information. */ /* Generate DBX and DWARF debugging information. */ -#define DBX_DEBUGGING_INFO 1 +#define DBX_DEBUGGING_INFO 1 #define DWARF2_DEBUGGING_INFO 1 /* Prefer STABS (for now). */ @@ -1734,7 +1780,7 @@ extern char m32r_punct_chars[256]; /* Specify the machine mode that this machine uses for the index in the tablejump instruction. */ -#define CASE_VECTOR_MODE Pmode +#define CASE_VECTOR_MODE (flag_pic ? SImode : Pmode) /* Define as C expression which evaluates to nonzero if the tablejump instruction expects the table to contain offsets from the address of the @@ -1755,8 +1801,8 @@ extern char m32r_punct_chars[256]; done, NIL if none. */ #define LOAD_EXTEND_OP(MODE) ZERO_EXTEND -/* Max number of bytes we can move from memory to memory - in one reasonably fast instruction. */ +/* Max number of bytes we can move from memory + to memory in one reasonably fast instruction. */ #define MOVE_MAX 4 /* Define this to be nonzero if shift instructions ignore all but the low-order diff --git a/gcc/config/m32r/m32r.md b/gcc/config/m32r/m32r.md index 4c9bb6f1276..5e562a7f5c0 100644 --- a/gcc/config/m32r/m32r.md +++ b/gcc/config/m32r/m32r.md @@ -297,6 +297,18 @@ "" " { + /* Fixup PIC cases. */ + if (flag_pic) + { + if (symbolic_operand (operands[1], QImode)) + { + if (reload_in_progress || reload_completed) + operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]); + else + operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX); + } + } + /* Everything except mem = const or mem = mem can be done easily. Objects in the small data area are handled too. */ @@ -325,6 +337,18 @@ "" " { + /* Fixup PIC cases. */ + if (flag_pic) + { + if (symbolic_operand (operands[1], HImode)) + { + if (reload_in_progress || reload_completed) + operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]); + else + operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX); + } + } + /* Everything except mem = const or mem = mem can be done easily. */ if (GET_CODE (operands[0]) == MEM) @@ -365,6 +389,18 @@ "" " { + /* Fixup PIC cases. */ + if (flag_pic) + { + if (symbolic_operand (operands[1], SImode)) + { + if (reload_in_progress || reload_completed) + operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]); + else + operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX); + } + } + /* Everything except mem = const or mem = mem can be done easily. */ if (GET_CODE (operands[0]) == MEM) @@ -590,6 +626,18 @@ "" " { + /* Fixup PIC cases. */ + if (flag_pic) + { + if (symbolic_operand (operands[1], DImode)) + { + if (reload_in_progress || reload_completed) + operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]); + else + operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX); + } + } + /* Everything except mem = const or mem = mem can be done easily. */ if (GET_CODE (operands[0]) == MEM) @@ -619,6 +667,18 @@ "" " { + /* Fixup PIC cases. */ + if (flag_pic) + { + if (symbolic_operand (operands[1], SFmode)) + { + if (reload_in_progress || reload_completed) + operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]); + else + operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX); + } + } + /* Everything except mem = const or mem = mem can be done easily. */ if (GET_CODE (operands[0]) == MEM) @@ -659,6 +719,18 @@ "" " { + /* Fixup PIC cases. */ + if (flag_pic) + { + if (symbolic_operand (operands[1], DFmode)) + { + if (reload_in_progress || reload_completed) + operands[1] = m32r_legitimize_pic_address (operands[1], operands[0]); + else + operands[1] = m32r_legitimize_pic_address (operands[1], NULL_RTX); + } + } + /* Everything except mem = const or mem = mem can be done easily. */ if (GET_CODE (operands[0]) == MEM) @@ -2269,7 +2341,27 @@ [(set_attr "type" "uncond_branch") (set_attr "length" "2")]) -(define_insn "tablejump" +(define_expand "tablejump" + [(parallel [(set (pc) (match_operand 0 "register_operand" "r")) + (use (label_ref (match_operand 1 "" "")))])] + "" + " +{ + /* In pic mode, our address differences are against the base of the + table. Add that base value back in; CSE ought to be able to combine + the two address loads. */ + if (flag_pic) + { + rtx tmp, tmp2; + + tmp = gen_rtx_LABEL_REF (Pmode, operands[1]); + tmp2 = operands[0]; + tmp = gen_rtx_PLUS (Pmode, tmp2, tmp); + operands[0] = memory_address (Pmode, tmp); + } +}") + +(define_insn "*tablejump_insn" [(set (pc) (match_operand:SI 0 "address_operand" "p")) (use (label_ref (match_operand 1 "" "")))] "" @@ -2284,7 +2376,11 @@ (match_operand 1 "" "")) (clobber (reg:SI 14))])] "" - "") + " +{ + if (flag_pic) + current_function_uses_pic_offset_table = 1; +}") (define_insn "*call_via_reg" [(call (mem:SI (match_operand:SI 0 "register_operand" "r")) @@ -2335,7 +2431,11 @@ (match_operand 2 "" ""))) (clobber (reg:SI 14))])] "" - "") + " +{ + if (flag_pic) + current_function_uses_pic_offset_table = 1; +}") (define_insn "*call_value_via_reg" [(set (match_operand 0 "register_operand" "=r") @@ -2357,6 +2457,9 @@ { int call26_p = call26_operand (operands[1], FUNCTION_MODE); + if (flag_pic) + current_function_uses_pic_offset_table = 1; + if (! call26_p) { /* We may not be able to reach with a `bl' insn so punt and leave it to @@ -2398,11 +2501,13 @@ ;; Special pattern to flush the icache. (define_insn "flush_icache" - [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 0)] + [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 0) + (match_operand 1 "" "") + (clobber (reg:SI 17))] "" - "* return \"nop ; flush-icache\";" - [(set_attr "type" "int2") - (set_attr "length" "2")]) + "* return \"trap %#%1 ; flush-icache\";" + [(set_attr "type" "int4") + (set_attr "length" "4")]) ;; Speed up fabs and provide correct sign handling for -0 @@ -2581,3 +2686,44 @@ "* m32r_output_block_move (insn, operands); return \"\"; " [(set_attr "type" "store8") (set_attr "length" "72")]) ;; Maximum + +;; PIC + +/* When generating pic, we need to load the symbol offset into a register. + So that the optimizer does not confuse this with a normal symbol load + we use an unspec. The offset will be loaded from a constant pool entry, + since that is the only type of relocation we can use. */ + +(define_insn "pic_load_addr" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(match_operand 1 "" "")] 4))] + "flag_pic" + "ld24 %0,%#%1" + [(set_attr "type" "int4")]) + +;; Load program counter insns. + +(define_insn "get_pc" + [(clobber (reg:SI 14)) + (set (match_operand 0 "register_operand" "=r") + (unspec [(match_operand 1 "" "")] 5)) + (use (match_operand:SI 2 "immediate_operand" ""))] + "flag_pic" + "* +{ + if (INTVAL(operands[2])) + return \"bl.s .+4\;ld24 %0,%#%1\;add %0,lr\"; + else + return \"bl.s .+4\;seth %0,%#shigh(%1)\;add3 %0,%0,%#low(%1+4)\;add %0,lr\";}" + [(set (attr "length") (if_then_else (ne (match_dup 2) (const_int 0)) + (const_int 8) + (const_int 12)))]) + +(define_expand "builtin_setjmp_receiver" + [(label_ref (match_operand 0 "" ""))] + "flag_pic" + " +{ + m32r_load_pic_register (); + DONE; +}") diff --git a/gcc/config/m32r/t-linux b/gcc/config/m32r/t-linux new file mode 100644 index 00000000000..03046579094 --- /dev/null +++ b/gcc/config/m32r/t-linux @@ -0,0 +1,42 @@ +# lib1funcs.asm is currently empty. +CROSS_LIBGCC1 = + +# These are really part of libgcc1, but this will cause them to be +# built correctly, so... + +LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c + +# Turn off the SDA while compiling libgcc2. There are no headers for it +# and we want maximal upward compatibility here. + +TARGET_LIBGCC2_CFLAGS = -G 0 -fPIC + +fp-bit.c: $(srcdir)/config/fp-bit.c + echo '#define FLOAT' > fp-bit.c + cat $(srcdir)/config/fp-bit.c >> fp-bit.c + +dp-bit.c: $(srcdir)/config/fp-bit.c + cat $(srcdir)/config/fp-bit.c > dp-bit.c + +# We need to use -fpic when we are using gcc to compile the routines in +# initfini.c. This is only really needed when we are going to use gcc/g++ +# to produce a shared library, but since we don't know ahead of time when +# we will be doing that, we just always use -fpic when compiling the +# routines in initfini.c. +# -fpic currently isn't supported for the m32r. + +CRTSTUFF_T_CFLAGS_S = -fPIC + + +# Don't run fixproto +STMP_FIXPROTO = + +# Don't install "assert.h" in gcc. We use the one in glibc. +INSTALL_ASSERT_H = + +# Do not build libgcc1. Let gcc generate those functions. The GNU/Linux +# C library can handle them. +LIBGCC1 = +CROSS_LIBGCC1 = +LIBGCC1_TEST = + diff --git a/gcc/config/m32r/xm-linux.h b/gcc/config/m32r/xm-linux.h new file mode 100644 index 00000000000..1c6f4629798 --- /dev/null +++ b/gcc/config/m32r/xm-linux.h @@ -0,0 +1,26 @@ +/* Configuration for GCC for Renesas M32R running Linux-based GNU systems. + Copyright (C) 2003 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. */ + +#include +#include + +/* Doubles are stored in memory with the high order word first. + This matters when cross-compiling. */ +#undef HOST_WORDS_BIG_ENDIAN diff --git a/gcc/config/m32r/xm-m32r.h b/gcc/config/m32r/xm-m32r.h new file mode 100644 index 00000000000..5859449839f --- /dev/null +++ b/gcc/config/m32r/xm-m32r.h @@ -0,0 +1,43 @@ +/* Configuration for GNU C-compiler for the M32R processor. + Copyright (C) 2003 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. */ + +/* This describes the machine the compiler is hosted on. */ +#define HOST_BITS_PER_CHAR 8 +#define HOST_BITS_PER_SHORT 16 +#define HOST_BITS_PER_INT 32 +#define HOST_BITS_PER_LONG 32 +#define HOST_BITS_PER_LONGLONG 64 + +/* Doubles are stored in memory with the high order word first. + This matters when cross-compiling. */ +#define HOST_WORDS_BIG_ENDIAN 1 + +/* target machine dependencies. + tm.h is a symbolic link to the actual target specific file. */ +#include "tm.h" + +/* Arguments to use with `exit'. */ +#define SUCCESS_EXIT_CODE 0 +#define FATAL_EXIT_CODE 33 + +/* If compiled with Sun CC, the use of alloca requires this #include. */ +#ifndef __GNUC__ +#include "alloca.h" +#endif diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 7e48a3bdb44..d634362fadc 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -400,8 +400,16 @@ in the following sections. -mno-crt0 -mrelax} @emph{M32R/D Options} -@gccoptlist{-m32r2 -m32rx -m32r -mcode-model=@var{model-type} @gol --msdata=@var{sdata-type} -G @var{num}} +@gccoptlist{-m32r2 -m32rx -m32r @gol +-mdebug @gol +-malign-loops -mno-align-loops @gol +-missue-rate=@var{number} @gol +-mbranch-cost=@var{number} @gol +-mmodel=@var{code-size-model-type} @gol +-msdata=@var{sdata-type} @gol +-mno-flush-func -mflush-func=@var{name} @gol +-mno-flush-trap -mflush-trap=@var{number} @gol +-G @var{num}} @emph{M88K Options} @gccoptlist{-m88000 -m88100 -m88110 -mbig-pic @gol @@ -6834,8 +6842,8 @@ Generate code for the M32R/X@. @opindex m32r Generate code for the M32R@. This is the default. -@item -mcode-model=small -@opindex mcode-model=small +@item -mmodel=small +@opindex mmodel=small Assume all objects live in the lower 16MB of memory (so that their addresses can be loaded with the @code{ld24} instruction), and assume all subroutines are reachable with the @code{bl} instruction. @@ -6844,14 +6852,14 @@ This is the default. The addressability of a particular object can be set with the @code{model} attribute. -@item -mcode-model=medium -@opindex mcode-model=medium +@item -mmodel=medium +@opindex mmodel=medium Assume objects may be anywhere in the 32-bit address space (the compiler will generate @code{seth/add3} instructions to load their addresses), and assume all subroutines are reachable with the @code{bl} instruction. -@item -mcode-model=large -@opindex mcode-model=large +@item -mmodel=large +@opindex mmodel=large Assume objects may be anywhere in the 32-bit address space (the compiler will generate @code{seth/add3} instructions to load their addresses), and assume subroutines may not be reachable with the @code{bl} instruction @@ -6893,6 +6901,49 @@ Compiling with different values of @var{num} may or may not work; if it doesn't the linker will give an error message---incorrect code will not be generated. +@item -mdebug +@opindex -mdebug +Makes the M32R specific code in the compiler display some statistics +that might help in debugging programs. + +@item -malign-loops +@opindex +Align all loops to a 32-byte boundary. + +@item -mno-align-loops +@opindex +Do not enforce a 32-byte alignment for loops. This is the default. + +@item -missue-rate=@var{number} +@opindex +Issue @var{number} instructions per cycle. @var{number} can only be 1 +or 2. + +@item -mbranch-cost=@var{number} +@opindex +@var{number} can only be 1 or 2. If it is 1 then branches will be +prefered over conditional code, if it is 2, then the opposite will +apply. + +@item -mflush-trap=@var{number} +@opindex +Specifies the trap number to use to flush the cache. The default is +12. Valid numbers are between 0 and 15 inclusive. + +@item -mno-flush-trap +@opindex +Specifies that the cache cannot be flushed by using a trap. + +@item -mflush-func=@var{name} +@opindex +Specifies the name of the operating system function to call to flush +the cache. The default is @emph{_flush_cache}, but a function call +will only be used if a trap is not available. + +@item -mno-flush-func +@opindex +Indicates that there is no OS function for flushing the cache. + @end table @node M88K Options