From 60d616b1f6deffcc57a4114f1a31559a17a3923c Mon Sep 17 00:00:00 2001 From: Mihail Ionescu Date: Fri, 17 Jan 2020 17:56:41 +0000 Subject: [PATCH] [GCC/ARM, 1/2] Add support for ASRL(reg) and LSLL(reg) instructions for Armv8.1-M Mainline This patch is adding the following instructions: ASRL (reg) LSLL (reg) *** gcc/ChangeLog *** 2020-01-17 Mihail-Calin Ionescu Sudakshina Das * config/arm/arm.md (ashldi3): Generate thumb2_lsll for TARGET_HAVE_MVE. (ashrdi3): Generate thumb2_asrl for TARGET_HAVE_MVE. * config/arm/arm.c (arm_hard_regno_mode_ok): Allocate even odd register pairs for doubleword quantities for ARMv8.1M-Mainline. * config/arm/thumb2.md (thumb2_asrl): New. (thumb2_lsll): Likewise. 2020-01-17 Mihail-Calin Ionescu Sudakshina Das * gcc.target/arm/armv8_1m-shift-reg_1.c: New test. --- gcc/ChangeLog | 10 +++++++ gcc/config/arm/arm.c | 8 +++--- gcc/config/arm/arm.md | 26 +++++++++++++++++++ gcc/config/arm/thumb2.md | 16 ++++++++++++ gcc/testsuite/ChangeLog | 5 ++++ .../gcc.target/arm/armv8_1m-shift-reg-1.c | 20 ++++++++++++++ 6 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.target/arm/armv8_1m-shift-reg-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4efbba67d89..2dadf5891e7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2020-01-17 Mihail-Calin Ionescu + Sudakshina Das + + * config/arm/arm.md (ashldi3): Generate thumb2_lsll for TARGET_HAVE_MVE. + (ashrdi3): Generate thumb2_asrl for TARGET_HAVE_MVE. + * config/arm/arm.c (arm_hard_regno_mode_ok): Allocate even odd + register pairs for doubleword quantities for ARMv8.1M-Mainline. + * config/arm/thumb2.md (thumb2_asrl): New. + (thumb2_lsll): Likewise. + 2020-01-17 Jakub Jelinek * config/arm/arm.c (cmse_nonsecure_call_inline_register_clear): Remove diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 57099cbc7fa..6ead410d1a8 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -24906,14 +24906,16 @@ arm_hard_regno_mode_ok (unsigned int regno, machine_mode mode) /* We allow almost any value to be stored in the general registers. Restrict doubleword quantities to even register pairs in ARM state - so that we can use ldrd. Do not allow very large Neon structure - opaque modes in general registers; they would use too many. */ + so that we can use ldrd. The same restriction applies for MVE + in order to support Armv8.1-M Mainline instructions. + Do not allow very large Neon structure opaque modes in general + registers; they would use too many. */ if (regno <= LAST_ARM_REGNUM) { if (ARM_NUM_REGS (mode) > 4) return false; - if (TARGET_THUMB2) + if (TARGET_THUMB2 && !TARGET_HAVE_MVE) return true; return !(TARGET_LDRD && GET_MODE_SIZE (mode) > 4 && (regno & 1) != 0); diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 528d134a751..315b04c4434 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -4399,6 +4399,22 @@ (match_operand:SI 2 "reg_or_int_operand")))] "TARGET_32BIT" " + if (TARGET_HAVE_MVE) + { + if (!reg_or_int_operand (operands[2], SImode)) + operands[2] = force_reg (SImode, operands[2]); + + /* Armv8.1-M Mainline double shifts are not expanded. */ + if (REG_P (operands[2])) + { + if (!reg_overlap_mentioned_p(operands[0], operands[1])) + emit_insn (gen_movdi (operands[0], operands[1])); + + emit_insn (gen_thumb2_lsll (operands[0], operands[2])); + DONE; + } + } + arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1], operands[2], gen_reg_rtx (SImode), gen_reg_rtx (SImode)); @@ -4426,6 +4442,16 @@ (match_operand:SI 2 "reg_or_int_operand")))] "TARGET_32BIT" " + /* Armv8.1-M Mainline double shifts are not expanded. */ + if (TARGET_HAVE_MVE && REG_P (operands[2])) + { + if (!reg_overlap_mentioned_p(operands[0], operands[1])) + emit_insn (gen_movdi (operands[0], operands[1])); + + emit_insn (gen_thumb2_asrl (operands[0], operands[2])); + DONE; + } + arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1], operands[2], gen_reg_rtx (SImode), gen_reg_rtx (SImode)); diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md index 3ca49112635..a5986de4859 100644 --- a/gcc/config/arm/thumb2.md +++ b/gcc/config/arm/thumb2.md @@ -1626,3 +1626,19 @@ } [(set_attr "predicable" "yes")] ) + +(define_insn "thumb2_asrl" + [(set (match_operand:DI 0 "arm_general_register_operand" "+r") + (ashiftrt:DI (match_dup 0) + (match_operand:SI 1 "arm_general_register_operand" "r")))] + "TARGET_HAVE_MVE" + "asrl%?\\t%Q0, %R0, %1" + [(set_attr "predicable" "yes")]) + +(define_insn "thumb2_lsll" + [(set (match_operand:DI 0 "arm_general_register_operand" "+r") + (ashift:DI (match_dup 0) + (match_operand:SI 1 "arm_general_register_operand" "r")))] + "TARGET_HAVE_MVE" + "lsll%?\\t%Q0, %R0, %1" + [(set_attr "predicable" "yes")]) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f7edad9a64c..9de42e4de42 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-01-17 Mihail-Calin Ionescu + Sudakshina Das + + * gcc.target/arm/armv8_1m-shift-reg_1.c: New test. + 2020-01-17 Jonathan Wakely PR testsuite/93227 diff --git a/gcc/testsuite/gcc.target/arm/armv8_1m-shift-reg-1.c b/gcc/testsuite/gcc.target/arm/armv8_1m-shift-reg-1.c new file mode 100644 index 00000000000..a97e9d687ef --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/armv8_1m-shift-reg-1.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=armv8.1-m.main+mve -mfloat-abi=softfp" } */ + +long long longval2; +int intval2; + +long long int +asrl_reg () +{ + return (longval2 >> intval2); +} + +long long unsigned int +lsll_reg (long long unsigned longval1, int intval1) +{ + return (longval1 << intval1); +} + +/* { dg-final { scan-assembler "asrl\\tr\[0-9\], r\[0-9\], r\[0-9\]" } } */ +/* { dg-final { scan-assembler "lsll\\tr\[0-9\], r\[0-9\], r\[0-9\]" } } */ -- 2.30.2