* pa/predicates.md (symbolic_operand): Add comment.
authordanglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 30 Nov 2005 13:51:32 +0000 (13:51 +0000)
committerdanglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 30 Nov 2005 13:51:32 +0000 (13:51 +0000)
* pa/pa.md (reload_insi_r1, reload_indi_r1): New reload expanders.
* pa/pa-protos.h (pa_secondary_reload_class): Delete.
* pa/pa.c (TARGET_SECONDARY_RELOAD): Define.
(pa_secondary_reload_class): Delete.
(pa_secondary_reload): New function derived from SECONDARY_RELOAD_CLASS
and pa_secondary_reload_class.  Reorder some checks.  Update inline
copy of symbolic operand.
* pa/pa.h (SECONDARY_RELOAD_CLASS): Delete.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@107719 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/pa/pa-protos.h
gcc/config/pa/pa.c
gcc/config/pa/pa.h
gcc/config/pa/pa.md
gcc/config/pa/predicates.md

index ddb830f..813e209 100644 (file)
@@ -1,3 +1,16 @@
+2005-11-30  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
+           Bernd Schmidt  <bernd.schmidt@analog.com>
+
+       * pa/predicates.md (symbolic_operand): Add comment.
+       * pa/pa.md (reload_insi_r1, reload_indi_r1): New reload expanders.
+       * pa/pa-protos.h (pa_secondary_reload_class): Delete.
+       * pa/pa.c (TARGET_SECONDARY_RELOAD): Define.
+       (pa_secondary_reload_class): Delete.
+       (pa_secondary_reload): New function derived from SECONDARY_RELOAD_CLASS
+       and pa_secondary_reload_class.  Reorder some checks.  Update inline
+       copy of symbolic operand.
+       * pa/pa.h (SECONDARY_RELOAD_CLASS): Delete.
+
 2005-11-30  Nathan Sidwell  <nathan@codesourcery.com>
 
        * loop-doloop.c (add_test): Only add jump notes if we did emit a
index d0daf72..0963844 100644 (file)
@@ -106,8 +106,6 @@ extern int emit_move_sequence (rtx *, enum machine_mode, rtx);
 extern int emit_hpdiv_const (rtx *, int);
 extern int is_function_label_plus_const (rtx);
 extern int jump_in_call_delay (rtx);
-extern enum reg_class pa_secondary_reload_class (enum reg_class,
-                                                enum machine_mode, rtx);
 extern int hppa_fpstore_bypass_p (rtx, rtx);
 extern int attr_length_millicode_call (rtx);
 extern int attr_length_call (rtx, int);
index 0eeb163..4dcd828 100644 (file)
@@ -150,6 +150,9 @@ static bool pa_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
 static int pa_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
                                 tree, bool);
 static struct machine_function * pa_init_machine_status (void);
+static enum reg_class pa_secondary_reload (bool, rtx, enum reg_class,
+                                          enum machine_mode,
+                                          secondary_reload_info *);
 
 
 /* Save the operands last given to a compare for use when we
@@ -299,6 +302,9 @@ static size_t n_deferred_plabels = 0;
 #undef TARGET_CANNOT_FORCE_CONST_MEM
 #define TARGET_CANNOT_FORCE_CONST_MEM pa_tls_referenced_p
 
+#undef TARGET_SECONDARY_RELOAD
+#define TARGET_SECONDARY_RELOAD pa_secondary_reload
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
 /* Parse the -mfixed-range= option string.  */
@@ -5565,49 +5571,47 @@ output_arg_descriptor (rtx call_insn)
   fputc ('\n', asm_out_file);
 }
 \f
-/* Return the class of any secondary reload register that is needed to
-   move IN into a register in class CLASS using mode MODE.
+static enum reg_class
+pa_secondary_reload (bool in_p, rtx x, enum reg_class class,
+                    enum machine_mode mode, secondary_reload_info *sri)
+{
+  int is_symbolic;
+  int regno = -1;
 
-   Profiling has showed this routine and its descendants account for
-   a significant amount of compile time (~7%).  So it has been
-   optimized to reduce redundant computations and eliminate useless
-   function calls.
+  /* Handle the easy stuff first.  */
+  if (class == R1_REGS)
+    return NO_REGS;
 
-   It might be worthwhile to try and make this a leaf function too.  */
+  if (REG_P (x))
+    {
+      regno = REGNO (x);
+      if (class == BASE_REG_CLASS && regno < FIRST_PSEUDO_REGISTER)
+       return NO_REGS;
+    }
 
