config.gcc (arm-wrs-vxworks): Remove dbxelf.h from tm_file.

gcc/
	* config.gcc (arm-wrs-vxworks): Remove dbxelf.h from tm_file.
	Add vx-common.h.  Include vxworks.h between vx-common.h and
	arm/vxworks.h.
	* config/vx-common.h (DWARF2_UNWIND_INFO): Undefine before
	redefining.
	* config/vxworks.h (TARGET_ASM_CONSTRUCTOR): Likewise.
	(TARGET_ASM_DESTRUCTOR): Likewise.
	* config/arm/vxworks.h (TARGET_OS_CPP_BUILTINS): Check arm_arch_xscale
	instead of arm_is_xscale.  Use VXWORKS_OS_CPP_BUILTINS.
	(OVERRIDE_OPTIONS, SUBTARGET_CPP_SPEC): Define.
	(CC1_SPEC): Add -tstrongarm.  Line up backslashes.
	(VXWORKS_ENDIAN_SPEC): Define.
	(ASM_SPEC): Add VXWORKS_ENDIAN_SPEC.
	(LIB_SPEC, STARTFILE_SPEC, ENDFILE_SPEC): Redefine to their
	VXWORKS_* equivalents.
	(LINK_SPEC): Likewise, but add VXWORKS_ENDIAN_SPEC.
	(ASM_FILE_START): Delete.
	(TARGET_VERSION): Reformat.
	(FPUTYPE_DEFAULT, FUNCTION_PROFILER): Define.
	(DEFAULT_STRUCTURE_SIZE_BOUNDARY): Define.
	* config/arm/t-vxworks (LIB1ASMSRC, LIB1ASMFUNCS): Define.
	(FPBIT, DPBIT): Define.
	(fp-bit.c, dp-bit.c): New rules.
	(MULTILIB_OPTIONS): Add strongarm, -mrtp and -mrtp/-fPIC multilibs.
	(MULTILIB_MATCHES, MULTILIB_EXCEPTIONS): Define.
	* config/arm/arm-protos.h (arm_emit_call_insn): Declare.
	* config/arm/arm.h: Include vxworks-dummy.h.
	* config/arm/arm.c (arm_elf_asm_constructor, arm_elf_asm_destructor):
	Mark with ATTRIBUTE_UNUSED.
	(arm_override_options): Do not allow VxWorks RTP PIC to be used
	for Thumb.  Force r9 to be the PIC register for VxWorks RTPs and
	make it incompatible with -msingle-pic-base.
	(arm_function_ok_for_sibcall): Return false for calls that might
	go through a VxWorks PIC PLT entry.
	(require_pic_register): New function, split out from...
	(legitimize_pic_address): ...here.  Do not use GOTOFF accesses
	for VxWorks RTPs.
	(arm_load_pic_register): Handle the VxWorks RTP initialization
	sequence.  Use pic_reg as a shorthand for cfun->machine->pic_reg.
	(arm_emit_call_insn): New function.
	(arm_assemble_integer): Do not use GOTOFF accesses for VxWorks RTP.
	* config/arm/arm.md (UNSPEC_PIC_OFFSET): New unspec number.
	(pic_offset_arm): New pattern.
	(call, call_value): Use arm_emit_call_insn.
	(call_internal, call_value_internal): New expanders.
	* config/arm/lib1funcs.asm (__PLT__): Define to empty for
	VxWorks unless __PIC__.

From-SVN: r125196
This commit is contained in:
Richard Sandiford 2007-05-30 19:04:09 +00:00 committed by Richard Sandiford
parent f52ae0770f
commit 9403b7f7ca
11 changed files with 347 additions and 149 deletions

View File

