*** expmed.c	Fri Apr  8 10:07:44 1994
--- expmed.c.next	Fri Apr  1 12:53:32 1994
***************
*** 421,429 ****
        /* If xop0 is a register, we need it in MAXMODE
  	 to make it acceptable to the format of insv.  */
        if (GET_CODE (xop0) == SUBREG)
! 	/* We can't just change the mode, because this might clobber op0,
! 	   and we will need the original value of op0 if insv fails.  */
! 	xop0 = gen_rtx (SUBREG, maxmode, SUBREG_REG (xop0), SUBREG_WORD (xop0));
        if (GET_CODE (xop0) == REG && GET_MODE (xop0) != maxmode)
  	xop0 = gen_rtx (SUBREG, maxmode, xop0, 0);
  
--- 421,427 ----
        /* If xop0 is a register, we need it in MAXMODE
  	 to make it acceptable to the format of insv.  */
        if (GET_CODE (xop0) == SUBREG)
! 	PUT_MODE (xop0, maxmode);
        if (GET_CODE (xop0) == REG && GET_MODE (xop0) != maxmode)
  	xop0 = gen_rtx (SUBREG, maxmode, xop0, 0);
  
***************
*** 517,533 ****
    int all_zero = 0;
    int all_one = 0;
  
-   /* If VALUE is a floating-point mode, access it as an integer of the
-      corresponding size.  This can occur on a machine with 64 bit registers
-      that uses SFmode for float.  This can also occur for unaligned float
-      structure fields.  */
-   if (GET_MODE_CLASS (GET_MODE (value)) == MODE_FLOAT)
-     {
-       if (GET_CODE (value) != REG)
- 	value = copy_to_reg (value);
-       value = gen_rtx (SUBREG, word_mode, value, 0);
-     }
- 
    /* There is a case not handled here:
       a structure with a known alignment of just a halfword
       and a field split across two aligned halfwords within the structure.
--- 515,520 ----
***************
*** 569,584 ****
  
        total_bits = GET_MODE_BITSIZE (mode);
  
-       /* Make sure bitpos is valid for the chosen mode.  Adjust BITPOS to
- 	 be be in the range 0 to total_bits-1, and put any excess bytes in
- 	 OFFSET.  */
-       if (bitpos >= total_bits)
- 	{
- 	  offset += (bitpos / total_bits) * (total_bits / BITS_PER_UNIT);
- 	  bitpos -= ((bitpos / total_bits) * (total_bits / BITS_PER_UNIT)
- 		     * BITS_PER_UNIT);
- 	}
- 
        /* Get ref to an aligned byte, halfword, or word containing the field.
  	 Adjust BITPOS to be position within a word,
  	 and OFFSET to be the offset of that word.
--- 556,561 ----
***************
*** 633,638 ****
--- 610,626 ----
  
        if (GET_MODE (value) != mode)
  	{
+ 	  /* If VALUE is a floating-point mode, access it as an integer
+ 	     of the corresponding size, then convert it.  This can occur on
+ 	     a machine with 64 bit registers that uses SFmode for float.  */
+ 	  if (GET_MODE_CLASS (GET_MODE (value)) == MODE_FLOAT)
+ 	    {
+ 	      if (GET_CODE (value) != REG)
+ 		value = copy_to_reg (value);
+ 	      value
+ 		= gen_rtx (SUBREG, word_mode, value, 0);
+ 	    }
+ 
  	  if ((GET_CODE (value) == REG || GET_CODE (value) == SUBREG)
  	      && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (value)))
  	    value = gen_lowpart (mode, value);
***************
*** 703,709 ****
      {
        rtx word = gen_lowpart_common (word_mode, value);
  
!       if (word && (value != word))
  	value = word;
        else
  	value = gen_lowpart_common (word_mode,
--- 691,697 ----
      {
        rtx word = gen_lowpart_common (word_mode, value);
  
!       if (word)
  	value = word;
        else
  	value = gen_lowpart_common (word_mode,
***************
*** 733,751 ****
  			 >> (bitsize - bitsdone - thissize))
  			& (((HOST_WIDE_INT) 1 << thissize) - 1));
        else
! 	{
! 	  /* The args are chosen so that the last part
! 	     includes the lsb.  */
! 	  int bit_offset = 0;
! 	  /* If the value isn't in memory, then it must be right aligned
! 	     if a register, so skip past the padding on the left.  If it
! 	     is in memory, then there is no padding on the left.  */
! 	  if (GET_CODE (value) != MEM)
! 	    bit_offset = BITS_PER_WORD - bitsize;
! 	  part = extract_fixed_bit_field (word_mode, value, 0, thissize,
! 					  bit_offset + bitsdone,
! 					  NULL_RTX, 1, align);
! 	}
  #else
        /* Fetch successively more significant portions.  */
        if (GET_CODE (value) == CONST_INT)
--- 721,731 ----
  			 >> (bitsize - bitsdone - thissize))
  			& (((HOST_WIDE_INT) 1 << thissize) - 1));
        else
