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]

insv, extv, extzv changes



FYI, I recently checked in this patch:

        * combine.c (make_extraction): If no mode is specified for
        an operand of insv, extv, or extzv, default it to word_mode.
        (simplify_comparison): Similarly.
        * expmed.c (store_bit_field): Similarly.
        (extract_bit_field): Similarly.
        * function.c (fixup_var_regs_1): Similarly.
        * recog.c (validate_replace_rtx_1): Similarly.
        * mips.md (extv, extzv, insv expanders): Default modes for most
        operands.  Handle TARGET_64BIT.
        (movdi_uld, movdi_usd): New patterns.
        * combine.c (make_extraction): If no mode is specified for
        an operand of insv, extv, or extzv, default it to word_mode.
        (simplify_comparison): Similarly.
        * expmed.c (store_bit_field): Similarly.
        (extract_bit_field): Similarly.
        * function.c (fixup_var_regs_1): Similarly.
        * recog.c (validate_replace_rtx_1): Similarly.
        * mips.md (extv, extzv, insv expanders): Default modes for most
        operands.  Handle TARGET_64BIT.
        (movdi_uld, movdi_usd): New patterns.

Index: combine.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/combine.c,v
retrieving revision 1.184
diff -c -3 -p -r1.184 combine.c
*** combine.c	1998/08/19 22:21:35	1.184
--- combine.c	1998/09/16 05:13:14
*************** make_extraction (mode, inner, pos, pos_r
*** 5723,5749 ****
  #ifdef HAVE_insv
    if (in_dest)
      {
!       wanted_inner_reg_mode = insn_operand_mode[(int) CODE_FOR_insv][0];
!       pos_mode = insn_operand_mode[(int) CODE_FOR_insv][2];
!       extraction_mode = insn_operand_mode[(int) CODE_FOR_insv][3];
      }
  #endif
  
  #ifdef HAVE_extzv
    if (! in_dest && unsignedp)
      {
!       wanted_inner_reg_mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
!       pos_mode = insn_operand_mode[(int) CODE_FOR_extzv][3];
!       extraction_mode = insn_operand_mode[(int) CODE_FOR_extzv][0];
      }
  #endif
  
  #ifdef HAVE_extv
    if (! in_dest && ! unsignedp)
      {
!       wanted_inner_reg_mode = insn_operand_mode[(int) CODE_FOR_extv][1];
!       pos_mode = insn_operand_mode[(int) CODE_FOR_extv][3];
!       extraction_mode = insn_operand_mode[(int) CODE_FOR_extv][0];
      }
  #endif
  
--- 5723,5767 ----
  #ifdef HAVE_insv
    if (in_dest)
      {
!       wanted_inner_reg_mode
! 	= (insn_operand_mode[(int) CODE_FOR_insv][0] == VOIDmode
! 	   ? word_mode
! 	   : insn_operand_mode[(int) CODE_FOR_insv][0]);
!       pos_mode = (insn_operand_mode[(int) CODE_FOR_insv][2] == VOIDmode
! 		  ? word_mode : insn_operand_mode[(int) CODE_FOR_insv][2]);
!       extraction_mode = (insn_operand_mode[(int) CODE_FOR_insv][3] == VOIDmode
! 			 ? word_mode
! 			 : insn_operand_mode[(int) CODE_FOR_insv][3]);
      }
  #endif
  
  #ifdef HAVE_extzv
    if (! in_dest && unsignedp)
      {
!       wanted_inner_reg_mode
! 	= (insn_operand_mode[(int) CODE_FOR_extzv][1] == VOIDmode
! 	   ? word_mode
! 	   : insn_operand_mode[(int) CODE_FOR_extzv][1]);
!       pos_mode = (insn_operand_mode[(int) CODE_FOR_extzv][3] == VOIDmode
! 		  ? word_mode : insn_operand_mode[(int) CODE_FOR_extzv][3]);
!       extraction_mode = (insn_operand_mode[(int) CODE_FOR_extzv][0] == VOIDmode
! 			 ? word_mode
! 			 : insn_operand_mode[(int) CODE_FOR_extzv][0]);
      }
  #endif
  
  #ifdef HAVE_extv
    if (! in_dest && ! unsignedp)
      {
!       wanted_inner_reg_mode
! 	= (insn_operand_mode[(int) CODE_FOR_extv][1] == VOIDmode
! 	   ? word_mode
! 	   : insn_operand_mode[(int) CODE_FOR_extv][1]);
!       pos_mode = (insn_operand_mode[(int) CODE_FOR_extv][3] == VOIDmode
! 		  ? word_mode : insn_operand_mode[(int) CODE_FOR_extv][3]);
!       extraction_mode = (insn_operand_mode[(int) CODE_FOR_extv][0] == VOIDmode
! 			 ? word_mode
! 			 : insn_operand_mode[(int) CODE_FOR_extv][0]);
      }
  #endif
  
*************** simplify_comparison (code, pop0, pop1)
*** 9880,9891 ****
  	      && (i = exact_log2 (INTVAL (XEXP (op0, 0)))) >= 0)
  	    {
  	      if (BITS_BIG_ENDIAN)
  #ifdef HAVE_extzv
! 		i = (GET_MODE_BITSIZE
! 		     (insn_operand_mode[(int) CODE_FOR_extzv][1]) - 1 - i);
  #else
! 	        i = BITS_PER_WORD - 1 - i;
  #endif
  
  	      op0 = XEXP (op0, 2);
  	      op1 = GEN_INT (i);
--- 9898,9913 ----
  	      && (i = exact_log2 (INTVAL (XEXP (op0, 0)))) >= 0)
  	    {
  	      if (BITS_BIG_ENDIAN)
+ 		{
  #ifdef HAVE_extzv
! 		  mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
! 		  if (mode == VOIDmode)
! 		    mode = word_mode;
! 		  i = (GET_MODE_BITSIZE (mode) - 1 - i);
  #else
! 	          i = BITS_PER_WORD - 1 - i;
  #endif
+ 		}
  
  	      op0 = XEXP (op0, 2);
  	      op1 = GEN_INT (i);
Index: expmed.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/expmed.c,v
retrieving revision 1.120
diff -c -3 -p -r1.120 expmed.c
*** expmed.c	1998/08/19 22:21:59	1.120
--- expmed.c	1998/09/16 05:13:20
*************** negate_rtx (mode, x)
*** 211,221 ****
  /* ??? Note that there are two different ideas here for how
     to determine the size to count bits within, for a register.
     One is BITS_PER_WORD, and the other is the size of operand 3
!    of the insv pattern.  (The latter assumes that an n-bit machine
!    will be able to insert bit fields up to n bits wide.)
!    It isn't certain that either of these is right.
!    extract_bit_field has the same quandary.  */
  
  rtx
  store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
       rtx str_rtx;
--- 211,221 ----
  /* ??? Note that there are two different ideas here for how
     to determine the size to count bits within, for a register.
     One is BITS_PER_WORD, and the other is the size of operand 3
!    of the insv pattern.
  
+    If operand 3 of the insv pattern is VOIDmode, then we will use BITS_PER_WORD
+    else, we use the mode of operand 3.  */
+ 
  rtx
  store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
       rtx str_rtx;
*************** store_bit_field (str_rtx, bitsize, bitnu
*** 230,235 ****
--- 230,243 ----
    register int offset = bitnum / unit;
    register int bitpos = bitnum % unit;
    register rtx op0 = str_rtx;
+ #ifdef HAVE_insv
+   int insv_bitsize;
+ 
+   if (insn_operand_mode[(int) CODE_FOR_insv][3] == VOIDmode)
+     insv_bitsize = GET_MODE_BITSIZE (word_mode);
+   else
+     insv_bitsize = GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_insv][3]);
+ #endif
  
    if (GET_CODE (str_rtx) == MEM && ! MEM_IN_STRUCT_P (str_rtx))
      abort ();
