From cfed471a5612a925d55dae4085aa10d230bf4494 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Fri, 22 Feb 2019 09:38:43 -0700 Subject: [PATCH] re PR rtl-optimization/87761 ([MIPS] New FAIL: gcc.target/mips/fix-r4000-10.c -O1 start with r265398) PR rtl-optimization/87761 * config/mips/mips.md: Add new combiner pattern to recognize a bitfield extraction using (ashiftrt (truncate (ashift (...)))). From-SVN: r269123 --- gcc/ChangeLog | 6 ++++++ gcc/config/mips/mips.md | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8b283d5014b..64dcda2560f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-02-22 Jeff Law + + PR rtl-optimization/87761 + * config/mips/mips.md: Add new combiner pattern to recognize + a bitfield extraction using (ashiftrt (truncate (ashift (...)))). + 2019-02-22 Matthew Malcomson PR target/89324 diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 25e0df218be..2ae1f7e0440 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -3502,6 +3502,47 @@ "exts\t%0,%1,%2,31" [(set_attr "type" "arith") (set_attr "mode" "")]) + +;; This could likely be generalized for any SUBDI mode, and any right +;; shift, but AFAICT this is used so rarely it is not worth the additional +;; complexity. +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=d") + (ashiftrt:SI + (truncate:SI + (ashift:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "const_arith_operand" ""))) + (match_operand:DI 3 "const_arith_operand" "")))] + "(ISA_HAS_EXTS && TARGET_64BIT + && UINTVAL (operands[2]) < 32 && UINTVAL (operands[3]) < 32 + && UINTVAL (operands[3]) >= UINTVAL (operands[2]))" + { + rtx xoperands[4]; + xoperands[0] = operands[0]; + xoperands[1] = operands[1]; + + /* The length of the field is the size of the outer mode less the outer + shift constant. We fix the outer mode as SImode for simplicity. */ + unsigned int right_shift = INTVAL (operands[3]); + xoperands[3] = GEN_INT (32 - right_shift); + + /* The field starts at the outer shift constant less the inner shift + constant. */ + unsigned int left_shift = INTVAL (operands[2]); + xoperands[2] = GEN_INT (right_shift - left_shift); + + /* Sanity checks. These constraints are taken from the MIPS ISA + manual. */ + gcc_assert (INTVAL (xoperands[2]) >= 0 && INTVAL (xoperands[2]) < 32); + gcc_assert (INTVAL (xoperands[3]) > 0 && INTVAL (xoperands[3]) <= 32); + gcc_assert (INTVAL (xoperands[2]) + INTVAL (xoperands[3]) > 0 + && INTVAL (xoperands[2]) + INTVAL (xoperands[3]) <= 32); + + output_asm_insn ("exts\t%0,%1,%2,%m3", xoperands); + return ""; + } + [(set_attr "type" "arith") + (set_attr "mode" "SI")]) ;; ;; .................... -- 2.30.2