summaryrefslogtreecommitdiffstats
path: root/gcc
diff options
context:
space:
mode:
authorgeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>2000-10-01 05:29:14 +0000
committergeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>2000-10-01 05:29:14 +0000
commit90e1e7afbdb35903ee5e011b8824708c03b998f3 (patch)
tree9b33000ba9e8cb51c596c7c89e8c48ae70621225 /gcc
parentdb9e2b98cab772c0cc7d86044f08c324d464f166 (diff)
downloadppe42-gcc-90e1e7afbdb35903ee5e011b8824708c03b998f3.tar.gz
ppe42-gcc-90e1e7afbdb35903ee5e011b8824708c03b998f3.zip
* config/rs6000/rs6000.md (movsi_to_cr): Remove the USE. Calculate
the mask value from the individual SET operations. (return_internal_si): Move the USE after the RETURN. (return_internal_di): Likewise. (return_and_restore_fpregs_si): Likewise. (return_and_restore_fpregs_di): Likewise. (return_eh_si): Likewise. (return_eh_di): Likewise. * config/rs6000/rs6000.c (mtcrf_operation): Don't look for, or check, the USE. (rs6000_emit_prologue): Don't emit the USE for movsi_to_cr. Don't generate a PARALLEL around a single operation movsi_to_cr. Generate the RETURN first in any PARALLELs. * rtlanal.c (single_set_1): Use fatal_insn to display the invalid insn. Check for more cases when a USE or CLOBBER occurs before a SET. * Makefile.in: Update dependencies for rtlanal.o. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@36683 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog21
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/config/rs6000/rs6000.c51
-rw-r--r--gcc/config/rs6000/rs6000.md41
-rw-r--r--gcc/rtlanal.c58
5 files changed, 103 insertions, 70 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9570b2835c0..15e6d46ae99 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,24 @@
+2000-09-30 Geoff Keating <geoffk@cygnus.com>
+
+ * config/rs6000/rs6000.md (movsi_to_cr): Remove the USE. Calculate
+ the mask value from the individual SET operations.
+ (return_internal_si): Move the USE after the RETURN.
+ (return_internal_di): Likewise.
+ (return_and_restore_fpregs_si): Likewise.
+ (return_and_restore_fpregs_di): Likewise.
+ (return_eh_si): Likewise.
+ (return_eh_di): Likewise.
+ * config/rs6000/rs6000.c (mtcrf_operation): Don't look for,
+ or check, the USE.
+ (rs6000_emit_prologue): Don't emit the USE for movsi_to_cr.
+ Don't generate a PARALLEL around a single operation movsi_to_cr.
+ Generate the RETURN first in any PARALLELs.
+
+ * rtlanal.c (single_set_1): Use fatal_insn to display the
+ invalid insn. Check for more cases when a USE or CLOBBER occurs
+ before a SET.
+ * Makefile.in: Update dependencies for rtlanal.o.
+
2000-09-30 Joseph S. Myers <jsm28@cam.ac.uk>
* i386.c: Move include of "config.h" to before that of <setjmp.h>.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index f5cd9dc7714..c1ecef078be 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1253,7 +1253,7 @@ rtl.o : rtl.c $(CONFIG_H) system.h $(RTL_H) bitmap.h $(GGC_H) toplev.h
print-rtl.o : print-rtl.c $(CONFIG_H) system.h $(RTL_H) hard-reg-set.h \
$(BASIC_BLOCK_H)
-rtlanal.o : rtlanal.c $(CONFIG_H) system.h $(RTL_H)
+rtlanal.o : rtlanal.c $(CONFIG_H) system.h toplev.h $(RTL_H)
errors.o : errors.c $(CONFIG_H) system.h errors.h
varasm.o : varasm.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) flags.h \
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 803c2db8965..e0bacdd7757 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -3006,25 +3006,22 @@ mtcrf_operation (op, mode)
{
int count = XVECLEN (op, 0);
int i;
- int bitmap = 0;
rtx src_reg;
/* Perform a quick check so we don't blow up below. */
- if (count < 2
- || GET_CODE (XVECEXP (op, 0, 0)) != USE
- || GET_CODE (XEXP (XVECEXP (op, 0, 0), 0)) != CONST_INT
- || GET_CODE (XVECEXP (op, 0, 1)) != SET
- || GET_CODE (SET_SRC (XVECEXP (op, 0, 1))) != UNSPEC
- || XVECLEN (SET_SRC (XVECEXP (op, 0, 1)), 0) != 2)
+ if (count < 1
+ || GET_CODE (XVECEXP (op, 0, 0)) != SET
+ || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC
+ || XVECLEN (SET_SRC (XVECEXP (op, 0, 0)), 0) != 2)
return 0;
- src_reg = XVECEXP (SET_SRC (XVECEXP (op, 0, 1)), 0, 0);
+ src_reg = XVECEXP (SET_SRC (XVECEXP (op, 0, 0)), 0, 0);
if (GET_CODE (src_reg) != REG
|| GET_MODE (src_reg) != SImode
|| ! INT_REGNO_P (REGNO (src_reg)))
return 0;
- for (i = 1; i < count; i++)
+ for (i = 0; i < count; i++)
{
rtx exp = XVECEXP (op, 0, i);
rtx unspec;
@@ -3037,7 +3034,6 @@ mtcrf_operation (op, mode)
return 0;
unspec = SET_SRC (exp);
maskval = 1 << (MAX_CR_REGNO - REGNO (SET_DEST (exp)));
- bitmap |= maskval;
if (GET_CODE (unspec) != UNSPEC
|| XINT (unspec, 1) != 20
@@ -3047,7 +3043,7 @@ mtcrf_operation (op, mode)
|| INTVAL (XVECEXP (unspec, 0, 1)) != maskval)
return 0;
}
- return INTVAL (XEXP (XVECEXP (op, 0, 0), 0)) == bitmap;
+ return 1;
}
/* Return 1 for an PARALLEL suitable for lmw. */
@@ -5974,38 +5970,39 @@ rs6000_emit_epilogue(sibcall)
if (info->cr_save_p)
{
rtx r12_rtx = gen_rtx_REG (SImode, 12);
+ int count = 0;
if (using_mfcr_multiple)
{
- rtvec p;
- int mask = 0;
- int count = 0;
-
for (i = 0; i < 8; i++)
if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
- {
- mask |= 1 << (7-i);
- count++;
- }
+ count++;
if (count == 0)
- abort();
+ abort ();
+ }
+
+ if (using_mfcr_multiple && count > 1)
+ {
+ rtvec p;
+ int ndx;
- p = rtvec_alloc (count + 1);
+ p = rtvec_alloc (count);
- RTVEC_ELT (p, 0) = gen_rtx_USE (VOIDmode, GEN_INT (mask));
- count = 1;
+ ndx = 0;
for (i = 0; i < 8; i++)
if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
{
rtvec r = rtvec_alloc (2);
RTVEC_ELT (r, 0) = r12_rtx;
RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
- RTVEC_ELT (p, count) =
+ RTVEC_ELT (p, ndx) =
gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
gen_rtx_UNSPEC (CCmode, r, 20));
- count++;
+ ndx++;
}
emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
+ if (ndx != count)
+ abort ();
}
else
for (i = 0; i < 8; i++)
@@ -6050,10 +6047,10 @@ rs6000_emit_epilogue(sibcall)
else
p = rtvec_alloc (2);
- RTVEC_ELT (p, 0) = gen_rtx_USE (VOIDmode,
+ RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
+ RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
gen_rtx_REG (Pmode,
LINK_REGISTER_REGNUM));
- RTVEC_ELT (p, 1) = gen_rtx_RETURN (VOIDmode);
/* If we have to restore more than two FP registers, branch to the
restore function. It will return to our caller. */
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 132fb3c1ef7..43e74683bcf 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -13295,13 +13295,20 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
(define_insn "*movsi_to_cr"
[(match_parallel 0 "mtcrf_operation"
- [(use (match_operand 1 "immediate_operand" "n"))
- (set (match_operand:CC 2 "cc_reg_operand" "=y")
- (unspec:CC [(match_operand:SI 3 "gpc_reg_operand" "r")
- (match_operand 4 "immediate_operand" "n")]
+ [(set (match_operand:CC 1 "cc_reg_operand" "=y")
+ (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
+ (match_operand 3 "immediate_operand" "n")]
20))])]
""
- "mtcrf %1,%3")
+ "*
+{
+ int mask = 0;
+ int i;
+ for (i = 0; i < XVECLEN (operands[0], 0); i++)
+ mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
+ operands[4] = GEN_INT (mask);
+ return \"mtcrf %4,%2\";
+}")
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=y")
@@ -13325,15 +13332,15 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
"{lm|lmw} %1,%2")
(define_insn "*return_internal_si"
- [(use (match_operand:SI 0 "register_operand" "lc"))
- (return)]
+ [(return)
+ (use (match_operand:SI 0 "register_operand" "lc"))]
"TARGET_32BIT"
"b%T0"
[(set_attr "type" "jmpreg")])
(define_insn "*return_internal_di"
- [(use (match_operand:DI 0 "register_operand" "lc"))
- (return)]
+ [(return)
+ (use (match_operand:DI 0 "register_operand" "lc"))]
"TARGET_64BIT"
"b%T0"
[(set_attr "type" "jmpreg")])
@@ -13343,8 +13350,8 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
(define_insn "*return_and_restore_fpregs_si"
[(match_parallel 0 "any_operand"
- [(use (match_operand:SI 1 "register_operand" "l"))
- (return)
+ [(return)
+ (use (match_operand:SI 1 "register_operand" "l"))
(use (match_operand:SI 2 "call_operand" "s"))
(set (match_operand:DF 3 "gpc_reg_operand" "=f")
(match_operand:DF 4 "memory_operand" "m"))])]
@@ -13353,8 +13360,8 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
(define_insn "*return_and_restore_fpregs_di"
[(match_parallel 0 "any_operand"
- [(use (match_operand:DI 1 "register_operand" "l"))
- (return)
+ [(return)
+ (use (match_operand:DI 1 "register_operand" "l"))
(use (match_operand:DI 2 "call_operand" "s"))
(set (match_operand:DF 3 "gpc_reg_operand" "=f")
(match_operand:DF 4 "memory_operand" "m"))])]
@@ -13460,8 +13467,8 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
(define_insn "return_eh_si"
- [(use (match_operand:SI 0 "register_operand" "lc"))
- (return)
+ [(return)
+ (use (match_operand:SI 0 "register_operand" "lc"))
(use (reg:SI 2))
(use (reg:SI 3))]
"TARGET_32BIT"
@@ -13469,8 +13476,8 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
[(set_attr "type" "jmpreg")])
(define_insn "return_eh_di"
- [(use (match_operand:DI 0 "register_operand" "lc"))
- (return)
+ [(return)
+ (use (match_operand:DI 0 "register_operand" "lc"))
(use (reg:DI 2))
(use (reg:DI 3))]
"TARGET_64BIT"
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 0d922c66c43..2e1ae1450e9 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -22,6 +22,7 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "toplev.h"
#include "rtl.h"
static int rtx_addr_can_trap_p PARAMS ((rtx));
@@ -878,7 +879,7 @@ single_set_1 (insn)
/* Instruction should not consist only from USEs and CLOBBERS,
since then gcc is allowed to remove it entirely. In case
something else is present, it should be first in the pattern. */
- abort();
+ fatal_insn ("USE or CLOBBER before SET:", insn);
#endif
case SET:
break;
@@ -895,34 +896,41 @@ single_set_1 (insn)
for (i = XVECLEN (pat, 0) - 1; i > 1; i--)
if (GET_CODE (XVECEXP (pat, 0, i)) != USE
&& GET_CODE (XVECEXP (pat, 0, i)) != CLOBBER)
- abort();
+ fatal_insn ("USE or CLOBBER before SET:", insn);
#endif
return set;
case SET:
- /* Multiple set insns - we are off the critical path now. */
- for (i = XVECLEN (pat, 0) - 1; i > 0; i--)
- {
- sub = XVECEXP (pat, 0, i);
- switch GET_CODE (sub)
- {
- case USE:
- case CLOBBER:
- break;
-
- case SET:
- if (!set
- || (find_reg_note (insn, REG_UNUSED, SET_DEST (set))
- && side_effects_p (set)))
- set = sub;
- else if (! find_reg_note (insn, REG_UNUSED, SET_DEST (sub))
- || side_effects_p (sub))
- return NULL_RTX;
- break;
+ {
+ int seen_clobber = 0;
- default:
- return NULL_RTX;
- }
- }
+ /* Multiple set insns - we are off the critical path now. */
+ for (i = 1; i < XVECLEN (pat, 0); i++)
+ {
+ sub = XVECEXP (pat, 0, i);
+ switch GET_CODE (sub)
+ {
+ case USE:
+ case CLOBBER:
+ seen_clobber = 1;
+ break;
+
+ case SET:
+ if (seen_clobber)
+ fatal_insn ("USE or CLOBBER before SET:", insn);
+ if (!set
+ || (find_reg_note (insn, REG_UNUSED, SET_DEST (set))
+ && side_effects_p (set)))
+ set = sub;
+ else if (! find_reg_note (insn, REG_UNUSED, SET_DEST (sub))
+ || side_effects_p (sub))
+ return NULL_RTX;
+ break;
+
+ default:
+ return NULL_RTX;
+ }
+ }
+ }
return set;
default:
return NULL_RTX;
OpenPOWER on IntegriCloud