Commit b12a00f1 by Richard Earnshaw Committed by Richard Earnshaw

re PR target/7525 ([ARM/Thumb] long calls stubs only in one code section, cannot…

re PR target/7525 ([ARM/Thumb] long calls stubs only in one code section, cannot branch to them from other section)

PR target/7525
* arm.h (struct machine_function): Add call_via field.
(thumb_call_via_label): Declare.
* arm.c (thumb_call_via_label): New variable.
(thumb_call_reg_needed): New variable.
(arm_output_function_epilogue): For Thumb code, output any per-function
call-indirect trampolines.
(thumb_call_via_reg): New function.
(arm_file_end): New function.
(TARGET_ASM_FILE_END): Call arm_file_end.
(aof_file_end): Likewise.
* arm-protos.h (thumb_call_via_reg): Declare.
* arm.md (call_reg_thumb, call_value_reg_thumb): Call
thumb_call_via_reg in normal case.

From-SVN: r93641
parent c224550f
2005-01-14 Richard Earnshaw <rearnsha@arm.com>
PR target/7525
* arm.h (struct machine_function): Add call_via field.
(thumb_call_via_label): Declare.
* arm.c (thumb_call_via_label): New variable.
(thumb_call_reg_needed): New variable.
(arm_output_function_epilogue): For Thumb code, output any per-function
call-indirect trampolines.
(thumb_call_via_reg): New function.
(arm_file_end): New function.
(TARGET_ASM_FILE_END): Call arm_file_end.
(aof_file_end): Likewise.
* arm-protos.h (thumb_call_via_reg): Declare.
* arm.md (call_reg_thumb, call_value_reg_thumb): Call
thumb_call_via_reg in normal case.
2005-01-14 Jakub Jelinek <jakub@redhat.com> 2005-01-14 Jakub Jelinek <jakub@redhat.com>
PR middle-end/19084 PR middle-end/19084
......
/* Prototypes for exported functions defined in arm.c and pe.c /* Prototypes for exported functions defined in arm.c and pe.c
Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc. Free Software Foundation, Inc.
Contributed by Richard Earnshaw (rearnsha@arm.com) Contributed by Richard Earnshaw (rearnsha@arm.com)
Minor hacks by Nick Clifton (nickc@cygnus.com) Minor hacks by Nick Clifton (nickc@cygnus.com)
...@@ -150,6 +150,7 @@ extern int thumb_shiftable_const (unsigned HOST_WIDE_INT); ...@@ -150,6 +150,7 @@ extern int thumb_shiftable_const (unsigned HOST_WIDE_INT);
extern void thumb_final_prescan_insn (rtx); extern void thumb_final_prescan_insn (rtx);
extern const char *thumb_load_double_from_address (rtx *); extern const char *thumb_load_double_from_address (rtx *);
extern const char *thumb_output_move_mem_multiple (int, rtx *); extern const char *thumb_output_move_mem_multiple (int, rtx *);
extern const char *thumb_call_via_reg (rtx);
extern void thumb_expand_movmemqi (rtx *); extern void thumb_expand_movmemqi (rtx *);
extern rtx *thumb_legitimize_pic_address (rtx, enum machine_mode, rtx); extern rtx *thumb_legitimize_pic_address (rtx, enum machine_mode, rtx);
extern int thumb_go_if_legitimate_address (enum machine_mode, rtx); extern int thumb_go_if_legitimate_address (enum machine_mode, rtx);
......
/* Output routines for GCC for ARM. /* Output routines for GCC for ARM.
Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004 Free Software Foundation, Inc. 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
and Martin Simmons (@harleqn.co.uk). and Martin Simmons (@harleqn.co.uk).
More major hacks by Richard Earnshaw (rearnsha@arm.com). More major hacks by Richard Earnshaw (rearnsha@arm.com).
...@@ -153,6 +153,9 @@ static int arm_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, ...@@ -153,6 +153,9 @@ static int arm_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
#ifndef ARM_PE #ifndef ARM_PE
static void arm_encode_section_info (tree, rtx, int); static void arm_encode_section_info (tree, rtx, int);
#endif #endif
static void arm_file_end (void);
#ifdef AOF_ASSEMBLER #ifdef AOF_ASSEMBLER
static void aof_globalize_label (FILE *, const char *); static void aof_globalize_label (FILE *, const char *);
static void aof_dump_imports (FILE *); static void aof_dump_imports (FILE *);
...@@ -188,6 +191,9 @@ static unsigned HOST_WIDE_INT arm_shift_truncation_mask (enum machine_mode); ...@@ -188,6 +191,9 @@ static unsigned HOST_WIDE_INT arm_shift_truncation_mask (enum machine_mode);
#undef TARGET_ATTRIBUTE_TABLE #undef TARGET_ATTRIBUTE_TABLE
#define TARGET_ATTRIBUTE_TABLE arm_attribute_table #define TARGET_ATTRIBUTE_TABLE arm_attribute_table
#undef TARGET_ASM_FILE_END
#define TARGET_ASM_FILE_END arm_file_end
#ifdef AOF_ASSEMBLER #ifdef AOF_ASSEMBLER
#undef TARGET_ASM_BYTE_OP #undef TARGET_ASM_BYTE_OP
#define TARGET_ASM_BYTE_OP "\tDCB\t" #define TARGET_ASM_BYTE_OP "\tDCB\t"
...@@ -366,6 +372,10 @@ const char * target_abi_name = NULL; ...@@ -366,6 +372,10 @@ const char * target_abi_name = NULL;
const char * structure_size_string = NULL; const char * structure_size_string = NULL;
int arm_structure_size_boundary = DEFAULT_STRUCTURE_SIZE_BOUNDARY; int arm_structure_size_boundary = DEFAULT_STRUCTURE_SIZE_BOUNDARY;
/* Used for Thumb call_via trampolines. */
rtx thumb_call_via_label[13];
static int thumb_call_reg_needed;
/* Bit values used to identify processor capabilities. */ /* Bit values used to identify processor capabilities. */
#define FL_CO_PROC (1 << 0) /* Has external co-processor bus */ #define FL_CO_PROC (1 << 0) /* Has external co-processor bus */
#define FL_ARCH3M (1 << 1) /* Extended multiply */ #define FL_ARCH3M (1 << 1) /* Extended multiply */
...@@ -9600,6 +9610,23 @@ arm_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED, ...@@ -9600,6 +9610,23 @@ arm_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
if (TARGET_THUMB) if (TARGET_THUMB)
{ {
int regno;
/* Emit any call-via-reg trampolines that are needed for v4t support
of call_reg and call_value_reg type insns. */
for (regno = 0; regno < SP_REGNUM; regno++)
{
rtx label = cfun->machine->call_via[regno];
if (label != NULL)
{
function_section (current_function_decl);
targetm.asm_out.internal_label (asm_out_file, "L",
CODE_LABEL_NUMBER (label));
asm_fprintf (asm_out_file, "\tbx\t%r\n", regno);
}
}
/* ??? Probably not safe to set this here, since it assumes that a /* ??? Probably not safe to set this here, since it assumes that a
function will be emitted as assembly immediately after we generate function will be emitted as assembly immediately after we generate
RTL for it. This does not happen for inline functions. */ RTL for it. This does not happen for inline functions. */
...@@ -13652,6 +13679,37 @@ thumb_output_move_mem_multiple (int n, rtx *operands) ...@@ -13652,6 +13679,37 @@ thumb_output_move_mem_multiple (int n, rtx *operands)
return ""; return "";
} }
/* Output a call-via instruction for thumb state. */
const char *
thumb_call_via_reg (rtx reg)
{
int regno = REGNO (reg);
rtx *labelp;
gcc_assert (regno < SP_REGNUM);
/* If we are in the normal text section we can use a single instance
per compilation unit. If we are doing function sections, then we need
an entry per section, since we can't rely on reachability. */
if (in_text_section ())
{
thumb_call_reg_needed = 1;
if (thumb_call_via_label[regno] == NULL)
thumb_call_via_label[regno] = gen_label_rtx ();
labelp = thumb_call_via_label + regno;
}
else
{
if (cfun->machine->call_via[regno] == NULL)
cfun->machine->call_via[regno] = gen_label_rtx ();
labelp = cfun->machine->call_via + regno;
}
output_asm_insn ("bl\t%a0", labelp);
return "";
}
/* Routines for generating rtl. */ /* Routines for generating rtl. */
void void
thumb_expand_movmemqi (rtx *operands) thumb_expand_movmemqi (rtx *operands)
...@@ -13762,6 +13820,31 @@ arm_asm_output_labelref (FILE *stream, const char *name) ...@@ -13762,6 +13820,31 @@ arm_asm_output_labelref (FILE *stream, const char *name)
asm_fprintf (stream, "%U%s", name); asm_fprintf (stream, "%U%s", name);
} }
static void
arm_file_end (void)
{
int regno;
if (! thumb_call_reg_needed)
return;
text_section ();
asm_fprintf (asm_out_file, "\t.code 16\n");
ASM_OUTPUT_ALIGN (asm_out_file, 1);
for (regno = 0; regno < SP_REGNUM; regno++)
{
rtx label = thumb_call_via_label[regno];
if (label != 0)
{
targetm.asm_out.internal_label (asm_out_file, "L",
CODE_LABEL_NUMBER (label));
asm_fprintf (asm_out_file, "\tbx\t%r\n", regno);
}
}
}
rtx aof_pic_label; rtx aof_pic_label;
#ifdef AOF_ASSEMBLER #ifdef AOF_ASSEMBLER
...@@ -13958,6 +14041,7 @@ aof_file_end (void) ...@@ -13958,6 +14041,7 @@ aof_file_end (void)
{ {
if (flag_pic) if (flag_pic)
aof_dump_pic_table (asm_out_file); aof_dump_pic_table (asm_out_file);
arm_file_end ();
aof_dump_imports (asm_out_file); aof_dump_imports (asm_out_file);
fputs ("\tEND\n", asm_out_file); fputs ("\tEND\n", asm_out_file);
} }
......
/* Definitions of target machine for GNU compiler, for ARM. /* Definitions of target machine for GNU compiler, for ARM.
Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004 Free Software Foundation, Inc. 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
and Martin Simmons (@harleqn.co.uk). and Martin Simmons (@harleqn.co.uk).
More major hacks by Richard Earnshaw (rearnsha@arm.com) More major hacks by Richard Earnshaw (rearnsha@arm.com)
...@@ -1703,9 +1703,16 @@ typedef struct machine_function GTY(()) ...@@ -1703,9 +1703,16 @@ typedef struct machine_function GTY(())
/* Records if sibcalls are blocked because an argument /* Records if sibcalls are blocked because an argument
register is needed to preserve stack alignment. */ register is needed to preserve stack alignment. */
int sibcall_blocked; int sibcall_blocked;
/* Labels for per-function Thumb call-via stubs. One per potential calling
register. We can never call via SP, LR or PC. */
rtx call_via[13];
} }
machine_function; machine_function;
/* As in the machine_function, a global set of call-via labels, for code
that is in text_section(). */
extern GTY(()) rtx thumb_call_via_label[13];
/* A C type for declaring a variable that is used as the first argument of /* A C type for declaring a variable that is used as the first argument of
`FUNCTION_ARG' and other related values. For some target machines, the `FUNCTION_ARG' and other related values. For some target machines, the
type `int' suffices and can hold the number of bytes of argument so far. */ type `int' suffices and can hold the number of bytes of argument so far. */
......
;;- Machine description for ARM for GNU compiler ;;- Machine description for ARM for GNU compiler
;; Copyright 1991, 1993, 1994, 1995, 1996, 1996, 1997, 1998, 1999, 2000, ;; Copyright 1991, 1993, 1994, 1995, 1996, 1996, 1997, 1998, 1999, 2000,
;; 2001, 2002, 2003 2004 Free Software Foundation, Inc. ;; 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
;; and Martin Simmons (@harleqn.co.uk). ;; and Martin Simmons (@harleqn.co.uk).
;; More major hacks by Richard Earnshaw (rearnsha@arm.com). ;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
...@@ -7436,7 +7436,7 @@ ...@@ -7436,7 +7436,7 @@
"* "*
{ {
if (!TARGET_CALLER_INTERWORKING) if (!TARGET_CALLER_INTERWORKING)
return \"bl\\t%__call_via_%0\"; return thumb_call_via_reg (operands[0]);
else if (operands[1] == const0_rtx) else if (operands[1] == const0_rtx)
return \"bl\\t%__interwork_call_via_%0\"; return \"bl\\t%__interwork_call_via_%0\";
else if (frame_pointer_needed) else if (frame_pointer_needed)
...@@ -7530,7 +7530,7 @@ ...@@ -7530,7 +7530,7 @@
"* "*
{ {
if (!TARGET_CALLER_INTERWORKING) if (!TARGET_CALLER_INTERWORKING)
return \"bl\\t%__call_via_%1\"; return thumb_call_via_reg (operands[1]);
else if (operands[2] == const0_rtx) else if (operands[2] == const0_rtx)
return \"bl\\t%__interwork_call_via_%1\"; return \"bl\\t%__interwork_call_via_%1\";
else if (frame_pointer_needed) else if (frame_pointer_needed)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment