diff options
author | Richard Earnshaw <rearnsha@arm.com> | 2019-10-18 19:01:57 +0000 |
---|---|---|
committer | Richard Earnshaw <rearnsha@gcc.gnu.org> | 2019-10-18 19:01:57 +0000 |
commit | 0250355849a16456a8b8e6dce2d2d7874696649e (patch) | |
tree | 9ef36497b857c198fccf6e6b3ea8d61b519b599c | |
parent | 0406dccda5c9adfaf65e132fda5b8c0fbc5ce1d5 (diff) | |
download | gcc-0250355849a16456a8b8e6dce2d2d7874696649e.zip gcc-0250355849a16456a8b8e6dce2d2d7874696649e.tar.gz gcc-0250355849a16456a8b8e6dce2d2d7874696649e.tar.bz2 |
[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_extend<mode>di2): Convert to define_expand.
(extend<mode>di2): Likewise.
From-SVN: r277166
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/arm/arm.md | 75 |
2 files changed, 59 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a4acdcc..7935f1f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2019-10-18 Richard Earnshaw <rearnsha@arm.com> + * config/arm/arm.md (zero_extend<mode>di2): Convert to define_expand. + (extend<mode>di2): Likewise. + +2019-10-18 Richard Earnshaw <rearnsha@arm.com> + * config/arm/arm-protos.h (arm_decompose_di_binop): New prototype. * config/arm/arm.c (arm_decompose_di_binop): New function. * config/arm/arm.md (adddi3): Also accept any const_int for op2. diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 5ba42a1..4a7a64e 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_extend<mode>di2" - [(set (match_operand:DI 0 "s_register_operand" "=r,?r") - (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>" - "<qhs_zextenddi_cstr>")))] +(define_expand "zero_extend<mode>di2" + [(set (match_operand:DI 0 "s_register_operand" "") + (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>" "")))] "TARGET_32BIT <qhs_zextenddi_cond>" - "#" - [(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>mode == SImode ? operands[1] : gen_reg_rtx (SImode); + op0_hi = gen_reg_rtx (SImode); + } + else + { + op0_lo = <MODE>mode == SImode ? operands[1] : res_lo; + op0_hi = res_hi; + } + if (<MODE>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 "extend<mode>di2" - [(set (match_operand:DI 0 "s_register_operand" "=r,?r,?r") - (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>" - "<qhs_extenddi_cstr>")))] +(define_expand "extend<mode>di2" + [(set (match_operand:DI 0 "s_register_operand" "") + (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>" "")))] "TARGET_32BIT <qhs_sextenddi_cond>" - "#" - [(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>mode == SImode ? operands[1] : gen_reg_rtx (SImode); + op0_hi = gen_reg_rtx (SImode); + } + else + { + op0_lo = <MODE>mode == SImode ? operands[1] : res_lo; + op0_hi = res_hi; + } + if (<MODE>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 |