-enum reg_class
-pa_secondary_reload_class (enum reg_class class, enum machine_mode mode, rtx in)
-{
-  int regno, is_symbolic;
+  /* If we have something like (mem (mem (...)), we can safely assume the
+     inner MEM will end up in a general register after reloading, so there's
+     no need for a secondary reload.  */
+  if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == MEM)
+    return NO_REGS;
 
   /* Trying to load a constant into a FP register during PIC code
-     generation will require %r1 as a scratch register.  */
+     generation requires %r1 as a scratch register.  */
   if (flag_pic
       && GET_MODE_CLASS (mode) == MODE_INT
       && FP_REG_CLASS_P (class)
-      && (GET_CODE (in) == CONST_INT || GET_CODE (in) == CONST_DOUBLE))
-    return R1_REGS;
-
-  /* Profiling showed the PA port spends about 1.3% of its compilation
-     time in true_regnum from calls inside pa_secondary_reload_class.  */
-
-  if (GET_CODE (in) == REG)
+      && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
     {
-      regno = REGNO (in);
-      if (regno >= FIRST_PSEUDO_REGISTER)
-       regno = true_regnum (in);
+      gcc_assert (mode == SImode || mode == DImode);
+      sri->icode = (mode == SImode ? CODE_FOR_reload_insi_r1
+                   : CODE_FOR_reload_indi_r1);
+      return NO_REGS;
     }
-  else if (GET_CODE (in) == SUBREG)
-    regno = true_regnum (in);
-  else
-    regno = -1;
 
-  /* If we have something like (mem (mem (...)), we can safely assume the
-     inner MEM will end up in a general register after reloading, so there's
-     no need for a secondary reload.  */
-  if (GET_CODE (in) == MEM
-      && GET_CODE (XEXP (in, 0)) == MEM)
-    return NO_REGS;
+  /* Profiling showed the PA port spends about 1.3% of its compilation
+     time in true_regnum from calls inside pa_secondary_reload_class.  */
+  if (regno >= FIRST_PSEUDO_REGISTER || GET_CODE (x) == SUBREG)
+    regno = true_regnum (x);
 
   /* Handle out of range displacement for integer mode loads/stores of
      FP registers.  */
@@ -5615,50 +5619,59 @@ pa_secondary_reload_class (enum reg_class class, enum machine_mode mode, rtx in)
        && GET_MODE_CLASS (mode) == MODE_INT
        && FP_REG_CLASS_P (class))
       || (class == SHIFT_REGS && (regno <= 0 || regno >= 32)))
-    return GENERAL_REGS;
+    {
+      sri->icode = in_p ? reload_in_optab[mode] : reload_out_optab[mode];
+      return NO_REGS;
+    }
 
   /* A SAR<->FP register copy requires a secondary register (GPR) as
      well as secondary memory.  */
   if (regno >= 0 && regno < FIRST_PSEUDO_REGISTER
       && ((REGNO_REG_CLASS (regno) == SHIFT_REGS && FP_REG_CLASS_P (class))
-         || (class == SHIFT_REGS && FP_REG_CLASS_P (REGNO_REG_CLASS (regno)))))
-    return GENERAL_REGS;
+         || (class == SHIFT_REGS
+             && FP_REG_CLASS_P (REGNO_REG_CLASS (regno)))))
+    {
+      sri->icode = in_p ? reload_in_optab[mode] : reload_out_optab[mode];
+      return NO_REGS;
+    }
 
-  if (GET_CODE (in) == HIGH)
-    in = XEXP (in, 0);
+  /* Secondary reloads of symbolic operands require %r1 as a scratch
+     register when we're generating PIC code and the operand isn't
+     readonly.  */
+  if (GET_CODE (x) == HIGH)
+    x = XEXP (x, 0);
 
   /* Profiling has showed GCC spends about 2.6% of its compilation
      time in symbolic_operand from calls inside pa_secondary_reload_class.
-
-     We use an inline copy and only compute its return value once to avoid
-     useless work.  */
-  switch (GET_CODE (in))
+     So, we use an inline copy to avoid useless work.  */
+  switch (GET_CODE (x))
     {
-      rtx tmp;
+      rtx op;
 
       case SYMBOL_REF:
+        is_symbolic = !SYMBOL_REF_TLS_MODEL (x);
+        break;
       case LABEL_REF:
         is_symbolic = 1;
         break;
       case CONST:
-       tmp = XEXP (in, 0);
-       is_symbolic = ((GET_CODE (XEXP (tmp, 0)) == SYMBOL_REF
-                       || GET_CODE (XEXP (tmp, 0)) == LABEL_REF)
-                      && GET_CODE (XEXP (tmp, 1)) == CONST_INT);
+       op = XEXP (x, 0);
+       is_symbolic = (((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
+                        && !SYMBOL_REF_TLS_MODEL (XEXP (op, 0)))
+                       || GET_CODE (XEXP (op, 0)) == LABEL_REF)
+                      && GET_CODE (XEXP (op, 1)) == CONST_INT);
         break;
-
       default:
         is_symbolic = 0;
         break;
     }
 
-  if (!flag_pic
-      && is_symbolic
-      && read_only_operand (in, VOIDmode))
-    return NO_REGS;
-
-  if (class != R1_REGS && is_symbolic)
-    return R1_REGS;
+  if (is_symbolic && (flag_pic || !read_only_operand (x, VOIDmode)))
+    {
+      gcc_assert (mode == SImode || mode == DImode);
+      sri->icode = (mode == SImode ? CODE_FOR_reload_insi_r1
+                   : CODE_FOR_reload_indi_r1);
+    }
 
   return NO_REGS;
 }
