aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/ia64/ia64.c15
-rw-r--r--gcc/config/ia64/ia64.md31
3 files changed, 48 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3a3bc0a..d5467b5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2000-08-20 Richard Henderson <rth@cygnus.com>
+
+ * config/ia64/ia64.c (emit_insn_group_barriers): Stop if ar.lc
+ assigned before a loop.
+
+ * config/ia64/ia64.md (ashlsi3): Zero extend the shift count.
+ (ashrsi3, lshrsi3): Likewise.
+
2000-08-20 Gabriel Dos Reis <gdr@codesourcery.com>
* c-lang.c: #include diagnostic.h
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index 3088a82..f0ad8ba4 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -3934,6 +3934,21 @@ emit_insn_group_barriers (insns)
switch (GET_CODE (insn))
{
case NOTE:
+ /* For very small loops we can wind up with extra stop bits
+ inside the loop because of not putting a stop after the
+ assignment to ar.lc before the loop label. */
+ /* ??? Ideally we'd do this for any register used in the first
+ insn group that's been written recently. */
+ if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
+ {
+ need_barrier = rws_access_regno (AR_LC_REGNUM, flags, 0);
+ if (need_barrier)
+ {
+ emit_insn_after (gen_insn_group_barrier (), insn);
+ memset (rws_sum, 0, sizeof(rws_sum));
+ prev_insn = NULL_RTX;
+ }
+ }
break;
case CALL_INSN:
diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md
index e0173e6..3afddea 100644
--- a/gcc/config/ia64/ia64.md
+++ b/gcc/config/ia64/ia64.md
@@ -2012,10 +2012,27 @@
;; ::
;; ::::::::::::::::::::
-(define_insn "ashlsi3"
+(define_expand "ashlsi3"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (ashift:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "reg_or_5bit_operand" "")))]
+ ""
+ "
+{
+ if (GET_CODE (operands[2]) != CONST_INT)
+ {
+ /* Why oh why didn't Intel arrange for SHIFT_COUNT_TRUNCATED? Now
+ we've got to get rid of stray bits outside the SImode register. */
+ rtx subshift = gen_reg_rtx (DImode);
+ emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
+ operands[2] = subshift;
+ }
+}")
+
+(define_insn "*ashlsi3_internal"
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
(ashift:SI (match_operand:SI 1 "register_operand" "r,r,r")
- (match_operand:SI 2 "reg_or_5bit_operand" "R,n,r")))]
+ (match_operand:DI 2 "reg_or_5bit_operand" "R,n,r")))]
""
"@
shladd %0 = %1, %2, r0
@@ -2036,9 +2053,10 @@
GEN_INT (32 - INTVAL (operands[2])), operands[2]));
else
{
+ rtx subshift = gen_reg_rtx (DImode);
emit_insn (gen_extendsidi2 (subtarget, operands[1]));
- emit_insn (gen_ashrdi3 (subtarget, subtarget,
- gen_lowpart (DImode, operands[2])));
+ emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
+ emit_insn (gen_ashrdi3 (subtarget, subtarget, subshift));
}
emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
DONE;
@@ -2057,9 +2075,10 @@
GEN_INT (32 - INTVAL (operands[2])), operands[2]));
else
{
+ rtx subshift = gen_reg_rtx (DImode);
emit_insn (gen_zero_extendsidi2 (subtarget, operands[1]));
- emit_insn (gen_lshrdi3 (subtarget, subtarget,
- gen_lowpart (DImode, operands[2])));
+ emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
+ emit_insn (gen_lshrdi3 (subtarget, subtarget, subshift));
}
emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
DONE;