Commit f5a1b0d2 by Nick Clifton

Apply ARM/Linux patches.

Rework cpu/architecture command line parsing.

From-SVN: r25380
parent 956662b2
1999-02-22 Nick Clifton <nickc@cygnus.com>
* config/arm/arm.h: Add TARGET_CPU_strongarm1100.
Add -mno-sched command line switch to disable scheduling of
instructions into the function's prologue.
(enum processor_type): Remove.
(TARGET_OPTIONS): Add "fpe=" option to match documentation.
(struct arm_cpu_select): Replace 'set_tune_p' and 'set_arch_p'
fields with 'processors' field.
(CONDITIONAL_REGISTER_USAGE): Allow r10 to be used if stack
checking is not enabled.
(RETURN_IN_MEMORY): Always call arm_return_in_memory.
* config/arm/arm.c: (arm_cpu): Remove.
(tune_flags): Remove.
(arm_is_strong): New variable: true iff the target processor is a
StrongARM.
(arm_is_6_or_7): New variable: true iff the target processor is an
ARM6 or and ARM7.
(arm_select): Fields reorganised.
(struct processors): processor_type field removed.
(all_procs): Remove.
(all_cores): New array: Definitions of all known ARM cpu cores.
(all_architectures): New array: Definitions of all known ARM
architectures.
(streq): New macro.
(FL_SCHED): New processor flag: processor required load
scheduling.
(FL_STRONG): New processor flag: processor is a StrongARM.
(arm_override_options): Reorganised to make code clearer.
(use_return_insn): Test for "not (TARGET_APCS and
frame_pointer_needed)".
(arm_return_in_memory): Improve handling of structures.
* config/arm/arm.md: Remove "cpu" attribute. Replace with
"is_strongarm" and "is_arm_6_or_7" attributes.
(zero_extendhisi2): Check for TARGET_SHORT_BY_BYTES before
arm_arch4.
(extendhisi2): Check for TARGET_SHORT_BY_BYTES before arm_arch4.
* invoke.texi (ARM Options): Document -mtune= and -mfp= options.
1999-02-22 Philip Blundell <philb@gnu.org>
* config/arm/linux-gas.h (INITIALIZE_TRAMPOLINE): Replace default
definition with one including cache synchronisation.
(CLEAR_INSN_CACHE): Correct syscall number and enable definition.
Move definition of inhibit_libc to...
* config/arm/xm-linux.h: ... here.
* config/arm/t-linux: Disable multilib configurations since the
only effect for most people is to cause builds to fail.
* config/arm/elf.h (ASM_FILE_START): Add .file directive.
(ASM_SPEC): Translate -mapcs-float to -mfloat for the assembler.
* config/arm/linux-elf.h (DEFAULT_VTABLE_THUNKS): Define.
(HANDLE_SYSV_PRAGMA): Likewise.
(LIB_SPEC): Copy definition from generic Linux files.
(LIBGCC_SPEC): Include -lfloat if -msoft-float was given.
(FP_DEFAULT): Set to SOFT3 on 32-bit targets.
(DWARF2_DEBUGGING_INFO): Define.
(PREFERRED_DEBUGGING_TYPE): Define as DBX_DEBUG.
Mon Feb 22 16:54:18 EST 1999 Andrew MacLeod <amacleod@cygnus.com> Mon Feb 22 16:54:18 EST 1999 Andrew MacLeod <amacleod@cygnus.com>
* loop.c (libcall_other_regs): Make extern. * loop.c (libcall_other_regs): Make extern.
......
...@@ -42,8 +42,8 @@ Boston, MA 02111-1307, USA. */ ...@@ -42,8 +42,8 @@ Boston, MA 02111-1307, USA. */
possible. */ possible. */
static int max_insns_skipped = 5; static int max_insns_skipped = 5;
extern FILE * asm_out_file;
/* Some function declarations. */ /* Some function declarations. */
extern FILE *asm_out_file;
static HOST_WIDE_INT int_log2 PROTO ((HOST_WIDE_INT)); static HOST_WIDE_INT int_log2 PROTO ((HOST_WIDE_INT));
static char *output_multi_immediate PROTO ((rtx *, char *, char *, int, static char *output_multi_immediate PROTO ((rtx *, char *, char *, int,
...@@ -74,9 +74,6 @@ static enum arm_cond_code get_arm_condition_code PROTO ((rtx)); ...@@ -74,9 +74,6 @@ static enum arm_cond_code get_arm_condition_code PROTO ((rtx));
rtx arm_compare_op0, arm_compare_op1; rtx arm_compare_op0, arm_compare_op1;
int arm_compare_fp; int arm_compare_fp;
/* What type of cpu are we compiling for? */
enum processor_type arm_cpu;
/* What type of floating point are we tuning for? */ /* What type of floating point are we tuning for? */
enum floating_point_type arm_fpu; enum floating_point_type arm_fpu;
...@@ -87,7 +84,7 @@ enum floating_point_type arm_fpu_arch; ...@@ -87,7 +84,7 @@ enum floating_point_type arm_fpu_arch;
enum prog_mode_type arm_prgmode; enum prog_mode_type arm_prgmode;
/* Set by the -mfp=... option */ /* Set by the -mfp=... option */
char *target_fp_name = NULL; char * target_fp_name = NULL;
/* Used to parse -mstructure_size_boundary command line option. */ /* Used to parse -mstructure_size_boundary command line option. */
char * structure_size_string = NULL; char * structure_size_string = NULL;
...@@ -99,8 +96,14 @@ int arm_fast_multiply = 0; ...@@ -99,8 +96,14 @@ int arm_fast_multiply = 0;
/* Nonzero if this chip supports the ARM Architecture 4 extensions */ /* Nonzero if this chip supports the ARM Architecture 4 extensions */
int arm_arch4 = 0; int arm_arch4 = 0;
/* Set to the features we should tune the code for (multiply speed etc). */ /* Nonzero if this chip can benefit from laod scheduling. */
int tune_flags = 0; int arm_ld_sched = 0;
/* Nonzero if this chip is a StrongARM. */
int arm_is_strong = 0;
/* Nonzero if this chip is a an ARM6 or an ARM7. */
int arm_is_6_or_7 = 0;
/* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference, we /* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference, we
must report the mode of the memory reference from PRINT_OPERAND to must report the mode of the memory reference from PRINT_OPERAND to
...@@ -134,7 +137,7 @@ rtx arm_target_insn; ...@@ -134,7 +137,7 @@ rtx arm_target_insn;
int arm_target_label; int arm_target_label;
/* The condition codes of the ARM, and the inverse function. */ /* The condition codes of the ARM, and the inverse function. */
char *arm_condition_codes[] = char * arm_condition_codes[] =
{ {
"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
"hi", "ls", "ge", "lt", "gt", "le", "al", "nv" "hi", "ls", "ge", "lt", "gt", "le", "al", "nv"
...@@ -142,84 +145,90 @@ char *arm_condition_codes[] = ...@@ -142,84 +145,90 @@ char *arm_condition_codes[] =
static enum arm_cond_code get_arm_condition_code (); static enum arm_cond_code get_arm_condition_code ();
#define streq(string1, string2) (strcmp (string1, string2) == 0)
/* Initialization code */ /* Initialization code */
struct arm_cpu_select arm_select[4] =
{
/* switch name, tune arch */
{ (char *)0, "--with-cpu=", 1, 1 },
{ (char *)0, "-mcpu=", 1, 1 },
{ (char *)0, "-march=", 0, 1 },
{ (char *)0, "-mtune=", 1, 0 },
};
#define FL_CO_PROC 0x01 /* Has external co-processor bus */ #define FL_CO_PROC 0x01 /* Has external co-processor bus */
#define FL_FAST_MULT 0x02 /* Fast multiply */ #define FL_FAST_MULT 0x02 /* Fast multiply */
#define FL_MODE26 0x04 /* 26-bit mode support */ #define FL_MODE26 0x04 /* 26-bit mode support */
#define FL_MODE32 0x08 /* 32-bit mode support */ #define FL_MODE32 0x08 /* 32-bit mode support */
#define FL_ARCH4 0x10 /* Architecture rel 4 */ #define FL_ARCH4 0x10 /* Architecture rel 4 */
#define FL_THUMB 0x20 /* Thumb aware */ #define FL_THUMB 0x20 /* Thumb aware */
#define FL_LDSCHED 0x40 /* Load scheduling necessary */
#define FL_STRONG 0x80 /* StrongARM */
struct processors struct processors
{ {
char *name; char * name;
enum processor_type type;
unsigned int flags; unsigned int flags;
}; };
/* Not all of these give usefully different compilation alternatives, /* Not all of these give usefully different compilation alternatives,
but there is no simple way of generalizing them. */ but there is no simple way of generalizing them. */
static struct processors all_procs[] = static struct processors all_cores[] =
{
/* ARM Cores */
{"arm2", FL_CO_PROC | FL_MODE26 },
{"arm250", FL_CO_PROC | FL_MODE26 },
{"arm3", FL_CO_PROC | FL_MODE26 },
{"arm6", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
{"arm60", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
{"arm600", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
{"arm610", FL_MODE26 | FL_MODE32 },
{"arm620", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
{"arm7", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
{"arm7m", FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT }, /* arm7m doesn't exist on its own, */
{"arm7d", FL_CO_PROC | FL_MODE26 | FL_MODE32 }, /* but only with D, (and I), */
{"arm7dm", FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT }, /* but those don't alter the code, */
{"arm7di", FL_CO_PROC | FL_MODE26 | FL_MODE32 }, /* so arm7m is sometimes used. */
{"arm7dmi", FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT },
{"arm70", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
{"arm700", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
{"arm700i", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
{"arm710", FL_MODE26 | FL_MODE32 },
{"arm710c", FL_MODE26 | FL_MODE32 },
{"arm7100", FL_MODE26 | FL_MODE32 },
{"arm7500", FL_MODE26 | FL_MODE32 },
{"arm7500fe", FL_CO_PROC | FL_MODE26 | FL_MODE32 }, /* Doesn't really have an external co-proc, but does have embedded fpu. */
{"arm7tdmi", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB },
{"arm8", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED },
{"arm810", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED },
{"arm9", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
{"arm9tdmi", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
{"strongarm", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_STRONG },
{"strongarm110", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_STRONG },
{"strongarm1100", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_STRONG },
{NULL, 0}
};
static struct processors all_architectures[] =
{ {
{"arm2", PROCESSOR_ARM2, FL_CO_PROC | FL_MODE26}, /* ARM Architectures */
{"arm250", PROCESSOR_ARM2, FL_CO_PROC | FL_MODE26},
{"arm3", PROCESSOR_ARM2, FL_CO_PROC | FL_MODE26}, {"armv2", FL_CO_PROC | FL_MODE26 },
{"arm6", PROCESSOR_ARM6, FL_CO_PROC | FL_MODE32 | FL_MODE26}, {"armv2a", FL_CO_PROC | FL_MODE26 },
{"arm600", PROCESSOR_ARM6, FL_CO_PROC | FL_MODE32 | FL_MODE26}, {"armv3", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
{"arm610", PROCESSOR_ARM6, FL_MODE32 | FL_MODE26}, {"armv3m", FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT },
{"arm7", PROCESSOR_ARM7, FL_CO_PROC | FL_MODE32 | FL_MODE26}, {"armv4", FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 },
/* arm7m doesn't exist on its own, only in conjunction with D, (and I), but
those don't alter the code, so it is sometimes known as the arm7m */
{"arm7m", PROCESSOR_ARM7, (FL_CO_PROC | FL_FAST_MULT | FL_MODE32
| FL_MODE26)},
{"arm7dm", PROCESSOR_ARM7, (FL_CO_PROC | FL_FAST_MULT | FL_MODE32
| FL_MODE26)},
{"arm7dmi", PROCESSOR_ARM7, (FL_CO_PROC | FL_FAST_MULT | FL_MODE32
| FL_MODE26)},
{"arm700", PROCESSOR_ARM7, FL_CO_PROC | FL_MODE32 | FL_MODE26},
{"arm710", PROCESSOR_ARM7, FL_MODE32 | FL_MODE26},
{"arm7100", PROCESSOR_ARM7, FL_MODE32 | FL_MODE26},
{"arm7500", PROCESSOR_ARM7, FL_MODE32 | FL_MODE26},
/* Doesn't really have an external co-proc, but does have embedded fpu */
{"arm7500fe", PROCESSOR_ARM7, FL_CO_PROC | FL_MODE32 | FL_MODE26},
{"arm7tdmi", PROCESSOR_ARM7, (FL_CO_PROC | FL_FAST_MULT | FL_MODE32
| FL_ARCH4 | FL_THUMB)},
{"arm8", PROCESSOR_ARM8, (FL_FAST_MULT | FL_MODE32 | FL_MODE26
| FL_ARCH4)},
{"arm810", PROCESSOR_ARM8, (FL_FAST_MULT | FL_MODE32 | FL_MODE26
| FL_ARCH4)},
/* The next two are the same, but arm9 only exists in the thumb variant */
{"arm9", PROCESSOR_ARM9, (FL_FAST_MULT | FL_MODE32 | FL_ARCH4
| FL_THUMB)},
{"arm9tdmi", PROCESSOR_ARM9, (FL_FAST_MULT | FL_MODE32 | FL_ARCH4
| FL_THUMB)},
{"strongarm", PROCESSOR_STARM, (FL_FAST_MULT | FL_MODE32 | FL_MODE26
| FL_ARCH4)},
{"strongarm110", PROCESSOR_STARM, (FL_FAST_MULT | FL_MODE32 | FL_MODE26
| FL_ARCH4)},
{"armv2", PROCESSOR_NONE, FL_CO_PROC | FL_MODE26},
{"armv2a", PROCESSOR_NONE, FL_CO_PROC | FL_MODE26},
{"armv3", PROCESSOR_NONE, FL_CO_PROC | FL_MODE32 | FL_MODE26},
{"armv3m", PROCESSOR_NONE, (FL_CO_PROC | FL_FAST_MULT | FL_MODE32
| FL_MODE26)},
{"armv4", PROCESSOR_NONE, (FL_CO_PROC | FL_FAST_MULT | FL_MODE32
| FL_MODE26 | FL_ARCH4)},
/* Strictly, FL_MODE26 is a permitted option for v4t, but there are no /* Strictly, FL_MODE26 is a permitted option for v4t, but there are no
implementations that support it, so we will leave it out for now. */ implementations that support it, so we will leave it out for now. */
{"armv4t", PROCESSOR_NONE, (FL_CO_PROC | FL_FAST_MULT | FL_MODE32 {"armv4t", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB },
| FL_ARCH4)}, {NULL, 0}
{NULL, 0, 0} };
/* This is a magic stucture. The 'string' field is magically filled in
with a pointer to the value specified by the user on the command line
assuming that the user has specified such a value. */
struct arm_cpu_select arm_select[] =
{
/* string name processors */
{ NULL, "-mcpu=", all_cores },
{ NULL, "-march=", all_architectures },
{ NULL, "-mtune=", all_cores }
}; };
/* Fix up any incompatible options that the user has specified. /* Fix up any incompatible options that the user has specified.
...@@ -227,10 +236,84 @@ static struct processors all_procs[] = ...@@ -227,10 +236,84 @@ static struct processors all_procs[] =
void void
arm_override_options () arm_override_options ()
{ {
int arm_thumb_aware = 0; unsigned int flags = 0;
int flags = 0;
unsigned i; unsigned i;
struct arm_cpu_select * ptr; struct arm_cpu_select * ptr;
/* Set up the flags based on the cpu/architecture selected by the user. */
for (i = sizeof (arm_select) / sizeof (arm_select[0]); i--;)
{
struct arm_cpu_select * ptr = arm_select + i;
if (ptr->string != NULL && ptr->string[0] != '\0')
{
struct processors * sel;
for (sel = ptr->processors; sel->name != NULL; sel ++)
if (streq (ptr->string, sel->name))
{
if (flags != 0)
{
/* We scan the arm_select array in the order:
tune -> arch -> cpu
So if we have been asked to tune for, say, an ARM8,
but we are told that the cpu is only an ARM6, then
we have problems. We detect this by seeing if the
flags bits accumulated so far can be supported by the
cpu/architecture type now being parsed. If they can,
then OR in any new bits. If they cannot then report
an error. */
if ((flags & sel->flags) != flags)
error ("switch %s%s overridden by another switch",
ptr->string, sel->name );
}
flags = sel->flags;
break;
}
if (sel->name == NULL)
error ("bad value (%s) for %s switch", ptr->string, ptr->name);
}
}
/* If the user did not specify a processor, choose one for them. */
if (flags == 0)
{
struct processors * sel;
int sought = 0;
if (TARGET_THUMB_INTERWORK)
{
sought |= FL_THUMB;
/* Force apcs-32 to be used for Thumb targets. */
target_flags |= ARM_FLAG_APCS_32;
}
if (TARGET_APCS_32)
sought |= FL_MODE32;
else
sought |= FL_MODE26;
if (sought != 0)
{
for (sel = all_cores; sel->name != NULL; sel++)
if ((sel->flags & sought) == sought)
{
flags = sel->flags;
break;
}
if (sel->name == NULL)
fatal ("Unable to select a cpu that matches command line specification");
}
else
{
/* The user did not specify any command line switches that require
a certain kind of CPU. Use TARGET_CPU_DEFAULT instead. */
static struct cpu_default static struct cpu_default
{ {
int cpu; int cpu;
...@@ -241,56 +324,82 @@ arm_override_options () ...@@ -241,56 +324,82 @@ arm_override_options ()
{ TARGET_CPU_arm2, "arm2" }, { TARGET_CPU_arm2, "arm2" },
{ TARGET_CPU_arm6, "arm6" }, { TARGET_CPU_arm6, "arm6" },
{ TARGET_CPU_arm610, "arm610" }, { TARGET_CPU_arm610, "arm610" },
{ TARGET_CPU_arm7dm, "arm7dm" }, { TARGET_CPU_arm7m, "arm7m" },
{ TARGET_CPU_arm7500fe, "arm7500fe" }, { TARGET_CPU_arm7500fe, "arm7500fe" },
{ TARGET_CPU_arm7tdmi, "arm7tdmi" }, { TARGET_CPU_arm7tdmi, "arm7tdmi" },
{ TARGET_CPU_arm8, "arm8" }, { TARGET_CPU_arm8, "arm8" },
{ TARGET_CPU_arm810, "arm810" }, { TARGET_CPU_arm810, "arm810" },
{ TARGET_CPU_arm9, "arm9" },
{ TARGET_CPU_strongarm, "strongarm" }, { TARGET_CPU_strongarm, "strongarm" },
{ TARGET_CPU_generic, "arm" },
{ 0, 0 } { 0, 0 }
}; };
struct cpu_default *def; struct cpu_default * def;
/* Set the default. */ /* Find the default. */
for (def = &cpu_defaults[0]; def->name; ++def) for (def = cpu_defaults; def->name; def ++)
if (def->cpu == TARGET_CPU_DEFAULT) if (def->cpu == TARGET_CPU_DEFAULT)
break; break;
if (! def->name)
if (def->name == NULL)
abort (); abort ();
arm_select[0].string = def->name; /* Find the default CPU's flags. */
for (sel = all_cores; sel->name != NULL; sel ++)
if (streq (def->name, sel->name))
break;
for (i = 0; i < sizeof (arm_select) / sizeof (arm_select[0]); i++) if (sel->name == NULL)
abort ();
flags = sel->flags;
}
}
/* Cope with some redundant flags. */
if (TARGET_6)
{ {
ptr = &arm_select[i]; warning ("Option '-m6' deprecated. Use: '-mapcs-32' or -mcpu=<proc>");
if (ptr->string != (char *)0 && ptr->string[0] != '\0') target_flags |= ARM_FLAG_APCS_32;
}
if (TARGET_3)
{ {
struct processors *sel; warning ("Option '-m3' deprecated. Use: '-mapcs-26' or -mcpu=<proc>");
target_flags &= ~ARM_FLAG_APCS_32;
}
for (sel = all_procs; sel->name != NULL; sel++) /* Make sure that the processor choice does not conflict with any of the
if (! strcmp (ptr->string, sel->name)) other command line choices. */
if (TARGET_APCS_32 && !(flags & FL_MODE32))
{ {
/* -march= is the only flag that can take an architecture warning ("target CPU does not support APCS-32" );
type, so if we match when the tune bit is set, the target_flags &= ~ ARM_FLAG_APCS_32;
option was invalid. */ }
if (ptr->set_tune_p) else if (! TARGET_APCS_32 && !(flags & FL_MODE26))
{ {
if (sel->type == PROCESSOR_NONE) warning ("target CPU does not support APCS-26" );
continue; /* Its an architecture, not a cpu */ target_flags |= ARM_FLAG_APCS_32;
arm_cpu = sel->type;
tune_flags = sel->flags;
} }
if (ptr->set_arch_p) if (TARGET_THUMB_INTERWORK && !(flags & FL_THUMB))
flags = sel->flags; {
warning ("target CPU does not support interworking" );
break; target_flags &= ~ARM_FLAG_THUMB;
} }
if (sel->name == NULL) /* If interworking is enabled then APCS-32 must be selected as well. */
error ("bad value (%s) for %s switch", ptr->string, ptr->name); if (TARGET_THUMB_INTERWORK)
{
if (! TARGET_APCS_32)
warning ("interworking forces APCS-32 to be used" );
target_flags |= ARM_FLAG_APCS_32;
} }
if (TARGET_APCS_STACK && ! TARGET_APCS)
{
warning ("-mapcs-stack-check incompatible with -mno-apcs-frame");
target_flags |= ARM_FLAG_APCS_FRAME;
} }
if (write_symbols != NO_DEBUG && flag_omit_frame_pointer) if (write_symbols != NO_DEBUG && flag_omit_frame_pointer)
...@@ -299,17 +408,11 @@ arm_override_options () ...@@ -299,17 +408,11 @@ arm_override_options ()
if (TARGET_POKE_FUNCTION_NAME) if (TARGET_POKE_FUNCTION_NAME)
target_flags |= ARM_FLAG_APCS_FRAME; target_flags |= ARM_FLAG_APCS_FRAME;
if (TARGET_6)
warning ("Option '-m6' deprecated. Use: '-mapcs-32' or -mcpu=<proc>");
if (TARGET_3)
warning ("Option '-m3' deprecated. Use: '-mapcs-26' or -mcpu=<proc>");
if (TARGET_APCS_REENT && flag_pic) if (TARGET_APCS_REENT && flag_pic)
fatal ("-fpic and -mapcs-reent are incompatible"); fatal ("-fpic and -mapcs-reent are incompatible");
if (TARGET_APCS_REENT) if (TARGET_APCS_REENT)
warning ("APCS reentrant code not supported."); warning ("APCS reentrant code not supported. Ignored");
/* If stack checking is disabled, we can use r10 as the PIC register, /* If stack checking is disabled, we can use r10 as the PIC register,
which keeps r9 available. */ which keeps r9 available. */
...@@ -326,93 +429,45 @@ arm_override_options () ...@@ -326,93 +429,45 @@ arm_override_options ()
if (TARGET_APCS_FLOAT) if (TARGET_APCS_FLOAT)
warning ("Passing floating point arguments in fp regs not yet supported"); warning ("Passing floating point arguments in fp regs not yet supported");
if (TARGET_APCS_STACK && ! TARGET_APCS) /* Initialise booleans used elsewhere in this file, and in arm.md */
{ arm_fast_multiply = (flags & FL_FAST_MULT) != 0;
warning ("-mapcs-stack-check incompatible with -mno-apcs-frame"); arm_arch4 = (flags & FL_ARCH4) != 0;
target_flags |= ARM_FLAG_APCS_FRAME; arm_ld_sched = (flags & FL_LDSCHED) != 0;
} arm_is_strong = (flags & FL_STRONG);
/* Default is to tune for an FPA */ /* The arm.md file needs to know if theprocessor is an ARM6 or an ARM7 */
arm_fpu = FP_HARD; arm_is_6_or_7 = ((flags & (FL_MODE26 | FL_MODE32)) && !(flags & FL_ARCH4));
/* Default value for floating point code... if no co-processor /* Default value for floating point code... if no co-processor
bus, then schedule for emulated floating point. Otherwise, bus, then schedule for emulated floating point. Otherwise,
assume the user has an FPA. assume the user has an FPA.
Note: this does not prevent use of floating point instructions, Note: this does not prevent use of floating point instructions,
-msoft-float does that. */ -msoft-float does that. */
if ((tune_flags & FL_CO_PROC) == 0) if ((flags & FL_CO_PROC) == 0)
arm_fpu = FP_SOFT3; arm_fpu = FP_SOFT3;
else
arm_fast_multiply = (flags & FL_FAST_MULT) != 0; arm_fpu = FP_HARD;
arm_arch4 = (flags & FL_ARCH4) != 0;
arm_thumb_aware = (flags & FL_THUMB) != 0;
if (target_fp_name) if (target_fp_name)
{ {
if (strcmp (target_fp_name, "2") == 0) if (streq (target_fp_name, "2"))
arm_fpu_arch = FP_SOFT2; arm_fpu_arch = FP_SOFT2;
else if (strcmp (target_fp_name, "3") == 0) else if (streq (target_fp_name, "3"))
arm_fpu_arch = FP_HARD; arm_fpu_arch = FP_SOFT3;
else else
fatal ("Invalid floating point emulation option: -mfpe=%s", fatal ("Invalid floating point emulation option: -mfpe-%s",
target_fp_name); target_fp_name);
} }
else else
arm_fpu_arch = FP_DEFAULT; arm_fpu_arch = FP_DEFAULT;
if (TARGET_THUMB_INTERWORK && ! arm_thumb_aware) if (TARGET_FPE && arm_fpu != FP_HARD)
{ arm_fpu = FP_SOFT2;
warning ("This processor variant does not support Thumb interworking");
target_flags &= ~ARM_FLAG_THUMB;
}
if (TARGET_FPE && arm_fpu == FP_HARD)
arm_fpu = FP_SOFT3;
/* If optimizing for space, don't synthesize constants */
if (optimize_size)
arm_constant_limit = 1;
/* Override a few things based on the tuning pararmeters. */ /* For arm2/3 there is no need to do any scheduling if there is only
switch (arm_cpu) a floating point emulator, or we are doing software floating-point. */
{ if ((TARGET_SOFT_FLOAT || arm_fpu != FP_HARD) && (flags & FL_MODE32) == 0)
case PROCESSOR_ARM2:
case PROCESSOR_ARM3:
/* For arm2/3 there is no need to do any scheduling if there is
only a floating point emulator, or we are doing software
floating-point. */
if (TARGET_SOFT_FLOAT || arm_fpu != FP_HARD)
flag_schedule_insns = flag_schedule_insns_after_reload = 0; flag_schedule_insns = flag_schedule_insns_after_reload = 0;
break;
case PROCESSOR_ARM6:
case PROCESSOR_ARM7:
break;
case PROCESSOR_ARM8:
case PROCESSOR_ARM9:
/* For these processors, it never costs more than 2 cycles to load a
constant, and the load scheduler may well reduce that to 1. */
arm_constant_limit = 1;
break;
case PROCESSOR_STARM:
/* Same as above */
arm_constant_limit = 1;
/* StrongARM has early execution of branches, a sequence that is worth
skipping is shorter. */
max_insns_skipped = 3;
break;
default:
fatal ("Unknown cpu type selected");
break;
}
/* If optimizing for size, bump the number of instructions that we
are prepared to conditionally execute (even on a StrongARM). */
if (optimize_size)
max_insns_skipped = 6;
arm_prog_mode = TARGET_APCS_32 ? PROG_MODE_PROG32 : PROG_MODE_PROG26; arm_prog_mode = TARGET_APCS_32 ? PROG_MODE_PROG32 : PROG_MODE_PROG26;
...@@ -425,6 +480,21 @@ arm_override_options () ...@@ -425,6 +480,21 @@ arm_override_options ()
else else
warning ("Structure size boundary can only be set to 8 or 32"); warning ("Structure size boundary can only be set to 8 or 32");
} }
/* If optimizing for space, don't synthesize constants.
For processors with load scheduling, it never costs more than 2 cycles
to load a constant, and the load scheduler may well reduce that to 1. */
if (optimize_size || (flags & FL_LDSCHED))
arm_constant_limit = 1;
/* If optimizing for size, bump the number of instructions that we
are prepared to conditionally execute (even on a StrongARM).
Otherwise for the StrongARM, which has early execution of branches,
a sequence that is worth skipping is shorter. */
if (optimize_size)
max_insns_skipped = 6;
else if (arm_is_strong)
max_insns_skipped = 3;
} }
/* Return 1 if it is possible to return using a single instruction */ /* Return 1 if it is possible to return using a single instruction */
...@@ -435,18 +505,19 @@ use_return_insn (iscond) ...@@ -435,18 +505,19 @@ use_return_insn (iscond)
{ {
int regno; int regno;
if (!reload_completed ||current_function_pretend_args_size if (!reload_completed
|| current_function_pretend_args_size
|| current_function_anonymous_args || current_function_anonymous_args
|| ((get_frame_size () + current_function_outgoing_args_size != 0) || ((get_frame_size () + current_function_outgoing_args_size != 0)
&& !(TARGET_APCS || frame_pointer_needed))) && !(TARGET_APCS && frame_pointer_needed)))
return 0; return 0;
/* Can't be done if interworking with Thumb, and any registers have been /* Can't be done if interworking with Thumb, and any registers have been
stacked. Similarly, on StrongARM, conditional returns are expensive stacked. Similarly, on StrongARM, conditional returns are expensive
if they aren't taken and registers have been stacked. */ if they aren't taken and registers have been stacked. */
if (iscond && arm_cpu == PROCESSOR_STARM && frame_pointer_needed) if (iscond && arm_is_strong && frame_pointer_needed)
return 0; return 0;
else if ((iscond && arm_cpu == PROCESSOR_STARM) if ((iscond && arm_is_strong)
|| TARGET_THUMB_INTERWORK) || TARGET_THUMB_INTERWORK)
for (regno = 0; regno < 16; regno++) for (regno = 0; regno < 16; regno++)
if (regs_ever_live[regno] && ! call_used_regs[regno]) if (regs_ever_live[regno] && ! call_used_regs[regno])
...@@ -1193,23 +1264,54 @@ arm_canonicalize_comparison (code, op1) ...@@ -1193,23 +1264,54 @@ arm_canonicalize_comparison (code, op1)
return code; return code;
} }
/* Decide whether a type should be returned in memory (true)
/* Handle aggregates that are not laid out in a BLKmode element. or in a register (false). This is called by the macro
This is a sub-element of RETURN_IN_MEMORY. */ RETURN_IN_MEMORY. */
int int
arm_return_in_memory (type) arm_return_in_memory (type)
tree type; tree type;
{ {
if (TREE_CODE (type) == RECORD_TYPE) if (! AGGREGATE_TYPE_P (type))
{
/* All simple types are returned in registers. */
return 0;
}
else if (int_size_in_bytes (type) > 4)
{
/* All structures/unions bigger than one word are returned in memory. */
return 1;
}
else if (TREE_CODE (type) == RECORD_TYPE)
{ {
tree field; tree field;
/* For a struct, we can return in a register if every element was a /* For a struct the APCS says that we must return in a register if
bit-field. */ every addressable element has an offset of zero. For practical
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) purposes this means that the structure can have at most one non
if (TREE_CODE (field) != FIELD_DECL bit-field element and that this element must be the first one in
|| ! DECL_BIT_FIELD_TYPE (field)) the structure. */
/* Find the first field, ignoring non FIELD_DECL things which will
have been created by C++. */
for (field = TYPE_FIELDS (type);
field && TREE_CODE (field) != FIELD_DECL;
field = TREE_CHAIN (field))
continue;
if (field == NULL)
return 0; /* An empty structure. Allowed by an extension to ANSI C. */
/* Now check the remaining fields, if any. */
for (field = TREE_CHAIN (field);
field;
field = TREE_CHAIN (field))
{
if (TREE_CODE (field) != FIELD_DECL)
continue;
if (! DECL_BIT_FIELD_TYPE (field))
return 1; return 1;
}
return 0; return 0;
} }
...@@ -1219,16 +1321,20 @@ arm_return_in_memory (type) ...@@ -1219,16 +1321,20 @@ arm_return_in_memory (type)
/* Unions can be returned in registers if every element is /* Unions can be returned in registers if every element is
integral, or can be returned in an integer register. */ integral, or can be returned in an integer register. */
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) for (field = TYPE_FIELDS (type);
field;
field = TREE_CHAIN (field))
{ {
if (TREE_CODE (field) != FIELD_DECL if (TREE_CODE (field) != FIELD_DECL)
|| (AGGREGATE_TYPE_P (TREE_TYPE (field)) continue;
&& RETURN_IN_MEMORY (TREE_TYPE (field)))
|| FLOAT_TYPE_P (TREE_TYPE (field))) if (RETURN_IN_MEMORY (TREE_TYPE (field)))
return 1; return 1;
} }
return 0; return 0;
} }
/* XXX Not sure what should be done for other aggregates, so put them in /* XXX Not sure what should be done for other aggregates, so put them in
memory. */ memory. */
return 1; return 1;
...@@ -1570,7 +1676,7 @@ arm_rtx_costs (x, code, outer_code) ...@@ -1570,7 +1676,7 @@ arm_rtx_costs (x, code, outer_code)
int add_cost = const_ok_for_arm (i) ? 4 : 8; int add_cost = const_ok_for_arm (i) ? 4 : 8;
int j; int j;
/* Tune as appropriate */ /* Tune as appropriate */
int booth_unit_size = ((tune_flags & FL_FAST_MULT) ? 8 : 2); int booth_unit_size = (arm_fast_multiply ? 8 : 2);
for (j = 0; i && j < 32; j += booth_unit_size) for (j = 0; i && j < 32; j += booth_unit_size)
{ {
...@@ -1581,7 +1687,7 @@ arm_rtx_costs (x, code, outer_code) ...@@ -1581,7 +1687,7 @@ arm_rtx_costs (x, code, outer_code)
return add_cost; return add_cost;
} }
return (((tune_flags & FL_FAST_MULT) ? 8 : 30) return ((arm_fast_multiply ? 8 : 30)
+ (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4) + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4)
+ (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 4)); + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 4));
...@@ -2595,9 +2701,7 @@ load_multiple_sequence (operands, nops, regs, base, load_offset) ...@@ -2595,9 +2701,7 @@ load_multiple_sequence (operands, nops, regs, base, load_offset)
/* For ARM8,9 & StrongARM, 2 ldr instructions are faster than an ldm if /* For ARM8,9 & StrongARM, 2 ldr instructions are faster than an ldm if
the offset isn't small enough */ the offset isn't small enough */
if (nops == 2 if (nops == 2 && arm_ld_sched)
&& (arm_cpu == PROCESSOR_ARM8 || arm_cpu == PROCESSOR_ARM9
|| arm_cpu == PROCESSOR_STARM))
return 0; return 0;
/* Can't do it without setting up the offset, only do this if it takes /* Can't do it without setting up the offset, only do this if it takes
...@@ -5074,7 +5178,7 @@ output_func_epilogue (f, frame_size) ...@@ -5074,7 +5178,7 @@ output_func_epilogue (f, frame_size)
if (use_return_insn (FALSE) && return_used_this_function) if (use_return_insn (FALSE) && return_used_this_function)
{ {
if ((frame_size + current_function_outgoing_args_size) != 0 if ((frame_size + current_function_outgoing_args_size) != 0
&& !(frame_pointer_needed || TARGET_APCS)) && !(frame_pointer_needed && TARGET_APCS))
abort (); abort ();
goto epilogue_done; goto epilogue_done;
} }
...@@ -5217,8 +5321,10 @@ output_func_epilogue (f, frame_size) ...@@ -5217,8 +5321,10 @@ output_func_epilogue (f, frame_size)
if (TARGET_THUMB_INTERWORK) if (TARGET_THUMB_INTERWORK)
{ {
if (! lr_save_eliminated) if (! lr_save_eliminated)
print_multi_reg(f, "ldmfd\t%ssp!", live_regs_mask | 0x4000, live_regs_mask |= 0x4000;
FALSE);
if (live_regs_mask != 0)
print_multi_reg (f, "ldmfd\t%ssp!", live_regs_mask, FALSE);
fprintf (f, "\tbx\t%slr\n", REGISTER_PREFIX); fprintf (f, "\tbx\t%slr\n", REGISTER_PREFIX);
} }
...@@ -5329,7 +5435,6 @@ emit_sfm (base_reg, count) ...@@ -5329,7 +5435,6 @@ emit_sfm (base_reg, count)
gen_rtvec (1, gen_rtx_REG (XFmode, gen_rtvec (1, gen_rtx_REG (XFmode,
base_reg++)), base_reg++)),
2)); 2));
for (i = 1; i < count; i++) for (i = 1; i < count; i++)
XVECEXP (par, 0, i) = gen_rtx_USE (VOIDmode, XVECEXP (par, 0, i) = gen_rtx_USE (VOIDmode,
gen_rtx_REG (XFmode, base_reg++)); gen_rtx_REG (XFmode, base_reg++));
...@@ -5443,8 +5548,9 @@ arm_expand_prologue () ...@@ -5443,8 +5548,9 @@ arm_expand_prologue ()
} }
/* If we are profiling, make sure no instructions are scheduled before /* If we are profiling, make sure no instructions are scheduled before
the call to mcount. */ the call to mcount. Similarly if the user has requested no
if (profile_flag || profile_block_flag) scheduling in the prolog. */
if (profile_flag || profile_block_flag || TARGET_NO_SCHED_PRO)
emit_insn (gen_blockage ()); emit_insn (gen_blockage ());
} }
......
/* Definitions of target machine for GNU compiler, for Acorn RISC Machine. /* Definitions of target machine for GNU compiler, for ARM.
Copyright (C) 1991, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. Copyright (C) 1991, 93, 94, 95, 96, 97, 98, 1999 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).
...@@ -53,6 +53,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -53,6 +53,7 @@ Boston, MA 02111-1307, USA. */
#define TARGET_CPU_arm810 0x0020 #define TARGET_CPU_arm810 0x0020
#define TARGET_CPU_strongarm 0x0040 #define TARGET_CPU_strongarm 0x0040
#define TARGET_CPU_strongarm110 0x0040 #define TARGET_CPU_strongarm110 0x0040
#define TARGET_CPU_strongarm1100 0x0040
#define TARGET_CPU_arm9 0x0080 #define TARGET_CPU_arm9 0x0080
#define TARGET_CPU_arm9tdmi 0x0080 #define TARGET_CPU_arm9tdmi 0x0080
/* Configure didn't specify */ /* Configure didn't specify */
...@@ -146,6 +147,7 @@ Unrecognized value in TARGET_CPU_DEFAULT. ...@@ -146,6 +147,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
%{march=arm9tdmi:-D__ARM_ARCH_4T__} \ %{march=arm9tdmi:-D__ARM_ARCH_4T__} \
%{march=strongarm:-D__ARM_ARCH_4__} \ %{march=strongarm:-D__ARM_ARCH_4__} \
%{march=strongarm110:-D__ARM_ARCH_4__} \ %{march=strongarm110:-D__ARM_ARCH_4__} \
%{march=strongarm1100:-D__ARM_ARCH_4__} \
%{march=armv2:-D__ARM_ARCH_2__} \ %{march=armv2:-D__ARM_ARCH_2__} \
%{march=armv2a:-D__ARM_ARCH_2__} \ %{march=armv2a:-D__ARM_ARCH_2__} \
%{march=armv3:-D__ARM_ARCH_3__} \ %{march=armv3:-D__ARM_ARCH_3__} \
...@@ -175,6 +177,7 @@ Unrecognized value in TARGET_CPU_DEFAULT. ...@@ -175,6 +177,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
%{mcpu=arm9tdmi:-D__ARM_ARCH_4T__} \ %{mcpu=arm9tdmi:-D__ARM_ARCH_4T__} \
%{mcpu=strongarm:-D__ARM_ARCH_4__} \ %{mcpu=strongarm:-D__ARM_ARCH_4__} \
%{mcpu=strongarm110:-D__ARM_ARCH_4__} \ %{mcpu=strongarm110:-D__ARM_ARCH_4__} \
%{mcpu=strongarm1100:-D__ARM_ARCH_4__} \
%{!mcpu*:%{!m6:%{!m2:%{!m3:%(cpp_cpu_arch_default)}}}}} \ %{!mcpu*:%{!m6:%{!m2:%{!m3:%(cpp_cpu_arch_default)}}}}} \
" "
...@@ -258,7 +261,7 @@ Unrecognized value in TARGET_CPU_DEFAULT. ...@@ -258,7 +261,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
extern int target_flags; extern int target_flags;
/* The floating point instruction architecture, can be 2 or 3 */ /* The floating point instruction architecture, can be 2 or 3 */
extern char *target_fp_name; extern char * target_fp_name;
/* Nonzero if the function prologue (and epilogue) should obey /* Nonzero if the function prologue (and epilogue) should obey
the ARM Procedure Call Standard. */ the ARM Procedure Call Standard. */
...@@ -318,6 +321,9 @@ extern char *target_fp_name; ...@@ -318,6 +321,9 @@ extern char *target_fp_name;
big-endian (for backwards compatibility with older versions of GCC). */ big-endian (for backwards compatibility with older versions of GCC). */
#define ARM_FLAG_LITTLE_WORDS (0x2000) #define ARM_FLAG_LITTLE_WORDS (0x2000)
/* Nonzero if we need to protect the prolog from scheduling */
#define ARM_FLAG_NO_SCHED_PRO (0x4000)
/* Nonzero if a call to abort should be generated if a noreturn /* Nonzero if a call to abort should be generated if a noreturn
function tries to return. */ function tries to return. */
#define ARM_FLAG_ABORT_NORETURN (0x8000) #define ARM_FLAG_ABORT_NORETURN (0x8000)
...@@ -337,6 +343,7 @@ function tries to return. */ ...@@ -337,6 +343,7 @@ function tries to return. */
#define TARGET_BIG_END (target_flags & ARM_FLAG_BIG_END) #define TARGET_BIG_END (target_flags & ARM_FLAG_BIG_END)
#define TARGET_THUMB_INTERWORK (target_flags & ARM_FLAG_THUMB) #define TARGET_THUMB_INTERWORK (target_flags & ARM_FLAG_THUMB)
#define TARGET_LITTLE_WORDS (target_flags & ARM_FLAG_LITTLE_WORDS) #define TARGET_LITTLE_WORDS (target_flags & ARM_FLAG_LITTLE_WORDS)
#define TARGET_NO_SCHED_PRO (target_flags & ARM_FLAG_NO_SCHED_PRO)
#define TARGET_ABORT_NORETURN (target_flags & ARM_FLAG_ABORT_NORETURN) #define TARGET_ABORT_NORETURN (target_flags & ARM_FLAG_ABORT_NORETURN)
/* SUBTARGET_SWITCHES is used to add flags on a per-config basis. /* SUBTARGET_SWITCHES is used to add flags on a per-config basis.
...@@ -391,68 +398,39 @@ function tries to return. */ ...@@ -391,68 +398,39 @@ function tries to return. */
{"abort-on-noreturn", ARM_FLAG_ABORT_NORETURN, \ {"abort-on-noreturn", ARM_FLAG_ABORT_NORETURN, \
"Generate a call to abort if a noreturn function returns"}, \ "Generate a call to abort if a noreturn function returns"}, \
{"no-abort-on-noreturn", -ARM_FLAG_ABORT_NORETURN, ""}, \ {"no-abort-on-noreturn", -ARM_FLAG_ABORT_NORETURN, ""}, \
{"sched-prolog", -ARM_FLAG_NO_SCHED_PRO, \
"Do not move instructions into a function's prologue" }, \
{"no-sched-prolog", ARM_FLAG_NO_SCHED_PRO, "" }, \
SUBTARGET_SWITCHES \ SUBTARGET_SWITCHES \
{"", TARGET_DEFAULT } \ {"", TARGET_DEFAULT } \
} }
#define TARGET_OPTIONS \ #define TARGET_OPTIONS \
{ \ { \
{"cpu=", \ {"cpu=", & arm_select[0].string, \
&arm_select[1].string, \ "Specify the name of the target CPU" }, \
"Specify the name of the target CPU"}, \ {"arch=", & arm_select[1].string, \
{"arch=", \ "Specify the name of the target architecture" }, \
&arm_select[2].string, \ {"tune=", & arm_select[2].string, "" }, \
"Specify the name of the target architecture"}, \ {"fpe=", & target_fp_name, "" }, \
{"tune=", \ {"fp=", & target_fp_name, \
&arm_select[3].string, \ "Specify the version of the floating point emulator" }, \
"Order instructions for best performance on this CPU"}, \ { "structure-size-boundary=", & structure_size_string, \
{"fp=", \ "Specify the minumum bit alignment of structures" } \
&target_fp_name, \
"Specify the version of the floating point emulator"}, \
{"structure-size-boundary=", \
&structure_size_string, \
"Specify the minumum bit alignment of structures"} \
} }
/* arm_select[0] is reserved for the default cpu. */
struct arm_cpu_select struct arm_cpu_select
{ {
char *string; char * string;
char *name; char * name;
int set_tune_p; struct processors * processors;
int set_arch_p;
}; };
/* This is a magic array. If the user specifies a command line switch
which matches one of the entries in TARGET_OPTIONS then the corresponding
string pointer will be set to the value specified by the user. */
extern struct arm_cpu_select arm_select[]; extern struct arm_cpu_select arm_select[];
#ifndef PROCESSOR_DEFAULT
#define PROCESSOR_DEFAULT PROCESSOR_ARM2
#endif
#ifndef TARGET_CPU_DEFAULT
#define TARGET_CPU_DEFAULT ((char *) 0)
#endif
/* Which processor we are running on, for instruction scheduling
purposes. */
enum processor_type
{
PROCESSOR_ARM2,
PROCESSOR_ARM3,
PROCESSOR_ARM6,
PROCESSOR_ARM7,
PROCESSOR_ARM8,
PROCESSOR_ARM9,
PROCESSOR_STARM,
PROCESSOR_NONE /* NOTE: This must be last, since it doesn't
appear in the attr_cpu list */
};
/* Recast the cpu class to be the cpu attribute. */
#define arm_cpu_attr ((enum attr_cpu)arm_cpu)
extern enum processor_type arm_cpu;
enum prog_mode_type enum prog_mode_type
{ {
prog_mode26, prog_mode26,
...@@ -493,6 +471,15 @@ extern int arm_fast_multiply; ...@@ -493,6 +471,15 @@ extern int arm_fast_multiply;
/* Nonzero if this chip supports the ARM Architecture 4 extensions */ /* Nonzero if this chip supports the ARM Architecture 4 extensions */
extern int arm_arch4; extern int arm_arch4;
/* Nonzero if this chip can benefit from load scheduling. */
extern int arm_ld_sched;
/* Nonzero if this chip is a StrongARM. */
extern int arm_is_strong;
/* Nonzero if this chip is a an ARM6 or an ARM7. */
extern int arm_is_6_or_7;
#ifndef TARGET_DEFAULT #ifndef TARGET_DEFAULT
#define TARGET_DEFAULT 0 #define TARGET_DEFAULT 0
#endif #endif
...@@ -635,7 +622,7 @@ extern char * structure_size_string; ...@@ -635,7 +622,7 @@ extern char * structure_size_string;
r4-r8 S register variable r4-r8 S register variable
r9 S (rfp) register variable (real frame pointer) r9 S (rfp) register variable (real frame pointer)
r10 F S (sl) stack limit (not currently used) r10 F S (sl) stack limit (used by -mapcs-stack-check)
r11 F S (fp) argument pointer r11 F S (fp) argument pointer
r12 (ip) temp workspace r12 (ip) temp workspace
r13 F S (sp) lower end of current stack frame r13 F S (sp) lower end of current stack frame
...@@ -730,6 +717,11 @@ extern char * structure_size_string; ...@@ -730,6 +717,11 @@ extern char * structure_size_string;
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \ fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 0; \ call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 0; \
} \ } \
else if (! TARGET_APCS_STACK) \
{ \
fixed_regs[10] = 0; \
call_used_regs[10] = 0; \
} \
} }
/* Return number of consecutive hard regs needed starting at reg REGNO /* Return number of consecutive hard regs needed starting at reg REGNO
...@@ -1062,9 +1054,7 @@ do { \ ...@@ -1062,9 +1054,7 @@ do { \
/* How large values are returned */ /* How large values are returned */
/* A C expression which can inhibit the returning of certain function values /* A C expression which can inhibit the returning of certain function values
in registers, based on the type of value. */ in registers, based on the type of value. */
#define RETURN_IN_MEMORY(TYPE) \ #define RETURN_IN_MEMORY(TYPE) arm_return_in_memory (TYPE)
(TYPE_MODE ((TYPE)) == BLKmode || \
(AGGREGATE_TYPE_P ((TYPE)) && arm_return_in_memory ((TYPE))))
/* Define DEFAULT_PCC_STRUCT_RETURN to 1 if all structure and union return /* Define DEFAULT_PCC_STRUCT_RETURN to 1 if all structure and union return
values must be in memory. On the ARM, they need only do so if larger values must be in memory. On the ARM, they need only do so if larger
...@@ -1779,8 +1769,8 @@ extern int arm_pic_register; ...@@ -1779,8 +1769,8 @@ extern int arm_pic_register;
#define FINALIZE_PIC arm_finalize_pic () #define FINALIZE_PIC arm_finalize_pic ()
/* We can't directly access anything that contains a symbol, nor can /* We can't directly access anything that contains a symbol,
we indirect via the constant pool */ nor can we indirect via the constant pool. */
#define LEGITIMATE_PIC_OPERAND_P(X) \ #define LEGITIMATE_PIC_OPERAND_P(X) \
(! symbol_mentioned_p (X) \ (! symbol_mentioned_p (X) \
&& (! CONSTANT_POOL_ADDRESS_P (X) \ && (! CONSTANT_POOL_ADDRESS_P (X) \
......
...@@ -45,10 +45,7 @@ ...@@ -45,10 +45,7 @@
; by the -mapcs-{32,26} flag, and possibly the -mcpu=... option. ; by the -mapcs-{32,26} flag, and possibly the -mcpu=... option.
(define_attr "prog_mode" "prog26,prog32" (const (symbol_ref "arm_prog_mode"))) (define_attr "prog_mode" "prog26,prog32" (const (symbol_ref "arm_prog_mode")))
; CPU attribute is used to determine the best instruction mix for performance (define_attr "is_strongarm" "no,yes" (const (symbol_ref "arm_is_strong")))
; on the named processor.
(define_attr "cpu" "arm2,arm3,arm6,arm7,arm8,arm9,st_arm"
(const (symbol_ref "arm_cpu_attr")))
; Floating Point Unit. If we only have floating point emulation, then there ; Floating Point Unit. If we only have floating point emulation, then there
; is no point in scheduling the floating point insns. (Well, for best ; is no point in scheduling the floating point insns. (Well, for best
...@@ -100,11 +97,9 @@ ...@@ -100,11 +97,9 @@
"normal,mult,block,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith,float_em,f_load,f_store,f_mem_r,r_mem_f,f_2_r,r_2_f,call,load,store1,store2,store3,store4" "normal,mult,block,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith,float_em,f_load,f_store,f_mem_r,r_mem_f,f_2_r,r_2_f,call,load,store1,store2,store3,store4"
(const_string "normal")) (const_string "normal"))
; Load scheduling, set from the cpu characteristic ; Load scheduling, set from the arm_ld_sched variable
(define_attr "ldsched" "no,yes" ; initialised by arm_override_options()
(if_then_else (eq_attr "cpu" "arm8,arm9,st_arm") (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
(const_string "yes")
(const_string "no")))
; condition codes: this one is used by final_prescan_insn to speed up ; condition codes: this one is used by final_prescan_insn to speed up
; conditionalizing instructions. It saves having to scan the rtl to see if ; conditionalizing instructions. It saves having to scan the rtl to see if
...@@ -137,10 +132,7 @@ ...@@ -137,10 +132,7 @@
; have one. Later ones, such as StrongARM, have write-back caches, so don't ; have one. Later ones, such as StrongARM, have write-back caches, so don't
; suffer blockages enough to warrent modelling this (and it can adversely ; suffer blockages enough to warrent modelling this (and it can adversely
; affect the schedule). ; affect the schedule).
(define_attr "model_wbuf" "no,yes" (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_is_6_or_7")))
(if_then_else (eq_attr "cpu" "arm6,arm7")
(const_string "yes")
(const_string "no")))
(define_attr "write_conflict" "no,yes" (define_attr "write_conflict" "no,yes"
(if_then_else (eq_attr "type" (if_then_else (eq_attr "type"
...@@ -267,13 +259,15 @@ ...@@ -267,13 +259,15 @@
(and (eq_attr "fpu" "fpa") (eq_attr "type" "f_mem_r")) 7 7) (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_mem_r")) 7 7)
(define_function_unit "core" 1 0 (define_function_unit "core" 1 0
(and (eq_attr "cpu" "!arm8,st_arm") (eq_attr "type" "mult")) 16 16) (and (eq_attr "ldsched" "no") (eq_attr "type" "mult")) 16 16)
(define_function_unit "core" 1 0 (define_function_unit "core" 1 0
(and (eq_attr "cpu" "arm8") (eq_attr "type" "mult")) 4 4) (and (and (eq_attr "ldsched" "yes") (eq_attr "is_strongarm" "no"))
(eq_attr "type" "mult")) 4 4)
(define_function_unit "core" 1 0 (define_function_unit "core" 1 0
(and (eq_attr "cpu" "st_arm") (eq_attr "type" "mult")) 3 2) (and (and (eq_attr "ldsched" "yes") (eq_attr "is_strongarm" "yes"))
(eq_attr "type" "mult")) 3 2)
(define_function_unit "core" 1 0 (eq_attr "type" "store2") 3 3) (define_function_unit "core" 1 0 (eq_attr "type" "store2") 3 3)
...@@ -1209,7 +1203,7 @@ ...@@ -1209,7 +1203,7 @@
(const_int 0))) (const_int 0)))
(clobber (match_scratch:QI 3 "=r"))] (clobber (match_scratch:QI 3 "=r"))]
"INTVAL (operands[2]) >= 0 && INTVAL (operands[1]) > 0 "INTVAL (operands[2]) >= 0 && INTVAL (operands[1]) > 0
&& (INTVAL (operands[2]) + INTVAL (operands[1]) <= 8)" && ((INTVAL (operands[2]) + INTVAL (operands[1])) <= 8)"
"* "*
operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1) operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
<< INTVAL (operands[2])); << INTVAL (operands[2]));
...@@ -2173,17 +2167,21 @@ ...@@ -2173,17 +2167,21 @@
"" ""
" "
{ {
if (arm_arch4 && GET_CODE (operands[1]) == MEM) if (GET_CODE (operands[1]) == MEM)
{ {
emit_insn (gen_rtx_SET (VOIDmode, operands[0], if (TARGET_SHORT_BY_BYTES)
gen_rtx_ZERO_EXTEND (SImode, operands[1]))); {
emit_insn (gen_movhi_bytes (operands[0], operands[1]));
DONE; DONE;
} }
if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM) else if (arm_arch4)
{ {
emit_insn (gen_movhi_bytes (operands[0], operands[1])); emit_insn (gen_rtx_SET (VOIDmode,
operands[0],
gen_rtx_ZERO_EXTEND (SImode, operands[1])));
DONE; DONE;
} }
}
if (! s_register_operand (operands[1], HImode)) if (! s_register_operand (operands[1], HImode))
operands[1] = copy_to_mode_reg (HImode, operands[1]); operands[1] = copy_to_mode_reg (HImode, operands[1]);
operands[1] = gen_lowpart (SImode, operands[1]); operands[1] = gen_lowpart (SImode, operands[1]);
...@@ -2275,18 +2273,20 @@ ...@@ -2275,18 +2273,20 @@
"" ""
" "
{ {
if (arm_arch4 && GET_CODE (operands[1]) == MEM) if (GET_CODE (operands[1]) == MEM)
{ {
emit_insn (gen_rtx_SET (VOIDmode, operands[0], if (TARGET_SHORT_BY_BYTES)
gen_rtx_SIGN_EXTEND (SImode, operands[1]))); {
emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
DONE; DONE;
} }
else if (arm_arch4)
if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM)
{ {
emit_insn (gen_extendhisi2_mem (operands[0], operands[1])); emit_insn (gen_rtx_SET (VOIDmode, operands[0],
gen_rtx_SIGN_EXTEND (SImode, operands[1])));
DONE; DONE;
} }
}
if (! s_register_operand (operands[1], HImode)) if (! s_register_operand (operands[1], HImode))
operands[1] = copy_to_mode_reg (HImode, operands[1]); operands[1] = copy_to_mode_reg (HImode, operands[1]);
operands[1] = gen_lowpart (SImode, operands[1]); operands[1] = gen_lowpart (SImode, operands[1]);
...@@ -2381,7 +2381,8 @@ ...@@ -2381,7 +2381,8 @@
{ {
if (arm_arch4 && GET_CODE (operands[1]) == MEM) if (arm_arch4 && GET_CODE (operands[1]) == MEM)
{ {
emit_insn (gen_rtx_SET (VOIDmode, operands[0], emit_insn (gen_rtx_SET (VOIDmode,
operands[0],
gen_rtx_SIGN_EXTEND (HImode, operands[1]))); gen_rtx_SIGN_EXTEND (HImode, operands[1])));
DONE; DONE;
} }
...@@ -2454,7 +2455,8 @@ ...@@ -2454,7 +2455,8 @@
{ {
if (arm_arch4 && GET_CODE (operands[1]) == MEM) if (arm_arch4 && GET_CODE (operands[1]) == MEM)
{ {
emit_insn (gen_rtx_SET (VOIDmode, operands[0], emit_insn (gen_rtx_SET (VOIDmode,
operands[0],
gen_rtx_SIGN_EXTEND (SImode, operands[1]))); gen_rtx_SIGN_EXTEND (SImode, operands[1])));
DONE; DONE;
} }
...@@ -6136,7 +6138,6 @@ ...@@ -6136,7 +6138,6 @@
} }
") ")
;; The next two patterns occur when an AND operation is followed by a ;; The next two patterns occur when an AND operation is followed by a
;; scc insn sequence ;; scc insn sequence
......
/* Definitions of target machine for GNU compiler, /* Definitions of target machine for GNU compiler,
for ARM with ELF obj format. for ARM with ELF obj format.
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
Contributed by Philip Blundell <philb@gnu.org> and Contributed by Philip Blundell <philb@gnu.org> and
Catherine Moore <clm@cygnus.com> Catherine Moore <clm@cygnus.com>
...@@ -100,7 +100,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -100,7 +100,7 @@ Boston, MA 02111-1307, USA. */
by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */ by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */
#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \ #define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \
do { \ do { \
char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \ char * name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
if (!flag_inhibit_size_directive && DECL_SIZE (DECL) \ if (!flag_inhibit_size_directive && DECL_SIZE (DECL) \
&& ! AT_END && TOP_LEVEL \ && ! AT_END && TOP_LEVEL \
&& DECL_INITIAL (DECL) == error_mark_node \ && DECL_INITIAL (DECL) == error_mark_node \
...@@ -143,7 +143,7 @@ do { \ ...@@ -143,7 +143,7 @@ do { \
#ifndef ASM_SPEC #ifndef ASM_SPEC
#define ASM_SPEC "%{mbig-endian:-EB} %{mcpu=*:-m%*} %{march=*:-m%*} \ #define ASM_SPEC "%{mbig-endian:-EB} %{mcpu=*:-m%*} %{march=*:-m%*} \
%{mapcs-*:-mapcs-%*} %{mthumb-interwork:-mthumb-interwork}" %{mapcs-*:-mapcs-%*} %{mthumb-interwork:-mthumb-interwork} %{mapcs-float:mfloat}"
#endif #endif
#ifndef LINK_SPEC #ifndef LINK_SPEC
...@@ -198,9 +198,10 @@ arm_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS) ...@@ -198,9 +198,10 @@ arm_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
#ifndef ASM_FILE_START #ifndef ASM_FILE_START
#define ASM_FILE_START(STREAM) \ #define ASM_FILE_START(STREAM) \
do { \ do { \
extern char *version_string; \ extern char * version_string; \
fprintf (STREAM, "%s Generated by gcc %s for ARM/elf\n", \ fprintf (STREAM, "%s Generated by gcc %s for ARM/elf\n", \
ASM_COMMENT_START, version_string); \ ASM_COMMENT_START, version_string); \
output_file_directive ((STREAM), main_input_filename); \
} while (0) } while (0)
#endif #endif
...@@ -209,7 +210,7 @@ do { \ ...@@ -209,7 +210,7 @@ do { \
#define ASM_OUTPUT_INTERNAL_LABEL(STREAM, PREFIX, NUM) \ #define ASM_OUTPUT_INTERNAL_LABEL(STREAM, PREFIX, NUM) \
do \ do \
{ \ { \
char *s = (char *) alloca (40 + strlen (PREFIX)); \ char * s = (char *) alloca (40 + strlen (PREFIX)); \
extern int arm_target_label, arm_ccfsm_state; \ extern int arm_target_label, arm_ccfsm_state; \
extern rtx arm_target_insn; \ extern rtx arm_target_insn; \
\ \
...@@ -332,6 +333,3 @@ do { \ ...@@ -332,6 +333,3 @@ do { \
fputc ('\n', FILE); } while (0) fputc ('\n', FILE); } while (0)
#include "arm/aout.h" #include "arm/aout.h"
...@@ -34,8 +34,20 @@ Boston, MA 02111-1307, USA. */ ...@@ -34,8 +34,20 @@ Boston, MA 02111-1307, USA. */
" %{mapcs-26:-mapcs-26} %(!mapcs-26:-mapcs-32}" " %{mapcs-26:-mapcs-26} %(!mapcs-26:-mapcs-32}"
#endif #endif
/* This was defined in linux.h. Define it here also. */
#undef DEFAULT_VTABLE_THUNKS
#define DEFAULT_VTABLE_THUNKS 1
/* Handle #pragma weak and #pragma pack. */
#define HANDLE_SYSV_PRAGMA
/* Now we define the strings used to build the spec file. */ /* Now we define the strings used to build the spec file. */
#define LIB_SPEC "%{!shared:%{!symbolic:-lc}}" #define LIB_SPEC \
"%{shared: -lc} \
%{!shared: %{pthread:-lpthread} \
%{profile:-lc_p} %{!profile: -lc}}"
#define LIBGCC_SPEC "%{msoft-float:-lfloat} -lgcc"
/* Add the compiler's crtend, and the library's crtn. */ /* Add the compiler's crtend, and the library's crtn. */
#define ENDFILE_SPEC "%{!shared:crtend.o%s} %{shared:crtendS.o%s} \ #define ENDFILE_SPEC "%{!shared:crtend.o%s} %{shared:crtendS.o%s} \
...@@ -64,6 +76,10 @@ Boston, MA 02111-1307, USA. */ ...@@ -64,6 +76,10 @@ Boston, MA 02111-1307, USA. */
#ifndef SUBTARGET_DEFAULT_APCS26 #ifndef SUBTARGET_DEFAULT_APCS26
#undef CPP_APCS_PC_DEFAULT_SPEC #undef CPP_APCS_PC_DEFAULT_SPEC
#define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_32__" #define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_32__"
/* On 32-bit machine it is always safe to assume we have the "new"
floating point system. */
#undef FP_DEFAULT
#define FP_DEFAULT FP_SOFT3
#endif #endif
/* Allow #sccs in preprocessor. */ /* Allow #sccs in preprocessor. */
...@@ -201,5 +217,10 @@ const_section () \ ...@@ -201,5 +217,10 @@ const_section () \
assemble_name (FILE, NAME2); \ assemble_name (FILE, NAME2); \
fputc ('\n', FILE); } while (0) fputc ('\n', FILE); } while (0)
/* Make DWARF2 an option, but keep DBX as the default for now.
Use -gdwarf2 to turn on DWARF2. */
#define DWARF2_DEBUGGING_INFO
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
#include "arm/elf.h" #include "arm/elf.h"
#include "arm/linux-gas.h" #include "arm/linux-gas.h"
/* Definitions of target machine for GNU compiler. /* Definitions of target machine for GNU compiler.
ARM Linux-based GNU systems version. ARM Linux-based GNU systems version.
Copyright (C) 1997, 1998 Free Software Foundation, Inc. Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
Contributed by Russell King <rmk92@ecs.soton.ac.uk>. Contributed by Russell King <rmk92@ecs.soton.ac.uk>.
This file is part of GNU CC. This file is part of GNU CC.
...@@ -59,29 +59,25 @@ Boston, MA 02111-1307, USA. */ ...@@ -59,29 +59,25 @@ Boston, MA 02111-1307, USA. */
#undef WCHAR_TYPE_SIZE #undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE BITS_PER_WORD #define WCHAR_TYPE_SIZE BITS_PER_WORD
#if 0 /* not yet */ /* Emit code to set up a trampoline and synchronise the caches. */
#undef INITIALIZE_TRAMPOLINE
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
{ \
emit_move_insn (gen_rtx (MEM, SImode, plus_constant ((TRAMP), 8)), \
(CXT)); \
emit_move_insn (gen_rtx (MEM, SImode, plus_constant ((TRAMP), 12)), \
(FNADDR)); \
emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__clear_cache"), \
0, VOIDmode, 2, TRAMP, Pmode, \
plus_constant (TRAMP, TRAMPOLINE_SIZE), Pmode); \
}
/* Clear the instruction cache from `beg' to `end'. This makes an /* Clear the instruction cache from `beg' to `end'. This makes an
inline system call to SYS_cacheflush. The arguments are as inline system call to SYS_cacheflush. */
follows:
cacheflush (start, end, flags)
*/
#define CLEAR_INSN_CACHE(BEG, END) \ #define CLEAR_INSN_CACHE(BEG, END) \
{ \ { \
register unsigned long _beg __asm ("a1") = (unsigned long) (BEG); \ register unsigned long _beg __asm ("a1") = (unsigned long) (BEG); \
register unsigned long _end __asm ("a2") = (unsigned long) (END); \ register unsigned long _end __asm ("a2") = (unsigned long) (END); \
register unsigned long _flg __asm ("a3") = 0; \ register unsigned long _flg __asm ("a3") = 0; \
__asm __volatile ("swi 0x9000b8"); \ __asm __volatile ("swi 0x9f0002"); \
} }
#endif
/* If cross-compiling, don't require stdio.h etc to build libgcc.a. */
#ifdef CROSS_COMPILE
#ifndef inhibit_libc
#define inhibit_libc
#endif
#endif
...@@ -23,9 +23,11 @@ dp-bit.c: $(srcdir)/config/fp-bit.c ...@@ -23,9 +23,11 @@ dp-bit.c: $(srcdir)/config/fp-bit.c
echo '#endif' >> dp-bit.c echo '#endif' >> dp-bit.c
cat $(srcdir)/config/fp-bit.c >> dp-bit.c cat $(srcdir)/config/fp-bit.c >> dp-bit.c
MULTILIB_OPTIONS = mlittle-endian/mbig-endian mhard-float/msoft-float mapcs-32/mapcs-26 fno-leading-underscore/fleading-underscore # MULTILIB_OPTIONS = mlittle-endian/mbig-endian mhard-float/msoft-float mapcs-32/mapcs-26 fno-leading-underscore/fleading-underscore
MULTILIB_DIRNAMES = le be fpu soft 32bit 26bit elf under # MULTILIB_DIRNAMES = le be fpu soft 32bit 26bit elf under
MULTILIB_MATCHES = # MULTILIB_MATCHES =
LIBGCC = stmp-multilib # LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib # INSTALL_LIBGCC = install-multilib
TARGET_LIBGCC2_CFLAGS = -Dinhibit_libc
...@@ -13,8 +13,10 @@ LIBGCC1 = libgcc1-asm.a ...@@ -13,8 +13,10 @@ LIBGCC1 = libgcc1-asm.a
LIB1ASMSRC = arm/lib1funcs.asm LIB1ASMSRC = arm/lib1funcs.asm
LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx
MULTILIB_OPTIONS = mapcs-32 # If you want to build both APCS variants as multilib options this is how
MULTILIB_DIRNAMES = apcs-32 # to do it.
#MULTILIB_OPTIONS = mapcs-32/apcs-26
#MULTILIB_DIRNAMES = apcs-32 apcs-26
LIBGCC = stmp-multilib LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib INSTALL_LIBGCC = install-multilib
...@@ -170,7 +170,7 @@ in the following sections. ...@@ -170,7 +170,7 @@ in the following sections.
-idirafter @var{dir} -idirafter @var{dir}
-include @var{file} -imacros @var{file} -include @var{file} -imacros @var{file}
-iprefix @var{file} -iwithprefix @var{dir} -iprefix @var{file} -iwithprefix @var{dir}
-iwithprefixbefore @var{dir} -isystem @var{dir} -iwithprefixbefore @var{dir} -isystem @var{dir} -isystem-c++ @var{dir}
-M -MD -MM -MMD -MG -nostdinc -P -trigraphs -M -MD -MM -MMD -MG -nostdinc -P -trigraphs
-undef -U@var{macro} -Wp,@var{option} -undef -U@var{macro} -Wp,@var{option}
@end smallexample @end smallexample
...@@ -259,6 +259,8 @@ in the following sections. ...@@ -259,6 +259,8 @@ in the following sections.
-mcpu= -march= -mfpe= -mcpu= -march= -mfpe=
-mstructure-size-boundary= -mstructure-size-boundary=
-mbsd -mxopen -mno-symrename -mbsd -mxopen -mno-symrename
-mabort-on-noreturn
-mno-sched-prolog
@emph{Thumb Options} @emph{Thumb Options}
-mtpcs-frame -mno-tpcs-frame -mtpcs-frame -mno-tpcs-frame
...@@ -1155,6 +1157,11 @@ offsets for adjusting the @samp{this} pointer at the call site. Newer ...@@ -1155,6 +1157,11 @@ offsets for adjusting the @samp{this} pointer at the call site. Newer
implementations store a single pointer to a @samp{thunk} function which implementations store a single pointer to a @samp{thunk} function which
does any necessary adjustment and then calls the target function. does any necessary adjustment and then calls the target function.
This option also enables a heuristic for controlling emission of
vtables; if a class has any non-inline virtual functions, the vtable
will be emitted in the translation unit containing the first one of
those.
Like all options that change the ABI, all C++ code, @emph{including Like all options that change the ABI, all C++ code, @emph{including
libgcc.a} must be built with the same setting of this option. libgcc.a} must be built with the same setting of this option.
...@@ -3796,13 +3803,17 @@ suppresses this pass. The post-processor is never run when the ...@@ -3796,13 +3803,17 @@ suppresses this pass. The post-processor is never run when the
compiler is built for cross-compilation. compiler is built for cross-compilation.
@item -mcpu=<name> @item -mcpu=<name>
@item -mtune=<name>
@kindex -mcpu= @kindex -mcpu=
@kindex -mtune=
This specifies the name of the target ARM processor. GCC uses this name This specifies the name of the target ARM processor. GCC uses this name
to determine what kind of instructions it can use when generating to determine what kind of instructions it can use when generating
assembly code. Permissable names are: arm2, arm250, arm3, arm6, arm60, assembly code. Permissable names are: arm2, arm250, arm3, arm6, arm60,
arm600, arm610, arm620, arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm600, arm610, arm620, arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi,
arm70, arm700, arm700i, arm710, arm710c, arm7100, arm7500, arm7500fe, arm70, arm700, arm700i, arm710, arm710c, arm7100, arm7500, arm7500fe,
arm7tdmi, arm8, strongarm, strongarm110 arm7tdmi, arm8, strongarm, strongarm110, strongarm1100, arm8, arm810,
arm9, arm9tdmi. @samp{-mtune=} is a synonym for @samp{-mcpue=} to
support older versions of GCC.
@item -march=<name> @item -march=<name>
@kindex -march= @kindex -march=
...@@ -3813,9 +3824,12 @@ of the @samp{-mcpu=} option. Permissable names are: armv2, armv2a, ...@@ -3813,9 +3824,12 @@ of the @samp{-mcpu=} option. Permissable names are: armv2, armv2a,
armv3, armv3m, armv4, armv4t armv3, armv3m, armv4, armv4t
@item -mfpe=<number> @item -mfpe=<number>
@item -mfp=<number>
@kindex -mfpe= @kindex -mfpe=
@kindex -mfp=
This specifes the version of the floating point emulation available on This specifes the version of the floating point emulation available on
the target. Permissable values are 2 and 3. the target. Permissable values are 2 and 3. @samp{-mfp=} is a synonym
for @samp{-mfpe=} to support older versions of GCC.
@item -mstructure-size-boundary=<n> @item -mstructure-size-boundary=<n>
@kindex -mstructure-size-boundary @kindex -mstructure-size-boundary
...@@ -3830,6 +3844,12 @@ libraries compiled with the other value, if they exchange information ...@@ -3830,6 +3844,12 @@ libraries compiled with the other value, if they exchange information
using structures or unions. Programmers are encouraged to use the 32 using structures or unions. Programmers are encouraged to use the 32
value as future versions of the toolchain may default to this value. value as future versions of the toolchain may default to this value.
@item -mabort-on-noreturn
@kindex -mabort-on-noreturn
@kindex -mnoabort-on-noreturn
Generate a call to the function abort at the end of a noreturn function.
It will be executed if the function tries to return.
@end table @end table
@node Thumb Options @node Thumb Options
...@@ -4666,7 +4686,9 @@ All modules should be compiled with the same @samp{-G @var{num}} value. ...@@ -4666,7 +4686,9 @@ All modules should be compiled with the same @samp{-G @var{num}} value.
@itemx -mno-regnames @itemx -mno-regnames
On System V.4 and embedded PowerPC systems do (do not) emit register On System V.4 and embedded PowerPC systems do (do not) emit register
names in the assembly language output using symbolic forms. names in the assembly language output using symbolic forms.
@end table @end table
@node RT Options @node RT Options
@subsection IBM RT Options @subsection IBM RT Options
@cindex RT options @cindex RT options
......
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