index 1787038..6fc265e 100644 (file)
@@ -527,16 +527,6 @@ extern struct rtx_def *hppa_pic_save_rtx (void);
    in some cases it is preferable to use a more restrictive class.  */
 #define PREFERRED_RELOAD_CLASS(X,CLASS) (CLASS)
 
-/* Return the register class of a scratch register needed to copy
-   IN into a register in CLASS in MODE, or a register in CLASS in MODE
-   to IN.  If it can be done directly NO_REGS is returned. 
-
-  Avoid doing any work for the common case calls.  */
-#define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
-  ((CLASS == BASE_REG_CLASS && GET_CODE (IN) == REG            \
-    && REGNO (IN) < FIRST_PSEUDO_REGISTER)                     \
-   ? NO_REGS : pa_secondary_reload_class (CLASS, MODE, IN))
-
 #define MAYBE_FP_REG_CLASS_P(CLASS) \
   reg_classes_intersect_p ((CLASS), FP_REGS)
 
index 83fdec6..8e28e8f 100644 (file)
     DONE;
 }")
 
-;; Reloading an SImode or DImode value requires a scratch register if
-;; going in to or out of float point registers.
+;; Handle SImode input reloads requiring %r1 as a scratch register.
+(define_expand "reload_insi_r1"
+  [(set (match_operand:SI 0 "register_operand" "=Z")
+       (match_operand:SI 1 "non_hard_reg_operand" ""))
+   (clobber (match_operand:SI 2 "register_operand" "=&a"))]
+  ""
+  "
+{
+  if (emit_move_sequence (operands, SImode, operands[2]))
+    DONE;
 
+  /* We don't want the clobber emitted, so handle this ourselves.  */
+  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
+  DONE;
+}")
+
+;; Handle SImode input reloads requiring a general register as a
+;; scratch register.
 (define_expand "reload_insi"
   [(set (match_operand:SI 0 "register_operand" "=Z")
        (match_operand:SI 1 "non_hard_reg_operand" ""))
   DONE;
 }")
 
+;; Handle SImode output reloads requiring a general register as a
+;; scratch register.
 (define_expand "reload_outsi"
   [(set (match_operand:SI 0 "non_hard_reg_operand" "")
        (match_operand:SI 1  "register_operand" "Z"))
     DONE;
 }")
 
-;; Reloading an SImode or DImode value requires a scratch register if
-;; going in to or out of float point registers.
-
+;; Handle DFmode input reloads requiring a general register as a
+;; scratch register.
 (define_expand "reload_indf"
   [(set (match_operand:DF 0 "register_operand" "=Z")
        (match_operand:DF 1 "non_hard_reg_operand" ""))
   DONE;
 }")
 
+;; Handle DFmode output reloads requiring a general register as a
+;; scratch register.
 (define_expand "reload_outdf" 
  [(set (match_operand:DF 0 "non_hard_reg_operand" "")
        (match_operand:DF 1  "register_operand" "Z"))
     DONE;
 }")
 
+;; Handle DImode input reloads requiring %r1 as a scratch register.
+(define_expand "reload_indi_r1"
+  [(set (match_operand:DI 0 "register_operand" "=Z")
+       (match_operand:DI 1 "non_hard_reg_operand" ""))
+   (clobber (match_operand:SI 2 "register_operand" "=&a"))]
+  ""
+  "
+{
+  if (emit_move_sequence (operands, DImode, operands[2]))
+    DONE;
+
+  /* We don't want the clobber emitted, so handle this ourselves.  */
+  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
+  DONE;
+}")
+
+;; Handle DImode input reloads requiring a general register as a
+;; scratch register.
 (define_expand "reload_indi"
   [(set (match_operand:DI 0 "register_operand" "=Z")
        (match_operand:DI 1 "non_hard_reg_operand" ""))
   DONE;
 }")
 
+;; Handle DImode output reloads requiring a general register as a
+;; scratch register.
 (define_expand "reload_outdi"
   [(set (match_operand:DI 0 "non_hard_reg_operand" "")
        (match_operand:DI 1 "register_operand" "Z"))
     DONE;
 }")
 
-;; Reloading an SImode or DImode value requires a scratch register if
-;; going in to or out of float point registers.
-
+;; Handle SFmode input reloads requiring a general register as a
+;; scratch register.
 (define_expand "reload_insf"
   [(set (match_operand:SF 0 "register_operand" "=Z")
        (match_operand:SF 1 "non_hard_reg_operand" ""))
   DONE;
 }")
 
+;; Handle SFmode output reloads requiring a general register as a
+;; scratch register.
 (define_expand "reload_outsf"
   [(set (match_operand:SF 0 "non_hard_reg_operand" "")
        (match_operand:SF 1  "register_operand" "Z"))
index b383569..685a494 100644 (file)
@@ -60,7 +60,8 @@
   return (memory_address_p (mode, op) && IS_INDEX_ADDR_P (op));
 })
 
-;; TODO: Add a comment.
+;; Return 1 iff OP is a symbolic operand.
+;; Note: an inline copy of this code is present in pa_secondary_reload.
 
 (define_predicate "symbolic_operand"
   (match_code "symbol_ref,label_ref,const")