From: rearnsha Date: Fri, 18 Oct 2019 19:01:57 +0000 (+0000) Subject: [arm] Early split zero- and sign-extension X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2e55c7de734c532d4ff53c4b8c25883ab640cf1d;p=thirdparty%2Fgcc.git [arm] Early split zero- and sign-extension This patch changes the insn patterns for zero- and sign-extend into define_expands that generate the appropriate word operations immediately. * config/arm/arm.md (zero_extenddi2): Convert to define_expand. (extenddi2): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@277166 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a4acdccc770f..7935f1f54415 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-10-18 Richard Earnshaw + + * config/arm/arm.md (zero_extenddi2): Convert to define_expand. + (extenddi2): Likewise. + 2019-10-18 Richard Earnshaw * config/arm/arm-protos.h (arm_decompose_di_binop): New prototype. diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 5ba42a13430b..4a7a64e66133 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -4196,31 +4196,64 @@ ;; Zero and sign extension instructions. -(define_insn "zero_extenddi2" - [(set (match_operand:DI 0 "s_register_operand" "=r,?r") - (zero_extend:DI (match_operand:QHSI 1 "" - "")))] +(define_expand "zero_extenddi2" + [(set (match_operand:DI 0 "s_register_operand" "") + (zero_extend:DI (match_operand:QHSI 1 "" "")))] "TARGET_32BIT " - "#" - [(set_attr "length" "4,8") - (set_attr "arch" "*,*") - (set_attr "ce_count" "2") - (set_attr "predicable" "yes") - (set_attr "type" "mov_reg,multiple")] + { + rtx res_lo, res_hi, op0_lo, op0_hi; + res_lo = gen_lowpart (SImode, operands[0]); + res_hi = gen_highpart (SImode, operands[0]); + if (can_create_pseudo_p ()) + { + op0_lo = mode == SImode ? operands[1] : gen_reg_rtx (SImode); + op0_hi = gen_reg_rtx (SImode); + } + else + { + op0_lo = mode == SImode ? operands[1] : res_lo; + op0_hi = res_hi; + } + if (mode != SImode) + emit_insn (gen_rtx_SET (op0_lo, + gen_rtx_ZERO_EXTEND (SImode, operands[1]))); + emit_insn (gen_movsi (op0_hi, const0_rtx)); + if (res_lo != op0_lo) + emit_move_insn (res_lo, op0_lo); + if (res_hi != op0_hi) + emit_move_insn (res_hi, op0_hi); + DONE; + } ) -(define_insn "extenddi2" - [(set (match_operand:DI 0 "s_register_operand" "=r,?r,?r") - (sign_extend:DI (match_operand:QHSI 1 "" - "")))] +(define_expand "extenddi2" + [(set (match_operand:DI 0 "s_register_operand" "") + (sign_extend:DI (match_operand:QHSI 1 "" "")))] "TARGET_32BIT " - "#" - [(set_attr "length" "4,8,8") - (set_attr "ce_count" "2") - (set_attr "shift" "1") - (set_attr "predicable" "yes") - (set_attr "arch" "*,a,t") - (set_attr "type" "mov_reg,multiple,multiple")] + { + rtx res_lo, res_hi, op0_lo, op0_hi; + res_lo = gen_lowpart (SImode, operands[0]); + res_hi = gen_highpart (SImode, operands[0]); + if (can_create_pseudo_p ()) + { + op0_lo = mode == SImode ? operands[1] : gen_reg_rtx (SImode); + op0_hi = gen_reg_rtx (SImode); + } + else + { + op0_lo = mode == SImode ? operands[1] : res_lo; + op0_hi = res_hi; + } + if (mode != SImode) + emit_insn (gen_rtx_SET (op0_lo, + gen_rtx_SIGN_EXTEND (SImode, operands[1]))); + emit_insn (gen_ashrsi3 (op0_hi, op0_lo, GEN_INT (31))); + if (res_lo != op0_lo) + emit_move_insn (res_lo, op0_lo); + if (res_hi != op0_hi) + emit_move_insn (res_hi, op0_hi); + DONE; + } ) ;; Splits for all extensions to DImode