@ -1,3 +1,53 @@
2007-05-30 Richard Sandiford <richard@codesourcery.com>
* config.gcc (arm-wrs-vxworks): Remove dbxelf.h from tm_file.
Add vx-common.h. Include vxworks.h between vx-common.h and
arm/vxworks.h.
* config/vx-common.h (DWARF2_UNWIND_INFO): Undefine before
redefining.
* config/vxworks.h (TARGET_ASM_CONSTRUCTOR): Likewise.
(TARGET_ASM_DESTRUCTOR): Likewise.
* config/arm/vxworks.h (TARGET_OS_CPP_BUILTINS): Check arm_arch_xscale
instead of arm_is_xscale. Use VXWORKS_OS_CPP_BUILTINS.
(OVERRIDE_OPTIONS, SUBTARGET_CPP_SPEC): Define.
(CC1_SPEC): Add -tstrongarm. Line up backslashes.
(VXWORKS_ENDIAN_SPEC): Define.
(ASM_SPEC): Add VXWORKS_ENDIAN_SPEC.
(LIB_SPEC, STARTFILE_SPEC, ENDFILE_SPEC): Redefine to their
VXWORKS_* equivalents.
(LINK_SPEC): Likewise, but add VXWORKS_ENDIAN_SPEC.
(ASM_FILE_START): Delete.
(TARGET_VERSION): Reformat.
(FPUTYPE_DEFAULT, FUNCTION_PROFILER): Define.
(DEFAULT_STRUCTURE_SIZE_BOUNDARY): Define.
* config/arm/t-vxworks (LIB1ASMSRC, LIB1ASMFUNCS): Define.
(FPBIT, DPBIT): Define.
(fp-bit.c, dp-bit.c): New rules.
(MULTILIB_OPTIONS): Add strongarm, -mrtp and -mrtp/-fPIC multilibs.
(MULTILIB_MATCHES, MULTILIB_EXCEPTIONS): Define.
* config/arm/arm-protos.h (arm_emit_call_insn): Declare.
* config/arm/arm.h: Include vxworks-dummy.h.
* config/arm/arm.c (arm_elf_asm_constructor, arm_elf_asm_destructor):
Mark with ATTRIBUTE_UNUSED.
(arm_override_options): Do not allow VxWorks RTP PIC to be used
for Thumb. Force r9 to be the PIC register for VxWorks RTPs and
make it incompatible with -msingle-pic-base.
(arm_function_ok_for_sibcall): Return false for calls that might
go through a VxWorks PIC PLT entry.
(require_pic_register): New function, split out from...
(legitimize_pic_address): ...here. Do not use GOTOFF accesses
for VxWorks RTPs.
(arm_load_pic_register): Handle the VxWorks RTP initialization
sequence. Use pic_reg as a shorthand for cfun->machine->pic_reg.
(arm_emit_call_insn): New function.
(arm_assemble_integer): Do not use GOTOFF accesses for VxWorks RTP.
* config/arm/arm.md (UNSPEC_PIC_OFFSET): New unspec number.
(pic_offset_arm): New pattern.
(call, call_value): Use arm_emit_call_insn.
(call_internal, call_value_internal): New expanders.
* config/arm/lib1funcs.asm (__PLT__): Define to empty for
VxWorks unless __PIC__.
2007-05-30 Eric Christopher <echristo@gmail.com>
* genrecog.c: Include regs.h in generated file.

View File

@ -697,7 +697,7 @@ arm-semi-aof | armel-semi-aof)
tmake_file="arm/t-arm arm/t-semi"
;;
arm-wrs-vxworks)
tm_file="dbxelf.h elfos.h svr4.h vxworks.h arm/elf.h arm/aout.h ${tm_file} arm/vxworks.h"
tm_file="elfos.h svr4.h arm/elf.h arm/aout.h ${tm_file} vx-common.h vxworks.h arm/vxworks.h"
tmake_file="${tmake_file} arm/t-arm arm/t-vxworks"
;;
arm*-*-freebsd*|strongarm*-*-freebsd*)

View File

@ -102,6 +102,7 @@ extern void arm_reload_out_hi (rtx *);
extern int arm_const_double_inline_cost (rtx);
extern bool arm_const_double_by_parts (rtx);
extern const char *fp_immediate_constant (rtx);
extern void arm_emit_call_insn (rtx, rtx);
extern const char *output_call (rtx *);
extern const char *output_call_mem (rtx *);
extern const char *output_mov_long_double_fpa_from_arm (rtx *);

View File

@ -148,8 +148,8 @@ static int arm_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
tree, bool);
#ifdef OBJECT_FORMAT_ELF
static void arm_elf_asm_constructor (rtx, int);
static void arm_elf_asm_destructor (rtx, int);
static void arm_elf_asm_constructor (rtx, int) ATTRIBUTE_UNUSED;
static void arm_elf_asm_destructor (rtx, int) ATTRIBUTE_UNUSED;
#endif
#ifndef ARM_PE
static void arm_encode_section_info (tree, rtx, int);
@ -1338,10 +1338,23 @@ arm_override_options (void)
ARM_DOUBLEWORD_ALIGN ? "8, 32 or 64": "8 or 32");
}
if (!TARGET_ARM && TARGET_VXWORKS_RTP && flag_pic)
{
error ("RTP PIC is incompatible with Thumb");
flag_pic = 0;
}
/* If stack checking is disabled, we can use r10 as the PIC register,
which keeps r9 available. The EABI specifies r9 as the PIC register. */
if (flag_pic && TARGET_SINGLE_PIC_BASE)
arm_pic_register = (TARGET_APCS_STACK || TARGET_AAPCS_BASED) ? 9 : 10;
{
if (TARGET_VXWORKS_RTP)
warning (0, "RTP PIC is incompatible with -msingle-pic-base");
arm_pic_register = (TARGET_APCS_STACK || TARGET_AAPCS_BASED) ? 9 : 10;
}
if (flag_pic && TARGET_VXWORKS_RTP)
arm_pic_register = 9;
if (arm_pic_register_string != NULL)
{
@ -1354,7 +1367,9 @@ arm_override_options (void)
else if (pic_register < 0 || call_used_regs[pic_register]
|| pic_register == HARD_FRAME_POINTER_REGNUM
|| pic_register == STACK_POINTER_REGNUM
|| pic_register >= PC_REGNUM)
|| pic_register >= PC_REGNUM
|| (TARGET_VXWORKS_RTP
&& (unsigned int) pic_register != arm_pic_register))
error ("unable to use '%s' for PIC register", arm_pic_register_string);
else
arm_pic_register = pic_register;
@ -3214,6 +3229,11 @@ arm_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
if (decl == NULL || TARGET_THUMB)
return false;
/* The PIC register is live on entry to VxWorks PLT entries, so we
must make the call before restoring the PIC register. */
if (TARGET_VXWORKS_RTP && flag_pic && !targetm.binds_local_p (decl))
return false;
/* Cannot tail-call to long calls, since these are out of range of
a branch instruction. */
if (arm_is_long_call_p (decl))
@ -3255,6 +3275,54 @@ legitimate_pic_operand_p (rtx x)
return 1;
}
/* Record that the current function needs a PIC register. Initialize
cfun->machine->pic_reg if we have not already done so. */
static void
require_pic_register (void)
{
/* A lot of the logic here is made obscure by the fact that this
routine gets called as part of the rtx cost estimation process.
We don't want those calls to affect any assumptions about the real
function; and further, we can't call entry_of_function() until we
start the real expansion process. */
if (!current_function_uses_pic_offset_table)
{
gcc_assert (!no_new_pseudos);
if (arm_pic_register != INVALID_REGNUM)
{
cfun->machine->pic_reg = gen_rtx_REG (Pmode, arm_pic_register);
/* Play games to avoid marking the function as needing pic
if we are being called as part of the cost-estimation
process. */
if (current_ir_type () != IR_GIMPLE)
current_function_uses_pic_offset_table = 1;
}
else
{
rtx seq;
cfun->machine->pic_reg = gen_reg_rtx (Pmode);
/* Play games to avoid marking the function as needing pic
if we are being called as part of the cost-estimation
process. */
if (current_ir_type () != IR_GIMPLE)
{
current_function_uses_pic_offset_table = 1;
start_sequence ();
arm_load_pic_register (0UL);
seq = get_insns ();
end_sequence ();
emit_insn_after (seq, entry_of_function ());
}
}
}
}
rtx
legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
{
@ -3267,48 +3335,8 @@ legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
rtx insn;
int subregs = 0;
/* If this function doesn't have a pic register, create one now.
A lot of the logic here is made obscure by the fact that this
routine gets called as part of the rtx cost estimation
process. We don't want those calls to affect any assumptions
about the real function; and further, we can't call
entry_of_function() until we start the real expansion
process. */
if (!current_function_uses_pic_offset_table)
{
gcc_assert (!no_new_pseudos);
if (arm_pic_register != INVALID_REGNUM)
{
cfun->machine->pic_reg = gen_rtx_REG (Pmode, arm_pic_register);
/* Play games to avoid marking the function as needing pic
if we are being called as part of the cost-estimation
process. */
if (current_ir_type () != IR_GIMPLE)
current_function_uses_pic_offset_table = 1;
}
else
{
rtx seq;
cfun->machine->pic_reg = gen_reg_rtx (Pmode);
/* Play games to avoid marking the function as needing pic
if we are being called as part of the cost-estimation
process. */
if (current_ir_type () != IR_GIMPLE)
{
current_function_uses_pic_offset_table = 1;
start_sequence ();
arm_load_pic_register (0UL);
seq = get_insns ();
end_sequence ();
emit_insn_after (seq, entry_of_function ());
}
}
}
/* If this function doesn't have a pic register, create one now. */
require_pic_register ();
if (reg == 0)
{
@ -3335,10 +3363,17 @@ legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
else /* TARGET_THUMB1 */
emit_insn (gen_pic_load_addr_thumb1 (address, orig));
/* 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
use GOTOFF unless we are absolutely sure that the symbol 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 GOTOFF is never valid on VxWorks. */
if ((GET_CODE (orig) == LABEL_REF
|| (GET_CODE (orig) == SYMBOL_REF &&
SYMBOL_REF_LOCAL_P (orig)))
&& NEED_GOT_RELOC)
&& NEED_GOT_RELOC
&& !TARGET_VXWORKS_RTP)
pic_ref = gen_rtx_PLUS (Pmode, cfun->machine->pic_reg, address);
else
{
@ -3478,7 +3513,7 @@ void
arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED)
{
#ifndef AOF_ASSEMBLER
rtx l1, labelno, pic_tmp, pic_tmp2, pic_rtx;
rtx l1, labelno, pic_tmp, pic_tmp2, pic_rtx, pic_reg;
rtx global_offset_table;
if (current_function_uses_pic_offset_table == 0 || TARGET_SINGLE_PIC_BASE)
@ -3486,72 +3521,88 @@ arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED)
gcc_assert (flag_pic);
/* We use an UNSPEC rather than a LABEL_REF because this label never appears
in the code stream. */
pic_reg = cfun->machine->pic_reg;
if (TARGET_VXWORKS_RTP)
{
pic_rtx = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
pic_rtx = gen_rtx_CONST (Pmode, pic_rtx);
emit_insn (gen_pic_load_addr_arm (pic_reg, pic_rtx));
labelno = GEN_INT (pic_labelno++);
l1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
l1 = gen_rtx_CONST (VOIDmode, l1);
emit_insn (gen_rtx_SET (Pmode, pic_reg, gen_rtx_MEM (Pmode, pic_reg)));
global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
/* On the ARM the PC register contains 'dot + 8' at the time of the
addition, on the Thumb it is 'dot + 4'. */
pic_tmp = plus_constant (l1, TARGET_ARM ? 8 : 4);
if (GOT_PCREL)
pic_tmp2 = gen_rtx_CONST (VOIDmode,
gen_rtx_PLUS (Pmode, global_offset_table, pc_rtx));
pic_tmp = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
emit_insn (gen_pic_offset_arm (pic_reg, pic_reg, pic_tmp));
}
else
pic_tmp2 = gen_rtx_CONST (VOIDmode, global_offset_table);
pic_rtx = gen_rtx_CONST (Pmode, gen_rtx_MINUS (Pmode, pic_tmp2, pic_tmp));
if (TARGET_ARM)
{
emit_insn (gen_pic_load_addr_arm (cfun->machine->pic_reg, pic_rtx));
emit_insn (gen_pic_add_dot_plus_eight (cfun->machine->pic_reg,
cfun->machine->pic_reg, labelno));
}
else if (TARGET_THUMB2)
{
/* Thumb-2 only allows very limited access to the PC. Calculate the
address in a temporary register. */
if (arm_pic_register != INVALID_REGNUM)
/* We use an UNSPEC rather than a LABEL_REF because this label
never appears in the code stream. */
labelno = GEN_INT (pic_labelno++);
l1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
l1 = gen_rtx_CONST (VOIDmode, l1);
global_offset_table
= gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
/* On the ARM the PC register contains 'dot + 8' at the time of the
addition, on the Thumb it is 'dot + 4'. */
pic_tmp = plus_constant (l1, TARGET_ARM ? 8 : 4);
if (GOT_PCREL)
{
pic_tmp = gen_rtx_REG (SImode,
thumb_find_work_register (saved_regs));
pic_tmp2 = gen_rtx_PLUS (Pmode, global_offset_table, pc_rtx);
pic_tmp2 = gen_rtx_CONST (VOIDmode, pic_tmp2);
}
else
{
gcc_assert (!no_new_pseudos);
pic_tmp = gen_reg_rtx (Pmode);
}
pic_tmp2 = gen_rtx_CONST (VOIDmode, global_offset_table);
emit_insn (gen_pic_load_addr_thumb2 (cfun->machine->pic_reg, pic_rtx));
emit_insn (gen_pic_load_dot_plus_four (pic_tmp, labelno));
emit_insn (gen_addsi3(cfun->machine->pic_reg, cfun->machine->pic_reg,
pic_tmp));
}
else /* TARGET_THUMB1 */
{
if (arm_pic_register != INVALID_REGNUM
&& REGNO (cfun->machine->pic_reg) > LAST_LO_REGNUM)
pic_rtx = gen_rtx_MINUS (Pmode, pic_tmp2, pic_tmp);
pic_rtx = gen_rtx_CONST (Pmode, pic_rtx);
if (TARGET_ARM)
{
/* We will have pushed the pic register, so we should always be
able to find a work register. */
pic_tmp = gen_rtx_REG (SImode,
thumb_find_work_register (saved_regs));
emit_insn (gen_pic_load_addr_thumb1 (pic_tmp, pic_rtx));
emit_insn (gen_movsi (pic_offset_table_rtx, pic_tmp));
emit_insn (gen_pic_load_addr_arm (pic_reg, pic_rtx));
emit_insn (gen_pic_add_dot_plus_eight (pic_reg, pic_reg, labelno));
}
else if (TARGET_THUMB2)
{
/* Thumb-2 only allows very limited access to the PC. Calculate the
address in a temporary register. */
if (arm_pic_register != INVALID_REGNUM)
{
pic_tmp = gen_rtx_REG (SImode,
thumb_find_work_register (saved_regs));
}
else
{
gcc_assert (!no_new_pseudos);
pic_tmp = gen_reg_rtx (Pmode);
}
emit_insn (gen_pic_load_addr_thumb2 (pic_reg, pic_rtx));
emit_insn (gen_pic_load_dot_plus_four (pic_tmp, labelno));
emit_insn (gen_addsi3 (pic_reg, pic_reg, pic_tmp));
}
else /* TARGET_THUMB1 */
{
if (arm_pic_register != INVALID_REGNUM
&& REGNO (pic_reg) > LAST_LO_REGNUM)
{
/* We will have pushed the pic register, so we should always be
able to find a work register. */
pic_tmp = gen_rtx_REG (SImode,
thumb_find_work_register (saved_regs));
emit_insn (gen_pic_load_addr_thumb1 (pic_tmp, pic_rtx));
emit_insn (gen_movsi (pic_offset_table_rtx, pic_tmp));
}
else
emit_insn (gen_pic_load_addr_thumb1 (pic_reg, pic_rtx));
emit_insn (gen_pic_add_dot_plus_four (pic_reg, pic_reg, labelno));
}
else
emit_insn (gen_pic_load_addr_thumb1 (cfun->machine->pic_reg, pic_rtx));
emit_insn (gen_pic_add_dot_plus_four (cfun->machine->pic_reg,
cfun->machine->pic_reg, labelno));
}
/* 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, cfun->machine->pic_reg));
emit_insn (gen_rtx_USE (VOIDmode, pic_reg));
#endif /* AOF_ASSEMBLER */
}
@ -8862,6 +8913,30 @@ vfp_emit_fstmd (int base_reg, int count)
return count * 8;
}
/* Emit a call instruction with pattern PAT. ADDR is the address of
the call target. */
void
arm_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 the call might use such an entry, add a use of the PIC register
to the instruction's CALL_INSN_FUNCTION_USAGE. */
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)))
{
require_pic_register ();
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), cfun->machine->pic_reg);
}
}
/* Output a 'call' insn. */
const char *
@ -11947,14 +12022,13 @@ arm_assemble_integer (rtx x, unsigned int size, int aligned_p)
if (NEED_GOT_RELOC && flag_pic && making_const_table &&
(GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF))
{
if (GET_CODE (x) == SYMBOL_REF
&& (CONSTANT_POOL_ADDRESS_P (x)
|| SYMBOL_REF_LOCAL_P (x)))
fputs ("(GOTOFF)", asm_out_file);
else if (GET_CODE (x) == LABEL_REF)
fputs ("(GOTOFF)", asm_out_file);
else
/* See legitimize_pic_address for an explanation of the
TARGET_VXWORKS_RTP check. */
if (TARGET_VXWORKS_RTP
|| (GET_CODE (x) == SYMBOL_REF && !SYMBOL_REF_LOCAL_P (x)))
fputs ("(GOT)", asm_out_file);
else
fputs ("(GOTOFF)", asm_out_file);
}
fputc ('\n', asm_out_file);
return true;

