Commit 7509c759 by Michael Meissner

Small data support; Windows NT attributes; windows NT call indrect fix

From-SVN: r11093
parent 8b4f9969
......@@ -77,13 +77,7 @@ Boston, MA 02111-1307, USA. */
}
#undef LINK_SPEC
#ifndef CROSS_COMPILE
#define LINK_SPEC "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro} -bnodelcsect\
%{static:-bnso -bI:/lib/syscalls.exp} %{!shared: %{g*:-bexport:/usr/lib/libg.exp}}\
%{static:-bnso %(link_syscalls) } %{!shared: %{g*: %(link_libg) }}\
%{shared:-bM:SRE}"
#else
#define LINK_SPEC "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro} -bnodelcsect\
%{static:-bnso} \
%{shared:-bM:SRE}"
#endif
......@@ -68,6 +68,10 @@ Boston, MA 02111-1307, USA. */
#define CPP_PREDEFINES \
"-DPPC -D__embedded__ -Asystem(embedded) -Acpu(powerpc) -Amachine(powerpc)"
/* Clue the simulator in to use netbsd */
#undef LINK_START_SPEC
#define LINK_START_SPEC "%{msim: %{!Ttext*: -Ttext 0x10000000}}"
/* Use the simulator crt0 or mvme and libgloss/newlib libraries if desired */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "crti.o%s \
......
......@@ -37,4 +37,4 @@ Boston, MA 02111-1307, USA. */
`MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */
#undef MULTILIB_DEFAULTS
#define MULTILIB_DEFAULTS { "mbig", "mbig-endian", "mcall-aix" }
#define MULTILIB_DEFAULTS { "mbig", "mbig-endian", "mcall-aix", "mno-sdata" }
......@@ -41,4 +41,4 @@ Boston, MA 02111-1307, USA. */
`MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */
#undef MULTILIB_DEFAULTS
#define MULTILIB_DEFAULTS { "mlittle", "mlittle-endian", "mcall-sysv" }
#define MULTILIB_DEFAULTS { "mlittle", "mlittle-endian", "mcall-sysv", "mno-sdata" }
......@@ -29,6 +29,10 @@ Boston, MA 02111-1307, USA. */
#define CPP_PREDEFINES \
"-DPPC -D__embedded__ -D__simulator__ -Asystem(embedded) -Asystem(simulator) -Acpu(powerpc) -Amachine(powerpc)"
/* Clue the simulator in to use netbsd */
#undef LINK_START_SPEC
#define LINK_START_SPEC "%{!mmvme: %{!Ttext*: -Ttext 0x10000000}}"
/* Use the simulator crt0 or mvme and libgloss/newlib libraries if desired */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "crti.o%s \
......
......@@ -37,6 +37,10 @@ Boston, MA 02111-1307, USA. */
#include "obstack.h"
#include "tree.h"
#ifndef TARGET_NO_PROTOTYPE
#define TARGET_NO_PROTOTYPE 0
#endif
extern char *language_string;
extern int profile_block_flag;
......@@ -836,6 +840,29 @@ input_operand (op, mode)
for an add will be valid. */
return add_operand (op, mode);
}
/* Return 1 for an operand in small memory on V.4/eabi */
int
small_data_operand (op, mode)
rtx op;
enum machine_mode mode;
{
rtx sym_ref, const_part;
if (DEFAULT_ABI != ABI_V4)
return 0;
if (GET_CODE (op) != SYMBOL_REF && GET_CODE (op) != CONST)
return 0;
sym_ref = eliminate_constant_term (op, &const_part);
if (!sym_ref || GET_CODE (sym_ref) != SYMBOL_REF || *XSTR (sym_ref, 0) != '@')
return 0;
return 1;
}
/* Initialize a variable CUM of type CUMULATIVE_ARGS
for a call to a function whose data type is FNTYPE.
......@@ -852,19 +879,19 @@ init_cumulative_args (cum, fntype, libname, incoming)
int incoming;
{
static CUMULATIVE_ARGS zero_cumulative;
enum rs6000_abi abi = DEFAULT_ABI;
*cum = zero_cumulative;
cum->words = 0;
cum->fregno = FP_ARG_MIN_REG;
cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
cum->call_cookie = CALL_NORMAL;
if (incoming)
{
cum->nargs_prototype = 1000; /* don't return an EXPR_LIST */
#ifdef TARGET_V4_CALLS
if (TARGET_V4_CALLS)
if (abi == ABI_V4)
cum->varargs_offset = RS6000_VARARGS_OFFSET;
#endif
}
else if (cum->prototype)
......@@ -876,6 +903,13 @@ init_cumulative_args (cum, fntype, libname, incoming)
cum->nargs_prototype = 0;
cum->orig_nargs = cum->nargs_prototype;
/* Check for DLL import functions */
if (abi == ABI_NT
&& fntype
&& lookup_attribute ("dllimport", TYPE_ATTRIBUTES (fntype)))
cum->call_cookie = CALL_NT_DLLIMPORT;
if (TARGET_DEBUG_ARG)
{
fprintf (stderr, "\ninit_cumulative_args:");
......@@ -886,10 +920,11 @@ init_cumulative_args (cum, fntype, libname, incoming)
tree_code_name[ (int)TREE_CODE (ret_type) ]);
}
#ifdef TARGET_V4_CALLS
if (TARGET_V4_CALLS && incoming)
if (abi == ABI_V4 && incoming)
fprintf (stderr, " varargs = %d, ", cum->varargs_offset);
#endif
if (cum->call_cookie == CALL_NT_DLLIMPORT)
fprintf (stderr, " dllimport,");
fprintf (stderr, " proto = %d, nargs = %d\n",
cum->prototype, cum->nargs_prototype);
......@@ -936,8 +971,7 @@ function_arg_advance (cum, mode, type, named)
cum->words += align;
cum->nargs_prototype--;
#ifdef TARGET_V4_CALLS
if (TARGET_V4_CALLS)
if (DEFAULT_ABI == ABI_V4)
{
/* Long longs must not be split between registers and stack */
if ((GET_MODE_CLASS (mode) != MODE_FLOAT || TARGET_SOFT_FLOAT)
......@@ -963,7 +997,6 @@ function_arg_advance (cum, mode, type, named)
cum->words += RS6000_ARG_SIZE (mode, type, 1);
}
else
#endif
if (named)
{
cum->words += RS6000_ARG_SIZE (mode, type, named);
......@@ -1020,20 +1053,27 @@ function_arg (cum, mode, type, named)
marker for software floating point, or compiler generated library calls. */
if (mode == VOIDmode)
{
#ifdef TARGET_V4_CALLS
if (TARGET_V4_CALLS && TARGET_HARD_FLOAT && cum->nargs_prototype < 0
enum rs6000_abi abi = DEFAULT_ABI;
if (abi == ABI_V4
&& TARGET_HARD_FLOAT
&& cum->nargs_prototype < 0
&& type && (cum->prototype || TARGET_NO_PROTOTYPE))
return GEN_INT ((cum->fregno == FP_ARG_MIN_REG) ? -1 : 1);
#endif
{
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 (0);
return GEN_INT (cum->call_cookie);
}
if (!named)
{
#ifdef TARGET_V4_CALLS
if (!TARGET_V4_CALLS)
#endif
if (DEFAULT_ABI != ABI_V4)
return NULL_RTX;
}
......@@ -1043,9 +1083,7 @@ function_arg (cum, mode, type, named)
if (USE_FP_FOR_ARG_P (*cum, mode, type))
{
if ((cum->nargs_prototype > 0)
#ifdef TARGET_V4_CALLS
|| TARGET_V4_CALLS /* V.4 never passes FP values in GP registers */
#endif
|| (DEFAULT_ABI == ABI_V4) /* V.4 never passes FP values in GP registers */
|| !type)
return gen_rtx (REG, mode, cum->fregno);
......@@ -1056,14 +1094,12 @@ function_arg (cum, mode, type, named)
gen_rtx (REG, mode, cum->fregno));
}
#ifdef TARGET_V4_CALLS
/* Long longs won't be split between register and stack */
else if (TARGET_V4_CALLS &&
else if (DEFAULT_ABI == ABI_V4 &&
align_words + RS6000_ARG_SIZE (mode, type, named) > GP_ARG_NUM_REG)
{
return NULL_RTX;
}
#endif
else if (align_words < GP_ARG_NUM_REG)
return gen_rtx (REG, mode, GP_ARG_MIN_REG + align_words);
......@@ -1085,10 +1121,8 @@ function_arg_partial_nregs (cum, mode, type, named)
if (! named)
return 0;
#ifdef TARGET_V4_CALLS
if (TARGET_V4_CALLS)
if (DEFAULT_ABI == ABI_V4)
return 0;
#endif
if (USE_FP_FOR_ARG_P (*cum, mode, type))
{
......@@ -1124,15 +1158,13 @@ function_arg_pass_by_reference (cum, mode, type, named)
tree type;
int named;
{
#ifdef TARGET_V4_CALLS
if (TARGET_V4_CALLS && type && AGGREGATE_TYPE_P (type))
if (DEFAULT_ABI == ABI_V4 && type && AGGREGATE_TYPE_P (type))
{
if (TARGET_DEBUG_ARG)
fprintf (stderr, "function_arg_pass_by_reference: aggregate\n");
return 1;
}
#endif
return 0;
}
......@@ -1169,13 +1201,11 @@ setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
"setup_vararg: words = %2d, fregno = %2d, nargs = %4d, proto = %d, mode = %4s, no_rtl= %d\n",
cum->words, cum->fregno, cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode), no_rtl);
#ifdef TARGET_V4_CALLS
if (TARGET_V4_CALLS && !no_rtl)
if (DEFAULT_ABI == ABI_V4 && !no_rtl)
{
rs6000_sysv_varargs_p = 1;
save_area = plus_constant (frame_pointer_rtx, RS6000_VARARGS_OFFSET);
}
#endif
if (cum->words < 8)
{
......@@ -1198,9 +1228,8 @@ setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
*pretend_size = (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD;
}
#ifdef TARGET_V4_CALLS
/* Save FP registers if needed. */
if (TARGET_V4_CALLS && TARGET_HARD_FLOAT && !no_rtl)
if (DEFAULT_ABI == ABI_V4 && TARGET_HARD_FLOAT && !no_rtl)
{
int fregno = cum->fregno;
int num_fp_reg = FP_ARG_V4_MAX_REG + 1 - fregno;
......@@ -1228,7 +1257,6 @@ setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
emit_label (lab);
}
}
#endif
}
/* If defined, is a C expression that produces the machine-specific
......@@ -2342,13 +2370,14 @@ print_operand_address (file, x)
else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
{
output_addr_const (file, x);
/* When TARGET_MINIMAL_TOC, use the indirected toc table pointer instead
of the toc pointer. */
if (DEFAULT_ABI == ABI_V4 && small_data_operand (x, GET_MODE (x)))
fprintf (file, "@sda21(%s)", reg_names[0]);
#ifdef TARGET_NO_TOC
if (TARGET_NO_TOC)
else if (TARGET_NO_TOC)
;
else
#endif
else
fprintf (file, "(%s)", reg_names[ TARGET_MINIMAL_TOC ? 30 : 2 ]);
}
else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
......@@ -3996,3 +4025,185 @@ rs6000_initialize_trampoline (addr, fnaddr, cxt)
return;
}
/* If defined, a C expression whose value is nonzero if IDENTIFIER
with arguments ARGS is a valid machine specific attribute for DECL.
The attributes in ATTRIBUTES have previously been assigned to DECL. */
int
rs6000_valid_decl_attribute_p (decl, attributes, identifier, args)
tree decl;
tree attributes;
tree identifier;
tree args;
{
return 0;
}
/* If defined, a C expression whose value is nonzero if IDENTIFIER
with arguments ARGS is a valid machine specific attribute for TYPE.
The attributes in ATTRIBUTES have previously been assigned to TYPE. */
int
rs6000_valid_type_attribute_p (type, attributes, identifier, args)
tree type;
tree attributes;
tree identifier;
tree args;
{
if (TREE_CODE (type) != FUNCTION_TYPE
&& TREE_CODE (type) != FIELD_DECL
&& TREE_CODE (type) != TYPE_DECL)
return 0;
if (DEFAULT_ABI == ABI_NT)
{
/* Stdcall attribute says callee is responsible for popping arguments
if they are not variable. */
if (is_attribute_p ("stdcall", identifier))
return (args == NULL_TREE);
/* Cdecl attribute says the callee is a normal C declaration */
if (is_attribute_p ("cdecl", identifier))
return (args == NULL_TREE);
/* Dllimport attribute says says the caller is to call the function
indirectly through a __imp_<name> pointer. */
if (is_attribute_p ("dllimport", identifier))
return (args == NULL_TREE);
/* Dllexport attribute says says the callee is to create a __imp_<name>
pointer. */
if (is_attribute_p ("dllexport", identifier))
return (args == NULL_TREE);
}
return 0;
}
/* If defined, a C expression whose value is zero if the attributes on
TYPE1 and TYPE2 are incompatible, one if they are compatible, and
two if they are nearly compatible (which causes a warning to be
generated). */
int
rs6000_comp_type_attributes (type1, type2)
tree type1;
tree type2;
{
return 1;
}
/* If defined, a C statement that assigns default attributes to newly
defined TYPE. */
void
rs6000_set_default_type_attributes (type)
tree type;
{
}
/* Return a dll import reference corresponding to to a call's SYMBOL_REF */
struct rtx_def *
rs6000_dll_import_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)
abort ();
call_name = XSTR (call_ref, 0);
len = sizeof ("__imp_") + strlen (call_name);
p = alloca (len);
reg2 = gen_reg_rtx (Pmode);
strcpy (p, "__imp_");
strcat (p, call_name);
node = get_identifier (p);
reg1 = force_reg (Pmode, gen_rtx (SYMBOL_REF, VOIDmode, IDENTIFIER_POINTER (node)));
emit_move_insn (reg2, gen_rtx (MEM, Pmode, reg1));
return reg2;
}
/* 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
kind of constant in RTL. The argument MODE is redundant except in
the case of a `const_int' rtx. Select the section by calling
`text_section' or one of the alternatives for other sections.
Do not define this macro if you put all constants in the read-only
data section. */
#ifdef USING_SVR4_H
void
rs6000_select_rtx_section (mode, x)
enum machine_mode mode;
rtx x;
{
if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x))
toc_section ();
else if (TARGET_SDATA && GET_MODE_SIZE (mode) > 0 && GET_MODE_SIZE (mode) <= 8)
sdata2_section ();
else
const_section ();
}
/* A C statement or statements to switch to the appropriate
section for output of DECL. DECL is either a `VAR_DECL' node
or a constant of some sort. RELOC indicates whether forming
the initial value of DECL requires link-time relocations. */
void
rs6000_select_section (decl, reloc)
tree decl;
int reloc;
{
int size = int_size_in_bytes (TREE_TYPE (decl));
if (TREE_CODE (decl) == STRING_CST)
{
if ((! flag_writable_strings) && TARGET_SDATA && (size <= 8))
sdata2_section ();
else if (! flag_writable_strings)
const_section ();
else if (TARGET_SDATA && (size <= 8))
sdata_section ();
else
data_section ();
}
else if (TREE_CODE (decl) == VAR_DECL)
{
if ((flag_pic && reloc)
|| !TREE_READONLY (decl)
|| TREE_SIDE_EFFECTS (decl)
|| !DECL_INITIAL (decl)
|| (DECL_INITIAL (decl) != error_mark_node
&& !TREE_CONSTANT (DECL_INITIAL (decl))))
{
if (TARGET_SDATA && (size <= 8) && (size > 0))
sdata_section ();
else
data_section ();
}
else
{
if (TARGET_SDATA && (size <= 8) && (size > 0))
sdata2_section ();
else
const_section ();
}
}
else
const_section ();
}
#endif /* USING_SVR4_H */
......@@ -140,6 +140,10 @@ Boston, MA 02111-1307, USA. */
Do not define this macro if it does not need to do anything. */
#ifndef SUBTARGET_EXTRA_SPECS
#define SUBTARGET_EXTRA_SPECS
#endif
#define EXTRA_SPECS \
{ "cpp_cpu", CPP_CPU_SPEC }, \
{ "cpp_default", CPP_DEFAULT_SPEC }, \
......@@ -147,7 +151,36 @@ Boston, MA 02111-1307, USA. */
{ "cpp_sysv_default", CPP_SYSV_DEFAULT_SPEC }, \
{ "cpp_endian", CPP_ENDIAN_SPEC }, \
{ "asm_cpu", ASM_CPU_SPEC }, \
{ "asm_default", ASM_DEFAULT_SPEC }
{ "asm_default", ASM_DEFAULT_SPEC }, \
{ "link_syscalls", LINK_SYSCALLS_SPEC }, \
{ "link_libg", LINK_LIBG_SPEC }, \
{ "link_path", LINK_PATH_SPEC }, \
{ "link_start", LINK_START_SPEC }, \
SUBTARGET_EXTRA_SPECS
/* Default paths to give linker under V.4 */
#ifndef LINK_PATH_SPEC
#define LINK_PATH_SPEC ""
#endif
/* Default location of syscalls.exp under AIX */
#ifndef CROSS_COMPILE
#define LINK_SYSCALLS_SPEC "-bI:/lib/syscalls.exp"
#else
#define LINK_SYSCALLS_SPEC ""
#endif
/* Default location of libg.exp under AIX */
#ifndef CROSS_COMPILE
#define LINK_LIBG_SPEC "-bexport:/usr/lib/libg.exp"
#else
#define LINK_LIBG_SPEC ""
#endif
/* Default starting address if specified */
#ifndef LINK_START_SPEC
#define LINK_START_SPEC ""
#endif
/* Define the options for the binder: Start text at 512, align all segments
to 512 bytes, and warn if there is text relocation.
......@@ -163,15 +196,9 @@ Boston, MA 02111-1307, USA. */
that to actually build a shared library you will also need to specify an
export list with the -Wl,-bE option. */
#ifndef CROSS_COMPILE
#define LINK_SPEC "-T512 -H512 %{!r:-btextro} -bhalt:4 -bnodelcsect\
%{static:-bnso} \
%{shared:-bM:SRE}"
#else
#define LINK_SPEC "-T512 -H512 %{!r:-btextro} -bhalt:4 -bnodelcsect\
%{static:-bnso -bI:/lib/syscalls.exp} \
%{!shared:%{g*:-bexport:/usr/lib/libg.exp}} %{shared:-bM:SRE}"
#endif
%{static:-bnso %(link_syscalls) } \
%{!shared:%{g*: %(link_libg) }} %{shared:-bM:SRE}"
/* Profiled library versions are used by linking with special directories. */
#define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\
......@@ -1206,13 +1233,24 @@ extern int rs6000_sysv_varargs_p;
/* Minimum and maximum floating point registers used to hold arguments. */
#define FP_ARG_MIN_REG 33
#define FP_ARG_MAX_REG 45
#define FP_ARG_AIX_MAX_REG 45
#define FP_ARG_V4_MAX_REG 40
#define FP_ARG_MAX_REG FP_ARG_AIX_MAX_REG
#define FP_ARG_NUM_REG (FP_ARG_MAX_REG - FP_ARG_MIN_REG + 1)
/* Return registers */
#define GP_ARG_RETURN GP_ARG_MIN_REG
#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 cutoff for using external functions to save floating point */
#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) == 62 || (FIRST_REG) == 63)
......@@ -1246,12 +1284,13 @@ extern int rs6000_sysv_varargs_p;
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 */
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 */
} CUMULATIVE_ARGS;
/* Define intermediate macro to compute the size (in registers) of an argument
......@@ -1423,6 +1462,35 @@ typedef struct rs6000_args
#define INITIALIZE_TRAMPOLINE(ADDR, FNADDR, CXT) \
rs6000_initialize_trampoline (ADDR, FNADDR, CXT)
/* If defined, a C expression whose value is nonzero if IDENTIFIER
with arguments ARGS is a valid machine specific attribute for DECL.
The attributes in ATTRIBUTES have previously been assigned to DECL. */
#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, NAME, ARGS) \
(rs6000_valid_decl_attribute_p (DECL, ATTRIBUTES, NAME, ARGS))
/* If defined, a C expression whose value is nonzero if IDENTIFIER
with arguments ARGS is a valid machine specific attribute for TYPE.
The attributes in ATTRIBUTES have previously been assigned to TYPE. */
#define VALID_MACHINE_TYPE_ATTRIBUTE(TYPE, ATTRIBUTES, NAME, ARGS) \
(rs6000_valid_type_attribute_p (TYPE, ATTRIBUTES, NAME, ARGS))
/* If defined, a C expression whose value is zero if the attributes on
TYPE1 and TYPE2 are incompatible, one if they are compatible, and
two if they are nearly compatible (which causes a warning to be
generated). */
#define COMP_TYPE_ATTRIBUTES(TYPE1, TYPE2) \
(rs6000_comp_type_attributes (TYPE1, TYPE2))
/* If defined, a C statement that assigns default attributes to newly
defined TYPE. */
#define SET_DEFAULT_TYPE_ATTRIBUTES(TYPE) \
(rs6000_set_default_type_attributes (TYPE))
/* Definitions for __builtin_return_address and __builtin_frame_address.
__builtin_return_address (0) should give link register (65), enable
this. */
......@@ -1618,6 +1686,9 @@ typedef struct rs6000_args
&& GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \
&& LEGITIMATE_CONSTANT_POOL_BASE_P (XEXP (XEXP (X, 0), 0))))
#define LEGITIMATE_SMALL_DATA_P(MODE, X) \
(DEFAULT_ABI == ABI_V4 && small_data_operand (X, MODE))
#define LEGITIMATE_ADDRESS_INTEGER_P(X,OFFSET) \
(GET_CODE (X) == CONST_INT \
&& (unsigned) (INTVAL (X) + (OFFSET) + 0x8000) < 0x10000)
......@@ -1658,6 +1729,8 @@ typedef struct rs6000_args
if ((GET_CODE (X) == PRE_INC || GET_CODE (X) == PRE_DEC) \
&& LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (X, 0))) \
goto ADDR; \
if (LEGITIMATE_SMALL_DATA_P (MODE, X)) \
goto ADDR; \
if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (X)) \
goto ADDR; \
if (LEGITIMATE_OFFSET_ADDRESS_P (MODE, X)) \
......@@ -2434,7 +2507,7 @@ toc_section () \
`assemble_name' uses this. */
#define ASM_OUTPUT_LABELREF(FILE,NAME) \
fprintf (FILE, NAME)
fputs (NAME, FILE)
/* This is how to output an internal numbered label where
PREFIX is the class of label and NUM is the number within the class. */
......@@ -2729,6 +2802,7 @@ extern int lwa_operand ();
extern int call_operand ();
extern int current_file_function_operand ();
extern int input_operand ();
extern int small_data_operand ();
extern void init_cumulative_args ();
extern void function_arg_advance ();
extern int function_arg_boundary ();
......@@ -2766,3 +2840,8 @@ extern int rs6000_adjust_cost ();
extern void rs6000_trampoline_template ();
extern int rs6000_trampoline_size ();
extern void rs6000_initialize_trampoline ();
extern int rs6000_comp_type_attributes ();
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 ();
......@@ -6405,6 +6405,15 @@
abort ();
operands[0] = XEXP (operands[0], 0);
/* Convert NT DLL imports into an indirect call. */
if (GET_CODE (operands[0]) == SYMBOL_REF
&& INTVAL (operands[2]) == (int)CALL_NT_DLLIMPORT)
{
operands[0] = rs6000_dll_import_ref (operands[0]);
operands[2] = GEN_INT ((int)CALL_NORMAL);
}
if (GET_CODE (operands[0]) != SYMBOL_REF)
{
if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC)
......@@ -6426,6 +6435,7 @@
else if (DEFAULT_ABI == ABI_NT)
{
/* NT function pointers are really pointers to a two word area */
rs6000_save_toc_p = 1;
emit_call_insn (gen_call_indirect_nt (force_reg (Pmode, operands[0]),
operands[1], operands[2],
toc_addr, toc_reg));
......@@ -6450,6 +6460,15 @@
abort ();
operands[1] = XEXP (operands[1], 0);
/* Convert NT DLL imports into an indirect call. */
if (GET_CODE (operands[1]) == SYMBOL_REF
&& INTVAL (operands[3]) == (int)CALL_NT_DLLIMPORT)
{
operands[1] = rs6000_dll_import_ref (operands[1]);
operands[3] = GEN_INT ((int)CALL_NORMAL);
}
if (GET_CODE (operands[1]) != SYMBOL_REF)
{
if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC)
......@@ -6472,6 +6491,7 @@
else if (DEFAULT_ABI == ABI_NT)
{
/* NT function pointers are really pointers to a two word area */
rs6000_save_toc_p = 1;
emit_call_insn (gen_call_value_indirect_nt (operands[0],
force_reg (Pmode, operands[1]),
operands[2], operands[3],
......@@ -6498,11 +6518,11 @@
""
"*
{
if (INTVAL (operands[2]) > 0)
return \"creqv 6,6,6\;bl %z0\";
else if (INTVAL (operands[2]) < 0)
return \"crxor 6,6,6\;bl %z0\";
switch ((enum rs6000_call_cookie)INTVAL (operands[2]))
{
case CALL_V4_SET_FP_ARGS: output_asm_insn (\"crxor 6,6,6\", operands); break;
case CALL_V4_CLEAR_FP_ARGS: output_asm_insn (\"creqv 6,6,6\", operands); break;
}
return \"bl %z0\";
}"
......@@ -6523,16 +6543,16 @@
"DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT"
"*
{
if (INTVAL (operands[2]) > 0)
output_asm_insn (\"creqv 6,6,6\", operands);
else if (INTVAL (operands[2]) < 0)
output_asm_insn (\"crxor 6,6,6\", operands);
/* Indirect calls should go through call_indirect */
if (GET_CODE (operands[0]) == REG)
abort ();
switch ((enum rs6000_call_cookie)INTVAL (operands[2]))
{
case CALL_V4_SET_FP_ARGS: output_asm_insn (\"crxor 6,6,6\", operands); break;
case CALL_V4_CLEAR_FP_ARGS: output_asm_insn (\"creqv 6,6,6\", operands); break;
}
return (TARGET_WINDOWS_NT) ? \"bl %z0\;.znop %z0\" : \"bl %z0\;%.\";
}"
[(set_attr "length" "8,12")])
......@@ -6545,16 +6565,16 @@
"DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4"
"*
{
if (INTVAL (operands[2]) > 0)
output_asm_insn (\"creqv 6,6,6\", operands);
else if (INTVAL (operands[2]) < 0)
output_asm_insn (\"crxor 6,6,6\", operands);
/* Indirect calls should go through call_indirect */
if (GET_CODE (operands[0]) == REG)
abort ();
switch ((enum rs6000_call_cookie)INTVAL (operands[2]))
{
case CALL_V4_SET_FP_ARGS: output_asm_insn (\"crxor 6,6,6\", operands); break;
case CALL_V4_CLEAR_FP_ARGS: output_asm_insn (\"creqv 6,6,6\", operands); break;
}
return \"bl %z0\";
}"
[(set_attr "length" "4,8")])
......@@ -6568,11 +6588,11 @@
""
"*
{
if (INTVAL (operands[3]) > 0)
return \"creqv 6,6,6\;bl %z1\";
else if (INTVAL (operands[3]) < 0)
return \"crxor 6,6,6\;bl %z1\";
switch ((enum rs6000_call_cookie)INTVAL (operands[3]))
{
case CALL_V4_SET_FP_ARGS: output_asm_insn (\"crxor 6,6,6\", operands); break;
case CALL_V4_CLEAR_FP_ARGS: output_asm_insn (\"creqv 6,6,6\", operands); break;
}
return \"bl %z1\";
}"
......@@ -6587,16 +6607,16 @@
"DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT"
"*
{
if (INTVAL (operands[3]) > 0)
output_asm_insn (\"creqv 6,6,6\", operands);
else if (INTVAL (operands[3]) < 0)
output_asm_insn (\"crxor 6,6,6\", operands);
/* This should be handled by call_value_indirect */
if (GET_CODE (operands[1]) == REG)
abort ();
switch ((enum rs6000_call_cookie)INTVAL (operands[3]))
{
case CALL_V4_SET_FP_ARGS: output_asm_insn (\"crxor 6,6,6\", operands); break;
case CALL_V4_CLEAR_FP_ARGS: output_asm_insn (\"creqv 6,6,6\", operands); break;
}
return (TARGET_WINDOWS_NT) ? \"bl %z1\;.znop %z1\" : \"bl %z1\;%.\";
}"
[(set_attr "length" "8,12")])
......@@ -6610,16 +6630,16 @@
"DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4"
"*
{
if (INTVAL (operands[3]) > 0)
output_asm_insn (\"creqv 6,6,6\", operands);
else if (INTVAL (operands[3]) < 0)
output_asm_insn (\"crxor 6,6,6\", operands);
/* This should be handled by call_value_indirect */
if (GET_CODE (operands[1]) == REG)
abort ();
switch ((enum rs6000_call_cookie)INTVAL (operands[3]))
{
case CALL_V4_SET_FP_ARGS: output_asm_insn (\"crxor 6,6,6\", operands); break;
case CALL_V4_CLEAR_FP_ARGS: output_asm_insn (\"creqv 6,6,6\", operands); break;
}
return \"bl %z1\";
}"
[(set_attr "length" "4,8")])
......
......@@ -25,7 +25,7 @@ Boston, MA 02111-1307, USA. */
#define MASK_NO_BITFIELD_TYPE 0x40000000 /* Set PCC_BITFIELD_TYPE_MATTERS to 0 */
#define MASK_STRICT_ALIGN 0x20000000 /* Set STRICT_ALIGNMENT to 1. */
#define MASK_RELOCATABLE 0x10000000 /* GOT pointers are PC relative */
#define MASK_UNUSED 0x08000000 /* UNUSED, was no-traceback */
#define MASK_SDATA 0x08000000 /* use eabi .sdata/.sdata2/.sbss relocations */
#define MASK_LITTLE_ENDIAN 0x04000000 /* target is little endian */
#define MASK_CALLS_1 0x02000000 /* First ABI bit (AIX, AIXDESC) */
#define MASK_PROTOTYPE 0x01000000 /* Only prototyped fcns pass variable args */
......@@ -40,6 +40,7 @@ Boston, MA 02111-1307, USA. */
#define TARGET_NO_BITFIELD_TYPE (target_flags & MASK_NO_BITFIELD_TYPE)
#define TARGET_STRICT_ALIGN (target_flags & MASK_STRICT_ALIGN)
#define TARGET_RELOCATABLE (target_flags & MASK_RELOCATABLE)
#define TARGET_SDATA (target_flags & MASK_SDATA)
#define TARGET_LITTLE_ENDIAN (target_flags & MASK_LITTLE_ENDIAN)
#define TARGET_PROTOTYPE (target_flags & MASK_PROTOTYPE)
#define TARGET_TOC ((target_flags & (MASK_64BIT \
......@@ -71,9 +72,12 @@ Boston, MA 02111-1307, USA. */
{ "strict-align", MASK_STRICT_ALIGN }, \
{ "no-strict-align", -MASK_STRICT_ALIGN }, \
{ "relocatable", MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC }, \
{ "relocatable", -MASK_SDATA }, \
{ "no-relocatable", -MASK_RELOCATABLE }, \
{ "relocatable-lib", MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC }, \
{ "no-relocatable-lib", -MASK_RELOCATABLE }, \
{ "sdata", MASK_SDATA }, \
{ "no-sdata", -MASK_SDATA }, \
{ "little-endian", MASK_LITTLE_ENDIAN }, \
{ "little", MASK_LITTLE_ENDIAN }, \
{ "big-endian", -MASK_LITTLE_ENDIAN }, \
......@@ -106,6 +110,23 @@ Boston, MA 02111-1307, USA. */
#define SUBTARGET_OVERRIDE_OPTIONS \
do { \
rs6000_current_abi = ((TARGET_AIXDESC_CALLS) ? ABI_AIX : \
(TARGET_NT_CALLS) ? ABI_NT : \
(TARGET_AIX_CALLS) ? ABI_AIX_NODESC : \
ABI_V4); \
\
if (TARGET_RELOCATABLE && TARGET_SDATA) \
{ \
target_flags &= ~MASK_SDATA; \
error ("-mrelocatable and -msdata are incompatible."); \
} \
\
if (TARGET_SDATA && DEFAULT_ABI != ABI_V4) \
{ \
target_flags &= ~MASK_SDATA; \
error ("-msdata and -mcall-aix are incompatible."); \
} \
\
if (TARGET_RELOCATABLE && !TARGET_MINIMAL_TOC) \
{ \
target_flags |= MASK_MINIMAL_TOC; \
......@@ -135,11 +156,6 @@ do { \
target_flags |= MASK_LITTLE_ENDIAN; \
error ("-mcall-nt must be little endian"); \
} \
\
rs6000_current_abi = ((TARGET_AIXDESC_CALLS) ? ABI_AIX : \
(TARGET_NT_CALLS) ? ABI_NT : \
(TARGET_AIX_CALLS) ? ABI_AIX_NODESC : \
ABI_V4); \
} while (0)
/* Default ABI to compile code for */
......@@ -156,8 +172,6 @@ do { \
/* System V.4 passes the first 8 floating arguments in registers,
instead of the first 13 like AIX does. */
#undef FP_ARG_MAX_REG
#define FP_ARG_AIX_MAX_REG 45
#define FP_ARG_V4_MAX_REG 40
#define FP_ARG_MAX_REG ((TARGET_AIX_CALLS) ? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG)
/* Size of the V.4 varargs area if needed */
......@@ -263,14 +277,20 @@ do { \
/* Besides the usual ELF sections, we need a toc section. */
#undef EXTRA_SECTIONS
#define EXTRA_SECTIONS in_const, in_ctors, in_dtors, in_toc
#define EXTRA_SECTIONS in_const, in_ctors, in_dtors, in_toc, in_sdata, in_sdata2, in_sbss
#undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTION_FUNCTIONS \
CONST_SECTION_FUNCTION \
CTORS_SECTION_FUNCTION \
DTORS_SECTION_FUNCTION \
TOC_SECTION_FUNCTION
TOC_SECTION_FUNCTION \
SDATA_SECTION_FUNCTION \
SDATA2_SECTION_FUNCTION \
SBSS_SECTION_FUNCTION
extern void toc_section (), sdata_section (), sdata2_section ();
extern void sbss_section ();
#define TOC_SECTION_FUNCTION \
void \
......@@ -321,16 +341,65 @@ toc_section () \
#define TOC_SECTION_ASM_OP "\t.section\t\".got\",\"aw\""
#define MINIMAL_TOC_SECTION_ASM_OP "\t.section\t\".got1\",\"aw\""
/* Use the TOC section for TOC entries. */
#define SDATA_SECTION_ASM_OP "\t.section\t\".sdata\",\"aw\""
#define SDATA2_SECTION_ASM_OP "\t.section\t\".sdata2\",\"a\""
#define SBSS_SECTION_ASM_OP "\t.section\t\".sbss\",\"aw\",@nobits"
#undef SELECT_RTX_SECTION
#define SELECT_RTX_SECTION(MODE, X) \
{ if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (X)) \
toc_section (); \
else \
const_section (); \
#define SDATA_SECTION_FUNCTION \
void \
sdata_section () \
{ \
if (in_section != in_sdata) \
{ \
in_section = in_sdata; \
fprintf (asm_out_file, "%s\n", SDATA_SECTION_ASM_OP); \
} \
}
#define SDATA2_SECTION_FUNCTION \
void \
sdata2_section () \
{ \
if (in_section != in_sdata2) \
{ \
in_section = in_sdata2; \
fprintf (asm_out_file, "%s\n", SDATA2_SECTION_ASM_OP); \
} \
}
#define SBSS_SECTION_FUNCTION \
void \
sbss_section () \
{ \
if (in_section != in_sbss) \
{ \
in_section = in_sbss; \
fprintf (asm_out_file, "%s\n", SBSS_SECTION_ASM_OP); \
} \
}
/* 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
kind of constant in RTL. The argument MODE is redundant except in
the case of a `const_int' rtx. Select the section by calling
`text_section' or one of the alternatives for other sections.
Do not define this macro if you put all constants in the read-only
data section. */
extern void rs6000_select_rtx_section (), rs6000_select_section ();
#undef SELECT_RTX_SECTION
#define SELECT_RTX_SECTION(MODE, X) rs6000_select_rtx_section (MODE, X)
/* A C statement or statements to switch to the appropriate
section for output of DECL. DECL is either a `VAR_DECL' node
or a constant of some sort. RELOC indicates whether forming
the initial value of DECL requires link-time relocations. */
#undef SELECT_SECTION
#define SELECT_SECTION(DECL,RELOC) rs6000_select_section (DECL, RELOC)
/* Return non-zero if this entry is to be written into the constant pool
in a special way. We do so if this is a SYMBOL_REF, LABEL_REF or a CONST
containing one of them. If -mfp-in-toc (the default), we also do
......@@ -423,12 +492,11 @@ extern int rs6000_pic_labelno;
#define ASM_OUTPUT_INTERNAL_LABEL_PREFIX(FILE,PREFIX) \
fprintf (FILE, ".%s", PREFIX)
/* Pass -mppc to the assembler, since that is what powerpc.h currently
implies. */
/* Pass various options to the assembler */
#undef ASM_SPEC
#define ASM_SPEC "-u %(asm_cpu) \
%{V} %{v:%{!V:-V}} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} \
%{mrelocatable} %{mrelocatable-lib} %{memb} \
%{mrelocatable} %{mrelocatable-lib} %{memb} %{msdata: -memb} \
%{mlittle} %{mlittle-endian} %{mbig} %{mbig-endian}"
/* Output .file and comments listing what options there are */
......@@ -528,14 +596,46 @@ do { \
XSTR (sym_ref, 0) = str; \
} \
} \
else if (TARGET_SDATA && DEFAULT_ABI == ABI_V4 \
&& TREE_CODE (DECL) == VAR_DECL) \
{ \
int size = int_size_in_bytes (TREE_TYPE (DECL)); \
tree section_name = DECL_SECTION_NAME (DECL); \
char *name = ((section_name) \
? IDENTIFIER_POINTER (section_name) \
: (char *)0); \
\
if ((size > 0 && size <= 8) \
|| (name \
&& (strcmp (name, ".sdata") == 0 \
|| strcmp (name, ".sdata2") == 0 \
|| strcmp (name, ".sbss") == 0 \
|| strcmp (name, ".sbss2") == 0 \
|| strcmp (name, ".PPC.EMB.sdata0") == 0 \
|| strcmp (name, ".PPC.EMB.sbss0") == 0))) \
{ \
rtx sym_ref = XEXP (DECL_RTL (DECL), 0); \
char *str = permalloc (2 + strlen (XSTR (sym_ref, 0))); \
strcpy (str, "@"); \
strcat (str, XSTR (sym_ref, 0)); \
XSTR (sym_ref, 0) = str; \
} \
} \
} while (0)
/* This macro gets just the user-specified name
out of the string in a SYMBOL_REF. Discard
a leading * */
a leading * or @. */
#undef STRIP_NAME_ENCODING
#define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME) \
(VAR) = ((SYMBOL_NAME) + ((SYMBOL_NAME)[0] == '*'))
(VAR) = ((SYMBOL_NAME) + (((SYMBOL_NAME)[0] == '*') || ((SYMBOL_NAME)[0] == '@')))
/* This is how to output a reference to a user-level label named NAME.
`assemble_name' uses this. */
#undef ASM_OUTPUT_LABELREF
#define ASM_OUTPUT_LABELREF(FILE,NAME) \
fputs ((NAME) + (NAME[0] == '@'), FILE)
/* But, to make this work, we have to output the stabs for the function
name *first*... */
......@@ -552,21 +652,17 @@ do { \
"-DPPC -Dunix -D__svr4__ -Asystem(unix) -Asystem(svr4) -Acpu(powerpc) -Amachine(powerpc)"
/* Don't put -Y P,<path> for cross compilers */
#undef LINK_SPEC
#ifdef CROSS_COMPILE
#define LINK_SPEC "\
%{h*} %{V} %{v:%{!V:-V}} \
%{b} %{Wl,*:%*} \
%{static:-dn -Bstatic} \
%{shared:-G -dy -z text %{!h*:%{o*:-h %*}}} \
%{symbolic:-Bsymbolic -G -dy -z text %{!h*:%{o*:-h %*}}} \
%{G:-G} \
%{YP,*} \
%{Qy:} %{!Qn:-Qy} \
%{mlittle: -oformat elf32-powerpcle } %{mlittle-endian: -oformat elf32-powerpcle } \
%{mbig: -oformat elf32-powerpc } %{mbig-endian: -oformat elf32-powerpc }"
#undef LINK_PATH_SPEC
#ifndef CROSS_COMPILE
#define LINK_PATH_SPEC "\
%{!nostdlib: %{!YP,*:%{p:-Y P,/usr/ccs/lib/libp:/usr/lib/libp:/usr/ccs/lib:/usr/lib} \
%{!p:-Y P,/usr/ccs/lib:/usr/lib}}}"
#else
#define LINK_PATH_SPEC ""
#endif
#undef LINK_SPEC
#define LINK_SPEC "\
%{h*} %{V} %{v:%{!V:-V}} \
%{b} %{Wl,*:%*} \
......@@ -575,12 +671,10 @@ do { \
%{symbolic:-Bsymbolic -G -dy -z text %{!h*:%{o*:-h %*}}} \
%{G:-G} \
%{YP,*} \
%{!nostdlib: %{!YP,*:%{p:-Y P,/usr/ccs/lib/libp:/usr/lib/libp:/usr/ccs/lib:/usr/lib} \
%{!p:-Y P,/usr/ccs/lib:/usr/lib}}} \
%(link_path) %(link_start) \
%{Qy:} %{!Qn:-Qy} \
%{mlittle: -oformat elf32-powerpcle } %{mlittle-endian: -oformat elf32-powerpcle } \
%{mbig: -oformat elf32-powerpc } %{mbig-endian: -oformat elf32-powerpc }"
#endif /* CROSS_COMPILE */
#undef CPP_SYSV_SPEC
#define CPP_SYSV_SPEC \
......@@ -612,4 +706,4 @@ do { \
`MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */
#undef MULTILIB_DEFAULTS
#define MULTILIB_DEFAULTS { "mbig", "mbig-endian", "mcall-sysv" }
#define MULTILIB_DEFAULTS { "mbig", "mbig-endian", "mcall-sysv", "mno-sdata" }
......@@ -42,4 +42,4 @@ Boston, MA 02111-1307, USA. */
`MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */
#undef MULTILIB_DEFAULTS
#define MULTILIB_DEFAULTS { "mlittle", "mlittle-endian", "mcall-sysv" }
#define MULTILIB_DEFAULTS { "mlittle", "mlittle-endian", "mcall-sysv", "mno-sdata" }
......@@ -19,11 +19,11 @@ fp-bit.c: $(srcdir)/config/fp-bit.c
MULTILIB_OPTIONS = msoft-float \
mlittle/mbig \
mcall-sysv/mcall-aix/mcall-aixdesc
mcall-sysv/mcall-aix # /mcall-aixdesc
MULTILIB_DIRNAMES = soft-float \
little big \
sysv aix aixdesc
sysv aix # aixdesc
MULTILIB_MATCHES = mlittle=mlittle-endian \
mbig=mbig-endian \
......@@ -31,7 +31,7 @@ MULTILIB_MATCHES = mlittle=mlittle-endian \
msoft-float=mcpu?821 \
msoft-float=mcpu?860
MULTILIB_EXCEPTIONS = *mlittle/*mcall-aixdesc*
#MULTILIB_EXCEPTIONS = *mlittle/*mcall-aixdesc*
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
......@@ -45,8 +45,8 @@ Boston, MA 02111-1307, USA. */
#undef LIB_SPEC
#define LIB_SPEC "%{mwindows:-subsystem:windows -entry:WinMainCRTStartup \
USER32.LIB GDI32.LIB COMDLG32.LIB WINSPOOL.LIB} \
%{!mwindows:-subsystem:console -entry:mainCRTStartup} \
%{mcrtmt:LIBCMT.LIB KERNEL32.LIB} %{!mcrtmt:LIBC.LIB KERNEL32.LIB} \
%{!mwindows:-subsystem console -e mainCRTStartup} \
%{mcrtmt:LIBCMT.LIB KERNEL32.LIB} %{!mcrtmt:-lkernel32 -lcygwin} \
%{v}"
#undef LINK_SPEC
......@@ -249,6 +249,19 @@ toc_section () \
fprintf (FILE, "\t.ualong .."); \
assemble_name (FILE, NAME); \
fprintf (FILE, ",.toc\n"); \
\
if (lookup_attribute ("dllexport", \
TYPE_ATTRIBUTES (TREE_TYPE (DECL)))) \
{ \
fprintf (FILE, "\t.globl __imp_"); \
assemble_name (FILE, NAME); \
fprintf (FILE, "\n__imp_"); \
assemble_name (FILE, NAME); \
fprintf (FILE, ":\n\t.ulong "); \
assemble_name (FILE, NAME); \
fprintf (FILE, "\n"); \
} \
\
fprintf (FILE, "\t.section .text\n\t.align 2\n.."); \
assemble_name (FILE, NAME); \
fprintf (FILE, ":\n"); \
......
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