char raw_buffer[MAX_REGISTER_SIZE]; int use_buffer = 0;
value_assign (struct value *toval, struct value *fromval){  struct type *type;  struct value *val;  char raw_buffer[MAX_REGISTER_SIZE];  int use_buffer = 0;  struct frame_id old_frame;  if (!toval->modifiable)    error ("Left operand of assignment is not a modifiable lvalue.");  COERCE_REF (toval);  type = VALUE_TYPE (toval);  if (VALUE_LVAL (toval) != lval_internalvar)    fromval = value_cast (type, fromval);  else    COERCE_ARRAY (fromval);  CHECK_TYPEDEF (type);  /* Since modifying a register can trash the frame chain, and modifying memory     can trash the frame cache, we save the old frame and then restore the new     frame afterwards.  */  old_frame = get_frame_id (deprecated_selected_frame);  switch (VALUE_LVAL (toval))    {    case lval_internalvar:      set_internalvar (VALUE_INTERNALVAR (toval), fromval);      val = value_copy (VALUE_INTERNALVAR (toval)->value);      val = value_change_enclosing_type (val, VALUE_ENCLOSING_TYPE (fromval));      VALUE_EMBEDDED_OFFSET (val) = VALUE_EMBEDDED_OFFSET (fromval);      VALUE_POINTED_TO_OFFSET (val) = VALUE_POINTED_TO_OFFSET (fromval);      return val;    case lval_internalvar_component:      set_internalvar_component (VALUE_INTERNALVAR (toval),				 VALUE_OFFSET (toval),				 VALUE_BITPOS (toval),				 VALUE_BITSIZE (toval),				 fromval);      break;    case lval_memory:      {	char *dest_buffer;	CORE_ADDR changed_addr;	int changed_len;	if (VALUE_BITSIZE (toval))	  {	    char buffer[sizeof (LONGEST)];	    /* We assume that the argument to read_memory is in units of	       host chars.  FIXME:  Is that correct?  */	    changed_len = (VALUE_BITPOS (toval)			   + VALUE_BITSIZE (toval)			   + HOST_CHAR_BIT - 1)	      / HOST_CHAR_BIT;	    if (changed_len > (int) sizeof (LONGEST))	      error ("Can't handle bitfields which don't fit in a %d bit word.",		     (int) sizeof (LONGEST) * HOST_CHAR_BIT);	    read_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),			 buffer, changed_len);	    modify_field (buffer, value_as_long (fromval),			  VALUE_BITPOS (toval), VALUE_BITSIZE (toval));	    changed_addr = VALUE_ADDRESS (toval) + VALUE_OFFSET (toval);	    dest_buffer = buffer;	  }	else if (use_buffer)	  {	    changed_addr = VALUE_ADDRESS (toval) + VALUE_OFFSET (toval);	    changed_len = use_buffer;	    dest_buffer = raw_buffer;	  }	else	  {	    changed_addr = VALUE_ADDRESS (toval) + VALUE_OFFSET (toval);	    changed_len = TYPE_LENGTH (type);	    dest_buffer = VALUE_CONTENTS (fromval);	  }	write_memory (changed_addr, dest_buffer, changed_len);	if (memory_changed_hook)	  memory_changed_hook (changed_addr, changed_len);	target_changed_event ();      }      break;    case lval_reg_frame_relative:    case lval_register:      {	struct frame_info *frame;	int value_reg;	/* Figure out which frame this is in currently.  */	if (VALUE_LVAL (toval) == lval_register)	  {	    frame = get_current_frame ();	    value_reg = VALUE_REGNO (toval);	  }	else	  {	    frame = frame_find_by_id (VALUE_FRAME_ID (toval));	    value_reg = VALUE_FRAME_REGNUM (toval);	  }	if (!frame)	  error ("Value being assigned to is no longer active.");		if (VALUE_LVAL (toval) == lval_reg_frame_relative	    && CONVERT_REGISTER_P (VALUE_FRAME_REGNUM (toval), type))	  {	    /* If TOVAL is a special machine register requiring	       conversion of program values to a special raw format.  */	    VALUE_TO_REGISTER (frame, VALUE_FRAME_REGNUM (toval),			       type, VALUE_CONTENTS (fromval));	  }	else	  {	    /* TOVAL is stored in a series of registers in the frame	       specified by the structure.  Copy that value out,	       modify it, and copy it back in.  */	    int amount_copied;	    int amount_to_copy;	    char *buffer;	    int reg_offset;	    int byte_offset;	    int regno;	    /* Locate the first register that falls in the value that	       needs to be transfered.  Compute the offset of the	       value in that register.  */	    {	      int offset;	      for (reg_offset = value_reg, offset = 0;		   offset + DEPRECATED_REGISTER_RAW_SIZE (reg_offset) <= VALUE_OFFSET (toval);		   reg_offset++);	      byte_offset = VALUE_OFFSET (toval) - offset;	    }	    /* Compute the number of register aligned values that need	       to be copied.  */	    if (VALUE_BITSIZE (toval))	      amount_to_copy = byte_offset + 1;	    else	      amount_to_copy = byte_offset + TYPE_LENGTH (type);	    	    /* And a bounce buffer.  Be slightly over generous.  */	    buffer = (char *) alloca (amount_to_copy + MAX_REGISTER_SIZE);	    /* Copy it in.  */	    for (regno = reg_offset, amount_copied = 0;		 amount_copied < amount_to_copy;		 amount_copied += DEPRECATED_REGISTER_RAW_SIZE (regno), regno++)	      frame_register_read (frame, regno, buffer + amount_copied);	    	    /* Modify what needs to be modified.  */	    if (VALUE_BITSIZE (toval))	      modify_field (buffer + byte_offset,			    value_as_long (fromval),			    VALUE_BITPOS (toval), VALUE_BITSIZE (toval));	    else if (use_buffer)	      memcpy (buffer + VALUE_OFFSET (toval), raw_buffer, use_buffer);	    else	      memcpy (buffer + byte_offset, VALUE_CONTENTS (fromval),		      TYPE_LENGTH (type));	    /* Copy it out.  */	    for (regno = reg_offset, amount_copied = 0;		 amount_copied < amount_to_copy;		 amount_copied += DEPRECATED_REGISTER_RAW_SIZE (regno), regno++)	      put_frame_register (frame, regno, buffer + amount_copied);	  }	if (register_changed_hook)	  register_changed_hook (-1);	target_changed_event ();	break;      }          default:      error ("Left operand of assignment is not an lvalue.");    }  /* Assigning to the stack pointer, frame pointer, and other     (architecture and calling convention specific) registers may     cause the frame cache to be out of date.  Assigning to memory     also can.  We just do this on all assignments to registers or     memory, for simplicity's sake; I doubt the slowdown matters.  */  switch (VALUE_LVAL (toval))    {    case lval_memory:    case lval_register:    case lval_reg_frame_relative:      reinit_frame_cache ();      /* Having destoroyed the frame cache, restore the selected frame.  */      /* FIXME: cagney/2002-11-02: There has to be a better way of	 doing this.  Instead of constantly saving/restoring the	 frame.  Why not create a get_selected_frame() function that,	 having saved the selected frame's ID can automatically	 re-find the previously selected frame automatically.  */      {	struct frame_info *fi = frame_find_by_id (old_frame);	if (fi != NULL)	  select_frame (fi);      }      break;    default:      break;    }    /* If the field does not entirely fill a LONGEST, then zero the sign bits.     If the field is signed, and is negative, then sign extend. */  if ((VALUE_BITSIZE (toval) > 0)      && (VALUE_BITSIZE (toval) < 8 * (int) sizeof (LONGEST)))    {      LONGEST fieldval = value_as_long (fromval);      LONGEST valmask = (((ULONGEST) 1) << VALUE_BITSIZE (toval)) - 1;      fieldval &= valmask;      if (!TYPE_UNSIGNED (type) && (fieldval & (valmask ^ (valmask >> 1))))	fieldval |= ~valmask;      fromval = value_from_longest (type, fieldval);    }  val = value_copy (toval);  memcpy (VALUE_CONTENTS_RAW (val), VALUE_CONTENTS (fromval),	  TYPE_LENGTH (type));  VALUE_TYPE (val) = type;  val = value_change_enclosing_type (val, VALUE_ENCLOSING_TYPE (fromval));  VALUE_EMBEDDED_OFFSET (val) = VALUE_EMBEDDED_OFFSET (fromval);  VALUE_POINTED_TO_OFFSET (val) = VALUE_POINTED_TO_OFFSET (fromval);  return val;}