/* -m68881 is the default */
#define CPP_SPEC \
"%{!msoft-float:%{mfpa:-D__HAVE_FPA__ }%{!mfpa:-D__HAVE_68881__ }}\
-%{!ansi:%{m68000:-Dmc68010}%{mc68000:-Dmc68010}%{!mc68000:%{!m68000:-Dmc68020}}}"
-
-#else
-#if TARGET_DEFAULT & 0100
-
-/* -mfpa is the default */
-#define CPP_SPEC \
-"%{!msoft-float:%{m68881:-D__HAVE_68881__ }%{!m68881:-D__HAVE_FPA__ }}\
+%{m68000:-D__mc68010__}%{mc68000:-D__mc68010__}%{!mc68000:%{!m68000:-D__mc68020__}}} \
%{!ansi:%{m68000:-Dmc68010}%{mc68000:-Dmc68010}%{!mc68000:%{!m68000:-Dmc68020}}}"
#else
/* -msoft-float is the default */
#define CPP_SPEC \
"%{m68881:-D__HAVE_68881__ }%{mfpa:-D__HAVE_FPA__ }\
+%{m68000:-D__mc68010__}%{mc68000:-D__mc68010__}%{!mc68000:%{!m68000:-D__mc68020__}}} \
%{!ansi:%{m68000:-Dmc68010}%{mc68000:-Dmc68010}%{!mc68000:%{!m68000:-Dmc68020}}}"
#endif
-#endif
/* Prevent error on `-sun3' and `-target sun3' options. */
#define WORD_SWITCH_TAKES_ARG(STR) \
(!strcmp (STR, "Tdata") || !strcmp (STR, "include") \
|| !strcmp (STR, "imacros") || !strcmp (STR, "target") \
- || !strcmp (STR, "assert"))
+ || !strcmp (STR, "assert") || !strcmp (STR, "aux-info"))
/* -m68000 requires special flags to the assembler. */
/* Allow folding division by zero. */
#define REAL_INFINITY
+/* Generate calls to memcpy, memcmp and memset. */
+#define TARGET_MEM_FUNCTIONS
+
/* This is how to output an assembler line defining a `double' constant. */
#undef ASM_OUTPUT_DOUBLE
{ \
if (REAL_VALUE_ISINF (VALUE)) \
fprintf (FILE, "\t.double 0r%s99e999\n", (VALUE) > 0 ? "" : "-"); \
- else if (isnan (VALUE)) \
+ else if (REAL_VALUE_ISNAN (VALUE)) \
{ \
union { double d; long l[2];} t; \
t.d = (VALUE); \
{ \
if (REAL_VALUE_ISINF (VALUE)) \
fprintf (FILE, "\t.single 0r%s99e999\n", (VALUE) > 0 ? "" : "-"); \
- else if (isnan (VALUE)) \
+ else if (REAL_VALUE_ISNAN (VALUE)) \
{ \
union { float f; long l;} t; \
t.f = (VALUE); \
there are no such switches except those implemented by GCC itself. */
#define WORD_SWITCH_TAKES_ARG(STR) \
- (!strcmp (STR, "include") || !strcmp (STR, "imacros"))
+ (!strcmp (STR, "include") || !strcmp (STR, "imacros") \
+ || !strcmp (STR, "aux-info"))
/* You should redefine CPP_PREDEFINES in any file which includes this one.
The definition should be appropriate for the type of target system
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE BITS_PER_WORD
+#define MULTIBYTE_CHARS
+
#undef ASM_BYTE_OP
#define ASM_BYTE_OP "\t.byte"
the linker seems to want the alignment of data objects
to depend on their types. We do exactly that here. */
-#define BSS_ASM_OP "\t.bss"
+#define BSS_ASM_OP ".bss"
#undef ASM_OUTPUT_ALIGNED_LOCAL
#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
do { \
- fprintf ((FILE), "%s\t%s,%u,%u\n", \
+ fprintf ((FILE), "\t%s\t%s,%u,%u\n", \
BSS_ASM_OP, (NAME), (SIZE), (ALIGN) / BITS_PER_UNIT); \
} while (0)
specific value in some section. This is the same for all known svr4
assemblers. */
-#define INT_ASM_OP "\t.long\t"
+#define INT_ASM_OP ".long"
/* This is the pseudo-op used to generate a contiguous sequence of byte
values from a double-quoted string WITHOUT HAVING A TERMINATING NUL
#define USE_CONST_SECTION 1
-#define CONST_SECTION_ASM_OP "\t.section\t.rodata"
-#define CTORS_SECTION_ASM_OP "\t.section\t.ctors,\"a\",@progbits\n"
-#define DTORS_SECTION_ASM_OP "\t.section\t.dtors,\"a\",@progbits\n"
+#define CONST_SECTION_ASM_OP ".section\t.rodata"
+#define CTORS_SECTION_ASM_OP ".section\t.ctors,\"a\",@progbits"
+#define DTORS_SECTION_ASM_OP ".section\t.dtors,\"a\",@progbits"
/* On svr4, we *do* have support for the .init section, and we can put
stuff in there to be executed before `main'. We let crtstuff.c and
says how to change sections to the .init section. This is the same
for all know svr4 assemblers. */
-#define INIT_SECTION_ASM_OP "\t.section\t.init"
+#define INIT_SECTION_ASM_OP ".section\t.init"
/* A default list of other sections which we might be "in" at any given
time. For targets that use additional sections (e.g. .tdesc) you
#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
do { \
ctors_section (); \
- fprintf (FILE, "%s\t ", INT_ASM_OP); \
+ fprintf (FILE, "\t%s\t ", INT_ASM_OP); \
assemble_name (FILE, NAME); \
fprintf (FILE, "\n"); \
} while (0)
#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \
do { \
dtors_section (); \
- fprintf (FILE, "%s\t ", INT_ASM_OP); \
+ fprintf (FILE, "\t%s\t ", INT_ASM_OP); \
assemble_name (FILE, NAME); \
fprintf (FILE, "\n"); \
} while (0)
different pseudo-op names for these, they may be overridden in the
file which includes this one. */
-#define TYPE_ASM_OP "\t.type"
-#define SIZE_ASM_OP "\t.size"
+#define TYPE_ASM_OP ".type"
+#define SIZE_ASM_OP ".size"
/* The following macro defines the format used to output the second
operand of the .type assembler directive. Different svr4 assemblers
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
do { \
- fprintf (FILE, "%s\t ", TYPE_ASM_OP); \
+ fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \
assemble_name (FILE, NAME); \
putc (',', FILE); \
fprintf (FILE, TYPE_OPERAND_FMT, "function"); \
#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \
do { \
- fprintf (FILE, "%s\t ", TYPE_ASM_OP); \
+ fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \
assemble_name (FILE, NAME); \
putc (',', FILE); \
fprintf (FILE, TYPE_OPERAND_FMT, "object"); \
putc ('\n', FILE); \
if (!flag_inhibit_size_directive) \
{ \
- fprintf (FILE, "%s\t ", SIZE_ASM_OP); \
+ fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \
assemble_name (FILE, NAME); \
fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (decl))); \
} \
labelno++; \
ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno); \
ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno); \
- fprintf (FILE, "%s\t ", SIZE_ASM_OP); \
+ fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \
assemble_name (FILE, (FNAME)); \
fprintf (FILE, ","); \
assemble_name (FILE, label); \
static struct obstack obstack;
+/* This is the obstack to build an environment variable to pass to
+ collect2 that describes all of the relavant switches of what to
+ pass the compiler in building the list of pointers to constructors
+ and destructors. */
+
+static struct obstack collect_obstack;
+
extern char *version_string;
static void set_spec ();
%{|!S:X} like %{!S:X}, but if there is an S switch, substitute `-'.
%{.S:X} substitutes X, but only if processing a file with suffix S.
%{!.S:X} substitutes X, but only if NOT processing a file with suffix S.
+ %(Spec) processes a specification defined in a specs file as *Spec:
+ %[Spec] as above, but put __ around -D arguments
The conditional text X in a %{S:X} or %{!S:X} construct may contain
other nested % constructs or spaces, or even newlines. They are
#ifndef WORD_SWITCH_TAKES_ARG
#define WORD_SWITCH_TAKES_ARG(STR) \
(!strcmp (STR, "Tdata") || !strcmp (STR, "include") \
- || !strcmp (STR, "imacros"))
+ || !strcmp (STR, "imacros") || !strcmp (STR, "aux-info"))
#endif
\f
/* Record the mapping from file suffixes for compilation specs. */
%{!Q:-quiet} -dumpbase %b.c %{d*} %{m*} %{a}\
%{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \
%{traditional} %{v:-version} %{pg:-p} %{p} %{f*}\
+ %{aux-info*}\
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
%{!S:as %{R} %{j} %{J} %{h} %{d2} %a \
%{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \
%{traditional} %{v:-version} %{pg:-p} %{p} %{f*} \
-lang-objc %{gen-decls} \
+ %{aux-info*}\
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
%{!S:as %{R} %{j} %{J} %{h} %{d2} %a \
%{!Q:-quiet} -dumpbase %b.cc %{d*} %{m*} %{a}\
%{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} %{traditional}\
%{v:-version} %{pg:-p} %{p} %{f*}\
+ %{aux-info*}\
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
%{!S:as %{R} %{j} %{J} %{h} %{d2} %a \
"cc1 %i %1 %{!Q:-quiet} %{d*} %{m*} %{a}\
%{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} %{traditional}\
%{v:-version} %{pg:-p} %{p} %{f*}\
+ %{aux-info*}\
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
%{!S:as %{R} %{j} %{J} %{h} %{d2} %a \
"cc1plus %i %1 %2 %{!Q:-quiet} %{d*} %{m*} %{a}\
%{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} %{traditional}\
%{v:-version} %{pg:-p} %{p} %{f*}\
+ %{aux-info*}\
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
%{!S:as %{R} %{j} %{J} %{h} %{d2} %a \
/* Use -l and have the linker do the search. */
static char *link_command_spec = "\
%{!c:%{!M:%{!MM:%{!E:%{!S:ld %X %l %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \
- %{r} %{T*} %{t} %{x} %{z}\
+ %{r} %{s} %{T*} %{t} %{x} %{z}\
%{!A:%{!nostdlib:%S}} \
%{L*} %D %o %{!nostdlib:-lgcc %L -lgcc %{!A:%E}}\n }}}}}";
#endif
else if (in[0] == '#')
{
while (*in && *in != '\n') in++;
- if (*in) in++;
}
else
*out++ = *in++;
}
\f
/* Structure to keep track of the specs that have been defined so far. These
- are accessed using %Sspecname in a compiler or link spec. */
+ are accessed using %(specname) or %[specname] in a compiler or link spec. */
struct spec_list
{
temp_filename_length = strlen (temp_filename);
}
\f
+
+/* Routine to add variables to the environment. We do this to pass
+ the pathname of the gcc driver, and the directories search to the
+ collect2 program, which is being run as ld. This way, we can be
+ sure of executing the right compiler when collect2 wants to build
+ constructors and destructors. Since the environment variables we
+ use come from an obstack, we don't have to worry about allocating
+ space for them. */
+
+#ifndef HAVE_PUTENV
+
+putenv (str)
+ char *str;
+{
+#ifndef __MSDOS__ /* not sure about MS/DOS */
+#ifndef VMS /* nor about VMS */
+
+ extern char **environ;
+ char **old_environ = environ;
+ char **envp;
+ int num_envs = 0;
+ int name_len = 1;
+ int str_len = strlen (str);
+ char *p = str;
+ int ch;
+
+ while ((ch = *p++) != '\0' && ch != '=')
+ name_len++;
+
+ if (!ch)
+ abort ();
+
+ /* Search for replacing an existing environment variable, and
+ count the number of total environment variables. */
+ for (envp = old_environ; *envp; envp++)
+ {
+ num_envs++;
+ if (!strncmp (str, *envp, name_len))
+ {
+ *envp = str;
+ return;
+ }
+ }
+
+ /* Add a new environment variable */
+ environ = (char **) xmalloc (sizeof (char *) * (num_envs+2));
+ *environ = str;
+ bcopy (old_environ, environ+1, sizeof (char *) * (num_envs+1));
+
+#endif /* VMS */
+#endif /* __MSDOS__ */
+}
+
+#endif /* HAVE_PUTENV */
+
+\f
+/* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables for collect. */
+
+static void
+putenv_from_prefixes (paths, env_var)
+ struct path_prefix *paths;
+ char *env_var;
+{
+ int suffix_len = (machine_suffix) ? strlen (machine_suffix) : 0;
+ int first_time = TRUE;
+ struct prefix_list *pprefix;
+
+ obstack_grow (&collect_obstack, env_var, strlen (env_var));
+
+ for (pprefix = paths->plist; pprefix != 0; pprefix = pprefix->next)
+ {
+ int len = strlen (pprefix->prefix);
+
+ if (machine_suffix)
+ {
+ if (!first_time)
+ obstack_grow (&collect_obstack, ":", 1);
+
+ first_time = FALSE;
+ obstack_grow (&collect_obstack, pprefix->prefix, len);
+ obstack_grow (&collect_obstack, machine_suffix, suffix_len);
+ }
+
+ if (!pprefix->require_machine_suffix)
+ {
+ if (!first_time)
+ obstack_grow (&collect_obstack, ":", 1);
+
+ first_time = FALSE;
+ obstack_grow (&collect_obstack, pprefix->prefix, len);
+ }
+ }
+ obstack_grow (&collect_obstack, "\0", 1);
+ putenv (obstack_finish (&collect_obstack));
+}
+
+\f
/* Search for NAME using the prefix list PREFIXES. MODE is passed to
access to check permissions.
Return 0 if not found, otherwise return its name, allocated with malloc. */
/* If -v, print what we are about to do, and maybe query. */
- if (verbose_flag || save_temps_flag)
+ if (verbose_flag)
{
/* Print each piped command as a separate line. */
for (i = 0; i < n_commands ; i++)
do_spec_1 (buf, 0, NULL);
}
}
+
+ /* Discard the closing paren or bracket. */
+ if (*p)
+ p++;
}
break;
/* First see whether we have %*. */
substitution = 0;
- while (*r && *r == '}')
+ while (r < q)
{
if (*r == '%' && r[1] == '*')
substitution = 1;
obstack_init (&obstack);
+ /* Set up to remember the pathname of gcc and any options
+ needed for collect. */
+ obstack_init (&collect_obstack);
+ obstack_grow (&collect_obstack, "COLLECT_GCC=", sizeof ("COLLECT_GCC=")-1);
+ obstack_grow (&collect_obstack, programname, strlen (programname)+1);
+ putenv (obstack_finish (&collect_obstack));
+
/* Choose directory for temp files. */
choose_temp_base ();
if (error_count == 0)
{
int tmp = execution_count;
+ int i;
+ int first_time;
+
+ /* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables
+ for collect. */
+ putenv_from_prefixes (&exec_prefix, "COMPILER_PATH=");
+ putenv_from_prefixes (&startfile_prefix, "LIBRARY_PATH=");
+
+ /* Build COLLECT_GCC_OPTIONS to have all of the options specified to
+ the compiler. */
+ obstack_grow (&collect_obstack, "COLLECT_GCC_OPTIONS=",
+ sizeof ("COLLECT_GCC_OPTIONS=")-1);
+
+ first_time = TRUE;
+ for (i = 0; i < n_switches; i++)
+ {
+ char **args;
+ if (!first_time)
+ obstack_grow (&collect_obstack, " ", 1);
+
+ first_time = FALSE;
+ obstack_grow (&collect_obstack, "-", 1);
+ obstack_grow (&collect_obstack, switches[i].part1,
+ strlen (switches[i].part1));
+
+ for (args = switches[i].args; args && *args; args++)
+ {
+ obstack_grow (&collect_obstack, " ", 1);
+ obstack_grow (&collect_obstack, *args, strlen (*args));
+ }
+ }
+ obstack_grow (&collect_obstack, "\0", 1);
+ putenv (obstack_finish (&collect_obstack));
+
value = do_spec (link_command_spec);
if (value < 0)
error_count = 1;
struct compiler *comp;
register char *p;
register char c;
+ struct spec_list *spec;
for (comp = compilers; comp->spec; comp++)
{
validate_switches (p + 1);
}
+ /* look through the linked list of extra specs read from the specs file */
+ for (spec = specs ; spec ; spec = spec->next)
+ {
+ p = spec->spec;
+ while (c = *p++)
+ if (c == '%' && *p == '{')
+ /* We have a switch spec. */
+ validate_switches (p + 1);
+ }
+
p = link_command_spec;
while (c = *p++)
if (c == '%' && *p == '{')