! 	/* The args are chosen so that the last part
! 	   includes the lsb.  */
! 	part = extract_fixed_bit_field (word_mode, value, 0, thissize,
! 					BITS_PER_WORD - bitsize + bitsdone,
! 					NULL_RTX, 1, align);
  #else
        /* Fetch successively more significant portions.  */
        if (GET_CODE (value) == CONST_INT)
***************
*** 757,776 ****
  #endif
  
        /* If OP0 is a register, then handle OFFSET here.
! 
! 	 When handling multiword bitfields, extract_bit_field may pass
! 	 down a word_mode SUBREG of a larger REG for a bitfield that actually
! 	 crosses a word boundary.  Thus, for a SUBREG, we must find
! 	 the current word starting from the base register.  */
!       if (GET_CODE (op0) == SUBREG)
  	{
- 	  word = operand_subword (SUBREG_REG (op0),
- 				  SUBREG_WORD (op0) + offset, 1,
- 				  GET_MODE (SUBREG_REG (op0)));
- 	  offset = 0;
- 	}
-       else if (GET_CODE (op0) == REG)
- 	{
  	  word = operand_subword (op0, offset, 1, GET_MODE (op0));
  	  offset = 0;
  	}
--- 737,745 ----
  #endif
  
        /* If OP0 is a register, then handle OFFSET here.
! 	 In the register case, UNIT must be a whole word.  */
!       if (GET_CODE (op0) == SUBREG || GET_CODE (op0) == REG)
  	{
  	  word = operand_subword (op0, offset, 1, GET_MODE (op0));
  	  offset = 0;
  	}
***************
*** 928,942 ****
  	    emit_move_insn (target_part, result_part);
  	}
  
!       if (unsignedp)
! 	return target;
!       /* Signed bit field: sign-extend with two arithmetic shifts.  */
!       target = expand_shift (LSHIFT_EXPR, mode, target,
! 			     build_int_2 (GET_MODE_BITSIZE (mode) - bitsize, 0),
! 			     NULL_RTX, 0);
!       return expand_shift (RSHIFT_EXPR, mode, target,
! 			   build_int_2 (GET_MODE_BITSIZE (mode) - bitsize, 0),
! 			   NULL_RTX, 0);
      }
    
    /* From here on we know the desired field is smaller than a word
--- 897,903 ----
  	    emit_move_insn (target_part, result_part);
  	}
  
!       return target;
      }
    
    /* From here on we know the desired field is smaller than a word
***************
*** 1524,1543 ****
        thissize = MIN (thissize, unit - thispos);
  
        /* If OP0 is a register, then handle OFFSET here.
! 
! 	 When handling multiword bitfields, extract_bit_field may pass
! 	 down a word_mode SUBREG of a larger REG for a bitfield that actually
! 	 crosses a word boundary.  Thus, for a SUBREG, we must find
! 	 the current word starting from the base register.  */
!       if (GET_CODE (op0) == SUBREG)
  	{
- 	  word = operand_subword_force (SUBREG_REG (op0),
- 					SUBREG_WORD (op0) + offset,
- 					GET_MODE (SUBREG_REG (op0)));
- 	  offset = 0;
- 	}
-       else if (GET_CODE (op0) == REG)
- 	{
  	  word = operand_subword_force (op0, offset, GET_MODE (op0));
  	  offset = 0;
  	}
--- 1485,1493 ----
        thissize = MIN (thissize, unit - thispos);
  
        /* If OP0 is a register, then handle OFFSET here.
! 	 In the register case, UNIT must be a whole word.  */
!       if (GET_CODE (op0) == SUBREG || GET_CODE (op0) == REG)
  	{
  	  word = operand_subword_force (op0, offset, GET_MODE (op0));
  	  offset = 0;
  	}
***************
*** 1642,1655 ****
  
    op1 = expand_expr (amount, NULL_RTX, VOIDmode, 0);
  
- #if SHIFT_COUNT_TRUNCATED
-   if (SHIFT_COUNT_TRUNCATED
-       && GET_CODE (op1) == CONST_INT
-       && (unsigned HOST_WIDE_INT) INTVAL (op1) >= GET_MODE_BITSIZE (mode))
-     op1 = GEN_INT ((unsigned HOST_WIDE_INT) INTVAL (op1)
- 		   % GET_MODE_BITSIZE (mode));
- #endif
- 
    if (op1 == const0_rtx)
      return shifted;
  
--- 1592,1597 ----
