back trace now works when using external memory and frameless functions; all
authorDavid Taylor <taylor@redhat.com>
Tue, 16 Dec 1997 07:43:26 +0000 (07:43 +0000)
committerDavid Taylor <taylor@redhat.com>
Tue, 16 Dec 1997 07:43:26 +0000 (07:43 +0000)
arguments are passed in args registers until we run out; finding saved regs
now has two offsets not just one doing double duty.
TARGET_READ_SP / TARGET_WRITE_SP are (temporarily?) commented out.

gdb/ChangeLog
gdb/config/d30v/tm-d30v.h
gdb/d30v-tdep.c

index 2df0bba..5596c8b 100644 (file)
@@ -1,3 +1,18 @@
+Tue Dec 16 10:29:16 1997  David Taylor  <taylor@texas.cygnus.com>
+
+       * d30v-tdep.c (d30v_frame_chain): don't or in DMEM_START to
+       FP_REGNUM value before return; (prologue_find_regs): two sets
+       of offsets -- frame pointer and stack pointer, not just one that
+       tries to do double duty; (d30v_frame_find_saved_regs): stop once
+       we hit pc (in case we're stopped in the middle of the prologue)
+       and improve handling of frameless prologues; (d30v_push_arguments):
+       *ALL* arguments go on the stack until we run out of args registers,
+       force sp to be 8 byte aligned.
+
+       * config/tm-d30v.h (EXTRACT_STRUCT_VALUE_ADDRESS): fix, it's r2,
+       not r0; (FRAME_CHAIN_VALID): handle use of external memory;
+       (STACK_ALIGN): define.
+
 Mon Dec 15 15:13:57 1997  Andrew Cagney  <cagney@b1.cygnus.com>
 
        * remote-sim.c (gdbsim_wait): When HAVE_SIGACTION and SA_RESTART
index 931c032..a1a5b58 100644 (file)
@@ -191,8 +191,7 @@ void d30v_do_registers_info PARAMS ((int regnum, int fpregs));
 /* Extract from an array REGBUF containing the (raw) register state
    the address in which a function should return its structure value,
    as a CORE_ADDR (or an expression that can be used as one).  */
-
-#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(CORE_ADDR *)(REGBUF))
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (((CORE_ADDR *)(REGBUF))[2])
 \f
 
 /* Define other aspects of the stack frame. 
@@ -222,8 +221,13 @@ extern void d30v_init_extra_frame_info PARAMS (( int fromleaf, struct frame_info
 #define FRAME_CHAIN_VALID(chain,frame) \
       ((chain) != 0 && (frame) != 0 && (frame)->pc > IMEM_START)
 #else
+#if 0
 #define FRAME_CHAIN_VALID(chain,fi)    \
       ((chain) != 0 && (fi) != 0 && (fi)->frame <= STACK_START)
+#else
+#define FRAME_CHAIN_VALID(chain,fi)    \
+      ((chain) != 0 && (fi) != 0 && (fi)->return_pc != 0)
+#endif
 #endif
 #define FRAME_SAVED_PC(FRAME)    ((FRAME)->return_pc)   
 #define FRAME_ARGS_ADDRESS(fi)   (fi)->frame
@@ -311,7 +315,7 @@ extern void d30v_pop_frame PARAMS((void));
 #define REGISTER_SIZE 4
 
 /* Need to handle SP special, as we need to select between spu and spi.  */
-
+#if 0                          /* XXX until the simulator is fixed */
 #define TARGET_READ_SP() ((read_register (PSW_REGNUM) & PSW_SM) \
                          ? read_register (SPU_REGNUM) \
                          : read_register (SPI_REGNUM))
@@ -319,6 +323,9 @@ extern void d30v_pop_frame PARAMS((void));
 #define TARGET_WRITE_SP(val) ((read_register (PSW_REGNUM) & PSW_SM) \
                          ? write_register (SPU_REGNUM, (val)) \
                          : write_register (SPI_REGNUM, (val)))
+#endif
+
+#define STACK_ALIGN(len)       (((len) + 7 ) & ~7)
 
 /* Turn this on to cause remote-sim.c to use sim_set/clear_breakpoint. */
 
index 50b3d0d..09cd9e3 100644 (file)
@@ -320,7 +320,7 @@ d30v_frame_chain (frame)
   if (!read_memory_unsigned_integer(fsr.regs[FP_REGNUM],4))
     return (CORE_ADDR)0;
 
-  return read_memory_unsigned_integer(fsr.regs[FP_REGNUM],4)| DMEM_START;
+  return read_memory_unsigned_integer(fsr.regs[FP_REGNUM],4);
 }  
 
 static int next_addr, uses_frame;
