Commit ec963611 by John David Anglin Committed by John David Anglin

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
parent b6a8dc3a
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> 2005-11-30 Nathan Sidwell <nathan@codesourcery.com>
* loop-doloop.c (add_test): Only add jump notes if we did emit a * loop-doloop.c (add_test): Only add jump notes if we did emit a
......
...@@ -106,8 +106,6 @@ extern int emit_move_sequence (rtx *, enum machine_mode, rtx); ...@@ -106,8 +106,6 @@ extern int emit_move_sequence (rtx *, enum machine_mode, rtx);
extern int emit_hpdiv_const (rtx *, int); extern int emit_hpdiv_const (rtx *, int);
extern int is_function_label_plus_const (rtx); extern int is_function_label_plus_const (rtx);
extern int jump_in_call_delay (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 hppa_fpstore_bypass_p (rtx, rtx);
extern int attr_length_millicode_call (rtx); extern int attr_length_millicode_call (rtx);
extern int attr_length_call (rtx, int); extern int attr_length_call (rtx, int);
......
...@@ -150,6 +150,9 @@ static bool pa_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, ...@@ -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, static int pa_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
tree, bool); tree, bool);
static struct machine_function * pa_init_machine_status (void); 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 /* Save the operands last given to a compare for use when we
...@@ -299,6 +302,9 @@ static size_t n_deferred_plabels = 0; ...@@ -299,6 +302,9 @@ static size_t n_deferred_plabels = 0;
#undef TARGET_CANNOT_FORCE_CONST_MEM #undef TARGET_CANNOT_FORCE_CONST_MEM
#define TARGET_CANNOT_FORCE_CONST_MEM pa_tls_referenced_p #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; struct gcc_target targetm = TARGET_INITIALIZER;
/* Parse the -mfixed-range= option string. */ /* Parse the -mfixed-range= option string. */
...@@ -5565,49 +5571,47 @@ output_arg_descriptor (rtx call_insn) ...@@ -5565,49 +5571,47 @@ output_arg_descriptor (rtx call_insn)
fputc ('\n', asm_out_file); fputc ('\n', asm_out_file);
} }
/* Return the class of any secondary reload register that is needed to static enum reg_class
move IN into a register in class CLASS using mode MODE. 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 /* Handle the easy stuff first. */
a significant amount of compile time (~7%). So it has been if (class == R1_REGS)
optimized to reduce redundant computations and eliminate useless return NO_REGS;
function calls.
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 /* If we have something like (mem (mem (...)), we can safely assume the
pa_secondary_reload_class (enum reg_class class, enum machine_mode mode, rtx in) inner MEM will end up in a general register after reloading, so there's
{ no need for a secondary reload. */
int regno, is_symbolic; 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 /* 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 if (flag_pic
&& GET_MODE_CLASS (mode) == MODE_INT && GET_MODE_CLASS (mode) == MODE_INT
&& FP_REG_CLASS_P (class) && FP_REG_CLASS_P (class)
&& (GET_CODE (in) == CONST_INT || GET_CODE (in) == CONST_DOUBLE)) && (GET_CODE (x) == CONST_INT || GET_CODE (x) == 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)
{ {
regno = REGNO (in); gcc_assert (mode == SImode || mode == DImode);
if (regno >= FIRST_PSEUDO_REGISTER) sri->icode = (mode == SImode ? CODE_FOR_reload_insi_r1
regno = true_regnum (in); : 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 /* Profiling showed the PA port spends about 1.3% of its compilation
inner MEM will end up in a general register after reloading, so there's time in true_regnum from calls inside pa_secondary_reload_class. */
no need for a secondary reload. */ if (regno >= FIRST_PSEUDO_REGISTER || GET_CODE (x) == SUBREG)
if (GET_CODE (in) == MEM regno = true_regnum (x);
&& GET_CODE (XEXP (in, 0)) == MEM)
return NO_REGS;
/* Handle out of range displacement for integer mode loads/stores of /* Handle out of range displacement for integer mode loads/stores of
FP registers. */ FP registers. */
...@@ -5615,50 +5619,59 @@ pa_secondary_reload_class (enum reg_class class, enum machine_mode mode, rtx in) ...@@ -5615,50 +5619,59 @@ pa_secondary_reload_class (enum reg_class class, enum machine_mode mode, rtx in)
&& GET_MODE_CLASS (mode) == MODE_INT && GET_MODE_CLASS (mode) == MODE_INT
&& FP_REG_CLASS_P (class)) && FP_REG_CLASS_P (class))
|| (class == SHIFT_REGS && (regno <= 0 || regno >= 32))) || (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 /* A SAR<->FP register copy requires a secondary register (GPR) as
well as secondary memory. */ well as secondary memory. */
if (regno >= 0 && regno < FIRST_PSEUDO_REGISTER if (regno >= 0 && regno < FIRST_PSEUDO_REGISTER
&& ((REGNO_REG_CLASS (regno) == SHIFT_REGS && FP_REG_CLASS_P (class)) && ((REGNO_REG_CLASS (regno) == SHIFT_REGS && FP_REG_CLASS_P (class))
|| (class == SHIFT_REGS && FP_REG_CLASS_P (REGNO_REG_CLASS (regno))))) || (class == SHIFT_REGS
return GENERAL_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) /* Secondary reloads of symbolic operands require %r1 as a scratch
in = XEXP (in, 0); 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 /* Profiling has showed GCC spends about 2.6% of its compilation
time in symbolic_operand from calls inside pa_secondary_reload_class. time in symbolic_operand from calls inside pa_secondary_reload_class.
So, we use an inline copy to avoid useless work. */
We use an inline copy and only compute its return value once to avoid switch (GET_CODE (x))
useless work. */
switch (GET_CODE (in))
{ {
rtx tmp; rtx op;
case SYMBOL_REF: case SYMBOL_REF:
is_symbolic = !SYMBOL_REF_TLS_MODEL (x);
break;
case LABEL_REF: case LABEL_REF:
is_symbolic = 1; is_symbolic = 1;
break; break;
case CONST: case CONST:
tmp = XEXP (in, 0); op = XEXP (x, 0);
is_symbolic = ((GET_CODE (XEXP (tmp, 0)) == SYMBOL_REF is_symbolic = (((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
|| GET_CODE (XEXP (tmp, 0)) == LABEL_REF) && !SYMBOL_REF_TLS_MODEL (XEXP (op, 0)))
&& GET_CODE (XEXP (tmp, 1)) == CONST_INT); || GET_CODE (XEXP (op, 0)) == LABEL_REF)
&& GET_CODE (XEXP (op, 1)) == CONST_INT);
break; break;
default: default:
is_symbolic = 0; is_symbolic = 0;
break; break;
} }
if (!flag_pic if (is_symbolic && (flag_pic || !read_only_operand (x, VOIDmode)))
&& is_symbolic {
&& read_only_operand (in, VOIDmode)) gcc_assert (mode == SImode || mode == DImode);
return NO_REGS; sri->icode = (mode == SImode ? CODE_FOR_reload_insi_r1
: CODE_FOR_reload_indi_r1);
if (class != R1_REGS && is_symbolic) }
return R1_REGS;
return NO_REGS; return NO_REGS;
} }
......
...@@ -527,16 +527,6 @@ extern struct rtx_def *hppa_pic_save_rtx (void); ...@@ -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. */ in some cases it is preferable to use a more restrictive class. */
#define PREFERRED_RELOAD_CLASS(X,CLASS) (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) \ #define MAYBE_FP_REG_CLASS_P(CLASS) \
reg_classes_intersect_p ((CLASS), FP_REGS) reg_classes_intersect_p ((CLASS), FP_REGS)
......
...@@ -2255,9 +2255,24 @@ ...@@ -2255,9 +2255,24 @@
DONE; DONE;
}") }")
;; Reloading an SImode or DImode value requires a scratch register if ;; Handle SImode input reloads requiring %r1 as a scratch register.
;; going in to or out of float point registers. (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" (define_expand "reload_insi"
[(set (match_operand:SI 0 "register_operand" "=Z") [(set (match_operand:SI 0 "register_operand" "=Z")
(match_operand:SI 1 "non_hard_reg_operand" "")) (match_operand:SI 1 "non_hard_reg_operand" ""))
...@@ -2273,6 +2288,8 @@ ...@@ -2273,6 +2288,8 @@
DONE; DONE;
}") }")
;; Handle SImode output reloads requiring a general register as a
;; scratch register.
(define_expand "reload_outsi" (define_expand "reload_outsi"
[(set (match_operand:SI 0 "non_hard_reg_operand" "") [(set (match_operand:SI 0 "non_hard_reg_operand" "")
(match_operand:SI 1 "register_operand" "Z")) (match_operand:SI 1 "register_operand" "Z"))
...@@ -3787,9 +3804,8 @@ ...@@ -3787,9 +3804,8 @@
DONE; DONE;
}") }")
;; Reloading an SImode or DImode value requires a scratch register if ;; Handle DFmode input reloads requiring a general register as a
;; going in to or out of float point registers. ;; scratch register.
(define_expand "reload_indf" (define_expand "reload_indf"
[(set (match_operand:DF 0 "register_operand" "=Z") [(set (match_operand:DF 0 "register_operand" "=Z")
(match_operand:DF 1 "non_hard_reg_operand" "")) (match_operand:DF 1 "non_hard_reg_operand" ""))
...@@ -3805,6 +3821,8 @@ ...@@ -3805,6 +3821,8 @@
DONE; DONE;
}") }")
;; Handle DFmode output reloads requiring a general register as a
;; scratch register.
(define_expand "reload_outdf" (define_expand "reload_outdf"
[(set (match_operand:DF 0 "non_hard_reg_operand" "") [(set (match_operand:DF 0 "non_hard_reg_operand" "")
(match_operand:DF 1 "register_operand" "Z")) (match_operand:DF 1 "register_operand" "Z"))
...@@ -4044,6 +4062,24 @@ ...@@ -4044,6 +4062,24 @@
DONE; 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" (define_expand "reload_indi"
[(set (match_operand:DI 0 "register_operand" "=Z") [(set (match_operand:DI 0 "register_operand" "=Z")
(match_operand:DI 1 "non_hard_reg_operand" "")) (match_operand:DI 1 "non_hard_reg_operand" ""))
...@@ -4059,6 +4095,8 @@ ...@@ -4059,6 +4095,8 @@
DONE; DONE;
}") }")
;; Handle DImode output reloads requiring a general register as a
;; scratch register.
(define_expand "reload_outdi" (define_expand "reload_outdi"
[(set (match_operand:DI 0 "non_hard_reg_operand" "") [(set (match_operand:DI 0 "non_hard_reg_operand" "")
(match_operand:DI 1 "register_operand" "Z")) (match_operand:DI 1 "register_operand" "Z"))
...@@ -4306,9 +4344,8 @@ ...@@ -4306,9 +4344,8 @@
DONE; DONE;
}") }")
;; Reloading an SImode or DImode value requires a scratch register if ;; Handle SFmode input reloads requiring a general register as a
;; going in to or out of float point registers. ;; scratch register.
(define_expand "reload_insf" (define_expand "reload_insf"
[(set (match_operand:SF 0 "register_operand" "=Z") [(set (match_operand:SF 0 "register_operand" "=Z")
(match_operand:SF 1 "non_hard_reg_operand" "")) (match_operand:SF 1 "non_hard_reg_operand" ""))
...@@ -4324,6 +4361,8 @@ ...@@ -4324,6 +4361,8 @@
DONE; DONE;
}") }")
;; Handle SFmode output reloads requiring a general register as a
;; scratch register.
(define_expand "reload_outsf" (define_expand "reload_outsf"
[(set (match_operand:SF 0 "non_hard_reg_operand" "") [(set (match_operand:SF 0 "non_hard_reg_operand" "")
(match_operand:SF 1 "register_operand" "Z")) (match_operand:SF 1 "register_operand" "Z"))
......
...@@ -60,7 +60,8 @@ ...@@ -60,7 +60,8 @@
return (memory_address_p (mode, op) && IS_INDEX_ADDR_P (op)); 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" (define_predicate "symbolic_operand"
(match_code "symbol_ref,label_ref,const") (match_code "symbol_ref,label_ref,const")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment