diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 749e21da0a3..5cf30867886 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2004-11-05 Richard Henderson + + * ia64.md (UNSPEC_SHRP): New. + (dshift_count_operand): New. + (ashrti3, ashrti3_internal, lshrti3, lshrti3_internal, shrp): New. + * ia64.c (rtx_needs_barrier): Handle UNSPEC_SHRP. + 2004-11-05 Joseph S. Myers * c-typeck.c (output_init_element): Return early if value is diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index 5f8dcaa5afd..0b65686512c 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -4899,6 +4899,7 @@ rtx_needs_barrier (rtx x, struct reg_flags flags, int pred) break; case UNSPEC_FR_RECIP_APPROX: + case UNSPEC_SHRP: need_barrier = rtx_needs_barrier (XVECEXP (x, 0, 0), flags, pred); need_barrier |= rtx_needs_barrier (XVECEXP (x, 0, 1), flags, pred); break; diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md index 31f14bb1765..4a01ba4d904 100644 --- a/gcc/config/ia64/ia64.md +++ b/gcc/config/ia64/ia64.md @@ -77,6 +77,7 @@ (UNSPEC_RET_ADDR 26) (UNSPEC_SETF_EXP 27) (UNSPEC_FR_SQRT_RECIP_APPROX 28) + (UNSPEC_SHRP 29) ]) (define_constants @@ -335,6 +336,11 @@ (and (match_code "const_int") (match_test "CONST_OK_FOR_J (INTVAL (op))")))) +;; True if OP is a 7 bit immediate operand. +(define_predicate "dshift_count_operand" + (and (match_code "const_int") + (match_test "INTVAL (op) >= 0 && INTVAL (op) < 128"))) + ;; True if OP is a 6 bit immediate operand. (define_predicate "shift_count_operand" (and (match_code "const_int") @@ -4654,6 +4660,96 @@ ;; :::::::::::::::::::: ;; :: +;; :: 128 bit Integer Shifts and Rotates +;; :: +;; :::::::::::::::::::: + +(define_expand "ashrti3" + [(set (match_operand:TI 0 "gr_register_operand" "") + (ashiftrt:TI (match_operand:TI 1 "gr_register_operand" "") + (match_operand:DI 2 "nonmemory_operand" "")))] + "" +{ + if (!dshift_count_operand (operands[2], DImode)) + FAIL; +}) + +(define_insn_and_split "*ashrti3_internal" + [(set (match_operand:TI 0 "gr_register_operand" "=r") + (ashiftrt:TI (match_operand:TI 1 "gr_register_operand" "r") + (match_operand:DI 2 "dshift_count_operand" "n")))] + "" + "#" + "reload_completed" + [(const_int 0)] +{ + HOST_WIDE_INT shift = INTVAL (operands[2]); + rtx lo = gen_lowpart (DImode, operands[1]); + rtx hi = gen_highpart (DImode, operands[1]); + rtx shiftlo = GEN_INT (shift & 63); + + if (shift & 64) + { + emit_insn (gen_ashrdi3 (lo, hi, shiftlo)); + emit_insn (gen_ashrdi3 (hi, hi, GEN_INT (63))); + } + else + { + emit_insn (gen_shrp (lo, hi, lo, shiftlo)); + emit_insn (gen_ashrdi3 (hi, hi, shiftlo)); + } + DONE; +}) + +(define_expand "lshrti3" + [(set (match_operand:TI 0 "gr_register_operand" "") + (lshiftrt:TI (match_operand:TI 1 "gr_register_operand" "") + (match_operand:DI 2 "nonmemory_operand" "")))] + "" +{ + if (!dshift_count_operand (operands[2], DImode)) + FAIL; +}) + +(define_insn_and_split "*lshrti3_internal" + [(set (match_operand:TI 0 "gr_register_operand" "=r") + (lshiftrt:TI (match_operand:TI 1 "gr_register_operand" "r") + (match_operand:DI 2 "dshift_count_operand" "n")))] + "" + "#" + "reload_completed" + [(const_int 0)] +{ + HOST_WIDE_INT shift = INTVAL (operands[2]); + rtx lo = gen_lowpart (DImode, operands[1]); + rtx hi = gen_highpart (DImode, operands[1]); + rtx shiftlo = GEN_INT (shift & 63); + + if (shift & 64) + { + emit_insn (gen_lshrdi3 (lo, hi, shiftlo)); + emit_move_insn (hi, const0_rtx); + } + else + { + emit_insn (gen_shrp (lo, hi, lo, shiftlo)); + emit_insn (gen_lshrdi3 (hi, hi, shiftlo)); + } + DONE; +}) + +(define_insn "shrp" + [(set (match_operand:DI 0 "gr_register_operand" "=r") + (unspec:DI [(match_operand:DI 1 "gr_register_operand" "r") + (match_operand:DI 2 "gr_register_operand" "r") + (match_operand:DI 3 "shift_count_operand" "M")] + UNSPEC_SHRP))] + "" + "shrp %0 = %1, %2, %3" + [(set_attr "itanium_class" "ishf")]) + +;; :::::::::::::::::::: +;; :: ;; :: 32 bit Integer Logical operations ;; :: ;; ::::::::::::::::::::