diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 663db73..8a6928f 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -14833,6 +14833,31 @@ [(const_int 0)] "ix86_split_ (operands, operands[3], mode); DONE;") +;; Split truncations of TImode right shifts into x86_64_shrd_1. +;; Split truncations of DImode right shifts into x86_shrd_1. +(define_insn_and_split "3_doubleword_lowpart" + [(set (match_operand:DWIH 0 "register_operand" "=&r") + (subreg:DWIH + (any_shiftrt: (match_operand: 1 "register_operand" "r") + (match_operand:QI 2 "const_int_operand")) 0)) + (clobber (reg:CC FLAGS_REG))] + "UINTVAL (operands[2]) < * BITS_PER_UNIT" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 0) + (ior:DWIH (lshiftrt:DWIH (match_dup 0) (match_dup 2)) + (subreg:DWIH + (ashift: (zero_extend: (match_dup 3)) + (match_dup 4)) 0))) + (clobber (reg:CC FLAGS_REG))])] +{ + split_double_mode (mode, &operands[1], 1, &operands[1], &operands[3]); + operands[4] = GEN_INT (( * BITS_PER_UNIT) - INTVAL (operands[2])); + if (!rtx_equal_p (operands[0], operands[3])) + emit_move_insn (operands[0], operands[3]); +}) + (define_insn "x86_64_shrd" [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") (ior:DI (lshiftrt:DI (match_dup 0)