diff options
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/ia64/ia64.c | 15 | ||||
-rw-r--r-- | gcc/config/ia64/ia64.md | 31 |
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; |