aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Earnshaw <rearnsha@arm.com>2019-10-18 19:01:57 +0000
committerRichard Earnshaw <rearnsha@gcc.gnu.org>2019-10-18 19:01:57 +0000
commit0250355849a16456a8b8e6dce2d2d7874696649e (patch)
tree9ef36497b857c198fccf6e6b3ea8d61b519b599c
parent0406dccda5c9adfaf65e132fda5b8c0fbc5ce1d5 (diff)
downloadgcc-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/ChangeLog5
-rw-r--r--gcc/config/arm/arm.md75
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