This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch] MIPS: add mips32r2 patterns to generate ext and insinsns.


latest patch.  hopefully it will be the last.  :)
tested with mips-sim-idt32 with -march=mips32r2 flag.

David.

2005-05-26  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.

2005-05-26  David Ung  <davidu@mips.com>

	* gcc.target/mips/ext_ins.c: New test for testing the generation
	MIPS32/64 rev 2 ext/ins instructions.

Index: gcc/config/mips/mips.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.c,v
retrieving revision 1.504
diff -c -p -b -r1.504 mips.c
*** gcc/config/mips/mips.c	26 May 2005 05:27:55 -0000	1.504
--- gcc/config/mips/mips.c	26 May 2005 13:23:00 -0000
*************** mips_expand_unaligned_store (rtx dest, r
*** 4159,4164 ****
--- 4159,4192 ----
    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.394
diff -c -p -b -r1.394 mips.h
*** gcc/config/mips/mips.h	26 May 2005 05:27:54 -0000	1.394
--- gcc/config/mips/mips.h	26 May 2005 13:23:30 -0000
*************** extern const struct mips_cpu_info *mips_
*** 670,675 ****
--- 670,680 ----
                                   && (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	26 May 2005 13:23:57 -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 (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")))]
+   "mips_use_ins_ext_p (operands[1], operands[2], operands[3])"
+   "<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 (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"))]
+   "mips_use_ins_ext_p (operands[0], operands[1], operands[2])"
+   "<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

Index: gcc.target/mips/ext_ins.c
===================================================================
RCS file: gcc.target/mips/ext_ins.c
diff -N gcc.target/mips/ext_ins.c
*** /dev/null   1 Jan 1970 00:00:00 -0000
--- gcc.target/mips/ext_ins.c   26 May 2005 13:29:36 -0000
***************
*** 0 ****
--- 1,25 ----
+ /* { dg-do compile } */
+ /* { dg-mips-options "-march=mips32r2" } */
+ /* { dg-final { scan-assembler "ext" } } */
+ /* { dg-final { scan-assembler "ins" } } */
+
+ struct A 
+ {
+   unsigned int i : 2;
+   unsigned int j : 3;
+   unsigned int k : 4;
+   unsigned int l : 5;
+ };
+
+ void func (struct A);
+
+ unsigned int ext (struct A a)
+ {
+   return a.j;
+ }
+
+ void ins (int i)
+ {
+   struct A c;
+   c.j = i;
+   func (c);
+ }



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]