aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJohn David Anglin <dave.anglin@nrc-cnrc.gc.ca>2005-11-30 13:51:32 +0000
committerJohn David Anglin <danglin@gcc.gnu.org>2005-11-30 13:51:32 +0000
commitec963611039e095aa654d81ffdd6b94ffd9aaee6 (patch)
treed5d1e284918b1142f448f7024c16298be8cfe218 /gcc
parentb6a8dc3ad64ea3ec42c21e6c7299bcba263c323d (diff)
downloadgcc-ec963611039e095aa654d81ffdd6b94ffd9aaee6.zip
gcc-ec963611039e095aa654d81ffdd6b94ffd9aaee6.tar.gz
gcc-ec963611039e095aa654d81ffdd6b94ffd9aaee6.tar.bz2
predicates.md (symbolic_operand): Add comment.
* 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. Co-Authored-By: Bernd Schmidt <bernd.schmidt@analog.com> From-SVN: r107719
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/config/pa/pa-protos.h2
-rw-r--r--gcc/config/pa/pa.c121
-rw-r--r--gcc/config/pa/pa.h10
-rw-r--r--gcc/config/pa/pa.md55
-rw-r--r--gcc/config/pa/predicates.md3
6 files changed, 129 insertions, 75 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ddb830f..813e209 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/pa/pa-protos.h b/gcc/config/pa/pa-protos.h
index d0daf72..0963844 100644
--- a/gcc/config/pa/pa-protos.h
+++ b/gcc/config/pa/pa-protos.h
@@ -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);
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 0eeb163..4dcd828 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -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;
/* Parse the -mfixed-range= option string. */
@@ -5565,49 +5571,47 @@ output_arg_descriptor (rtx call_insn)
fputc ('\n', asm_out_file);
}
-/* 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;
}
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index 1787038..6fc265e 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -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)
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index 83fdec6..8e28e8f 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -2255,9 +2255,24 @@
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" ""))
@@ -2273,6 +2288,8 @@
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"))
@@ -3787,9 +3804,8 @@
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" ""))
@@ -3805,6 +3821,8 @@
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"))
@@ -4044,6 +4062,24 @@
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" ""))
@@ -4059,6 +4095,8 @@
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"))
@@ -4306,9 +4344,8 @@
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" ""))
@@ -4324,6 +4361,8 @@
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"))
diff --git a/gcc/config/pa/predicates.md b/gcc/config/pa/predicates.md
index b383569..685a494 100644
--- a/gcc/config/pa/predicates.md
+++ b/gcc/config/pa/predicates.md
@@ -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")