Commit ad126521 by Kazuhiro Inaoka Committed by Nick Clifton

Add support for m32r-linux target.

From-SVN: r75263
parent 04d1e6e2
2003-12-31 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
* 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 <kazu@cs.umass.edu>
* config/i386/i386.h: Remove an unnecessary #undef.
......
......@@ -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"
......
/* 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()
/* 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}}"
/* 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);
......
......@@ -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=<n<=15)",
m32r_cache_flush_trap_string);
}
}
/* Vectors to keep interesting information about registers where it can easily
......@@ -509,6 +531,9 @@ addr24_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
rtx sym;
if (flag_pic)
return 0;
if (GET_CODE (op) == LABEL_REF)
return TARGET_ADDR24;
......@@ -549,7 +574,8 @@ addr32_operand (rtx op, enum machine_mode mode)
else if (GET_CODE (op) == CONST
&& GET_CODE (XEXP (op, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
&& GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
&& GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
&& ! flag_pic)
sym = XEXP (XEXP (op, 0), 0);
else
return 0;
......@@ -563,6 +589,9 @@ addr32_operand (rtx op, enum machine_mode mode)
int
call26_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (flag_pic)
return 0;
if (GET_CODE (op) == SYMBOL_REF)
return SYMBOL_REF_MODEL (op) != M32R_MODEL_LARGE;
......@@ -574,6 +603,9 @@ call26_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
int
seth_add3_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (flag_pic)
return 0;
if (GET_CODE (op) == SYMBOL_REF
|| GET_CODE (op) == LABEL_REF)
return 1;
......@@ -711,6 +743,7 @@ move_src_operand (rtx op, enum machine_mode mode)
{
switch (GET_CODE (op))
{
case LABEL_REF :
case SYMBOL_REF :
case CONST :
return addr24_operand (op, mode);
......@@ -726,8 +759,8 @@ move_src_operand (rtx op, enum machine_mode mode)
}
else
return 1;
case LABEL_REF :
return TARGET_ADDR24;
case CONSTANT_P_RTX:
return 1;
case CONST_DOUBLE :
if (mode == SFmode)
return 1;
......@@ -1801,6 +1834,7 @@ m32r_compute_frame_size (int size) /* # of var. bytes allocated. */
unsigned int gmask;
enum m32r_function_type fn_type;
int interrupt_p;
int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table);
var_size = M32R_STACK_ALIGN (size);
args_size = M32R_STACK_ALIGN (current_function_outgoing_args_size);
......@@ -1818,7 +1852,8 @@ m32r_compute_frame_size (int size) /* # of var. bytes allocated. */
/* Calculate space needed for registers. */
for (regno = 0; regno < M32R_MAX_INT_REGS; regno++)
{
if (MUST_SAVE_REGISTER (regno, interrupt_p))
if (MUST_SAVE_REGISTER (regno, interrupt_p)
|| (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
{
reg_size += UNITS_PER_WORD;
gmask |= 1 << regno;
......@@ -1826,7 +1861,7 @@ m32r_compute_frame_size (int size) /* # of var. bytes allocated. */
}
current_frame_info.save_fp = MUST_SAVE_FRAME_POINTER;
current_frame_info.save_lr = MUST_SAVE_RETURN_ADDR;
current_frame_info.save_lr = MUST_SAVE_RETURN_ADDR || pic_reg_used;
reg_size += ((current_frame_info.save_fp + current_frame_info.save_lr)
* UNITS_PER_WORD);
......@@ -1865,6 +1900,21 @@ m32r_first_insn_address (void)
return 0;
}
/* The table we use to reference PIC data. */
static rtx global_offset_table;
void
m32r_load_pic_register (void)
{
global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
emit_insn (gen_get_pc (pic_offset_table_rtx, global_offset_table,
gen_rtx_CONST_INT(SImode, TARGET_MODEL_SMALL)));
/* Need to emit this whether or not we obey regdecls,
since setjmp/longjmp can cause life info to screw up. */
emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
}
/* Expand the m32r prologue as a series of insns. */
void
......@@ -1873,6 +1923,7 @@ m32r_expand_prologue (void)
int regno;
int frame_size;
unsigned int gmask;
int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table);
if (! current_frame_info.initialized)
m32r_compute_frame_size (get_frame_size ());
......@@ -1935,6 +1986,14 @@ m32r_expand_prologue (void)
emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx));
if (current_function_profile)
/* Push lr for mcount (form_pc, x). */
emit_insn (gen_movsi_push (stack_pointer_rtx,
gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM)));
if (pic_reg_used)
m32r_load_pic_register ();
if (current_function_profile && !pic_reg_used)
emit_insn (gen_blockage ());
}
......@@ -2084,18 +2143,122 @@ direct_return (void)
if (! current_frame_info.initialized)
m32r_compute_frame_size (get_frame_size ());
return current_frame_info.total_size == 0;
return current_frame_info.total_size == 0;
}
/* PIC. */
int
m32r_legitimate_pic_operand_p (rtx x)
{
if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
return 0;
if (GET_CODE (x) == CONST
&& GET_CODE (XEXP (x, 0)) == PLUS
&& (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
|| GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF)
&& (GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT))
return 0;
return 1;
}
rtx
m32r_legitimize_pic_address (rtx orig, rtx reg)
{
#ifdef DEBUG_PIC
printf("m32r_legitimize_pic_address()\n");
#endif
if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
{
rtx pic_ref, address;
rtx insn;
int subregs = 0;
if (reg == 0)
{
if (reload_in_progress || reload_completed)
abort ();
else
reg = gen_reg_rtx (Pmode);
subregs = 1;
}
if (subregs)
address = gen_reg_rtx (Pmode);
else
address = reg;
emit_insn (gen_pic_load_addr (address, orig));
emit_insn (gen_addsi3 (address, address, pic_offset_table_rtx));
pic_ref = gen_rtx (MEM, Pmode, address);
RTX_UNCHANGING_P (pic_ref) = 1;
insn = emit_move_insn (reg, pic_ref);
current_function_uses_pic_offset_table = 1;
#if 0
/* Put a REG_EQUAL note on this insn, so that it can be optimized
by loop. */
REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, orig,
REG_NOTES (insn));
#endif
return reg;
}
else if (GET_CODE (orig) == CONST)
{
rtx base, offset;
if (GET_CODE (XEXP (orig, 0)) == PLUS
&& XEXP (XEXP (orig, 0), 1) == pic_offset_table_rtx)
return orig;
if (reg == 0)
{
if (reload_in_progress || reload_completed)
abort ();
else
reg = gen_reg_rtx (Pmode);
}
if (GET_CODE (XEXP (orig, 0)) == PLUS)
{
base = m32r_legitimize_pic_address (XEXP (XEXP (orig, 0), 0), reg);
if (base == reg)
offset = m32r_legitimize_pic_address (XEXP (XEXP (orig, 0), 1), NULL_RTX);
else
offset = m32r_legitimize_pic_address (XEXP (XEXP (orig, 0), 1), reg);
}
else
return orig;
if (GET_CODE (offset) == CONST_INT)
{
if (INT16_P (INTVAL (offset)))
return plus_constant (base, INTVAL (offset));
else if (! reload_in_progress && ! reload_completed)
offset = force_reg (Pmode, offset);
else
/* If we reach here, then something is seriously wrong. */
abort ();
}
return gen_rtx (PLUS, Pmode, base, offset);
}
return orig;
}
/* Emit special PIC prologues and epilogues. */
void
m32r_finalize_pic (void)
{
/* Nothing to do. */
current_function_uses_pic_offset_table |= current_function_profile;
}
/* Nested function support. */
......@@ -2120,6 +2283,9 @@ m32r_file_start (void)
fprintf (asm_out_file,
"%s M32R/D special options: -G " HOST_WIDE_INT_PRINT_UNSIGNED "\n",
ASM_COMMENT_START, g_switch_value);
if (TARGET_LITTLE_ENDIAN)
fprintf (asm_out_file, "\t.little\n");
}
/* Print operand X (an rtx) in assembler syntax to file FILE.
......
......@@ -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;
}")
# 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 =
/* 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 <m32r/xm-m32r.h>
#include <xm-linux.h>
/* Doubles are stored in memory with the high order word first.
This matters when cross-compiling. */
#undef HOST_WORDS_BIG_ENDIAN
/* 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
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment