Commit a82c7f05 by Richard Henderson

alpha-protos.h (alpha_arg_info_reg_val): Protect with RTX_CODE.

        * config/alpha/alpha-protos.h (alpha_arg_info_reg_val): Protect
        with RTX_CODE.
        (alpha_write_linkage): Protect with BUFSIZ.
        (alpha_need_linkage): Update prototype.
        * config/alpha/alpha.c (function_arg): Move VMS code here.
        (alpha_links_base): Remove.
        (alpha_links): New.
        (mark_alpha_links_node, mark_alpha_links): New.
        (alpha_write_one_linkage): New.
        (alpha_need_linkage): Use a splay tree.  Build the linkage symbol.
        (alpha_write_linkage): Use splay_tree_foreach.
        * config/alpha/alpha.md (call_vms): Use alpha_need_linkage
        to get the linkage symbol.
        (call_value_vms): Likewise.
        * config/alpha/elf.h (output_file_directive): Remove decl.
        (ctors_section, dtors_section): Prototype.
        (sbss_section, sdata_section): Prototype.
        * config/alpha/vms.h (FUNCTION_ARG): Remove.
        (readonly_section, link_section, literals_section): Prototype.
        (ctors_section, dtors_section): Prototype.
        (vms_valid_decl_attribute_p): Remove decl.
        (alpha_arg_type, alpha_arg_info_reg_val): Likewise.

