aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/arm
diff options
context:
space:
mode:
authorRichard Sandiford <richard@codesourcery.com>2007-05-30 19:04:09 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2007-05-30 19:04:09 +0000
commit9403b7f7ca8b53fd375cd3eeef000cd673e9aea1 (patch)
treebaff0d3a538bb698c45e8ef4c45ce55e481960cf /gcc/config/arm
parentf52ae0770fce807982338b7018c30c7c6cf77d3a (diff)
downloadgcc-9403b7f7ca8b53fd375cd3eeef000cd673e9aea1.zip
gcc-9403b7f7ca8b53fd375cd3eeef000cd673e9aea1.tar.gz
gcc-9403b7f7ca8b53fd375cd3eeef000cd673e9aea1.tar.bz2
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
Diffstat (limited to 'gcc/config/arm')
-rw-r--r--gcc/config/arm/arm-protos.h1
-rw-r--r--gcc/config/arm/arm.c284
-rw-r--r--gcc/config/arm/arm.h2
-rw-r--r--gcc/config/arm/arm.md38
-rw-r--r--gcc/config/arm/lib1funcs.asm2
-rw-r--r--gcc/config/arm/t-vxworks31
-rw-r--r--gcc/config/arm/vxworks.h77
7 files changed, 290 insertions, 145 deletions
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index d9ec19a..ea81271 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -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 *);
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index cf7c62c..587b74f 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -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. */
-
- 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_tmp2 = gen_rtx_CONST (VOIDmode,
- gen_rtx_PLUS (Pmode, global_offset_table, pc_rtx));
- else
- pic_tmp2 = gen_rtx_CONST (VOIDmode, global_offset_table);
+ 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));
- pic_rtx = gen_rtx_CONST (Pmode, gen_rtx_MINUS (Pmode, pic_tmp2, pic_tmp));
+ emit_insn (gen_rtx_SET (Pmode, pic_reg, gen_rtx_MEM (Pmode, pic_reg)));
- 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));
+ pic_tmp = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
+ emit_insn (gen_pic_offset_arm (pic_reg, pic_reg, pic_tmp));
}
- else if (TARGET_THUMB2)
+ else
{
- /* 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
+ pic_tmp2 = gen_rtx_CONST (VOIDmode, global_offset_table);
+
+ pic_rtx = gen_rtx_MINUS (Pmode, pic_tmp2, pic_tmp);
+ pic_rtx = gen_rtx_CONST (Pmode, pic_rtx);
+
+ if (TARGET_ARM)
{
- gcc_assert (!no_new_pseudos);
- pic_tmp = gen_reg_rtx (Pmode);
+ 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 (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)
+ 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 */
{
- /* 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));
+ 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;
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index e73b576..62d7485 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -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[];
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 2ae732a..664f23d 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -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"))
diff --git a/gcc/config/arm/lib1funcs.asm b/gcc/config/arm/lib1funcs.asm
index 4cc6b60..0c6e440 100644
--- a/gcc/config/arm/lib1funcs.asm
+++ b/gcc/config/arm/lib1funcs.asm
@@ -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
diff --git a/gcc/config/arm/t-vxworks b/gcc/config/arm/t-vxworks
index e620cfd..978aa5e 100644
--- a/gcc/config/arm/t-vxworks
+++ b/gcc/config/arm/t-vxworks
@@ -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
-MULTILIB_OPTIONS = \
- t4/t4be/t4t/t4tbe/t5/t5be/t5t/t5tbe/txscale/txscalebe
+# 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
-MULTILIB_DIRNAMES = \
- ARMARCH4gnu ARMARCH4gnube ARMARCH4_Tgnu ARMARCH4_Tgnube \
- ARMARCH5gnu ARMARCH5gnube ARMARCH5_Tgnu ARMARCH5_Tgnube \
- XSCALEgnu XSCALEgnube
+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 = \
+ 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*
diff --git a/gcc/config/arm/vxworks.h b/gcc/config/arm/vxworks.h
index 319c1e8..e3f2be0 100644
--- a/gcc/config/arm/vxworks.h
+++ b/gcc/config/arm/vxworks.h
@@ -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