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
This commit is contained in:
Richard Sandiford 2007-05-10 11:15:07 +00:00 committed by Richard Sandiford
parent 31b40480a4
commit 1910440ea6
10 changed files with 189 additions and 19 deletions

View File

@ -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.

View File

@ -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"

View File

@ -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);

View File

@ -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)
/* 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)
{
emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
return true;
}
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. */

View File

@ -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 (); \

View File

@ -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;
})

View File

@ -0,0 +1,5 @@
# Multilibs for VxWorks.
MULTILIB_OPTIONS = mrtp fPIC
MULTILIB_MATCHES = fPIC=fpic
MULTILIB_EXCEPTIONS = fPIC

View File

@ -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

View File

@ -1,3 +1,7 @@
2007-05-10 Richard Sandiford <richard@codesourcery.com>
* config.host (sparc-wrs-vxworks): New target.
2007-04-14 Kazu Hirata <kazu@codesourcery.com>
* config.host: Recognize fido.

View File

@ -594,6 +594,8 @@ sparc-*-sysv4*)
;;
sparc64-*-elf*)
;;
sparc-wrs-vxworks)
;;
sparc64-*-freebsd*|ultrasparc-*-freebsd*)
;;
sparc64-*-linux*) # 64-bit SPARC's running GNU/Linux