From 9403b7f7ca8b53fd375cd3eeef000cd673e9aea1 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 30 May 2007 19:04:09 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 50 ++++++++ gcc/config.gcc | 2 +- gcc/config/arm/arm-protos.h | 1 + gcc/config/arm/arm.c | 284 +++++++++++++++++++++++++++---------------- gcc/config/arm/arm.h | 2 + gcc/config/arm/arm.md | 38 +++++- gcc/config/arm/lib1funcs.asm | 2 + gcc/config/arm/t-vxworks | 31 +++-- gcc/config/arm/vxworks.h | 77 +++++++----- gcc/config/vx-common.h | 1 + gcc/config/vxworks.h | 2 + 11 files changed, 344 insertions(+), 146 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1d68df0..940dd31 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,53 @@ +2007-05-30 Richard Sandiford + + * 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 * genrecog.c: Include regs.h in generated file. diff --git a/gcc/config.gcc b/gcc/config.gcc index 977aafe..1b7caa8 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -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*) 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 diff --git a/gcc/config/vx-common.h b/gcc/config/vx-common.h index 992cdcd..d2ae673 100644 --- a/gcc/config/vx-common.h +++ b/gcc/config/vx-common.h @@ -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. */ diff --git a/gcc/config/vxworks.h b/gcc/config/vxworks.h index b4351a2..c975371 100644 --- a/gcc/config/vxworks.h +++ b/gcc/config/vxworks.h @@ -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); -- 2.7.4