diff options
author | Richard Sandiford <richard@codesourcery.com> | 2007-05-10 11:15:07 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2007-05-10 11:15:07 +0000 |
commit | 1910440ea6f09731f4c475f8556c101e8944340c (patch) | |
tree | 6dd6c8dc5926e50ceabcd4e33f3edafd37e19c3c /gcc | |
parent | 31b40480a461ba486b17ad808fd0266546fabddf (diff) | |
download | gcc-1910440ea6f09731f4c475f8556c101e8944340c.zip gcc-1910440ea6f09731f4c475f8556c101e8944340c.tar.gz gcc-1910440ea6f09731f4c475f8556c101e8944340c.tar.bz2 |
config.gcc (sparc-wrs-vxworks): New target.
gcc/
* config.gcc (sparc-wrs-vxworks): New target.
* config/sparc/vxworks.h, config/sparc/t-vxworks: New files.
* config/sparc/sparc-protos.h (sparc_emit_call_insn): Declare.
* config/sparc/sparc.h: Include vxworks-dummy.h.
(PRINT_OPERAND_ADDRESS): Extend SYMBOL_REF handling to
include LABEL_REFs too.
* config/sparc/sparc.c (sparc_expand_move): Don't assume that
_GLOBAL_OFFSET_TABLE_ - label_ref is a link-time constant on
VxWorks.
(legitimize_pic_address): Handle LABEL_REFs like SYMBOL_REFs
on VxWorks.
(load_pic_register): Use gen_vxworks_load_got for VxWorks.
(sparc_emit_call_insn): New function.
(sparc_function_ok_for_sibcall): Restrict sibcalls to locally-binding
functions when generating VxWorks PIC.
* config/sparc/sparc.md (vxworks_load_got): New pattern.
(call, call_value): Use sparc_emit_call_insn instead of
emit_call_insn.
libgcc/
* config.host (sparc-wrs-vxworks): New target.
From-SVN: r124595
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 21 | ||||
-rw-r--r-- | gcc/config.gcc | 4 | ||||
-rw-r--r-- | gcc/config/sparc/sparc-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.c | 74 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.h | 3 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.md | 32 | ||||
-rw-r--r-- | gcc/config/sparc/t-vxworks | 5 | ||||
-rw-r--r-- | gcc/config/sparc/vxworks.h | 64 |
8 files changed, 184 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index afae5e2..60c3c9c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2007-05-10 Richard Sandiford <richard@codesourcery.com> + + * config.gcc (sparc-wrs-vxworks): New target. + * config/sparc/vxworks.h, config/sparc/t-vxworks: New files. + * config/sparc/sparc-protos.h (sparc_emit_call_insn): Declare. + * config/sparc/sparc.h: Include vxworks-dummy.h. + (PRINT_OPERAND_ADDRESS): Extend SYMBOL_REF handling to + include LABEL_REFs too. + * config/sparc/sparc.c (sparc_expand_move): Don't assume that + _GLOBAL_OFFSET_TABLE_ - label_ref is a link-time constant on + VxWorks. + (legitimize_pic_address): Handle LABEL_REFs like SYMBOL_REFs + on VxWorks. + (load_pic_register): Use gen_vxworks_load_got for VxWorks. + (sparc_emit_call_insn): New function. + (sparc_function_ok_for_sibcall): Restrict sibcalls to locally-binding + functions when generating VxWorks PIC. + * config/sparc/sparc.md (vxworks_load_got): New pattern. + (call, call_value): Use sparc_emit_call_insn instead of + emit_call_insn. + 2007-05-09 Bob Wilson <bob.wilson@acm.org> * config/xtensa/xtensa.c (xtensa_output_literal): Don't use #if. diff --git a/gcc/config.gcc b/gcc/config.gcc index 31b10d4..a26f3dd 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -2370,6 +2370,10 @@ sparc-*-sysv4*) extra_parts="crtbegin.o crtend.o" use_fixproto=yes ;; +sparc-wrs-vxworks) + tm_file="${tm_file} elfos.h svr4.h sparc/sysv4.h vx-common.h vxworks.h sparc/vxworks.h" + tmake_file="${tmake_file} sparc/t-vxworks" + ;; sparc64-*-elf*) tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sp64-elf.h" extra_options="${extra_options} sparc/little-endian.opt" diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h index 4fb862c..c1b2813 100644 --- a/gcc/config/sparc/sparc-protos.h +++ b/gcc/config/sparc/sparc-protos.h @@ -73,6 +73,7 @@ extern int legitimate_address_p (enum machine_mode, rtx, int); extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx); extern rtx legitimize_tls_address (rtx); extern rtx legitimize_address (rtx, rtx, enum machine_mode); +extern void sparc_emit_call_insn (rtx, rtx); extern void sparc_defer_case_vector (rtx, rtx, int); extern bool sparc_expand_move (enum machine_mode, rtx *); extern void sparc_emit_set_const32 (rtx, rtx); diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index be07ce7..f94af2a 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -980,17 +980,27 @@ sparc_expand_move (enum machine_mode mode, rtx *operands) if (pic_address_needs_scratch (operands[1])) operands[1] = legitimize_pic_address (operands[1], mode, 0); - if (GET_CODE (operands[1]) == LABEL_REF && mode == SImode) - { - emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1])); - return true; - } + /* VxWorks does not impose a fixed gap between segments; the run-time + gap can be different from the object-file gap. We therefore can't + assume X - _GLOBAL_OFFSET_TABLE_ is a link-time constant unless we + are absolutely sure that X is in the same segment as the GOT. + Unfortunately, the flexibility of linker scripts means that we + can't be sure of that in general, so assume that _G_O_T_-relative + accesses are never valid on VxWorks. */ + if (GET_CODE (operands[1]) == LABEL_REF && !TARGET_VXWORKS_RTP) + { + if (mode == SImode) + { + emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1])); + return true; + } - if (GET_CODE (operands[1]) == LABEL_REF && mode == DImode) - { - gcc_assert (TARGET_ARCH64); - emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1])); - return true; + if (mode == DImode) + { + gcc_assert (TARGET_ARCH64); + emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1])); + return true; + } } if (symbolic_operand (operands[1], mode)) @@ -3212,7 +3222,9 @@ rtx legitimize_pic_address (rtx orig, enum machine_mode mode ATTRIBUTE_UNUSED, rtx reg) { - if (GET_CODE (orig) == SYMBOL_REF) + if (GET_CODE (orig) == SYMBOL_REF + /* See the comment in sparc_expand_move. */ + || (TARGET_VXWORKS_RTP && GET_CODE (orig) == LABEL_REF)) { rtx pic_ref, address; rtx insn; @@ -3377,6 +3389,13 @@ load_pic_register (bool delay_pic_helper) { int orig_flag_pic = flag_pic; + if (TARGET_VXWORKS_RTP) + { + emit_insn (gen_vxworks_load_got ()); + emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx)); + return; + } + /* If we haven't initialized the special PIC symbols, do so now. */ if (!pic_helper_symbol_name[0]) { @@ -3405,6 +3424,29 @@ load_pic_register (bool delay_pic_helper) since we may not fall out the bottom. */ emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx)); } + +/* Emit a call instruction with the pattern given by PAT. ADDR is the + address of the call target. */ + +void +sparc_emit_call_insn (rtx pat, rtx addr) +{ + rtx insn; + + insn = emit_call_insn (pat); + + /* The PIC register is live on entry to VxWorks PIC PLT entries. */ + if (TARGET_VXWORKS_RTP + && flag_pic + && GET_CODE (addr) == SYMBOL_REF + && (SYMBOL_REF_DECL (addr) + ? !targetm.binds_local_p (SYMBOL_REF_DECL (addr)) + : !SYMBOL_REF_LOCAL_P (addr))) + { + use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx); + current_function_uses_pic_offset_table = 1; + } +} /* Return 1 if RTX is a MEM which is known to be aligned to at least a DESIRED byte boundary. */ @@ -7771,13 +7813,19 @@ sparc_elf_asm_named_section (const char *name, unsigned int flags, the sibling call right? Well, in the C++ case we can end up passing the pointer to the struct return area to a constructor (which returns void) and then nothing else happens. Such a sibling call would look - valid without the added check here. */ + valid without the added check here. + + VxWorks PIC PLT entries require the global pointer to be initialized + on entry. We therefore can't emit sibling calls to them. */ static bool sparc_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED) { return (decl && flag_delayed_branch - && (TARGET_ARCH64 || ! current_function_returns_struct)); + && (TARGET_ARCH64 || ! current_function_returns_struct) + && !(TARGET_VXWORKS_RTP + && flag_pic + && !targetm.binds_local_p (decl))); } /* libfunc renaming. */ diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index db0e34e..1a4805b 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -22,6 +22,8 @@ along with GCC; see the file COPYING. If not, write to the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include "config/vxworks-dummy.h" + /* Note that some other tm.h files include this one and then override whatever definitions are necessary. */ @@ -2409,6 +2411,7 @@ extern int sparc_indent_opcode; else if (GET_CODE (index) == REG) \ fprintf (FILE, "+%s", reg_names[REGNO (index)]); \ else if (GET_CODE (index) == SYMBOL_REF \ + || GET_CODE (index) == LABEL_REF \ || GET_CODE (index) == CONST) \ fputc ('+', FILE), output_addr_const (FILE, index); \ else gcc_unreachable (); \ diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 387b340..6d5797d 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -1874,6 +1874,22 @@ "flag_pic" "or\t%1, %%lo(%a3-(%a2-.)), %0") +;; Set up the PIC register for VxWorks. + +(define_expand "vxworks_load_got" + [(set (match_dup 0) + (high:SI (match_dup 1))) + (set (match_dup 0) + (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1)))) + (set (match_dup 0) + (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))] + "TARGET_VXWORKS_RTP" +{ + operands[0] = pic_offset_table_rtx; + operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE); + operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX); +}) + (define_expand "movdi" [(set (match_operand:DI 0 "nonimmediate_operand" "") (match_operand:DI 1 "general_operand" ""))] @@ -6676,7 +6692,7 @@ { rtx fn_rtx; - gcc_assert (GET_MODE (operands[0]) == FUNCTION_MODE); + gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE); gcc_assert (GET_CODE (operands[3]) == CONST_INT); @@ -6712,18 +6728,20 @@ /* We accept negative sizes for untyped calls. */ if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0) - emit_call_insn + sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx), operands[3], - gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15))))); + gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))), + XEXP (fn_rtx, 0)); else - emit_call_insn + sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx), - gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15))))); + gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))), + XEXP (fn_rtx, 0)); finish_call: @@ -6840,7 +6858,7 @@ rtx fn_rtx; rtvec vec; - gcc_assert (GET_MODE (operands[1]) == FUNCTION_MODE); + gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE); fn_rtx = operands[1]; @@ -6849,7 +6867,7 @@ gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)), gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15))); - emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec)); + sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0)); DONE; }) diff --git a/gcc/config/sparc/t-vxworks b/gcc/config/sparc/t-vxworks new file mode 100644 index 0000000..2aabf1a --- /dev/null +++ b/gcc/config/sparc/t-vxworks @@ -0,0 +1,5 @@ +# Multilibs for VxWorks. + +MULTILIB_OPTIONS = mrtp fPIC +MULTILIB_MATCHES = fPIC=fpic +MULTILIB_EXCEPTIONS = fPIC diff --git a/gcc/config/sparc/vxworks.h b/gcc/config/sparc/vxworks.h new file mode 100644 index 0000000..7faacea --- /dev/null +++ b/gcc/config/sparc/vxworks.h @@ -0,0 +1,64 @@ +/* Definitions of target machine for GNU compiler, + for SPARC targeting the VxWorks run time environment. + Copyright (C) 2007 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_OS_CPP_BUILTINS() \ + do \ + { \ + builtin_define ("__sparc"); \ + builtin_define ("CPU=SIMSPARCSOLARIS"); \ + VXWORKS_OS_CPP_BUILTINS (); \ + } \ + while (0) + +#undef OVERRIDE_OPTIONS +#define OVERRIDE_OPTIONS \ + do \ + { \ + VXWORKS_OVERRIDE_OPTIONS; \ + sparc_override_options (); \ + } \ + while (0) + +#undef CPP_SUBTARGET_SPEC +#define CPP_SUBTARGET_SPEC VXWORKS_ADDITIONAL_CPP_SPEC + +#undef LIB_SPEC +#define LIB_SPEC VXWORKS_LIB_SPEC +#undef LINK_SPEC +#define LINK_SPEC VXWORKS_LINK_SPEC +#undef STARTFILE_SPEC +#define STARTFILE_SPEC VXWORKS_STARTFILE_SPEC +#undef ENDFILE_SPEC +#define ENDFILE_SPEC VXWORKS_ENDFILE_SPEC + +#undef TARGET_VERSION +#define TARGET_VERSION fputs (" (SPARC/VxWorks)", stderr); + +#undef FUNCTION_PROFILER +#define FUNCTION_PROFILER VXWORKS_FUNCTION_PROFILER + +/* Use standard numbered ctors/dtors sections. */ +#undef CTORS_SECTION_ASM_OP +#undef DTORS_SECTION_ASM_OP + +/* We cannot use PC-relative accesses for VxWorks PIC because there is no + fixed gap between segments. */ +#undef ASM_PREFERRED_EH_DATA_FORMAT |