aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/ia64
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2001-08-18 20:04:19 -0700
committerRichard Henderson <rth@gcc.gnu.org>2001-08-18 20:04:19 -0700
commit6ca3c22fd16679c55c3d44e19b646a5dec513244 (patch)
treef05313d8fdbcc9289591f51b7bf29335cf3310d0 /gcc/config/ia64
parent8e8de25448d2c52d6d2b4134167b60b19dfc54d0 (diff)
downloadgcc-6ca3c22fd16679c55c3d44e19b646a5dec513244.zip
gcc-6ca3c22fd16679c55c3d44e19b646a5dec513244.tar.gz
gcc-6ca3c22fd16679c55c3d44e19b646a5dec513244.tar.bz2
flow.c (mark_regs_live_at_end): Use regs_invalidated_by_call.
* flow.c (mark_regs_live_at_end): Use regs_invalidated_by_call. * regclass.c (init_reg_sets_1): Fix typo. * config/ia64/ia64.c (ar_pfs_reg_operand): New. (ia64_expand_call): Pass ar.pfs to sibcall expanders. (ia64_compute_frame_size): Make ar.unat live when in use. (ia64_epilogue_uses): Reformat; do not check current_function_is_leaf for ar.pfs; remove ar.unat handling. * config/ia64/ia64.h (CALL_REALLY_USED_REGISTERS): ar.unat is call-saved. (PREDICATE_CODES): Add ar_pfs_reg_operand. * config/ia64/ia64-protos.h: Update decls. * config/ia64/ia64.md (sibcall_nopic): Use ar.pfs. (sibcall_pic): Likewise. From-SVN: r45021
Diffstat (limited to 'gcc/config/ia64')
-rw-r--r--gcc/config/ia64/ia64-protos.h1
-rw-r--r--gcc/config/ia64/ia64.c89
-rw-r--r--gcc/config/ia64/ia64.h7
-rw-r--r--gcc/config/ia64/ia64.md6
4 files changed, 59 insertions, 44 deletions
diff --git a/gcc/config/ia64/ia64-protos.h b/gcc/config/ia64/ia64-protos.h
index e9c2c5c..03d2952 100644
--- a/gcc/config/ia64/ia64-protos.h
+++ b/gcc/config/ia64/ia64-protos.h
@@ -62,6 +62,7 @@ extern int not_postinc_memory_operand PARAMS((rtx, enum machine_mode));
extern int predicate_operator PARAMS((rtx, enum machine_mode));
extern int ar_lc_reg_operand PARAMS((rtx, enum machine_mode));
extern int ar_ccv_reg_operand PARAMS((rtx, enum machine_mode));
+extern int ar_pfs_reg_operand PARAMS((rtx, enum machine_mode));
extern int general_tfmode_operand PARAMS((rtx, enum machine_mode));
extern int destination_tfmode_operand PARAMS((rtx, enum machine_mode));
extern int tfreg_or_fp01_operand PARAMS((rtx, enum machine_mode));
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index aee3ee2..08660a7 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -788,6 +788,18 @@ ar_ccv_reg_operand (op, mode)
&& REGNO (op) == AR_CCV_REGNUM);
}
+/* Return 1 if this is the ar.pfs register. */
+
+int
+ar_pfs_reg_operand (op, mode)
+ register rtx op;
+ enum machine_mode mode;
+{
+ return ((GET_MODE (op) == mode || mode == VOIDmode)
+ && GET_CODE (op) == REG
+ && REGNO (op) == AR_PFS_REGNUM);
+}
+
/* Like general_operand, but don't allow (mem (addressof)). */
int
@@ -1107,11 +1119,12 @@ ia64_expand_call (retval, addr, nextarg, sibcall_p)
rtx nextarg;
int sibcall_p;
{
- rtx insn, b0, gp_save, narg_rtx;
+ rtx insn, b0, pfs, gp_save, narg_rtx;
int narg;
addr = XEXP (addr, 0);
b0 = gen_rtx_REG (DImode, R_BR (0));
+ pfs = gen_rtx_REG (DImode, AR_PFS_REGNUM);
if (! nextarg)
narg = 0;
@@ -1124,7 +1137,7 @@ ia64_expand_call (retval, addr, nextarg, sibcall_p)
if (TARGET_NO_PIC || TARGET_AUTO_PIC)
{
if (sibcall_p)
- insn = gen_sibcall_nopic (addr, narg_rtx, b0);
+ insn = gen_sibcall_nopic (addr, narg_rtx, b0, pfs);
else if (! retval)
insn = gen_call_nopic (addr, narg_rtx, b0);
else
@@ -1151,7 +1164,7 @@ ia64_expand_call (retval, addr, nextarg, sibcall_p)
gen_rtx_MEM (DImode, plus_constant (addr, 8)));
if (sibcall_p)
- insn = gen_sibcall_pic (dest, narg_rtx, b0);
+ insn = gen_sibcall_pic (dest, narg_rtx, b0, pfs);
else if (! retval)
insn = gen_call_pic (dest, narg_rtx, b0);
else
@@ -1164,7 +1177,7 @@ ia64_expand_call (retval, addr, nextarg, sibcall_p)
else if (TARGET_CONST_GP)
{
if (sibcall_p)
- insn = gen_sibcall_nopic (addr, narg_rtx, b0);
+ insn = gen_sibcall_nopic (addr, narg_rtx, b0, pfs);
else if (! retval)
insn = gen_call_nopic (addr, narg_rtx, b0);
else
@@ -1174,7 +1187,7 @@ ia64_expand_call (retval, addr, nextarg, sibcall_p)
else
{
if (sibcall_p)
- emit_call_insn (gen_sibcall_pic (addr, narg_rtx, b0));
+ emit_call_insn (gen_sibcall_pic (addr, narg_rtx, b0, pfs));
else
{
emit_move_insn (gp_save, pic_offset_table_rtx);
@@ -1548,6 +1561,7 @@ ia64_compute_frame_size (size)
ar.unat as well. */
if (spilled_gr_p || cfun->machine->n_varargs)
{
+ regs_ever_live[AR_UNAT_REGNUM] = 1;
SET_HARD_REG_BIT (mask, AR_UNAT_REGNUM);
current_frame_info.reg_save_ar_unat = find_gr_spill (spill_size == 0);
if (current_frame_info.reg_save_ar_unat == 0)
@@ -6633,42 +6647,39 @@ int
ia64_epilogue_uses (regno)
int regno;
{
- /* When a function makes a call through a function descriptor, we
- will write a (potentially) new value to "gp". After returning
- from such a call, we need to make sure the function restores the
- original gp-value, even if the function itself does not use the
- gp anymore. */
- if (regno == R_GR (1)
- && TARGET_CONST_GP
- && !(TARGET_AUTO_PIC || TARGET_NO_PIC))
- return 1;
-
- /* For functions defined with the syscall_linkage attribute, all input
- registers are marked as live at all function exits. This prevents the
- register allocator from using the input registers, which in turn makes it
- possible to restart a system call after an interrupt without having to
- save/restore the input registers. This also prevents kernel data from
- leaking to application code. */
-
- if (IN_REGNO_P (regno)
- && lookup_attribute ("syscall_linkage",
- TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
- return 1;
-
- /* Conditional return patterns can't represent the use of `b0' as
- the return address, so we force the value live this way. */
- if (regno == R_BR (0))
- return 1;
+ switch (regno)
+ {
+ case R_GR (1):
+ /* When a function makes a call through a function descriptor, we
+ will write a (potentially) new value to "gp". After returning
+ from such a call, we need to make sure the function restores the
+ original gp-value, even if the function itself does not use the
+ gp anymore. */
+ return (TARGET_CONST_GP && !(TARGET_AUTO_PIC || TARGET_NO_PIC));
+
+ case IN_REG (0): case IN_REG (1): case IN_REG (2): case IN_REG (3):
+ case IN_REG (4): case IN_REG (5): case IN_REG (6): case IN_REG (7):
+ /* For functions defined with the syscall_linkage attribute, all
+ input registers are marked as live at all function exits. This
+ prevents the register allocator from using the input registers,
+ which in turn makes it possible to restart a system call after
+ an interrupt without having to save/restore the input registers.
+ This also prevents kernel data from leaking to application code. */
+ return lookup_attribute ("syscall_linkage",
+ TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))) != NULL;
+
+ case R_BR (0):
+ /* Conditional return patterns can't represent the use of `b0' as
+ the return address, so we force the value live this way. */
+ return 1;
- if (regs_ever_live[AR_LC_REGNUM] && regno == AR_LC_REGNUM)
- return 1;
- if (! current_function_is_leaf && regno == AR_PFS_REGNUM)
- return 1;
- if (TEST_HARD_REG_BIT (current_frame_info.mask, AR_UNAT_REGNUM)
- && regno == AR_UNAT_REGNUM)
- return 1;
+ case AR_PFS_REGNUM:
+ /* Likewise for ar.pfs, which is used by br.ret. */
+ return 1;
- return 0;
+ default:
+ return 0;
+ }
}
/* Return true if IDENTIFIER is a valid attribute for TYPE. */
diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h
index d1a1fed..97e609f 100644
--- a/gcc/config/ia64/ia64.h
+++ b/gcc/config/ia64/ia64.h
@@ -635,11 +635,11 @@ while (0)
/* Like `CALL_USED_REGISTERS' but used to overcome a historical
problem which makes CALL_USED_REGISTERS *always* include
- all the FIXED_REGISTERS. Until this problem has been
+ all the FIXED_REGISTERS. Until this problem has been
resolved this macro can be used to overcome this situation.
In particular, block_propagate() requires this list
be acurate, or we can remove registers which should be live.
- This macro is used in regs_invalidated_by_call ()*/
+ This macro is used in regs_invalidated_by_call. */
#define CALL_REALLY_USED_REGISTERS \
{ /* General registers. */ \
@@ -668,7 +668,7 @@ while (0)
/* Branch registers. */ \
1, 0, 0, 0, 0, 0, 1, 1, \
/*FP RA CCV UNAT PFS LC EC */ \
- 0, 0, 1, 1, 1, 0, 0 \
+ 0, 0, 1, 0, 1, 0, 0 \
}
@@ -2667,6 +2667,7 @@ do { \
{ "condop_operator", {PLUS, MINUS, IOR, XOR, AND}}, \
{ "ar_lc_reg_operand", {REG}}, \
{ "ar_ccv_reg_operand", {REG}}, \
+{ "ar_pfs_reg_operand", {REG}}, \
{ "general_tfmode_operand", {SUBREG, REG, CONST_DOUBLE, MEM}}, \
{ "destination_tfmode_operand", {SUBREG, REG, MEM}}, \
{ "tfreg_or_fp01_operand", {REG, CONST_DOUBLE}},
diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md
index f5af33f..5c1b930 100644
--- a/gcc/config/ia64/ia64.md
+++ b/gcc/config/ia64/ia64.md
@@ -4673,7 +4673,8 @@
(define_insn "sibcall_nopic"
[(call (mem:DI (match_operand:DI 0 "call_operand" "b,i"))
(match_operand 1 "" ""))
- (use (match_operand:DI 2 "register_operand" "=b,b"))]
+ (use (match_operand:DI 2 "register_operand" "=b,b"))
+ (use (match_operand:DI 3 "ar_pfs_reg_operand" ""))]
""
"br%+.many %0"
[(set_attr "itanium_class" "br,scall")])
@@ -4701,7 +4702,8 @@
[(call (mem:DI (match_operand:DI 0 "call_operand" "bi"))
(match_operand 1 "" ""))
(use (unspec [(reg:DI 1)] 9))
- (use (match_operand:DI 2 "register_operand" "=b"))]
+ (use (match_operand:DI 2 "register_operand" "=b"))
+ (use (match_operand:DI 3 "ar_pfs_reg_operand" ""))]
""
"br%+.many %0"
[(set_attr "itanium_class" "br")])