From-SVN: r34220
parent d80eb1e1
...@@ -109,11 +109,17 @@ extern int check_float_value PARAMS ((enum machine_mode, ...@@ -109,11 +109,17 @@ extern int check_float_value PARAMS ((enum machine_mode,
#ifdef HAVE_MACHINE_MODES #ifdef HAVE_MACHINE_MODES
extern enum avms_arg_type alpha_arg_type PARAMS ((enum machine_mode)); extern enum avms_arg_type alpha_arg_type PARAMS ((enum machine_mode));
#endif #endif
#ifdef RTX_CODE
extern rtx alpha_arg_info_reg_val PARAMS ((CUMULATIVE_ARGS)); extern rtx alpha_arg_info_reg_val PARAMS ((CUMULATIVE_ARGS));
#endif
#ifdef BUFSIZ
extern void alpha_write_linkage PARAMS ((FILE *)); extern void alpha_write_linkage PARAMS ((FILE *));
#endif
#endif /* OPEN_VMS */ #endif /* OPEN_VMS */
extern void alpha_need_linkage PARAMS ((const char *, int)); #ifdef RTX_CODE
extern rtx alpha_need_linkage PARAMS ((const char *, int));
#endif
#ifdef TREE_CODE #ifdef TREE_CODE
extern tree alpha_build_va_list PARAMS ((void)); extern tree alpha_build_va_list PARAMS ((void));
......
...@@ -3722,9 +3722,12 @@ function_arg (cum, mode, type, named) ...@@ -3722,9 +3722,12 @@ function_arg (cum, mode, type, named)
int named ATTRIBUTE_UNUSED; int named ATTRIBUTE_UNUSED;
{ {
int basereg; int basereg;
int num_args;
#ifndef OPEN_VMS
if (cum >= 6) if (cum >= 6)
return NULL_RTX; return NULL_RTX;
num_args = cum;
/* VOID is passed as a special flag for "last argument". */ /* VOID is passed as a special flag for "last argument". */
if (type == void_type_node) if (type == void_type_node)
...@@ -3733,6 +3736,14 @@ function_arg (cum, mode, type, named) ...@@ -3733,6 +3736,14 @@ function_arg (cum, mode, type, named)
return NULL_RTX; return NULL_RTX;
else if (FUNCTION_ARG_PASS_BY_REFERENCE (cum, mode, type, named)) else if (FUNCTION_ARG_PASS_BY_REFERENCE (cum, mode, type, named))
basereg = 16; basereg = 16;
#else
if (mode == VOIDmode)
return alpha_arg_info_reg_val (cum);
num_args = cum.num_args;
if (num_args >= 6 || MUST_PASS_IN_STACK (mode, type))
return NULL_RTX;
#endif /* OPEN_VMS */
else if (TARGET_FPREGS else if (TARGET_FPREGS
&& (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT && (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
|| GET_MODE_CLASS (mode) == MODE_FLOAT)) || GET_MODE_CLASS (mode) == MODE_FLOAT))
...@@ -3740,7 +3751,7 @@ function_arg (cum, mode, type, named) ...@@ -3740,7 +3751,7 @@ function_arg (cum, mode, type, named)
else else
basereg = 16; basereg = 16;
return gen_rtx_REG (mode, cum + basereg); return gen_rtx_REG (mode, num_args + basereg);
} }
tree tree
...@@ -5866,109 +5877,165 @@ alpha_arg_info_reg_val (cum) ...@@ -5866,109 +5877,165 @@ alpha_arg_info_reg_val (cum)
return GEN_INT (regval); return GEN_INT (regval);
} }
#include <splay-tree.h>
/* Structure to collect function names for final output /* Structure to collect function names for final output
in link section. */ in link section. */
enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN}; enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
struct alpha_links
struct alpha_links { {
struct alpha_links *next; rtx linkage;
char *name;
enum links_kind kind; enum links_kind kind;
}; };
static struct alpha_links *alpha_links_base = 0; static splay_tree alpha_links;
static int mark_alpha_links_node PARAMS ((splay_tree_node, void *));
static void mark_alpha_links PARAMS ((void *));
static int alpha_write_one_linkage PARAMS ((splay_tree_node, void *));
/* Protect alpha_links from garbage collection. */
static int
mark_alpha_links_node (node, data)
splay_tree_node node;
void *data ATTRIBUTE_UNUSED;
{
struct alpha_links *links = (struct alpha_links *) node->value;
ggc_mark_rtx (links->linkage);
return 0;
}
static void
mark_alpha_links (ptr)
void *ptr;
{
splay_tree tree = *(splay_tree *) ptr;
splay_tree_foreach (tree, mark_alpha_links_node, NULL);
}
/* Make (or fake) .linkage entry for function call. /* Make (or fake) .linkage entry for function call.
IS_LOCAL is 0 if name is used in call, 1 if name is used in definition. */ IS_LOCAL is 0 if name is used in call, 1 if name is used in definition.
void Return an SYMBOL_REF rtx for the linkage. */
rtx
alpha_need_linkage (name, is_local) alpha_need_linkage (name, is_local)
const char *name; const char *name;
int is_local; int is_local;
{ {
rtx x; splay_tree_node node;
struct alpha_links *lptr, *nptr; struct alpha_links *al;
if (name[0] == '*') if (name[0] == '*')
name++; name++;
/* Is this name already defined ? */ if (alpha_links)
{
/* Is this name already defined? */
for (lptr = alpha_links_base; lptr; lptr = lptr->next) node = splay_tree_lookup (alpha_links, (splay_tree_key) name);
if (strcmp (lptr->name, name) == 0) if (node)
{ {
if (is_local) al = (struct alpha_links *) node->value;
{ if (is_local)
/* Defined here but external assumed. */ {
if (lptr->kind == KIND_EXTERN) /* Defined here but external assumed. */
lptr->kind = KIND_LOCAL; if (al->kind == KIND_EXTERN)
} al->kind = KIND_LOCAL;
else }
{ else
/* Used here but unused assumed. */ {
if (lptr->kind == KIND_UNUSED) /* Used here but unused assumed. */
lptr->kind = KIND_LOCAL; if (al->kind == KIND_UNUSED)
} al->kind = KIND_LOCAL;
return; }
} return al->linkage;
}
}
else
{
alpha_links = splay_tree_new ((splay_tree_compare_fn) strcmp,
(splay_tree_delete_key_fn) free,
(splay_tree_delete_key_fn) free);
ggc_add_root (&alpha_links, 1, 1, mark_alpha_links);
}
nptr = (struct alpha_links *) xmalloc (sizeof (struct alpha_links)); al = (struct alpha_links *) xmalloc (sizeof (struct alpha_links));
nptr->next = alpha_links_base; name = xstrdup (name);
nptr->name = xstrdup (name);
/* Assume external if no definition. */ /* Assume external if no definition. */
nptr->kind = (is_local ? KIND_UNUSED : KIND_EXTERN); al->kind = (is_local ? KIND_UNUSED : KIND_EXTERN);
/* Ensure we have an IDENTIFIER so assemble_name can mark is used. */ /* Ensure we have an IDENTIFIER so assemble_name can mark it used. */
get_identifier (name); get_identifier (name);
alpha_links_base = nptr; /* Construct a SYMBOL_REF for us to call. */
{
size_t name_len = strlen (name);
char *linksym = ggc_alloc_string (NULL, name_len + 6);
linksym[0] = '$';
memcpy (linksym + 1, name, name_len);
memcpy (linksym + 1 + name_len, "..lk", 5);
al->linkage = gen_rtx_SYMBOL_REF (Pmode, linksym);
}
splay_tree_insert (alpha_links, (splay_tree_key) name,
(splay_tree_value) al);
return; return al->linkage;
} }
static int
alpha_write_one_linkage (node, data)
splay_tree_node node;
void *data;
{
const char *name = (const char *) node->key;
struct alpha_links *links = (struct alpha_links *) node->value;
FILE *stream = (FILE *) data;
if (links->kind == KIND_UNUSED
|| ! TREE_SYMBOL_REFERENCED (get_identifier (name)))
return 0;
fprintf (stream, "$%s..lk:\n", name);
if (links->kind == KIND_LOCAL)
{
/* Local and used, build linkage pair. */
fprintf (stream, "\t.quad %s..en\n", name);
fprintf (stream, "\t.quad %s\n", name);
}
else
{
/* External and used, request linkage pair. */
fprintf (stream, "\t.linkage %s\n", name);
}
return 0;
}
void void
alpha_write_linkage (stream) alpha_write_linkage (stream)
FILE *stream; FILE *stream;
{ {
struct alpha_links *lptr, *nptr;
readonly_section (); readonly_section ();
fprintf (stream, "\t.align 3\n"); fprintf (stream, "\t.align 3\n");
splay_tree_foreach (alpha_links, alpha_write_one_linkage, stream);
for (lptr = alpha_links_base; lptr; lptr = nptr)
{
nptr = lptr->next;
if (lptr->kind == KIND_UNUSED
|| ! TREE_SYMBOL_REFERENCED (get_identifier (lptr->name)))
continue;
fprintf (stream, "$%s..lk:\n", lptr->name);
if (lptr->kind == KIND_LOCAL)
{
/* Local and used, build linkage pair. */
fprintf (stream, "\t.quad %s..en\n", lptr->name);
fprintf (stream, "\t.quad %s\n", lptr->name);
}
else
/* External and used, request linkage pair. */
fprintf (stream, "\t.linkage %s\n", lptr->name);
}
} }
#else #else
void rtx
alpha_need_linkage (name, is_local) alpha_need_linkage (name, is_local)
const char *name ATTRIBUTE_UNUSED; const char *name ATTRIBUTE_UNUSED;
int is_local ATTRIBUTE_UNUSED; int is_local ATTRIBUTE_UNUSED;
{ {
return NULL_RTX;
} }
#endif /* OPEN_VMS */ #endif /* OPEN_VMS */
...@@ -3914,24 +3914,9 @@ ...@@ -3914,24 +3914,9 @@
emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]); emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]);
if (GET_CODE (operands[0]) == SYMBOL_REF) if (GET_CODE (operands[0]) == SYMBOL_REF)
{ {
extern char *savealloc (); rtx linkage = alpha_need_linkage (XSTR (operands[0], 0), 0);
const char *symbol = XSTR (operands[0], 0);
char *linksym;
rtx linkage;
if (*symbol == '*')
symbol++;
linksym = savealloc (strlen (symbol) + 6);
alpha_need_linkage (symbol, 0);
linksym[0] = '$';
strcpy (linksym+1, symbol);
strcat (linksym, \"..lk\");
linkage = gen_rtx_SYMBOL_REF (Pmode, linksym);
emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage)); emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage));
operands[2] operands[2]
= validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8))); = validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8)));
} }
...@@ -3939,7 +3924,6 @@ ...@@ -3939,7 +3924,6 @@
{ {
emit_move_insn (gen_rtx_REG (Pmode, 26), emit_move_insn (gen_rtx_REG (Pmode, 26),
gen_rtx_MEM (Pmode, plus_constant (operands[0], 8))); gen_rtx_MEM (Pmode, plus_constant (operands[0], 8)));
operands[2] = operands[0]; operands[2] = operands[0];
} }
...@@ -4035,23 +4019,9 @@ ...@@ -4035,23 +4019,9 @@
emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]); emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
if (GET_CODE (operands[1]) == SYMBOL_REF) if (GET_CODE (operands[1]) == SYMBOL_REF)
{ {
extern char *savealloc (); rtx linkage = alpha_need_linkage (XSTR (operands[1], 0), 0);
const char *symbol = XSTR (operands[1], 0);
char *linksym;
rtx linkage;
if (*symbol == '*')
symbol++;
linksym = savealloc (strlen (symbol) + 6);
alpha_need_linkage (symbol, 0);
linksym[0] = '$';
strcpy (linksym+1, symbol);
strcat (linksym, \"..lk\");
linkage = gen_rtx_SYMBOL_REF (Pmode, linksym);
emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage)); emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage));
operands[3] operands[3]
= validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8))); = validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8)));
} }
...@@ -4059,7 +4029,6 @@ ...@@ -4059,7 +4029,6 @@
{ {
emit_move_insn (gen_rtx_REG (Pmode, 26), emit_move_insn (gen_rtx_REG (Pmode, 26),
gen_rtx_MEM (Pmode, plus_constant (operands[1], 8))); gen_rtx_MEM (Pmode, plus_constant (operands[1], 8)));
operands[3] = operands[1]; operands[3] = operands[1];
} }
}") }")
......
...@@ -66,8 +66,6 @@ do { \ ...@@ -66,8 +66,6 @@ do { \
} \ } \
} while (0) } while (0)
extern void output_file_directive ();
/* Attach a special .ident directive to the end of the file to identify /* Attach a special .ident directive to the end of the file to identify
the version of GCC which compiled this code. The format of the the version of GCC which compiled this code. The format of the
.ident string is patterned after the ones produced by native svr4 .ident string is patterned after the ones produced by native svr4
...@@ -265,6 +263,11 @@ do { \ ...@@ -265,6 +263,11 @@ do { \
SECTION_FUNCTION_TEMPLATE(sbss_section, in_sbss, SBSS_SECTION_ASM_OP) \ SECTION_FUNCTION_TEMPLATE(sbss_section, in_sbss, SBSS_SECTION_ASM_OP) \
SECTION_FUNCTION_TEMPLATE(sdata_section, in_sdata, SDATA_SECTION_ASM_OP) SECTION_FUNCTION_TEMPLATE(sdata_section, in_sdata, SDATA_SECTION_ASM_OP)
extern void ctors_section PARAMS ((void));
extern void dtors_section PARAMS ((void));
extern void sbss_section PARAMS ((void));
extern void sdata_section PARAMS ((void));
#undef READONLY_DATA_SECTION #undef READONLY_DATA_SECTION
#define READONLY_DATA_SECTION() const_section () #define READONLY_DATA_SECTION() const_section ()
...@@ -282,7 +285,6 @@ const_section () \ ...@@ -282,7 +285,6 @@ const_section () \
} }
#define SECTION_FUNCTION_TEMPLATE(FN, ENUM, OP) \ #define SECTION_FUNCTION_TEMPLATE(FN, ENUM, OP) \
void FN PARAMS ((void)); \
void FN () \ void FN () \
{ \ { \
if (in_section != ENUM) \ if (in_section != ENUM) \
......
...@@ -155,41 +155,6 @@ typedef struct {int num_args; enum avms_arg_type atypes[6];} avms_arg_info; ...@@ -155,41 +155,6 @@ typedef struct {int num_args; enum avms_arg_type atypes[6];} avms_arg_info;
(CUM).atypes[0] = (CUM).atypes[1] = (CUM).atypes[2] = I64; \ (CUM).atypes[0] = (CUM).atypes[1] = (CUM).atypes[2] = I64; \
(CUM).atypes[3] = (CUM).atypes[4] = (CUM).atypes[5] = I64; (CUM).atypes[3] = (CUM).atypes[4] = (CUM).atypes[5] = I64;
/* Update the data in CUM to advance over an argument
of mode MODE and data type TYPE.
(TYPE is null for libcalls where that information may not be available.) */
extern enum avms_arg_type alpha_arg_type ();
/* Determine where to put an argument to a function.
Value is zero to push the argument on the stack,
or a hard register in which to store the argument.
MODE is the argument's machine mode (or VOIDmode for no more args).
TYPE is the data type of the argument (as a tree).
This is null for libcalls where that information may
not be available.
CUM is a variable of type CUMULATIVE_ARGS which gives info about
the preceding args and about the function being called.
NAMED is nonzero if this argument is a named parameter
(otherwise it is an extra parameter matching an ellipsis).
On Alpha the first 6 words of args are normally in registers
and the rest are pushed. */
extern struct rtx_def *alpha_arg_info_reg_val ();
#undef FUNCTION_ARG
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
((MODE) == VOIDmode ? alpha_arg_info_reg_val (CUM) \
: ((CUM.num_args) < 6 && ! MUST_PASS_IN_STACK (MODE, TYPE) \
? gen_rtx_REG ((MODE), \
((CUM).num_args + 16 \
+ ((TARGET_FPREGS \
&& (GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT \
|| GET_MODE_CLASS (MODE) == MODE_FLOAT)) \
* 32))) \
: 0))
#undef FUNCTION_ARG_ADVANCE #undef FUNCTION_ARG_ADVANCE
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
if (MUST_PASS_IN_STACK (MODE, TYPE)) \ if (MUST_PASS_IN_STACK (MODE, TYPE)) \
...@@ -333,6 +298,12 @@ dtors_section () \ ...@@ -333,6 +298,12 @@ dtors_section () \
} \ } \
} }
extern void readonly_section PARAMS ((void));
extern void link_section PARAMS ((void));
extern void literals_section PARAMS ((void));
extern void ctors_section PARAMS ((void));
extern void dtors_section PARAMS ((void));
#undef ASM_OUTPUT_ADDR_DIFF_ELT #undef ASM_OUTPUT_ADDR_DIFF_ELT
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) abort () #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) abort ()
...@@ -419,7 +390,6 @@ do { \ ...@@ -419,7 +390,6 @@ do { \
#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, NAME, ARGS) \ #define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, NAME, ARGS) \
(vms_valid_decl_attribute_p (DECL, ATTRIBUTES, NAME, ARGS)) (vms_valid_decl_attribute_p (DECL, ATTRIBUTES, NAME, ARGS))
extern int vms_valid_decl_attribute_p ();
#undef SDB_DEBUGGING_INFO #undef SDB_DEBUGGING_INFO
#undef MIPS_DEBUGGING_INFO #undef MIPS_DEBUGGING_INFO
......
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