This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch] MIPS: add mips32r2 patterns to generate ext and insinsns.
ok.. here is the latest patch. :)
I will add a test case in a seperate patch.
David.
2005-05-25 David Ung <davidu@mips.com>
* config/mips/mips.c (mips_use_ins_ext_p): New helper function
that determines whether the MIPS32/64 R2 ext/ins should be used.
* config/mips/mips.h (ISA_HAS_EXT_INS): New macro.
* config/mips/mips.md (extzv): Changed predicate for operand to
nonimmediate_operand. Add code to generate insn patterns for
extzvsi and extzvdi.
(extzv<mode>): New pattern to match mips32r2 ext insn.
(insv): Similarly for insertion.
(insvs<mode>): Similarly.
Index: gcc/config/mips/mips.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.c,v
retrieving revision 1.503
diff -c -p -b -r1.503 mips.c
*** gcc/config/mips/mips.c 13 May 2005 15:24:29 -0000 1.503
--- gcc/config/mips/mips.c 25 May 2005 18:06:07 -0000
*************** mips_expand_unaligned_store (rtx dest, r
*** 4165,4170 ****
--- 4165,4198 ----
return true;
}
+ /* Return true if we can use the MIPS32/64 R2 ext/ins instructions.
+ Return false if OP is not in a register, zero/invalid length bitfields
+ or lengths equal to word size. */
+
+ bool
+ mips_use_ins_ext_p (rtx op, rtx l, rtx p)
+ {
+ HOST_WIDE_INT len, pos;
+
+ if (!ISA_HAS_EXT_INS
+ || !register_operand (op, VOIDmode))
+ return false;
+
+ /* 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. */
+
+ len = INTVAL (l);
+ pos = INTVAL (p);
+
+ if (len <= 0 || len >= BITS_PER_WORD || pos < 0
+ || pos + len > BITS_PER_WORD)
+ return false;
+
+ return true;
+ }
+
/* Set up globals to generate code for the ISA or processor
described by INFO. */
Index: gcc/config/mips/mips.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.h,v
retrieving revision 1.393
diff -c -p -b -r1.393 mips.h
*** gcc/config/mips/mips.h 13 May 2005 15:24:34 -0000 1.393
--- gcc/config/mips/mips.h 25 May 2005 18:07:41 -0000
*************** extern const struct mips_cpu_info *mips_
*** 671,676 ****
--- 671,681 ----
&& (ISA_MIPS32R2 \
))
+ /* ISA includes the MIPS32/64 rev 2 ext and ins instructions. */
+ #define ISA_HAS_EXT_INS (!TARGET_MIPS16 \
+ && (ISA_MIPS32R2 \
+ ))
+
/* True if the result of a load is not available to the next instruction.
A nop will then be needed between instructions like "lw $4,..."
and "addiu $4,$4,1". */
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 25 May 2005 18:08:07 -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,2859 ----
INTVAL (operands[2]),
INTVAL (operands[3])))
DONE;
! else if (!mips_use_ins_ext_p(operands[1], operands[2], operands[3]))
FAIL;
+ else
+ {
+ 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 "extzv<mode>"
+ [(set (match_operand:GPR 0 "register_operand" "=d")
+ (zero_extract:GPR (match_operand:GPR 1 "register_operand" "d")
+ (match_operand:SI 2 "immediate_operand" "I")
+ (match_operand:SI 3 "immediate_operand" "I")))]
+ "ISA_HAS_EXT_INS"
+ "<d>ext\t%0,%1,%3,%2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "<MODE>")])
+
+
(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 ****
INTVAL (operands[1]),
INTVAL (operands[2])))
DONE;
! else
FAIL;
})
;; Unaligned word moves generated by the bit field patterns.
;;
;; As far as the rtl is concerned, both the left-part and right-part
--- 2863,2892 ----
INTVAL (operands[1]),
INTVAL (operands[2])))
DONE;
! else if (!mips_use_ins_ext_p(operands[0], operands[1], operands[2]))
FAIL;
+ else
+ {
+ 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 "insv<mode>"
+ [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand" "+d")
+ (match_operand:SI 1 "immediate_operand" "I")
+ (match_operand:SI 2 "immediate_operand" "I"))
+ (match_operand:GPR 3 "reg_or_0_operand" "dJ"))]
+ "ISA_HAS_EXT_INS"
+ "<d>ins\t%0,%z3,%2,%1"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "<MODE>")])
+
;; Unaligned word moves generated by the bit field patterns.
;;
;; As far as the rtl is concerned, both the left-part and right-part