This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


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

RFA: correct mn10300 saved regs handling



2001-05-06  Jim Blandy  <jimb@redhat.com>

	Correct and expand handling of `movm' instruction, and register
	saves in general.
	* config/mn10300/tm-mn10300.h (D0_REGNUM, A0_REGNUM, MDRQ_REGNUM,
	MCRH_REGNUM, MCRL_REGNUM, MCVF_REGNUM): New definitions.
	(enum movm_register_bits): New enum.
	* mn10300-tdep.c (set_movm_offsets): Use symbolic names for the
	bits, not hex literals.  Handle the `other', `exreg0', and
	`exother' bits.  Correct handling of `exreg1': it saves r4, r5,
	r6, and r7, not r2, r3, r4, and r5.
	(saved_regs_size): New function.
	(mn10300_frame_chain, mn10300_frame_saved_pc): Use it, instead
	of computing the same thing inline, incorrectly.

*** gdb/mn10300-tdep.c.base	Fri May  4 16:27:44 2001
--- gdb/mn10300-tdep.c	Sun May  6 20:15:55 2001
***************
*** 216,247 ****
    if (fi == NULL || movm_args == 0)
      return;
  
!   if (movm_args & 0x10)
      {
        fi->saved_regs[A3_REGNUM] = fi->frame + offset;
        offset += 4;
      }
!   if (movm_args & 0x20)
      {
        fi->saved_regs[A2_REGNUM] = fi->frame + offset;
        offset += 4;
      }
!   if (movm_args & 0x40)
      {
        fi->saved_regs[D3_REGNUM] = fi->frame + offset;
        offset += 4;
      }
!   if (movm_args & 0x80)
      {
        fi->saved_regs[D2_REGNUM] = fi->frame + offset;
        offset += 4;
      }
!   if (AM33_MODE && movm_args & 0x02)
      {
!       fi->saved_regs[E0_REGNUM + 5] = fi->frame + offset;
!       fi->saved_regs[E0_REGNUM + 4] = fi->frame + offset + 4;
!       fi->saved_regs[E0_REGNUM + 3] = fi->frame + offset + 8;
!       fi->saved_regs[E0_REGNUM + 2] = fi->frame + offset + 12;
      }
  }
  
--- 216,278 ----
    if (fi == NULL || movm_args == 0)
      return;
  
!   if (movm_args & movm_other_bit)
!     {
!       fi->saved_regs[LAR_REGNUM]    = fi->frame + offset;
!       fi->saved_regs[LIR_REGNUM]    = fi->frame + offset + 4;
!       fi->saved_regs[MDR_REGNUM]    = fi->frame + offset + 8;
!       fi->saved_regs[A0_REGNUM + 1] = fi->frame + offset + 12;
!       fi->saved_regs[A0_REGNUM]     = fi->frame + offset + 16;
!       fi->saved_regs[D0_REGNUM + 1] = fi->frame + offset + 20;
!       fi->saved_regs[D0_REGNUM]     = fi->frame + offset + 24;
!       offset += 28;
!     }
!   if (movm_args & movm_a3_bit)
      {
        fi->saved_regs[A3_REGNUM] = fi->frame + offset;
        offset += 4;
      }
!   if (movm_args & movm_a2_bit)
      {
        fi->saved_regs[A2_REGNUM] = fi->frame + offset;
        offset += 4;
      }
!   if (movm_args & movm_d3_bit)
      {
        fi->saved_regs[D3_REGNUM] = fi->frame + offset;
        offset += 4;
      }
!   if (movm_args & movm_d2_bit)
      {
        fi->saved_regs[D2_REGNUM] = fi->frame + offset;
        offset += 4;
      }
!   if (AM33_MODE)
      {
!       if (movm_args & movm_exother_bit)
!         {
!           fi->saved_regs[MCVF_REGNUM]   = fi->frame + offset;
!           fi->saved_regs[MCRL_REGNUM]   = fi->frame + offset + 4;
!           fi->saved_regs[MCRH_REGNUM]   = fi->frame + offset + 8;
!           fi->saved_regs[MDRQ_REGNUM]   = fi->frame + offset + 12;
!           fi->saved_regs[E0_REGNUM + 1] = fi->frame + offset + 16;
!           fi->saved_regs[E0_REGNUM + 0] = fi->frame + offset + 20;
!           offset += 24;
!         }
!       if (movm_args & movm_exreg1_bit)
!         {
!           fi->saved_regs[E0_REGNUM + 7] = fi->frame + offset;
!           fi->saved_regs[E0_REGNUM + 6] = fi->frame + offset + 4;
!           fi->saved_regs[E0_REGNUM + 5] = fi->frame + offset + 8;
!           fi->saved_regs[E0_REGNUM + 4] = fi->frame + offset + 12;
!           offset += 16;
!         }
!       if (movm_args & movm_exreg0_bit)
!         {
!           fi->saved_regs[E0_REGNUM + 3] = fi->frame + offset;
!           fi->saved_regs[E0_REGNUM + 2] = fi->frame + offset + 4;
!           offset += 8;
!         }
      }
  }
  