@@ -440,16 +440,16 @@ prologue_find_regs (op, fsr, addr)
   if ((op & OP_MASK_ALL_BUT_IMM) == OP_SUB_SP_IMM)
     {
       offset = EXTRACT_IMM6(op);
-      next_addr -= offset;
+      frame_size += -offset;
       return 1;
     }
 
-  /* st  rn, @(sp,0) */
+  /* st  rn, @(sp,0) -- observed */
   if (((op & OP_MASK_ALL_BUT_RA) == OP_STW_SP_R0) ||
       ((op & OP_MASK_ALL_BUT_RA) == OP_STW_SP_IMM0))
     {
       n = EXTRACT_RA(op);
-      fsr->regs[n] = next_addr;
+      fsr->regs[n] = (- frame_size);
       return 1;
     }
 
@@ -458,8 +458,8 @@ prologue_find_regs (op, fsr, addr)
       ((op & OP_MASK_ALL_BUT_RA) == OP_ST2W_SP_IMM0))
     {
       n = EXTRACT_RA(op);
-      fsr->regs[n] = next_addr;
-      fsr->regs[n+1] = next_addr+4;
+      fsr->regs[n] = (- frame_size);
+      fsr->regs[n+1] = (- frame_size) + 4;
       return 1;
     }
 
@@ -490,7 +490,7 @@ d30v_frame_find_saved_regs (fi, fsr)
   pc = get_pc_function_start (fi->pc);
 
   uses_frame = 0;
-  while (1)
+  while (pc < fi->pc)
     {
       opl = (unsigned long)read_memory_integer (pc, 4);
       opr = (unsigned long)read_memory_integer (pc+4, 4);
@@ -554,7 +554,7 @@ d30v_frame_find_saved_regs (fi, fsr)
     }
   
   fi->size = frame_size;
-  if (!fp)
+  if (!fp || !uses_frame)
 #if 0
     fp = read_register(SP_REGNUM) | DMEM_START;
 #else
@@ -571,7 +571,7 @@ d30v_frame_find_saved_regs (fi, fsr)
   else
     fi->return_pc = read_register(LR_REGNUM);
   
-  /* th SP is not normally (ever?) saved, but check anyway */
+  /* the SP is not normally (ever?) saved, but check anyway */
   if (!fsr->regs[SP_REGNUM])
     {
       /* if the FP was saved, that means the current FP is valid, */
@@ -861,27 +861,37 @@ d30v_push_arguments (nargs, args, sp, struct_return, struct_addr)
       struct type *arg_type = check_typedef (VALUE_TYPE (arg));
       len = TYPE_LENGTH (arg_type);
       contents = VALUE_CONTENTS(arg);
-      val = extract_signed_integer (contents, len);
       if (len > 4)
        {
          /* we need multiple registers */
          int ndx;
 
-         for (ndx = 0; ndx < len; ndx += 4, len -= 4)
+         for (ndx = 0; len > 0; ndx += 8, len -= 8)
            {
+             if (regnum & 1)
+               regnum++;       /* all args > 4 bytes start in even register */
+
              if (regnum < 18)
                {
-                 if (len > 4)
-                   val = extract_signed_integer (&contents[ndx], 4);
-                 else
-                   val = extract_signed_integer (&contents[ndx], len);
+                 val = extract_signed_integer (&contents[ndx], 4);
+                 write_register (regnum++, val);
 
+                 if (len >= 8)
+                   val = extract_signed_integer (&contents[ndx+4], 4);
+                 else
+                   val = extract_signed_integer (&contents[ndx+4], len-4);
                  write_register (regnum++, val);
                }
              else
                {
                  /* no more registers available.  put it on the stack */
-                 sp -= len;
+
+                 /* all args > 4 bytes are padded to a multiple of 8 bytes
+                  and start on an 8 byte boundary */
+                 if (sp & 7)
+                   sp -= (sp & 7); /* align it */
+
+                 sp -= ((len + 7) & ~7); /* allocate space */
                  write_memory (sp, &contents[ndx], len);
                  break;
                }
@@ -891,16 +901,20 @@ d30v_push_arguments (nargs, args, sp, struct_return, struct_addr)
        {
          if (regnum < 18 )
            {
+             val = extract_signed_integer (contents, len);
              write_register (regnum++, val);
            }
          else
            {
-             sp -= len;
-             store_address (buffer, len, val);
-             write_memory (sp, buffer, len);
+             /* all args are padded to a multiple of 4 bytes (at least) */
+             sp -= ((len + 3) & ~3);
+             write_memory (sp, contents, len);
            }
        }
     }
+  if (sp & 7)
+    /* stack pointer is not on an 8 byte boundary -- align it */
+    sp -= (sp & 7);
   return sp;
 }