summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>1999-02-22 16:47:59 +0000
committernickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>1999-02-22 16:47:59 +0000
commit9888ad6d0aae045a7c142479341642cbe023a568 (patch)
treea2fe88d03bd68ea8ca2592dc1d58cf9345eeb24f
parent22e2b0d04b4f635c1091942c78f8b6c7079b1db9 (diff)
downloadgcc-9888ad6d0aae045a7c142479341642cbe023a568.tar.gz
Apply ARM/Linux patches.
Rework cpu/architecture command line parsing. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@25380 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog64
-rw-r--r--gcc/config/arm/arm.c572
-rw-r--r--gcc/config/arm/arm.h104
-rw-r--r--gcc/config/arm/arm.md103
-rw-r--r--gcc/config/arm/elf.h14
-rw-r--r--gcc/config/arm/linux-elf.h23
-rw-r--r--gcc/config/arm/linux-gas.h34
-rw-r--r--gcc/config/arm/t-arm-elf12
-rw-r--r--gcc/config/arm/t-linux6
-rw-r--r--gcc/invoke.texi28
10 files changed, 581 insertions, 379 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ab0a16bfa9f..719f6c11e17 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,67 @@
+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>
* loop.c (libcall_other_regs): Make extern.
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index fa86deefbca..6866da554a4 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -42,8 +42,8 @@ Boston, MA 02111-1307, USA. */
possible. */
static int max_insns_skipped = 5;
+extern FILE * asm_out_file;
/* Some function declarations. */
-extern FILE *asm_out_file;
static HOST_WIDE_INT int_log2 PROTO ((HOST_WIDE_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));
rtx arm_compare_op0, arm_compare_op1;
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? */
enum floating_point_type arm_fpu;
@@ -87,7 +84,7 @@ enum floating_point_type arm_fpu_arch;
enum prog_mode_type arm_prgmode;
/* Set by the -mfp=... option */
-char *target_fp_name = NULL;
+char * target_fp_name = NULL;
/* Used to parse -mstructure_size_boundary command line option. */
char * structure_size_string = NULL;
@@ -99,8 +96,14 @@ int arm_fast_multiply = 0;
/* Nonzero if this chip supports the ARM Architecture 4 extensions */
int arm_arch4 = 0;
-/* Set to the features we should tune the code for (multiply speed etc). */
-int tune_flags = 0;
+/* Nonzero if this chip can benefit from laod scheduling. */
+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
must report the mode of the memory reference from PRINT_OPERAND to
@@ -134,7 +137,7 @@ rtx arm_target_insn;
int arm_target_label;
/* 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",
"hi", "ls", "ge", "lt", "gt", "le", "al", "nv"
@@ -142,84 +145,90 @@ char *arm_condition_codes[] =
static enum arm_cond_code get_arm_condition_code ();
+#define streq(string1, string2) (strcmp (string1, string2) == 0)
/* 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_FAST_MULT 0x02 /* Fast multiply */
#define FL_MODE26 0x04 /* 26-bit mode support */
#define FL_MODE32 0x08 /* 32-bit mode support */
#define FL_ARCH4 0x10 /* Architecture rel 4 */
#define FL_THUMB 0x20 /* Thumb aware */
+#define FL_LDSCHED 0x40 /* Load scheduling necessary */
+#define FL_STRONG 0x80 /* StrongARM */
struct processors
{
- char *name;
- enum processor_type type;
+ char * name;
unsigned int flags;
};
/* Not all of these give usefully different compilation alternatives,
but there is no simple way of generalizing them. */
-static struct processors all_procs[] =
+static struct processors all_cores[] =
{
- {"arm2", PROCESSOR_ARM2, FL_CO_PROC | FL_MODE26},
- {"arm250", PROCESSOR_ARM2, FL_CO_PROC | FL_MODE26},
- {"arm3", PROCESSOR_ARM2, FL_CO_PROC | FL_MODE26},
- {"arm6", PROCESSOR_ARM6, FL_CO_PROC | FL_MODE32 | FL_MODE26},
- {"arm600", PROCESSOR_ARM6, FL_CO_PROC | FL_MODE32 | FL_MODE26},
- {"arm610", PROCESSOR_ARM6, FL_MODE32 | FL_MODE26},
- {"arm7", PROCESSOR_ARM7, FL_CO_PROC | FL_MODE32 | FL_MODE26},
- /* 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)},
+ /* 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[] =
+{
+ /* ARM Architectures */
+
+ {"armv2", FL_CO_PROC | FL_MODE26 },
+ {"armv2a", FL_CO_PROC | FL_MODE26 },
+ {"armv3", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
+ {"armv3m", FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT },
+ {"armv4", FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 },
/* 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. */
- {"armv4t", PROCESSOR_NONE, (FL_CO_PROC | FL_FAST_MULT | FL_MODE32
- | FL_ARCH4)},
- {NULL, 0, 0}
+ {"armv4t", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB },
+ {NULL, 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.
@@ -227,64 +236,40 @@ static struct processors all_procs[] =
void
arm_override_options ()
{
- int arm_thumb_aware = 0;
- int flags = 0;
+ unsigned int flags = 0;
unsigned i;
struct arm_cpu_select * ptr;
- static struct cpu_default
- {
- int cpu;
- char * name;
- }
- cpu_defaults[] =
- {
- { TARGET_CPU_arm2, "arm2" },
- { TARGET_CPU_arm6, "arm6" },
- { TARGET_CPU_arm610, "arm610" },
- { TARGET_CPU_arm7dm, "arm7dm" },
- { TARGET_CPU_arm7500fe, "arm7500fe" },
- { TARGET_CPU_arm7tdmi, "arm7tdmi" },
- { TARGET_CPU_arm8, "arm8" },
- { TARGET_CPU_arm810, "arm810" },
- { TARGET_CPU_strongarm, "strongarm" },
- { 0, 0 }
- };
- struct cpu_default *def;
-
- /* Set the default. */
- for (def = &cpu_defaults[0]; def->name; ++def)
- if (def->cpu == TARGET_CPU_DEFAULT)
- break;
- if (! def->name)
- abort ();
-
- arm_select[0].string = def->name;
-
- for (i = 0; i < sizeof (arm_select) / sizeof (arm_select[0]); i++)
+
+ /* Set up the flags based on the cpu/architecture selected by the user. */
+ for (i = sizeof (arm_select) / sizeof (arm_select[0]); i--;)
{
- ptr = &arm_select[i];
- if (ptr->string != (char *)0 && ptr->string[0] != '\0')
+ struct arm_cpu_select * ptr = arm_select + i;
+
+ if (ptr->string != NULL && ptr->string[0] != '\0')
{
- struct processors *sel;
+ struct processors * sel;
- for (sel = all_procs; sel->name != NULL; sel++)
- if (! strcmp (ptr->string, sel->name))
+ for (sel = ptr->processors; sel->name != NULL; sel ++)
+ if (streq (ptr->string, sel->name))
{
- /* -march= is the only flag that can take an architecture
- type, so if we match when the tune bit is set, the
- option was invalid. */
- if (ptr->set_tune_p)
+ if (flags != 0)
{
- if (sel->type == PROCESSOR_NONE)
- continue; /* Its an architecture, not a cpu */
-
- arm_cpu = sel->type;
- tune_flags = sel->flags;
+ /* 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 );
}
- if (ptr->set_arch_p)
- flags = sel->flags;
-
+ flags = sel->flags;
+
break;
}
@@ -293,23 +278,141 @@ arm_override_options ()
}
}
+ /* 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
+ {
+ int cpu;
+ char * name;
+ }
+ cpu_defaults[] =
+ {
+ { TARGET_CPU_arm2, "arm2" },
+ { TARGET_CPU_arm6, "arm6" },
+ { TARGET_CPU_arm610, "arm610" },
+ { TARGET_CPU_arm7m, "arm7m" },
+ { TARGET_CPU_arm7500fe, "arm7500fe" },
+ { TARGET_CPU_arm7tdmi, "arm7tdmi" },
+ { TARGET_CPU_arm8, "arm8" },
+ { TARGET_CPU_arm810, "arm810" },
+ { TARGET_CPU_arm9, "arm9" },
+ { TARGET_CPU_strongarm, "strongarm" },
+ { TARGET_CPU_generic, "arm" },
+ { 0, 0 }
+ };
+ struct cpu_default * def;
+
+ /* Find the default. */
+ for (def = cpu_defaults; def->name; def ++)
+ if (def->cpu == TARGET_CPU_DEFAULT)
+ break;
+
+ if (def->name == NULL)
+ abort ();
+
+ /* Find the default CPU's flags. */
+ for (sel = all_cores; sel->name != NULL; sel ++)
+ if (streq (def->name, sel->name))
+ break;
+
+ if (sel->name == NULL)
+ abort ();
+
+ flags = sel->flags;
+ }
+ }
+
+ /* Cope with some redundant flags. */
+ if (TARGET_6)
+ {
+ warning ("Option '-m6' deprecated. Use: '-mapcs-32' or -mcpu=<proc>");
+ target_flags |= ARM_FLAG_APCS_32;
+ }
+
+ if (TARGET_3)
+ {
+ warning ("Option '-m3' deprecated. Use: '-mapcs-26' or -mcpu=<proc>");
+ target_flags &= ~ARM_FLAG_APCS_32;
+ }
+
+ /* Make sure that the processor choice does not conflict with any of the
+ other command line choices. */
+ if (TARGET_APCS_32 && !(flags & FL_MODE32))
+ {
+ warning ("target CPU does not support APCS-32" );
+ target_flags &= ~ ARM_FLAG_APCS_32;
+ }
+ else if (! TARGET_APCS_32 && !(flags & FL_MODE26))
+ {
+ warning ("target CPU does not support APCS-26" );
+ target_flags |= ARM_FLAG_APCS_32;
+ }
+
+ if (TARGET_THUMB_INTERWORK && !(flags & FL_THUMB))
+ {
+ warning ("target CPU does not support interworking" );
+ target_flags &= ~ARM_FLAG_THUMB;
+ }
+
+ /* If interworking is enabled then APCS-32 must be selected as well. */
+ 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)
warning ("-g with -fomit-frame-pointer may not give sensible debugging");
if (TARGET_POKE_FUNCTION_NAME)
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)
fatal ("-fpic and -mapcs-reent are incompatible");
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,
which keeps r9 available. */
@@ -326,93 +429,45 @@ arm_override_options ()
if (TARGET_APCS_FLOAT)
warning ("Passing floating point arguments in fp regs not yet supported");
- if (TARGET_APCS_STACK && ! TARGET_APCS)
- {
- warning ("-mapcs-stack-check incompatible with -mno-apcs-frame");
- target_flags |= ARM_FLAG_APCS_FRAME;
- }
-
- /* Default is to tune for an FPA */
- arm_fpu = FP_HARD;
-
+ /* Initialise booleans used elsewhere in this file, and in arm.md */
+ arm_fast_multiply = (flags & FL_FAST_MULT) != 0;
+ arm_arch4 = (flags & FL_ARCH4) != 0;
+ arm_ld_sched = (flags & FL_LDSCHED) != 0;
+ arm_is_strong = (flags & FL_STRONG);
+
+ /* The arm.md file needs to know if theprocessor is an ARM6 or an ARM7 */
+ arm_is_6_or_7 = ((flags & (FL_MODE26 | FL_MODE32)) && !(flags & FL_ARCH4));
+
/* Default value for floating point code... if no co-processor
bus, then schedule for emulated floating point. Otherwise,
assume the user has an FPA.
Note: this does not prevent use of floating point instructions,
-msoft-float does that. */
- if ((tune_flags & FL_CO_PROC) == 0)
+ if ((flags & FL_CO_PROC) == 0)
arm_fpu = FP_SOFT3;
-
- arm_fast_multiply = (flags & FL_FAST_MULT) != 0;
- arm_arch4 = (flags & FL_ARCH4) != 0;
- arm_thumb_aware = (flags & FL_THUMB) != 0;
-
+ else
+ arm_fpu = FP_HARD;
+
if (target_fp_name)
{
- if (strcmp (target_fp_name, "2") == 0)
+ if (streq (target_fp_name, "2"))
arm_fpu_arch = FP_SOFT2;
- else if (strcmp (target_fp_name, "3") == 0)
- arm_fpu_arch = FP_HARD;
+ else if (streq (target_fp_name, "3"))
+ arm_fpu_arch = FP_SOFT3;
else
- fatal ("Invalid floating point emulation option: -mfpe=%s",
+ fatal ("Invalid floating point emulation option: -mfpe-%s",
target_fp_name);
}
else
arm_fpu_arch = FP_DEFAULT;
+
+ if (TARGET_FPE && arm_fpu != FP_HARD)
+ arm_fpu = FP_SOFT2;
- if (TARGET_THUMB_INTERWORK && ! arm_thumb_aware)
- {
- 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. */
- switch (arm_cpu)
- {
- 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;
- 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;
+ /* 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) && (flags & FL_MODE32) == 0)
+ flag_schedule_insns = flag_schedule_insns_after_reload = 0;
arm_prog_mode = TARGET_APCS_32 ? PROG_MODE_PROG32 : PROG_MODE_PROG26;
@@ -425,6 +480,21 @@ arm_override_options ()
else
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 */
@@ -435,19 +505,20 @@ use_return_insn (iscond)
{
int regno;
- if (!reload_completed ||current_function_pretend_args_size
+ if (!reload_completed
+ || current_function_pretend_args_size
|| current_function_anonymous_args
|| ((get_frame_size () + current_function_outgoing_args_size != 0)
- && !(TARGET_APCS || frame_pointer_needed)))
+ && !(TARGET_APCS && frame_pointer_needed)))
return 0;
/* Can't be done if interworking with Thumb, and any registers have been
stacked. Similarly, on StrongARM, conditional returns are expensive
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;
- else if ((iscond && arm_cpu == PROCESSOR_STARM)
- || TARGET_THUMB_INTERWORK)
+ if ((iscond && arm_is_strong)
+ || TARGET_THUMB_INTERWORK)
for (regno = 0; regno < 16; regno++)
if (regs_ever_live[regno] && ! call_used_regs[regno])
return 0;
@@ -888,7 +959,7 @@ arm_gen_constant (code, mode, val, target, source, subtargets, generate)
gen_rtx_NOT (mode,
gen_rtx_ASHIFT (mode,
source,
- shift))));
+ shift))));
emit_insn (gen_rtx_SET (VOIDmode, target,
gen_rtx_NOT (mode,
gen_rtx_LSHIFTRT (mode, sub,
@@ -909,11 +980,11 @@ arm_gen_constant (code, mode, val, target, source, subtargets, generate)
gen_rtx_NOT (mode,
gen_rtx_LSHIFTRT (mode,
source,
- shift))));
+ shift))));
emit_insn (gen_rtx_SET (VOIDmode, target,
gen_rtx_NOT (mode,
gen_rtx_ASHIFT (mode, sub,
- shift))));
+ shift))));
}
return 2;
}
@@ -1192,24 +1263,55 @@ arm_canonicalize_comparison (code, op1)
return code;
}
-
-/* Handle aggregates that are not laid out in a BLKmode element.
- This is a sub-element of RETURN_IN_MEMORY. */
+/* Decide whether a type should be returned in memory (true)
+ or in a register (false). This is called by the macro
+ RETURN_IN_MEMORY. */
int
arm_return_in_memory (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;
- /* For a struct, we can return in a register if every element was a
- bit-field. */
- for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
- if (TREE_CODE (field) != FIELD_DECL
- || ! DECL_BIT_FIELD_TYPE (field))
- return 1;
+ /* For a struct the APCS says that we must return in a register if
+ every addressable element has an offset of zero. For practical
+ purposes this means that the structure can have at most one non
+ bit-field element and that this element must be the first one in
+ 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 0;
}
@@ -1219,16 +1321,20 @@ arm_return_in_memory (type)
/* Unions can be returned in registers if every element is
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
- || (AGGREGATE_TYPE_P (TREE_TYPE (field))
- && RETURN_IN_MEMORY (TREE_TYPE (field)))
- || FLOAT_TYPE_P (TREE_TYPE (field)))
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+
+ if (RETURN_IN_MEMORY (TREE_TYPE (field)))
return 1;
}
+
return 0;
}
+
/* XXX Not sure what should be done for other aggregates, so put them in
memory. */
return 1;
@@ -1389,7 +1495,7 @@ arm_finalize_pic ()
gen_rtx_PLUS (Pmode, global_offset_table, pc_rtx));
pic_rtx = gen_rtx_CONST (Pmode, gen_rtx_MINUS (Pmode, pic_tmp2, pic_tmp));
-
+
emit_insn (gen_pic_load_addr (pic_offset_table_rtx, pic_rtx));
emit_jump_insn (gen_pic_add_dot_plus_eight(l1, pic_offset_table_rtx));
emit_label (l1);
@@ -1570,7 +1676,7 @@ arm_rtx_costs (x, code, outer_code)
int add_cost = const_ok_for_arm (i) ? 4 : 8;
int j;
/* 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)
{
@@ -1581,7 +1687,7 @@ arm_rtx_costs (x, code, outer_code)
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, 1)) ? 0 : 4));
@@ -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
the offset isn't small enough */
- if (nops == 2
- && (arm_cpu == PROCESSOR_ARM8 || arm_cpu == PROCESSOR_ARM9
- || arm_cpu == PROCESSOR_STARM))
+ if (nops == 2 && arm_ld_sched)
return 0;
/* 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)
if (use_return_insn (FALSE) && return_used_this_function)
{
if ((frame_size + current_function_outgoing_args_size) != 0
- && !(frame_pointer_needed || TARGET_APCS))
+ && !(frame_pointer_needed && TARGET_APCS))
abort ();
goto epilogue_done;
}
@@ -5217,8 +5321,10 @@ output_func_epilogue (f, frame_size)
if (TARGET_THUMB_INTERWORK)
{
if (! lr_save_eliminated)
- print_multi_reg(f, "ldmfd\t%ssp!", live_regs_mask | 0x4000,
- FALSE);
+ live_regs_mask |= 0x4000;
+
+ if (live_regs_mask != 0)
+ print_multi_reg (f, "ldmfd\t%ssp!", live_regs_mask, FALSE);
fprintf (f, "\tbx\t%slr\n", REGISTER_PREFIX);
}
@@ -5329,7 +5435,6 @@ emit_sfm (base_reg, count)
gen_rtvec (1, gen_rtx_REG (XFmode,
base_reg++)),
2));
-
for (i = 1; i < count; i++)
XVECEXP (par, 0, i) = gen_rtx_USE (VOIDmode,
gen_rtx_REG (XFmode, base_reg++));
@@ -5443,8 +5548,9 @@ arm_expand_prologue ()
}
/* If we are profiling, make sure no instructions are scheduled before
- the call to mcount. */
- if (profile_flag || profile_block_flag)
+ the call to mcount. Similarly if the user has requested no
+ scheduling in the prolog. */
+ if (profile_flag || profile_block_flag || TARGET_NO_SCHED_PRO)
emit_insn (gen_blockage ());
}
@@ -5784,10 +5890,10 @@ final_prescan_insn (insn, opvec, noperands)
if (arm_ccfsm_state == 4)
{
if (insn == arm_target_insn)
- {
- arm_target_insn = NULL;
- arm_ccfsm_state = 0;
- }
+ {
+ arm_target_insn = NULL;
+ arm_ccfsm_state = 0;
+ }
return;
}
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index ce117ff90b2..15ac18be924 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -1,4 +1,4 @@
-/* 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.
Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
and Martin Simmons (@harleqn.co.uk).
@@ -53,6 +53,7 @@ Boston, MA 02111-1307, USA. */
#define TARGET_CPU_arm810 0x0020
#define TARGET_CPU_strongarm 0x0040
#define TARGET_CPU_strongarm110 0x0040
+#define TARGET_CPU_strongarm1100 0x0040
#define TARGET_CPU_arm9 0x0080
#define TARGET_CPU_arm9tdmi 0x0080
/* Configure didn't specify */
@@ -146,6 +147,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
%{march=arm9tdmi:-D__ARM_ARCH_4T__} \
%{march=strongarm:-D__ARM_ARCH_4__} \
%{march=strongarm110:-D__ARM_ARCH_4__} \
+%{march=strongarm1100:-D__ARM_ARCH_4__} \
%{march=armv2:-D__ARM_ARCH_2__} \
%{march=armv2a:-D__ARM_ARCH_2__} \
%{march=armv3:-D__ARM_ARCH_3__} \
@@ -175,6 +177,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
%{mcpu=arm9tdmi:-D__ARM_ARCH_4T__} \
%{mcpu=strongarm:-D__ARM_ARCH_4__} \
%{mcpu=strongarm110:-D__ARM_ARCH_4__} \
+ %{mcpu=strongarm1100:-D__ARM_ARCH_4__} \
%{!mcpu*:%{!m6:%{!m2:%{!m3:%(cpp_cpu_arch_default)}}}}} \
"
@@ -258,7 +261,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
extern int target_flags;
/* 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
the ARM Procedure Call Standard. */
@@ -318,6 +321,9 @@ extern char *target_fp_name;
big-endian (for backwards compatibility with older versions of GCC). */
#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
function tries to return. */
#define ARM_FLAG_ABORT_NORETURN (0x8000)
@@ -337,6 +343,7 @@ function tries to return. */
#define TARGET_BIG_END (target_flags & ARM_FLAG_BIG_END)
#define TARGET_THUMB_INTERWORK (target_flags & ARM_FLAG_THUMB)
#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)
/* SUBTARGET_SWITCHES is used to add flags on a per-config basis.
@@ -391,68 +398,39 @@ function tries to return. */
{"abort-on-noreturn", ARM_FLAG_ABORT_NORETURN, \
"Generate a call to abort if a noreturn function returns"}, \
{"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 \
{"", TARGET_DEFAULT } \
}
#define TARGET_OPTIONS \
{ \
- {"cpu=", \
- &arm_select[1].string, \
- "Specify the name of the target CPU"}, \
- {"arch=", \
- &arm_select[2].string, \
- "Specify the name of the target architecture"}, \
- {"tune=", \
- &arm_select[3].string, \
- "Order instructions for best performance on this CPU"}, \
- {"fp=", \
- &target_fp_name, \
- "Specify the version of the floating point emulator"}, \
- {"structure-size-boundary=", \
- &structure_size_string, \
- "Specify the minumum bit alignment of structures"} \
+ {"cpu=", & arm_select[0].string, \
+ "Specify the name of the target CPU" }, \
+ {"arch=", & arm_select[1].string, \
+ "Specify the name of the target architecture" }, \
+ {"tune=", & arm_select[2].string, "" }, \
+ {"fpe=", & target_fp_name, "" }, \
+ {"fp=", & 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
{
- char *string;
- char *name;
- int set_tune_p;
- int set_arch_p;
+ char * string;
+ char * name;
+ struct processors * processors;
};
+/* 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[];
-#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
{
prog_mode26,
@@ -493,6 +471,15 @@ extern int arm_fast_multiply;
/* Nonzero if this chip supports the ARM Architecture 4 extensions */
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
#define TARGET_DEFAULT 0
#endif
@@ -634,8 +621,8 @@ extern char * structure_size_string;
r4-r8 S register variable
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
r12 (ip) temp workspace
r13 F S (sp) lower end of current stack frame
@@ -730,6 +717,11 @@ extern char * structure_size_string;
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
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
@@ -1062,9 +1054,7 @@ do { \
/* How large values are returned */
/* A C expression which can inhibit the returning of certain function values
in registers, based on the type of value. */
-#define RETURN_IN_MEMORY(TYPE) \
- (TYPE_MODE ((TYPE)) == BLKmode || \
- (AGGREGATE_TYPE_P ((TYPE)) && arm_return_in_memory ((TYPE))))
+#define RETURN_IN_MEMORY(TYPE) arm_return_in_memory (TYPE)
/* 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
@@ -1779,8 +1769,8 @@ extern int arm_pic_register;
#define FINALIZE_PIC arm_finalize_pic ()
-/* We can't directly access anything that contains a symbol, nor can
- we indirect via the constant pool */
+/* We can't directly access anything that contains a symbol,
+ nor can we indirect via the constant pool. */
#define LEGITIMATE_PIC_OPERAND_P(X) \
(! symbol_mentioned_p (X) \
&& (! CONSTANT_POOL_ADDRESS_P (X) \
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index cf4212bb6fc..a87932e8756 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -45,10 +45,7 @@
; by the -mapcs-{32,26} flag, and possibly the -mcpu=... option.
(define_attr "prog_mode" "prog26,prog32" (const (symbol_ref "arm_prog_mode")))
-; CPU attribute is used to determine the best instruction mix for performance
-; on the named processor.
-(define_attr "cpu" "arm2,arm3,arm6,arm7,arm8,arm9,st_arm"
- (const (symbol_ref "arm_cpu_attr")))
+(define_attr "is_strongarm" "no,yes" (const (symbol_ref "arm_is_strong")))
; Floating Point Unit. If we only have floating point emulation, then there
; is no point in scheduling the floating point insns. (Well, for best
@@ -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"
(const_string "normal"))
-; Load scheduling, set from the cpu characteristic
-(define_attr "ldsched" "no,yes"
- (if_then_else (eq_attr "cpu" "arm8,arm9,st_arm")
- (const_string "yes")
- (const_string "no")))
+; Load scheduling, set from the arm_ld_sched variable
+; initialised by arm_override_options()
+(define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
; 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
@@ -137,10 +132,7 @@
; 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
; affect the schedule).
-(define_attr "model_wbuf" "no,yes"
- (if_then_else (eq_attr "cpu" "arm6,arm7")
- (const_string "yes")
- (const_string "no")))
+(define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_is_6_or_7")))
(define_attr "write_conflict" "no,yes"
(if_then_else (eq_attr "type"
@@ -267,13 +259,15 @@
(and (eq_attr "fpu" "fpa") (eq_attr "type" "f_mem_r")) 7 7)
(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
- (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
- (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)
@@ -1209,7 +1203,7 @@
(const_int 0)))
(clobber (match_scratch:QI 3 "=r"))]
"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)
<< INTVAL (operands[2]));
@@ -1287,7 +1281,7 @@
emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
emit_insn (gen_iorsi3 (op1, gen_rtx_LSHIFTRT (SImode, operands[0],
- operands[1]),
+ operands[1]),
op0));
emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
}
@@ -2173,16 +2167,20 @@
""
"
{
- if (arm_arch4 && GET_CODE (operands[1]) == MEM)
+ if (GET_CODE (operands[1]) == MEM)
{
- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
- gen_rtx_ZERO_EXTEND (SImode, operands[1])));
- DONE;
- }
- if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM)
- {
- emit_insn (gen_movhi_bytes (operands[0], operands[1]));
- DONE;
+ if (TARGET_SHORT_BY_BYTES)
+ {
+ emit_insn (gen_movhi_bytes (operands[0], operands[1]));
+ DONE;
+ }
+ else if (arm_arch4)
+ {
+ emit_insn (gen_rtx_SET (VOIDmode,
+ operands[0],
+ gen_rtx_ZERO_EXTEND (SImode, operands[1])));
+ DONE;
+ }
}
if (! s_register_operand (operands[1], HImode))
operands[1] = copy_to_mode_reg (HImode, operands[1]);
@@ -2274,19 +2272,21 @@
(const_int 16)))]
""
"
-{
- if (arm_arch4 && GET_CODE (operands[1]) == MEM)
- {
- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
- gen_rtx_SIGN_EXTEND (SImode, operands[1])));
- DONE;
- }
-
- if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM)
+{
+ if (GET_CODE (operands[1]) == MEM)
{
- emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
- DONE;
- }
+ if (TARGET_SHORT_BY_BYTES)
+ {
+ emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
+ DONE;
+ }
+ else if (arm_arch4)
+ {
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+ gen_rtx_SIGN_EXTEND (SImode, operands[1])));
+ DONE;
+ }
+ }
if (! s_register_operand (operands[1], HImode))
operands[1] = copy_to_mode_reg (HImode, operands[1]);
operands[1] = gen_lowpart (SImode, operands[1]);
@@ -2381,7 +2381,8 @@
{
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])));
DONE;
}
@@ -2437,8 +2438,8 @@
&& GET_CODE (XEXP (operands[1], 1)) != CONST_INT
&& ! s_register_operand (XEXP (operands[1], 1), VOIDmode))
operands[1] = gen_rtx_PLUS (GET_MODE (operands[1]),
- XEXP (operands[1], 1),
- XEXP (operands[1], 0));
+ XEXP (operands[1], 1),
+ XEXP (operands[1], 0));
}
")
@@ -2454,7 +2455,8 @@
{
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])));
DONE;
}
@@ -2508,8 +2510,8 @@
&& GET_CODE (XEXP (operands[1], 1)) != CONST_INT
&& ! s_register_operand (XEXP (operands[1], 1), VOIDmode))
operands[1] = gen_rtx_PLUS (GET_MODE (operands[1]),
- XEXP (operands[1], 1),
- XEXP (operands[1], 0));
+ XEXP (operands[1], 1),
+ XEXP (operands[1], 0));
}
")
@@ -3260,7 +3262,7 @@
XEXP (XEXP (operands[0], 0), 1)));
emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_MEM (DFmode, operands[2]),
- operands[1]));
+ operands[1]));
if (code == POST_DEC)
emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
@@ -4184,10 +4186,10 @@
extern int arm_ccfsm_state;
if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
- {
- arm_ccfsm_state += 2;
- return \"\";
- }
+ {
+ arm_ccfsm_state += 2;
+ return \"\";
+ }
return \"b%?\\t%l0\";
}")
@@ -6136,7 +6138,6 @@
}
")
-
;; The next two patterns occur when an AND operation is followed by a
;; scc insn sequence
diff --git a/gcc/config/arm/elf.h b/gcc/config/arm/elf.h
index 28af933ef09..c244b8cb23c 100644
--- a/gcc/config/arm/elf.h
+++ b/gcc/config/arm/elf.h
@@ -1,6 +1,6 @@
/* Definitions of target machine for GNU compiler,
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
Catherine Moore <clm@cygnus.com>
@@ -100,7 +100,7 @@ Boston, MA 02111-1307, USA. */
by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */
#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \
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) \
&& ! AT_END && TOP_LEVEL \
&& DECL_INITIAL (DECL) == error_mark_node \
@@ -143,7 +143,7 @@ do { \
#ifndef ASM_SPEC
#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
#ifndef LINK_SPEC
@@ -198,9 +198,10 @@ arm_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
#ifndef ASM_FILE_START
#define ASM_FILE_START(STREAM) \
do { \
- extern char *version_string; \
+ extern char * version_string; \
fprintf (STREAM, "%s Generated by gcc %s for ARM/elf\n", \
ASM_COMMENT_START, version_string); \
+ output_file_directive ((STREAM), main_input_filename); \
} while (0)
#endif
@@ -209,7 +210,7 @@ do { \
#define ASM_OUTPUT_INTERNAL_LABEL(STREAM, PREFIX, NUM) \
do \
{ \
- char *s = (char *) alloca (40 + strlen (PREFIX)); \
+ char * s = (char *) alloca (40 + strlen (PREFIX)); \
extern int arm_target_label, arm_ccfsm_state; \
extern rtx arm_target_insn; \
\
@@ -332,6 +333,3 @@ do { \
fputc ('\n', FILE); } while (0)
#include "arm/aout.h"
-
-
-
diff --git a/gcc/config/arm/linux-elf.h b/gcc/config/arm/linux-elf.h
index 7d08cad9efd..97caad5da62 100644
--- a/gcc/config/arm/linux-elf.h
+++ b/gcc/config/arm/linux-elf.h
@@ -34,8 +34,20 @@ Boston, MA 02111-1307, USA. */
" %{mapcs-26:-mapcs-26} %(!mapcs-26:-mapcs-32}"
#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. */
-#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. */
#define ENDFILE_SPEC "%{!shared:crtend.o%s} %{shared:crtendS.o%s} \
@@ -64,6 +76,10 @@ Boston, MA 02111-1307, USA. */
#ifndef SUBTARGET_DEFAULT_APCS26
#undef CPP_APCS_PC_DEFAULT_SPEC
#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
/* Allow #sccs in preprocessor. */
@@ -201,5 +217,10 @@ const_section () \
assemble_name (FILE, NAME2); \
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/linux-gas.h"
diff --git a/gcc/config/arm/linux-gas.h b/gcc/config/arm/linux-gas.h
index 72567f39158..f2b5d42e1e2 100644
--- a/gcc/config/arm/linux-gas.h
+++ b/gcc/config/arm/linux-gas.h
@@ -1,6 +1,6 @@
/* Definitions of target machine for GNU compiler.
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>.
This file is part of GNU CC.
@@ -59,29 +59,25 @@ Boston, MA 02111-1307, USA. */
#undef WCHAR_TYPE_SIZE
#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
- inline system call to SYS_cacheflush. The arguments are as
- follows:
-
- cacheflush (start, end, flags)
-
-*/
-
+ inline system call to SYS_cacheflush. */
#define CLEAR_INSN_CACHE(BEG, END) \
{ \
register unsigned long _beg __asm ("a1") = (unsigned long) (BEG); \
register unsigned long _end __asm ("a2") = (unsigned long) (END); \
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
diff --git a/gcc/config/arm/t-arm-elf b/gcc/config/arm/t-arm-elf
index 528936c4ef6..4d2efec9c53 100644
--- a/gcc/config/arm/t-arm-elf
+++ b/gcc/config/arm/t-arm-elf
@@ -23,9 +23,11 @@ dp-bit.c: $(srcdir)/config/fp-bit.c
echo '#endif' >> 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_DIRNAMES = le be fpu soft 32bit 26bit elf under
-MULTILIB_MATCHES =
+# 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_MATCHES =
-LIBGCC = stmp-multilib
-INSTALL_LIBGCC = install-multilib
+# LIBGCC = stmp-multilib
+# INSTALL_LIBGCC = install-multilib
+
+TARGET_LIBGCC2_CFLAGS = -Dinhibit_libc
diff --git a/gcc/config/arm/t-linux b/gcc/config/arm/t-linux
index 841c00b478f..9fdeae93c7a 100644
--- a/gcc/config/arm/t-linux
+++ b/gcc/config/arm/t-linux
@@ -13,8 +13,10 @@ LIBGCC1 = libgcc1-asm.a
LIB1ASMSRC = arm/lib1funcs.asm
LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx
-MULTILIB_OPTIONS = mapcs-32
-MULTILIB_DIRNAMES = apcs-32
+# If you want to build both APCS variants as multilib options this is how
+# to do it.
+#MULTILIB_OPTIONS = mapcs-32/apcs-26
+#MULTILIB_DIRNAMES = apcs-32 apcs-26
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
diff --git a/gcc/invoke.texi b/gcc/invoke.texi
index 20fb3d25965..82a7737943f 100644
--- a/gcc/invoke.texi
+++ b/gcc/invoke.texi
@@ -170,7 +170,7 @@ in the following sections.
-idirafter @var{dir}
-include @var{file} -imacros @var{file}
-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
-undef -U@var{macro} -Wp,@var{option}
@end smallexample
@@ -259,6 +259,8 @@ in the following sections.
-mcpu= -march= -mfpe=
-mstructure-size-boundary=
-mbsd -mxopen -mno-symrename
+-mabort-on-noreturn
+-mno-sched-prolog
@emph{Thumb Options}
-mtpcs-frame -mno-tpcs-frame
@@ -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
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
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
compiler is built for cross-compilation.
@item -mcpu=<name>
+@item -mtune=<name>
@kindex -mcpu=
+@kindex -mtune=
This specifies the name of the target ARM processor. GCC uses this name
to determine what kind of instructions it can use when generating
assembly code. Permissable names are: arm2, arm250, arm3, arm6, arm60,
arm600, arm610, arm620, arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi,
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>
@kindex -march=
@@ -3813,9 +3824,12 @@ of the @samp{-mcpu=} option. Permissable names are: armv2, armv2a,
armv3, armv3m, armv4, armv4t
@item -mfpe=<number>
+@item -mfp=<number>
@kindex -mfpe=
+@kindex -mfp=
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>
@kindex -mstructure-size-boundary
@@ -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
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
@node Thumb Options
@@ -4666,7 +4686,9 @@ All modules should be compiled with the same @samp{-G @var{num}} value.
@itemx -mno-regnames
On System V.4 and embedded PowerPC systems do (do not) emit register
names in the assembly language output using symbolic forms.
+
@end table
+
@node RT Options
@subsection IBM RT Options
@cindex RT options