This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] MIPS: add mips32r2 patterns to generate ext and ins insns.
- From: David Ung <davidu at mips dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 23 May 2005 18:14:51 +0100
- Subject: [patch] MIPS: add mips32r2 patterns to generate ext and ins insns.
hi,
This patch adds patterns for generating the mips32 release 2 ext/inv
insn to mips.md.
ok to commit??
David.
2005-05-23 David Ung <davidu@mips.com>
* config/mips/mips.md (extzv): Changed predicate for operand to
nonimmediate_operand. Add code to generate insn patterns for
extzvsi and extzvdi.
(extzvsi, extzvdi): New patterns to match mips32r2 ext insn.
(insv): Similarly for insertion.
(insvsi, insvdi): Similarly.
Index: gcc/config/mips/mips.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.md,v
retrieving revision 1.319
diff -c -p -b -r1.319 mips.md
*** gcc/config/mips/mips.md 13 May 2005 15:24:35 -0000 1.319
--- gcc/config/mips/mips.md 23 May 2005 17:08:46 -0000
*************** beq\t%2,%.,1b\;\
*** 2818,2824 ****
(define_expand "extzv"
[(set (match_operand 0 "register_operand")
! (zero_extract (match_operand:QI 1 "memory_operand")
(match_operand 2 "immediate_operand")
(match_operand 3 "immediate_operand")))]
"!TARGET_MIPS16"
--- 2818,2824 ----
(define_expand "extzv"
[(set (match_operand 0 "register_operand")
! (zero_extract (match_operand 1 "nonimmediate_operand")
(match_operand 2 "immediate_operand")
(match_operand 3 "immediate_operand")))]
"!TARGET_MIPS16"
*************** beq\t%2,%.,1b\;\
*** 2827,2838 ****
INTVAL (operands[2]),
INTVAL (operands[3])))
DONE;
else
FAIL;
})
(define_expand "insv"
! [(set (zero_extract (match_operand:QI 0 "memory_operand")
(match_operand 1 "immediate_operand")
(match_operand 2 "immediate_operand"))
(match_operand 3 "reg_or_0_operand"))]
--- 2827,2888 ----
INTVAL (operands[2]),
INTVAL (operands[3])))
DONE;
+ else if (!ISA_MIPS32R2
+ || !register_operand (operands[1], VOIDmode))
+ FAIL;
else
+ {
+ /* MIPS ins/ext insns don't support zero length bitfields or fields
+ extending beyond the left or right-most bits. Also, we reject
+ lengths equal to a word as they are better handled by the move
+ patterns. */
+
+ HOST_WIDE_INT len = INTVAL (operands[2]);
+ HOST_WIDE_INT pos = INTVAL (operands[3]);
+
+ if (len <= 0 || len >= BITS_PER_WORD || pos < 0
+ || pos + len > BITS_PER_WORD)
FAIL;
+
+ if (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
+ emit_insn (gen_extzvdi (operands[0], operands[1], operands[2],
+ operands[3]));
+ else
+ emit_insn (gen_extzvsi (operands[0], operands[1], operands[2],
+ operands[3]));
+
+ DONE;
+ }
})
+ (define_insn "extzvsi"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
+ (match_operand:SI 2 "immediate_operand" "I")
+ (match_operand:SI 3 "immediate_operand" "I")))]
+ "ISA_MIPS32R2 && !TARGET_MIPS16"
+ "*
+ {
+ operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
+ operands[3] = GEN_INT (INTVAL (operands[3]) & 31);
+ return \"ext\\t%0,%1,%3,%2\";
+ }")
+
+ (define_insn "extzvdi"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (zero_extract:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand:SI 2 "immediate_operand" "I")
+ (match_operand:SI 3 "immediate_operand" "I")))]
+ "ISA_MIPS32R2 && TARGET_64BIT && !TARGET_MIPS16"
+ "*
+ {
+ operands[2] = GEN_INT (INTVAL (operands[2]) & 63);
+ operands[3] = GEN_INT (INTVAL (operands[3]) & 63);
+ return \"dext\\t%0,%1,%3,%2\";
+ }")
+
(define_expand "insv"
! [(set (zero_extract (match_operand 0 "nonimmediate_operand")
(match_operand 1 "immediate_operand")
(match_operand 2 "immediate_operand"))
(match_operand 3 "reg_or_0_operand"))]
*************** beq\t%2,%.,1b\;\
*** 2842,2851 ****
--- 2892,2951 ----
INTVAL (operands[1]),
INTVAL (operands[2])))
DONE;
+ else if (!ISA_MIPS32R2
+ || !register_operand (operands[1], VOIDmode))
+ FAIL;
else
+ {
+ /* MIPS ins/ext insns don't support zero length bitfields or fields
+ extending beyond the left or right-most bits. Also, we reject
+ lengths equal to a word as they are better handled by the move
+ patterns. */
+
+ HOST_WIDE_INT len = INTVAL (operands[1]);
+ HOST_WIDE_INT pos = INTVAL (operands[2]);
+
+ if (len <= 0 || len >= BITS_PER_WORD || pos < 0
+ || pos + len > BITS_PER_WORD)
FAIL;
+
+ if (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
+ emit_insn (gen_insvdi (operands[0], operands[1], operands[2],
+ operands[3]));
+ else
+ emit_insn (gen_insvsi (operands[0], operands[1], operands[2],
+ operands[3]));
+
+ DONE;
+ }
})
+ (define_insn "insvsi"
+ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
+ (match_operand:SI 1 "immediate_operand" "I")
+ (match_operand:SI 2 "immediate_operand" "I"))
+ (match_operand:SI 3 "reg_or_0_operand" "dJ"))]
+ "ISA_MIPS32R2 && !TARGET_MIPS16"
+ "*
+ {
+ operands[1] = GEN_INT (INTVAL (operands[1]) & 31);
+ operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
+ return \"ins\\t%0,%z3,%2,%1\";
+ }")
+
+ (define_insn "insvdi"
+ [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "d")
+ (match_operand:SI 1 "immediate_operand" "I")
+ (match_operand:SI 2 "immediate_operand" "I"))
+ (match_operand:DI 3 "reg_or_0_operand" "dJ"))]
+ "ISA_MIPS32R2 && TARGET_64BIT && !TARGET_MIPS16"
+ "*
+ {
+ operands[1] = GEN_INT (INTVAL (operands[1]) & 63);
+ operands[2] = GEN_INT (INTVAL (operands[2]) & 63);
+ return \"dins\\t%0,%z3,%2,%1\";
+ }")
+
;; Unaligned word moves generated by the bit field patterns.
;;
;; As far as the rtl is concerned, both the left-part and right-part