*************** store_bit_field (str_rtx, bitsize, bitnu
*** 400,420 ****
        && GET_MODE (value) != BLKmode
        && !(bitsize == 1 && GET_CODE (value) == CONST_INT)
        /* Ensure insv's size is wide enough for this field.  */
!       && (GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_insv][3])
! 	  >= bitsize)
        && ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
! 	    && (bitsize + bitpos
! 		> GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_insv][3]))))
      {
        int xbitpos = bitpos;
        rtx value1;
        rtx xop0 = op0;
        rtx last = get_last_insn ();
        rtx pat;
!       enum machine_mode maxmode
! 	= insn_operand_mode[(int) CODE_FOR_insv][3];
! 
        int save_volatile_ok = volatile_ok;
        volatile_ok = 1;
  
        /* If this machine's insv can only insert into a register, copy OP0
--- 408,429 ----
        && GET_MODE (value) != BLKmode
        && !(bitsize == 1 && GET_CODE (value) == CONST_INT)
        /* Ensure insv's size is wide enough for this field.  */
!       && (insv_bitsize >= bitsize)
        && ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
! 	    && (bitsize + bitpos > insv_bitsize)))
      {
        int xbitpos = bitpos;
        rtx value1;
        rtx xop0 = op0;
        rtx last = get_last_insn ();
        rtx pat;
!       enum machine_mode maxmode;
        int save_volatile_ok = volatile_ok;
+ 
+       maxmode = insn_operand_mode[(int) CODE_FOR_insv][3];
+       if (maxmode == VOIDmode)
+ 	maxmode = word_mode;
+ 
        volatile_ok = 1;
  
        /* If this machine's insv can only insert into a register, copy OP0
*************** extract_bit_field (str_rtx, bitsize, bit
*** 896,902 ****
--- 905,932 ----
    register rtx op0 = str_rtx;
    rtx spec_target = target;
    rtx spec_target_subreg = 0;
+ #ifdef HAVE_extv
+   int extv_bitsize;
+ #endif
+ #ifdef HAVE_extzv
+   int extzv_bitsize;
+ #endif
+ 
+ #ifdef HAVE_extv
+   if (insn_operand_mode[(int) CODE_FOR_extv][0] == VOIDmode)
+     extv_bitsize = GET_MODE_BITSIZE (word_mode);
+   else
+     extv_bitsize = GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extv][0]);
+ #endif
  
+ #ifdef HAVE_extzv
+   if (insn_operand_mode[(int) CODE_FOR_extzv][0] == VOIDmode)
+     extzv_bitsize = GET_MODE_BITSIZE (word_mode);
+   else
+     extzv_bitsize
+       = GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extzv][0]);
+ #endif
+ 
    /* Discount the part of the structure before the desired byte.
       We need to know how many bytes are safe to reference after it.  */
    if (total_size >= 0)
*************** extract_bit_field (str_rtx, bitsize, bit
*** 1075,1085 ****
      {
  #ifdef HAVE_extzv
        if (HAVE_extzv
! 	  && (GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extzv][0])
! 	      >= bitsize)
  	  && ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
! 		&& (bitsize + bitpos
! 		    > GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extzv][0]))))
  	{
  	  int xbitpos = bitpos, xoffset = offset;
  	  rtx bitsize_rtx, bitpos_rtx;
--- 1105,1113 ----
      {
  #ifdef HAVE_extzv
        if (HAVE_extzv
! 	  && (extzv_bitsize >= bitsize)
  	  && ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
! 		&& (bitsize + bitpos > extzv_bitsize)))
  	{
  	  int xbitpos = bitpos, xoffset = offset;
  	  rtx bitsize_rtx, bitpos_rtx;
*************** extract_bit_field (str_rtx, bitsize, bit
*** 1089,1097 ****
  	  rtx xspec_target = spec_target;
  	  rtx xspec_target_subreg = spec_target_subreg;
  	  rtx pat;
! 	  enum machine_mode maxmode
! 	    = insn_operand_mode[(int) CODE_FOR_extzv][0];
  
  	  if (GET_CODE (xop0) == MEM)
  	    {
  	      int save_volatile_ok = volatile_ok;
--- 1117,1128 ----
  	  rtx xspec_target = spec_target;
  	  rtx xspec_target_subreg = spec_target_subreg;
  	  rtx pat;
! 	  enum machine_mode maxmode;
  
+ 	  maxmode = insn_operand_mode[(int) CODE_FOR_extzv][0];
+ 	  if (maxmode == VOIDmode)
+ 	    maxmode = word_mode;
+ 
  	  if (GET_CODE (xop0) == MEM)
  	    {
  	      int save_volatile_ok = volatile_ok;
*************** extract_bit_field (str_rtx, bitsize, bit
*** 1215,1225 ****
      {
  #ifdef HAVE_extv
        if (HAVE_extv
! 	  && (GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extv][0])
! 	      >= bitsize)
  	  && ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
! 		&& (bitsize + bitpos
! 		    > GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extv][0]))))
  	{
  	  int xbitpos = bitpos, xoffset = offset;
  	  rtx bitsize_rtx, bitpos_rtx;
--- 1246,1254 ----
      {
  #ifdef HAVE_extv
        if (HAVE_extv
! 	  && (extv_bitsize >= bitsize)
  	  && ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
! 		&& (bitsize + bitpos > extv_bitsize)))
  	{
  	  int xbitpos = bitpos, xoffset = offset;
  	  rtx bitsize_rtx, bitpos_rtx;
*************** extract_bit_field (str_rtx, bitsize, bit
*** 1228,1235 ****
  	  rtx xspec_target = spec_target;
  	  rtx xspec_target_subreg = spec_target_subreg;
  	  rtx pat;
! 	  enum machine_mode maxmode
! 	    = insn_operand_mode[(int) CODE_FOR_extv][0];
  
  	  if (GET_CODE (xop0) == MEM)
  	    {
--- 1257,1267 ----
  	  rtx xspec_target = spec_target;
  	  rtx xspec_target_subreg = spec_target_subreg;
  	  rtx pat;
! 	  enum machine_mode maxmode;
! 
! 	  maxmode = insn_operand_mode[(int) CODE_FOR_extv][0];
! 	  if (maxmode == VOIDmode)
! 	    maxmode = word_mode;
  
  	  if (GET_CODE (xop0) == MEM)
  	    {
Index: function.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/function.c,v
retrieving revision 1.173
diff -c -3 -p -r1.173 function.c
*** function.c	1998/08/19 22:22:06	1.173
--- function.c	1998/09/16 05:13:29
*************** fixup_var_refs_1 (var, promoted_mode, lo
*** 1990,2000 ****
  
  #ifdef HAVE_extzv
  	      if (GET_CODE (x) == ZERO_EXTRACT)
! 		wanted_mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
  #endif
  #ifdef HAVE_extv
  	      if (GET_CODE (x) == SIGN_EXTRACT)
! 		wanted_mode = insn_operand_mode[(int) CODE_FOR_extv][1];
  #endif
  	      /* If we have a narrower mode, we can do something.  */
  	      if (wanted_mode != VOIDmode
--- 1990,2008 ----
  
  #ifdef HAVE_extzv
  	      if (GET_CODE (x) == ZERO_EXTRACT)
! 		{
! 		  wanted_mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
! 		  if (wanted_mode == VOIDmode)
! 		    wanted_mode = word_mode;
! 		}
  #endif
  #ifdef HAVE_extv
  	      if (GET_CODE (x) == SIGN_EXTRACT)
! 		{
! 		  wanted_mode = insn_operand_mode[(int) CODE_FOR_extv][1];
! 		  if (wanted_mode == VOIDmode)
! 		    wanted_mode = word_mode;
! 		}
  #endif
  	      /* If we have a narrower mode, we can do something.  */
  	      if (wanted_mode != VOIDmode
*************** fixup_var_refs_1 (var, promoted_mode, lo
*** 2183,2192 ****
  		&& ! mode_dependent_address_p (XEXP (tem, 0))
  		&& ! MEM_VOLATILE_P (tem))
  	      {
! 		enum machine_mode wanted_mode
! 		  = insn_operand_mode[(int) CODE_FOR_insv][0];
  		enum machine_mode is_mode = GET_MODE (tem);
  		HOST_WIDE_INT pos = INTVAL (XEXP (outerdest, 2));
  
  		/* If we have a narrower mode, we can do something.  */
  		if (GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode))
--- 2191,2203 ----
  		&& ! mode_dependent_address_p (XEXP (tem, 0))
  		&& ! MEM_VOLATILE_P (tem))
  	      {
! 		enum machine_mode wanted_mode;
  		enum machine_mode is_mode = GET_MODE (tem);
  		HOST_WIDE_INT pos = INTVAL (XEXP (outerdest, 2));
+ 
+ 		wanted_mode = insn_operand_mode[(int) CODE_FOR_insv][0];
+ 		if (wanted_mode == VOIDmode)
+ 		  wanted_mode = word_mode;
  
  		/* If we have a narrower mode, we can do something.  */
  		if (GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode))
Index: recog.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/recog.c,v
retrieving revision 1.58
diff -c -3 -p -r1.58 recog.c
*** recog.c	1998/08/23 06:19:49	1.58
--- recog.c	1998/09/16 05:13:31
*************** validate_replace_rtx_1 (loc, from, to, o
*** 484,494 ****
  
  #ifdef HAVE_extzv
  	  if (code == ZERO_EXTRACT)
! 	    wanted_mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
  #endif
  #ifdef HAVE_extv
  	  if (code == SIGN_EXTRACT)
! 	    wanted_mode = insn_operand_mode[(int) CODE_FOR_extv][1];
  #endif
  
  	  /* If we have a narrower mode, we can do something.  */
--- 484,502 ----
  
  #ifdef HAVE_extzv
  	  if (code == ZERO_EXTRACT)
! 	    {
! 	      wanted_mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
! 	      if (wanted_mode == VOIDmode)
! 		wanted_mode = word_mode;
! 	    }
  #endif
  #ifdef HAVE_extv
  	  if (code == SIGN_EXTRACT)
! 	    {
! 	      wanted_mode = insn_operand_mode[(int) CODE_FOR_extv][1];
! 	      if (wanted_mode == VOIDmode)
! 		wanted_mode = word_mode;
! 	    }
  #endif
  
  	  /* If we have a narrower mode, we can do something.  */
Index: config/mips/mips.md
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/config/mips/mips.md,v
retrieving revision 1.127
diff -c -3 -p -r1.127 mips.md
*** mips.md	1998/09/01 21:25:39	1.127
--- mips.md	1998/09/16 05:13:43
*************** move\\t%0,%z4\\n\\
*** 4581,4604 ****
  
  ;; Bit field extract patterns which use lwl/lwr.
  
- ;; ??? There should be DImode variants for 64 bit code, but the current
- ;; bitfield scheme can't handle that.  We would need to add new optabs
- ;; in order to make that work.
- 
  ;; ??? There could be HImode variants for the ulh/ulhu/ush macros.
  ;; It isn't clear whether this will give better code.
  
  (define_expand "extv"
!   [(set (match_operand:SI 0 "register_operand" "")
! 	(sign_extract:SI (match_operand:QI 1 "memory_operand" "")
! 			 (match_operand:SI 2 "immediate_operand" "")
! 			 (match_operand:SI 3 "immediate_operand" "")))]
    "!TARGET_MIPS16"
    "
  {
!   /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
!      then fail.  */
!   if (INTVAL (operands[2]) != 32 || (INTVAL (operands[3]) % 8) != 0)
      FAIL;
  
    /* This can happen for a 64 bit target, when extracting a value from
--- 4581,4610 ----
  
  ;; Bit field extract patterns which use lwl/lwr.
  
  ;; ??? There could be HImode variants for the ulh/ulhu/ush macros.
  ;; It isn't clear whether this will give better code.
  
+ ;; Only specify the mode operand 1, the rest are assumed to be word_mode.
  (define_expand "extv"
!   [(set (match_operand 0 "register_operand" "")
! 	(sign_extract (match_operand:QI 1 "memory_operand" "")
! 		      (match_operand 2 "immediate_operand" "")
! 		      (match_operand 3 "immediate_operand" "")))]
    "!TARGET_MIPS16"
    "
  {
!   /* If the field does not start on a byte boundary, then fail.  */
!   if (INTVAL (operands[3]) % 8 != 0) 
!     FAIL;
! 
!   /* MIPS I and MIPS II can only handle a 32bit field.  */
!   if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
!     FAIL;
! 
!   /* MIPS III and MIPS IV can handle both 32bit and 64bit fields.  */
!   if (TARGET_64BIT
!       && INTVAL (operands[2]) != 64
!       && INTVAL (operands[2]) != 32)
      FAIL;
  
    /* This can happen for a 64 bit target, when extracting a value from
*************** move\\t%0,%z4\\n\\
*** 4610,4633 ****
    /* Change the mode to BLKmode for aliasing purposes.  */
    operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
  
!   /* Otherwise, emit a lwl/lwr pair to load the value.  */
!   emit_insn (gen_movsi_ulw (operands[0], operands[1]));
    DONE;
  }")
  
  (define_expand "extzv"
!   [(set (match_operand:SI 0 "register_operand" "")
! 	(zero_extract:SI (match_operand:QI 1 "memory_operand" "")
! 			 (match_operand:SI 2 "immediate_operand" "")
! 			 (match_operand:SI 3 "immediate_operand" "")))]
    "!TARGET_MIPS16"
    "
  {
!   /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
!      then fail.  */
!   if (INTVAL (operands[2]) != 32 || (INTVAL (operands[3]) % 8) != 0)
      FAIL;
  
    /* This can happen for a 64 bit target, when extracting a value from
       a 64 bit union member.  extract_bit_field doesn't verify that our
       source matches the predicate, so we force it to be a MEM here.  */
--- 4616,4660 ----
    /* Change the mode to BLKmode for aliasing purposes.  */
    operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
  
!   /* Otherwise, emit a l[wd]l/l[wd]r pair to load the value.  */
!   if (INTVAL (operands[2]) == 64)
!     emit_insn (gen_movdi_uld (operands[0], operands[1]));
!   else
!     {
!       if (TARGET_64BIT)
! 	{
! 	  operands[0] = gen_lowpart (SImode, operands[0]);
! 	  if (operands[0] == NULL_RTX)
! 	    FAIL;
! 	}
!       emit_insn (gen_movsi_ulw (operands[0], operands[1]));
!     }
    DONE;
  }")
  
+ ;; Only specify the mode operand 1, the rest are assumed to be word_mode.
  (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"
    "
  {
!   /* If the field does not start on a byte boundary, then fail.  */
!   if (INTVAL (operands[3]) % 8 != 0) 
      FAIL;
  
+   /* MIPS I and MIPS II can only handle a 32bit field.  */
+   if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
+     FAIL;
+ 
+   /* MIPS III and MIPS IV can handle both 32bit and 64bit fields.  */
+   if (TARGET_64BIT
+       && INTVAL (operands[2]) != 64
+       && INTVAL (operands[2]) != 32)
+     FAIL;
+ 
    /* This can happen for a 64 bit target, when extracting a value from
       a 64 bit union member.  extract_bit_field doesn't verify that our
       source matches the predicate, so we force it to be a MEM here.  */
*************** move\\t%0,%z4\\n\\
*** 4638,4658 ****
    operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
  
    /* Otherwise, emit a lwl/lwr pair to load the value.  */
!   emit_insn (gen_movsi_ulw (operands[0], operands[1]));
    DONE;
  }")
  
  (define_expand "insv"
!   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
! 			 (match_operand:SI 1 "immediate_operand" "")
! 			 (match_operand:SI 2 "immediate_operand" ""))
! 	(match_operand:SI 3 "register_operand" ""))]
    "!TARGET_MIPS16"
    "
  {
!   /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
!      then fail.  */
!   if (INTVAL (operands[1]) != 32 || (INTVAL (operands[2]) % 8) != 0)
      FAIL;
  
    /* This can happen for a 64 bit target, when storing into a 32 bit union
--- 4665,4706 ----
    operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
  
    /* Otherwise, emit a lwl/lwr pair to load the value.  */
!   if (INTVAL (operands[2]) == 64)
!     emit_insn (gen_movdi_uld (operands[0], operands[1]));
!   else
!     {
!       if (TARGET_64BIT)
! 	{
! 	  operands[0] = gen_lowpart (SImode, operands[0]);
! 	  if (operands[0] == NULL_RTX)
! 	    FAIL;
! 	}
!       emit_insn (gen_movsi_ulw (operands[0], operands[1]));
!     }
    DONE;
  }")
  
+ ;; Only specify the mode operands 0, the rest are assumed to be word_mode.
  (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 "register_operand" ""))]
    "!TARGET_MIPS16"
    "
  {
!   /* If the field does not start on a byte boundary, then fail.  */
!   if (INTVAL (operands[2]) % 8 != 0) 
!     FAIL;
! 
!   /* MIPS I and MIPS II can only handle a 32bit field.  */
!   if (!TARGET_64BIT && INTVAL (operands[1]) != 32)
!     FAIL;
! 
!   /* MIPS III and MIPS IV can handle both 32bit and 64bit fields.  */
!   if (TARGET_64BIT
!       && INTVAL (operands[1]) != 64
!       && INTVAL (operands[1]) != 32)
      FAIL;
  
    /* This can happen for a 64 bit target, when storing into a 32 bit union
*************** move\\t%0,%z4\\n\\
*** 4664,4671 ****
    /* Change the mode to BLKmode for aliasing purposes.  */
    operands[0] = change_address (operands[0], BLKmode, XEXP (operands[0], 0));
  
!   /* Otherwise, emit a swl/swr pair to load the value.  */
!   emit_insn (gen_movsi_usw (operands[0], operands[3]));
    DONE;
  }")
  
--- 4712,4730 ----
    /* Change the mode to BLKmode for aliasing purposes.  */
    operands[0] = change_address (operands[0], BLKmode, XEXP (operands[0], 0));
  
!   /* Otherwise, emit a s[wd]l/s[wd]r pair to load the value.  */
!   if (INTVAL (operands[1]) == 64)
!     emit_insn (gen_movdi_usd (operands[0], operands[3]));
!   else
!     {
!       if (TARGET_64BIT)
! 	{
! 	  operands[3] = gen_lowpart (SImode, operands[3]);
! 	  if (operands[3] == NULL_RTX)
! 	    FAIL;
! 	}
!       emit_insn (gen_movsi_usw (operands[0], operands[3]));
!     }
    DONE;
  }")
  
*************** move\\t%0,%z4\\n\\
*** 4721,4726 ****
--- 4780,4844 ----
      return \"sw\\t%1,%0\";
  
    return \"usw\\t%z1,%0\";
+ }"
+   [(set_attr "type"	"store")
+    (set_attr "mode"	"SI")
+    (set_attr "length"	"2,4")])
+ 
+ ;; Bit field extract patterns which use ldl/ldr.
+ 
+ ;; unaligned double word moves generated by the bit field patterns
+ 
+ (define_insn "movdi_uld"
+   [(set (match_operand:DI 0 "register_operand" "=&d,&d")
+ 	(unspec:DI [(match_operand:BLK 1 "general_operand" "R,o")] 0))]
+   ""
+   "*
+ {
+   rtx offset = const0_rtx;
+   rtx addr = XEXP (operands[1], 0);
+   rtx mem_addr = eliminate_constant_term (addr, &offset);
+   char *ret;
+ 
+   if (TARGET_STATS)
+     mips_count_memory_refs (operands[1], 2);
+ 
+   /* The stack/frame pointers are always aligned, so we can convert
+      to the faster lw if we are referencing an aligned stack location.  */
+ 
+   if ((INTVAL (offset) & 7) == 0
+       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
+     ret = \"ld\\t%0,%1\";
+   else
+     ret = \"uld\\t%0,%1\";
+ 
+   return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
+ }"
+   [(set_attr "type"	"load,load")
+    (set_attr "mode"	"SI")
+    (set_attr "length"	"2,4")])
+ 
+ (define_insn "movdi_usd"
+   [(set (match_operand:BLK 0 "memory_operand" "=R,o")
+ 	(unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")] 1))]
+   ""
+   "*
+ {
+   rtx offset = const0_rtx;
+   rtx addr = XEXP (operands[0], 0);
+   rtx mem_addr = eliminate_constant_term (addr, &offset);
+ 
+   if (TARGET_STATS)
+     mips_count_memory_refs (operands[0], 2);
+ 
+   /* The stack/frame pointers are always aligned, so we can convert
+      to the faster sw if we are referencing an aligned stack location.  */
+ 
+   if ((INTVAL (offset) & 7) == 0
+       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
+     return \"sd\\t%1,%0\";
+ 
+   return \"usd\\t%z1,%0\";
  }"
    [(set_attr "type"	"store")
     (set_attr "mode"	"SI")
  


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