***************
*** 529,534 ****
--- 560,591 ----
    return addr;
  }
  
+ 
+ /* Function: saved_regs_size
+    Return the size in bytes of the register save area, based on the
+    saved_regs array in FI.  */
+ static int
+ saved_regs_size (struct frame_info *fi)
+ {
+   int adjust = 0;
+   int i;
+ 
+   /* Reserve four bytes for every register saved.  */
+   for (i = 0; i < NUM_REGS; i++)
+     if (fi->saved_regs[i])
+       adjust += 4;
+ 
+   /* If we saved LIR, then it's most likely we used a `movm'
+      instruction with the `other' bit set, in which case the SP is
+      decremented by an extra four bytes, "to simplify calculation
+      of the transfer area", according to the processor manual.  */
+   if (fi->saved_regs[LIR_REGNUM])
+     adjust += 4;
+ 
+   return adjust;
+ }
+ 
+ 
  /* Function: frame_chain
     Figure out and return the caller's frame pointer given current
     frame_info struct.
***************
*** 579,597 ****
      }
    else
      {
!       int adjust = 0;
! 
!       adjust += (fi->saved_regs[D2_REGNUM] ? 4 : 0);
!       adjust += (fi->saved_regs[D3_REGNUM] ? 4 : 0);
!       adjust += (fi->saved_regs[A2_REGNUM] ? 4 : 0);
!       adjust += (fi->saved_regs[A3_REGNUM] ? 4 : 0);
!       if (AM33_MODE)
! 	{
! 	  adjust += (fi->saved_regs[E0_REGNUM + 5] ? 4 : 0);
! 	  adjust += (fi->saved_regs[E0_REGNUM + 4] ? 4 : 0);
! 	  adjust += (fi->saved_regs[E0_REGNUM + 3] ? 4 : 0);
! 	  adjust += (fi->saved_regs[E0_REGNUM + 2] ? 4 : 0);
! 	}
  
        /* Our caller does not have a frame pointer.  So his frame starts
           at the base of our frame (fi->frame) + register save space
--- 636,642 ----
      }
    else
      {
!       int adjust = saved_regs_size (fi);
  
        /* Our caller does not have a frame pointer.  So his frame starts
           at the base of our frame (fi->frame) + register save space
***************
*** 767,785 ****
  static CORE_ADDR
  mn10300_frame_saved_pc (struct frame_info *fi)
  {
!   int adjust = 0;
! 
!   adjust += (fi->saved_regs[D2_REGNUM] ? 4 : 0);
!   adjust += (fi->saved_regs[D3_REGNUM] ? 4 : 0);
!   adjust += (fi->saved_regs[A2_REGNUM] ? 4 : 0);
!   adjust += (fi->saved_regs[A3_REGNUM] ? 4 : 0);
!   if (AM33_MODE)
!     {
!       adjust += (fi->saved_regs[E0_REGNUM + 5] ? 4 : 0);
!       adjust += (fi->saved_regs[E0_REGNUM + 4] ? 4 : 0);
!       adjust += (fi->saved_regs[E0_REGNUM + 3] ? 4 : 0);
!       adjust += (fi->saved_regs[E0_REGNUM + 2] ? 4 : 0);
!     }
  
    return (read_memory_integer (fi->frame + adjust, REGISTER_SIZE));
  }
--- 812,818 ----
  static CORE_ADDR
  mn10300_frame_saved_pc (struct frame_info *fi)
  {
!   int adjust = saved_regs_size (fi);
  
    return (read_memory_integer (fi->frame + adjust, REGISTER_SIZE));
  }
*** gdb/config/mn10300/tm-mn10300.h.base	Fri May  4 14:55:16 2001
--- gdb/config/mn10300/tm-mn10300.h	Sun May  6 20:04:25 2001
***************
*** 43,50 ****
--- 43,52 ----
  #define REGISTER_RAW_SIZE(REG) 4
  #endif
  
+ #define D0_REGNUM 0
  #define D2_REGNUM 2
  #define D3_REGNUM 3
+ #define A0_REGNUM 4
  #define A2_REGNUM 6
  #define A3_REGNUM 7
  #define SP_REGNUM 8
***************
*** 53,62 ****
--- 55,79 ----
  #define PSW_REGNUM 11
  #define LIR_REGNUM 12
  #define LAR_REGNUM 13
+ #define MDRQ_REGNUM 14
  #define E0_REGNUM 15
+ #define MCRH_REGNUM 26
+ #define MCRL_REGNUM 27
+ #define MCVF_REGNUM 28
  /* start-sanitize-am33-2 */
  #define FS0_REGNUM 32
  /* end-sanitize-am33-2 */
+ 
+ enum movm_register_bits {
+   movm_exother_bit = 0x01,
+   movm_exreg1_bit  = 0x02,
+   movm_exreg0_bit  = 0x04,
+   movm_other_bit   = 0x08,
+   movm_a3_bit      = 0x10,
+   movm_a2_bit      = 0x20,
+   movm_d3_bit      = 0x40,
+   movm_d2_bit      = 0x80
+ };
  
  #define INIT_FRAME_PC		/* Not necessary */
  


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