pa.c (fix_range): New function to mark a range(s) of registers as fixed registers.
authorJohn David Anglin <dave.anglin@nrc-cnrc.gc.ca>
Wed, 14 Jul 2004 16:27:37 +0000 (16:27 +0000)
committerJohn David Anglin <danglin@gcc.gnu.org>
Wed, 14 Jul 2004 16:27:37 +0000 (16:27 +0000)
* 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
gcc/config/pa/pa.c
gcc/config/pa/pa.h
gcc/doc/invoke.texi

index 7110df0fabf624cdb55df12db5c72b19dd877efe..b24e2245dc993b3a1aa97f5678ff02ff00d063e9 100644 (file)
@@ -1,3 +1,12 @@
+2004-07-14  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
+
+       * 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  <edelsohn@gnu.org>
 
        * config/rs6000/rs6000.c (function_arg_padding): Do not pad SFmode
index 7f4ba45c2c6d759d7c1f8045558276cbfb0ada9e..ebe7a52abaa64879006330a6fe947bff98f92fdc 100644 (file)
@@ -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;
 \f
+/* 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.  */
index 0ceedc6834832e4edb659054c63be32cce929b67..9e259f308b9fe4c1346e9d224e821f8e221ce60d 100644 (file)
@@ -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:
index a4785f080f2f38a249f818be50bd82775d29121b..7bf2d40259da8313cbe79615977620c0a6d5ce3a 100644 (file)
@@ -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