OSDN Git Service

gcc/
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 30 May 2007 19:04:09 +0000 (19:04 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 30 May 2007 19:04:09 +0000 (19:04 +0000)
* 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__.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@125196 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config.gcc
gcc/config/arm/arm-protos.h
gcc/config/arm/arm.c
gcc/config/arm/arm.h
gcc/config/arm/arm.md
gcc/config/arm/lib1funcs.asm
gcc/config/arm/t-vxworks
gcc/config/arm/vxworks.h
gcc/config/vx-common.h
gcc/config/vxworks.h

index 1d68df0..940dd31 100644 (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.
index 977aafe..1b7caa8 100644 (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*)
index d9ec19a..ea81271 100644 (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 *);
index cf7c62c..587b74f 100644 (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.  */
-
-  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;
index e73b576..62d7485 100644 (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[];
 
index 2ae732a..664f23d 100644 (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.
   ]
 )
 
   ""
 )
 
+(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"
   "TARGET_EITHER"
   "
   {
-    rtx callee;
+    rtx callee, pat;
     
     /* In an untyped call, we can get NULL for operand 2.  */
     if (operands[2] == NULL_RTX)
        ? 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 "" ""))
   "TARGET_EITHER"
   "
   {
-    rtx callee;
+    rtx pat, callee;
     
     /* In an untyped call, we can get NULL for operand 2.  */
     if (operands[3] == 0)
        ? 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"))
index 4cc6b60..0c6e440 100644 (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
index e620cfd..978aa5e 100644 (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
 
-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*
index 319c1e8..e3f2be0 100644 (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
index 992cdcd..d2ae673 100644 (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.  */
index b4351a2..c975371 100644 (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);