Commit 6a4cee5f by Michael Meissner

Add attribute((longcall)) support

From-SVN: r11416
parent de3a68a1
......@@ -939,6 +939,10 @@ init_cumulative_args (cum, fntype, libname, incoming)
&& lookup_attribute ("dllimport", TYPE_ATTRIBUTES (fntype)))
cum->call_cookie = CALL_NT_DLLIMPORT;
/* Also check for longcall's */
else if (fntype && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype)))
cum->call_cookie = CALL_LONG;
if (TARGET_DEBUG_ARG)
{
fprintf (stderr, "\ninit_cumulative_args:");
......@@ -952,9 +956,12 @@ init_cumulative_args (cum, fntype, libname, incoming)
if (abi == ABI_V4 && incoming)
fprintf (stderr, " varargs = %d, ", cum->varargs_offset);
if (cum->call_cookie == CALL_NT_DLLIMPORT)
if (cum->call_cookie & CALL_NT_DLLIMPORT)
fprintf (stderr, " dllimport,");
if (cum->call_cookie & CALL_LONG)
fprintf (stderr, " longcall,");
fprintf (stderr, " proto = %d, nargs = %d\n",
cum->prototype, cum->nargs_prototype);
}
......@@ -1089,12 +1096,10 @@ function_arg (cum, mode, type, named)
&& cum->nargs_prototype < 0
&& type && (cum->prototype || TARGET_NO_PROTOTYPE))
{
if (cum->call_cookie != CALL_NORMAL)
abort ();
return GEN_INT ((cum->fregno == FP_ARG_MIN_REG)
? CALL_V4_SET_FP_ARGS
: CALL_V4_CLEAR_FP_ARGS);
return GEN_INT (cum->call_cookie
| ((cum->fregno == FP_ARG_MIN_REG)
? CALL_V4_SET_FP_ARGS
: CALL_V4_CLEAR_FP_ARGS));
}
return GEN_INT (cum->call_cookie);
......@@ -4248,6 +4253,11 @@ rs6000_valid_type_attribute_p (type, attributes, identifier, args)
&& TREE_CODE (type) != TYPE_DECL)
return 0;
/* Longcall attribute says that the function is not within 2**26 bytes
of the current function, and to do an indirect call. */
if (is_attribute_p ("longcall", identifier))
return (args == NULL_TREE);
if (DEFAULT_ABI == ABI_NT)
{
/* Stdcall attribute says callee is responsible for popping arguments
......@@ -4324,6 +4334,34 @@ rs6000_dll_import_ref (call_ref)
return reg2;
}
/* Return a reference suitable for calling a function with the longcall attribute. */
struct rtx_def *
rs6000_longcall_ref (call_ref)
rtx call_ref;
{
char *call_name;
int len;
char *p;
rtx reg1, reg2;
tree node;
if (GET_CODE (call_ref) != SYMBOL_REF)
return call_ref;
/* System V adds '.' to the internal name, so skip them. */
call_name = XSTR (call_ref, 0);
if (*call_name == '.')
{
while (*call_name == '.')
call_name++;
node = get_identifier (call_name);
call_ref = gen_rtx (SYMBOL_REF, VOIDmode, IDENTIFIER_POINTER (node));
}
return force_reg (Pmode, call_ref);
}
/* A C statement or statements to switch to the appropriate section
for output of RTX in mode MODE. You can assume that RTX is some
......
......@@ -1246,13 +1246,11 @@ extern int rs6000_sysv_varargs_p;
#define FP_ARG_RETURN FP_ARG_MIN_REG
/* Flags for the call/call_value rtl operations set up by function_arg */
enum rs6000_call_cookie
{
CALL_V4_SET_FP_ARGS = -1, /* V4, FP args passed */
CALL_NORMAL = 0, /* no special processing */
CALL_V4_CLEAR_FP_ARGS = 1, /* V4, no FP args passed */
CALL_NT_DLLIMPORT = 2 /* NT, this is a DLL import call */
};
#define CALL_NORMAL 0x00000000 /* no special processing */
#define CALL_NT_DLLIMPORT 0x00000001 /* NT, this is a DLL import call */
#define CALL_V4_CLEAR_FP_ARGS 0x00000002 /* V.4, no FP args passed */
#define CALL_V4_SET_FP_ARGS 0x00000004 /* V.4, FP args were passed */
#define CALL_LONG 0x00000008 /* always call indirect */
/* Define cutoff for using external functions to save floating point */
#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) == 62 || (FIRST_REG) == 63)
......@@ -1287,13 +1285,13 @@ enum rs6000_call_cookie
typedef struct rs6000_args
{
int words; /* # words uses for passing GP registers */
int fregno; /* next available FP register */
int nargs_prototype; /* # args left in the current prototype */
int orig_nargs; /* Original value of nargs_prototype */
int varargs_offset; /* offset of the varargs save area */
int prototype; /* Whether a prototype was defined */
enum rs6000_call_cookie call_cookie; /* Do special things for this call */
int words; /* # words uses for passing GP registers */
int fregno; /* next available FP register */
int nargs_prototype; /* # args left in the current prototype */
int orig_nargs; /* Original value of nargs_prototype */
int varargs_offset; /* offset of the varargs save area */
int prototype; /* Whether a prototype was defined */
int call_cookie; /* Do special things for this call */
} CUMULATIVE_ARGS;
/* Define intermediate macro to compute the size (in registers) of an argument
......@@ -2879,3 +2877,4 @@ extern int rs6000_valid_decl_attribute_p ();
extern int rs6000_valid_type_attribute_p ();
extern void rs6000_set_default_type_attributes ();
extern struct rtx_def *rs6000_dll_import_ref ();
extern struct rtx_def *rs6000_longcall_ref ();
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