View File

@ -26,6 +26,8 @@
#ifndef GCC_ARM_H
#define GCC_ARM_H
#include "config/vxworks-dummy.h"
/* The architecture define. */
extern char arm_arch_name[];

View File

@ -95,6 +95,8 @@
; instruction stream.
(UNSPEC_STACK_ALIGN 20) ; Doubleword aligned stack pointer. Used to
; generate correct unwind information.
(UNSPEC_PIC_OFFSET 22) ; A symbolic 12-bit OFFSET that has been treated
; correctly for PIC usage.
]
)
@ -4919,6 +4921,16 @@
""
)
(define_insn "pic_offset_arm"
[(set (match_operand:SI 0 "register_operand" "=r")
(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
(unspec:SI [(match_operand:SI 2 "" "X")]
UNSPEC_PIC_OFFSET))))]
"TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
"ldr%?\\t%0, [%1,%2]"
[(set_attr "type" "load1")]
)
(define_expand "builtin_setjmp_receiver"
[(label_ref (match_operand 0 "" ""))]
"flag_pic"
@ -8145,7 +8157,7 @@
"TARGET_EITHER"
"
{
rtx callee;
rtx callee, pat;
/* In an untyped call, we can get NULL for operand 2. */
if (operands[2] == NULL_RTX)
@ -8159,9 +8171,19 @@
? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
: !REG_P (callee))
XEXP (operands[0], 0) = force_reg (Pmode, callee);
pat = gen_call_internal (operands[0], operands[1], operands[2]);
arm_emit_call_insn (pat, XEXP (operands[0], 0));
DONE;
}"
)
(define_expand "call_internal"
[(parallel [(call (match_operand 0 "memory_operand" "")
(match_operand 1 "general_operand" ""))
(use (match_operand 2 "" ""))
(clobber (reg:SI LR_REGNUM))])])
(define_insn "*call_reg_armv5"
[(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
(match_operand 1 "" ""))
@ -8239,7 +8261,7 @@
"TARGET_EITHER"
"
{
rtx callee;
rtx pat, callee;
/* In an untyped call, we can get NULL for operand 2. */
if (operands[3] == 0)
@ -8253,9 +8275,21 @@
? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
: !REG_P (callee))
XEXP (operands[1], 0) = force_reg (Pmode, callee);
pat = gen_call_value_internal (operands[0], operands[1],
operands[2], operands[3]);
arm_emit_call_insn (pat, XEXP (operands[1], 0));
DONE;
}"
)
(define_expand "call_value_internal"
[(parallel [(set (match_operand 0 "" "")
(call (match_operand 1 "memory_operand" "")
(match_operand 2 "general_operand" "")))
(use (match_operand 3 "" ""))
(clobber (reg:SI LR_REGNUM))])])
(define_insn "*call_value_reg_armv5"
[(set (match_operand 0 "" "")
(call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))

View File

@ -54,6 +54,8 @@ Boston, MA 02110-1301, USA. */
#ifdef __ELF__
#ifdef __thumb__
#define __PLT__ /* Not supported in Thumb assembler (for now). */
#elif defined __vxworks && !defined __PIC__
#define __PLT__ /* Not supported by the kernel loader. */
#else
#define __PLT__ (PLT)
#endif

View File

@ -1,10 +1,27 @@
# Multilibs for VxWorks.
LIB1ASMSRC = arm/lib1funcs.asm
LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _bb_init_func _call_via_rX _interwork_call_via_rX
# We want fine grained libraries, so use the new code to build the
# floating point emulation libraries.
FPBIT = fp-bit.c
DPBIT = dp-bit.c
fp-bit.c: $(srcdir)/config/fp-bit.c
echo '#define FLOAT' > fp-bit.c
echo '#ifndef __ARMEB__' >> fp-bit.c
echo '#define FLOAT_BIT_ORDER_MISMATCH' >> fp-bit.c
echo '#endif' >> fp-bit.c
cat $(srcdir)/config/fp-bit.c >> fp-bit.c
dp-bit.c: $(srcdir)/config/fp-bit.c
echo '#ifndef __ARMEB__' > dp-bit.c
echo '#define FLOAT_BIT_ORDER_MISMATCH' >> dp-bit.c
echo '#endif' >> dp-bit.c
cat $(srcdir)/config/fp-bit.c >> dp-bit.c
MULTILIB_OPTIONS = \
t4/t4be/t4t/t4tbe/t5/t5be/t5t/t5tbe/txscale/txscalebe
MULTILIB_DIRNAMES = \
ARMARCH4gnu ARMARCH4gnube ARMARCH4_Tgnu ARMARCH4_Tgnube \
ARMARCH5gnu ARMARCH5gnube ARMARCH5_Tgnu ARMARCH5_Tgnube \
XSCALEgnu XSCALEgnube
mrtp fPIC \
t4/t4be/t4t/t4tbe/t5/t5be/t5t/t5tbe/tstrongarm/txscale/txscalebe
MULTILIB_MATCHES = fPIC=fpic
# Don't build -fPIC multilibs for kernel or Thumb code.
MULTILIB_EXCEPTIONS = fPIC* mrtp/fPIC/*t[45]t*

View File

@ -25,13 +25,12 @@ Boston, MA 02110-1301, USA. */
#define TARGET_OS_CPP_BUILTINS() \
do { \
builtin_define ("__vxworks"); \
if (TARGET_BIG_END) \
builtin_define ("ARMEB"); \
else \
builtin_define ("ARMEL"); \
\
if (arm_is_xscale) \
if (arm_arch_xscale) \
builtin_define ("CPU=XSCALE"); \
else if (arm_arch5) \
builtin_define ("CPU=ARMARCH5"); \
@ -42,54 +41,70 @@ Boston, MA 02110-1301, USA. */
else \
builtin_define ("CPU=ARMARCH4"); \
} \
VXWORKS_OS_CPP_BUILTINS (); \
} while (0)
#undef OVERRIDE_OPTIONS
#define OVERRIDE_OPTIONS \
do \
{ \
VXWORKS_OVERRIDE_OPTIONS; \
arm_override_options (); \
} \
while (0)
/* Subsume the arm/elf.h definition, and add RTP hooks. */
#undef SUBTARGET_CPP_SPEC
#define SUBTARGET_CPP_SPEC "-D__ELF__" VXWORKS_ADDITIONAL_CPP_SPEC
#undef CC1_SPEC
#define CC1_SPEC \
"%{t4: -mlittle-endian -march=armv4 ; \
t4be: -mbig-endian -march=armv4 ; \
"%{tstrongarm:-mlittle-endian -mcpu=strongarm ; \
t4: -mlittle-endian -march=armv4 ; \
t4be: -mbig-endian -march=armv4 ; \
t4t: -mthumb -mthumb-interwork -mlittle-endian -march=armv4t ; \
t4tbe: -mthumb -mthumb-interwork -mbig-endian -march=armv4t ; \
t5: -mlittle-endian -march=armv5 ; \
t5be: -mbig-endian -march=armv5 ; \
t5: -mlittle-endian -march=armv5 ; \
t5be: -mbig-endian -march=armv5 ; \
t5t: -mthumb -mthumb-interwork -mlittle-endian -march=armv5 ; \
t5tbe: -mthumb -mthumb-interwork -mbig-endian -march=armv5 ; \
txscale: -mlittle-endian -mcpu=xscale ; \
txscalebe: -mbig-endian -mcpu=xscale ; \
txscale: -mlittle-endian -mcpu=xscale ; \
txscalebe: -mbig-endian -mcpu=xscale ; \
: -march=armv4}"
/* Pass -EB for big-endian targets. */
#define VXWORKS_ENDIAN_SPEC \
"%{mbig-endian|t4be|t4tbe|t5be|t5tbe|txscalebe:-EB}"
/* The -Q options from svr4.h aren't understood and must be removed. */
#undef ASM_SPEC
#define ASM_SPEC \
"%{v:-V} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*}"
"%{v:-V} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} " VXWORKS_ENDIAN_SPEC
/* VxWorks does all the library stuff itself. */
#undef LIB_SPEC
#define LIB_SPEC ""
#undef LINK_SPEC
#define LINK_SPEC VXWORKS_LINK_SPEC " " VXWORKS_ENDIAN_SPEC
/* VxWorks uses object files, not loadable images. make linker just
combine objects. */
#undef LINK_SPEC
#define LINK_SPEC "-r"
#undef LIB_SPEC
#define LIB_SPEC VXWORKS_LIB_SPEC
/* VxWorks provides the functionality of crt0.o and friends itself. */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC ""
#undef STARTFILE_SPEC
#define STARTFILE_SPEC VXWORKS_STARTFILE_SPEC
#undef ENDFILE_SPEC
#define ENDFILE_SPEC ""
#undef ENDFILE_SPEC
#define ENDFILE_SPEC VXWORKS_ENDFILE_SPEC
#undef TARGET_VERSION
#define TARGET_VERSION fputs (" (ARM/VxWorks)", stderr);
#undef TARGET_VERSION
#define TARGET_VERSION fputs (" (ARM/VxWorks)", stderr);
/* There is no default multilib. */
#undef MULTILIB_DEFAULTS
#undef ASM_FILE_START
#define ASM_FILE_START(STREAM) \
do \
{ \
fprintf (STREAM, "%s Generated by GCC %s for ARM/VxWorks\n", \
ASM_COMMENT_START, version_string); \
} \
while (0)
#define FPUTYPE_DEFAULT FPUTYPE_VFP
#undef FUNCTION_PROFILER
#define FUNCTION_PROFILER VXWORKS_FUNCTION_PROFILER
/* We want to be compatible with a version of "2.96" at one point in
the past before this macro was changed. */
#undef DEFAULT_STRUCTURE_SIZE_BOUNDARY
#define DEFAULT_STRUCTURE_SIZE_BOUNDARY 8

View File

@ -63,6 +63,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#define WINT_TYPE_SIZE 16
/* Dwarf2 unwind info is not supported. */
#undef DWARF2_UNWIND_INFO
#define DWARF2_UNWIND_INFO 0
/* VxWorks uses DWARF2. */

View File

@ -92,7 +92,9 @@ extern void vxworks_override_options (void);
/* VxWorks requires special handling of constructors and destructors.
All VxWorks configurations must use these functions. */
#undef TARGET_ASM_CONSTRUCTOR
#define TARGET_ASM_CONSTRUCTOR vxworks_asm_out_constructor
#undef TARGET_ASM_DESTRUCTOR
#define TARGET_ASM_DESTRUCTOR vxworks_asm_out_destructor
extern void vxworks_asm_out_constructor (rtx symbol, int priority);
extern void vxworks_asm_out_destructor (rtx symbol, int priority);