From a2017852eec2470633015d24cf8e6e43f40f9914 Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Wed, 14 Jul 2004 16:27:37 +0000 Subject: [PATCH] pa.c (fix_range): New function to mark a range(s) of registers as fixed registers. * pa.c (fix_range): New function to mark a range(s) of registers as fixed registers. (override_options): Call fix_range if the -mfixed-range option string is not empty. * pa.h (TARGET_OPTIONS): Add -mfixed-range option. * doc/invoke.texi (-mfixed-range): Document new option. From-SVN: r84690 --- gcc/ChangeLog | 9 +++++ gcc/config/pa/pa.c | 94 +++++++++++++++++++++++++++++++++++++++++---- gcc/config/pa/pa.h | 24 +++++++----- gcc/doc/invoke.texi | 9 +++++ 4 files changed, 120 insertions(+), 16 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7110df0fabf..b24e2245dc9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2004-07-14 John David Anglin + + * pa.c (fix_range): New function to mark a range(s) of registers as + fixed registers. + (override_options): Call fix_range if the -mfixed-range option string + is not empty. + * pa.h (TARGET_OPTIONS): Add -mfixed-range option. + * doc/invoke.texi (-mfixed-range): Document new option. + 2004-07-14 David Edelsohn * config/rs6000/rs6000.c (function_arg_padding): Do not pad SFmode diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 7f4ba45c2c6..ebe7a52abaa 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -86,6 +86,7 @@ hppa_fpstore_bypass_p (rtx out_insn, rtx in_insn) #endif static void copy_reg_pointer (rtx, rtx); +static void fix_range (const char *); static int hppa_address_cost (rtx); static bool hppa_rtx_costs (rtx, int, int, int *); static inline rtx force_mode (enum machine_mode, rtx); @@ -152,18 +153,21 @@ static bool pa_pass_by_reference (CUMULATIVE_ARGS *ca, enum machine_mode, rtx hppa_compare_op0, hppa_compare_op1; enum cmp_type hppa_branch_type; -/* Which cpu we are scheduling for. */ -enum processor_type pa_cpu; - -/* String to hold which cpu we are scheduling for. */ -const char *pa_cpu_string; - /* Which architecture we are generating code for. */ enum architecture_type pa_arch; /* String to hold which architecture we are generating code for. */ const char *pa_arch_string; +/* String used with the -mfixed-range= option. */ +const char *pa_fixed_range_string; + +/* Which cpu we are scheduling for. */ +enum processor_type pa_cpu; + +/* String to hold which cpu we are scheduling for. */ +const char *pa_cpu_string; + /* Counts for the number of callee-saved general and floating point registers which were saved by the current function's prologue. */ static int gr_saved, fr_saved; @@ -280,6 +284,79 @@ static size_t n_deferred_plabels = 0; struct gcc_target targetm = TARGET_INITIALIZER; +/* Parse the -mfixed-range= option string. */ + +static void +fix_range (const char *const_str) +{ + int i, first, last; + char *str, *dash, *comma; + + /* str must be of the form REG1'-'REG2{,REG1'-'REG} where REG1 and + REG2 are either register names or register numbers. The effect + of this option is to mark the registers in the range from REG1 to + REG2 as ``fixed'' so they won't be used by the compiler. This is + used, e.g., to ensure that kernel mode code doesn't use f32-f127. */ + + i = strlen (const_str); + str = (char *) alloca (i + 1); + memcpy (str, const_str, i + 1); + + while (1) + { + dash = strchr (str, '-'); + if (!dash) + { + warning ("value of -mfixed-range must have form REG1-REG2"); + return; + } + *dash = '\0'; + + comma = strchr (dash + 1, ','); + if (comma) + *comma = '\0'; + + first = decode_reg_name (str); + if (first < 0) + { + warning ("unknown register name: %s", str); + return; + } + + last = decode_reg_name (dash + 1); + if (last < 0) + { + warning ("unknown register name: %s", dash + 1); + return; + } + + *dash = '-'; + + if (first > last) + { + warning ("%s-%s is an empty range", str, dash + 1); + return; + } + + for (i = first; i <= last; ++i) + fixed_regs[i] = call_used_regs[i] = 1; + + if (!comma) + break; + + *comma = ','; + str = comma + 1; + } + + /* Check if all floating point registers have been fixed. */ + for (i = FP_REG_FIRST; i <= FP_REG_LAST; i++) + if (!fixed_regs[i]) + break; + + if (i > FP_REG_LAST) + target_flags |= MASK_DISABLE_FPREGS; +} + void override_options (void) { @@ -321,7 +398,7 @@ override_options (void) warning ("unknown -mschedule= option (%s).\nValid options are 700, 7100, 7100LC, 7200, 7300, and 8000\n", pa_cpu_string); } - /* Set the instruction set architecture. */ + /* Set the instruction architecture. */ if (pa_arch_string && ! strcmp (pa_arch_string, "1.0")) { pa_arch_string = "1.0"; @@ -346,6 +423,9 @@ override_options (void) warning ("unknown -march= option (%s).\nValid options are 1.0, 1.1, and 2.0\n", pa_arch_string); } + if (pa_fixed_range_string) + fix_range (pa_fixed_range_string); + /* Unconditional branches in the delay slot are not compatible with dwarf2 call frame information. There is no benefit in using this optimization on PA8000 and later processors. */ diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h index 0ceedc68348..9e259f308b9 100644 --- a/gcc/config/pa/pa.h +++ b/gcc/config/pa/pa.h @@ -45,12 +45,6 @@ enum processor_type PROCESSOR_8000 }; -/* For -mschedule= option. */ -extern const char *pa_cpu_string; -extern enum processor_type pa_cpu; - -#define pa_cpu_attr ((enum attr_cpu)pa_cpu) - /* Which architecture to generate code for. */ enum architecture_type @@ -66,6 +60,15 @@ struct rtx_def; extern const char *pa_arch_string; extern enum architecture_type pa_arch; +/* For -mfixed-range= option. */ +extern const char *pa_fixed_range_string; + +/* For -mschedule= option. */ +extern const char *pa_cpu_string; +extern enum processor_type pa_cpu; + +#define pa_cpu_attr ((enum attr_cpu)pa_cpu) + /* Print subsidiary information on the compiler version in use. */ #define TARGET_VERSION fputs (" (hppa)", stderr); @@ -306,10 +309,13 @@ extern int target_flags; #define TARGET_OPTIONS \ { \ - { "schedule=", &pa_cpu_string, \ - N_("Specify CPU for scheduling purposes"), 0}, \ { "arch=", &pa_arch_string, \ - N_("Specify architecture for code generation. Values are 1.0, 1.1, and 2.0. 2.0 requires gas snapshot 19990413 or later."), 0}\ + N_("Specify PA-RISC architecture for code generation. " \ + "Values are 1.0, 1.1 and 2.0."), 0}, \ + { "fixed-range=", &pa_fixed_range_string, \ + N_("Specify range of registers to make fixed"), 0}, \ + { "schedule=", &pa_cpu_string, \ + N_("Specify CPU for scheduling purposes"), 0} \ } /* Support for a compile-time default CPU, et cetera. The rules are: diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index a4785f080f2..7bf2d40259d 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -461,6 +461,7 @@ in the following sections. @gccoptlist{-march=@var{architecture-type} @gol -mbig-switch -mdisable-fpregs -mdisable-indexing @gol -mfast-indirect-calls -mgas -mgnu-ld -mhp-ld @gol +-mfixed-range=@var{register-range} @gol -mjump-in-delay -mlinker-opt -mlong-calls @gol -mlong-load-store -mno-big-switch -mno-disable-fpregs @gol -mno-disable-indexing -mno-fast-indirect-calls -mno-gas @gol @@ -7720,6 +7721,14 @@ allows GCC to emit code which performs faster indirect calls. This option will not work in the presence of shared libraries or nested functions. +@item -mfixed-range=@var{register-range} +@opindex mfixed-range +Generate code treating the given register range as fixed registers. +A fixed register is one that the register allocator can not use. This is +useful when compiling kernel code. A register range is specified as +two registers separated by a dash. Multiple register ranges can be +specified separated by a comma. + @item -mlong-load-store @opindex mlong-load-store Generate 3-instruction load and store sequences as sometimes required by -- 2.30.2