Additional code in expand_expr_unaligned

Richard Kenner kenner@vlsi1.ultra.nyu.edu
Mon Nov 29 14:41:00 GMT 1999


I just committed this patch (which is safe, since the new code does
things where the old code would have aborted).

Mon Nov 29 16:56:42 1999  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

	* expr.c (expand_expr_unaligned): Add more code from full case
	that is needed when OP0 is in a register.

*** expr.c.nov28	Sun Nov 28 08:46:31 1999
--- expr.c	Sun Nov 28 10:27:35 1999
*************** expand_expr_unaligned (exp, palign)
*** 7855,7862 ****
  	  }
  
! 	/* Get a reference to just this component.  */
! 	op0 = change_address (op0, mode1,
! 			      plus_constant (XEXP (op0, 0),
! 					     (bitpos / BITS_PER_UNIT)));
  
  	/* Adjust the alignment in case the bit position is not
--- 7860,7923 ----
  	  }
  
! 	/* In cases where an aligned union has an unaligned object
! 	   as a field, we might be extracting a BLKmode value from
! 	   an integer-mode (e.g., SImode) object.  Handle this case
! 	   by doing the extract into an object as wide as the field
! 	   (which we know to be the width of a basic mode), then
! 	   storing into memory, and changing the mode to BLKmode.
! 	   If we ultimately want the address (EXPAND_CONST_ADDRESS or
! 	   EXPAND_INITIALIZER), then we must not copy to a temporary.  */
! 	if (mode1 == VOIDmode
! 	    || GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG
! 	    || (SLOW_UNALIGNED_ACCESS
! 		&& (TYPE_ALIGN (type) > alignment * BITS_PER_UNIT
! 		    || bitpos % TYPE_ALIGN (type) != 0)))
! 	  {
! 	    enum machine_mode ext_mode = mode_for_size (bitsize, MODE_INT, 1);
! 
! 	    if (ext_mode == BLKmode)
! 	      {
! 		/* In this case, BITPOS must start at a byte boundary.  */
! 		if (GET_CODE (op0) != MEM
! 		    || bitpos % BITS_PER_UNIT != 0)
! 		  abort ();
! 
! 		op0 = change_address (op0, VOIDmode,
! 				      plus_constant (XEXP (op0, 0),
! 						     bitpos / BITS_PER_UNIT));
! 	      }
! 	    else
! 	      {
! 		rtx new = assign_stack_temp (ext_mode,
! 					     bitsize / BITS_PER_UNIT, 0);
! 
! 		op0 = extract_bit_field (validize_mem (op0), bitsize, bitpos,
! 					 unsignedp, NULL_RTX, ext_mode,
! 					 ext_mode, alignment,
! 					 int_size_in_bytes (TREE_TYPE (tem)));
! 
! 		/* If the result is a record type and BITSIZE is narrower than
! 		   the mode of OP0, an integral mode, and this is a big endian
! 		   machine, we must put the field into the high-order bits.  */
! 		if (TREE_CODE (type) == RECORD_TYPE && BYTES_BIG_ENDIAN
! 		    && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
! 		    && bitsize < GET_MODE_BITSIZE (GET_MODE (op0)))
! 		  op0 = expand_shift (LSHIFT_EXPR, GET_MODE (op0), op0,
! 				      size_int (GET_MODE_BITSIZE
! 						(GET_MODE (op0))
! 						- bitsize),
! 				      op0, 1);
! 
! 
! 		emit_move_insn (new, op0);
! 		op0 = copy_rtx (new);
! 		PUT_MODE (op0, BLKmode);
! 	      }
! 	  }
! 	else
! 	  /* Get a reference to just this component.  */
! 	  op0 = change_address (op0, mode1,
! 				  plus_constant (XEXP (op0, 0),
! 						 (bitpos / BITS_PER_UNIT)));
  
  	/* Adjust the alignment in case the bit position is not


More information about the Gcc-patches mailing list