From 0250355849a16456a8b8e6dce2d2d7874696649e Mon Sep 17 00:00:00 2001 From: Richard Earnshaw Date: Fri, 18 Oct 2019 19:01:57 +0000 Subject: [PATCH] [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. From-SVN: r277166 --- gcc/ChangeLog | 5 +++ gcc/config/arm/arm.md | 75 +++++++++++++++++++++++++++++++------------ 2 files changed, 59 insertions(+), 21 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a4acdccc770..7935f1f5441 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 5ba42a13430..4a7a64e6613 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