Tue Nov 17 11:17:06 1992 Ian Lance Taylor (ian@cygnus.com)
authorIan Lance Taylor <ian@airs.com>
Tue, 17 Nov 1992 21:46:17 +0000 (21:46 +0000)
committerIan Lance Taylor <ian@airs.com>
Tue, 17 Nov 1992 21:46:17 +0000 (21:46 +0000)
  * tm-rs6000.h (BELIEVE_PCC_PROMOTION): Define, since AIX cc gets
it right.
(aix_framedata): added nosavedpc field.
(SAVED_PC_AFTER_CALL): Don't try to optimize; just call
read_register.
(FRAMELESS_FUNCTION_INVOCATION): Pass second argument of 0.
(FRAME_SAVED_PC): If PC not saved, use SAVED_PC_AFTER_CALL.
* rs6000-tdep.c (skip_prologue): Handle gcc generated stfd
instructions as function_frame_info does.  Expand special case of
st r31,-4(r1) to be st r31,NUM(r1), since gcc can generate offsets
other than -4.
(pop_frame): Add 4 rather than sizeof (int) to avoid host
dependence.
(function_frame_info): Set frameless if the function has no frame,
and set nosavedpc if the PC was not saved.  Handle gcc generated
stfd 31,-4(31); st 31, -12(31) correctly.
(frameless_function_invocation): New second argument pcsaved; if 0
return whether the function has a frame, if 1 return whether the
function saved PC.
(frame_initial_stack_address): Correct typo: cache registers for
callee_fi, not for fi, (avoids reading garbage memory locations).

gdb/ChangeLog
gdb/rs6000-tdep.c
gdb/tm-rs6000.h

index 58d5758d6dd04f887f2d418f1ad18410091a0969..a9991420b37a9d81f081a4613adfa20eb3eddb3d 100644 (file)
@@ -1,5 +1,34 @@
+Tue Nov 17 11:17:06 1992  Ian Lance Taylor  (ian@cygnus.com)
+
+       * tm-rs6000.h (BELIEVE_PCC_PROMOTION): Define, since AIX cc gets
+       it right.
+       (aix_framedata): added nosavedpc field.
+       (SAVED_PC_AFTER_CALL): Don't try to optimize; just call
+       read_register.
+       (FRAMELESS_FUNCTION_INVOCATION): Pass second argument of 0.
+       (FRAME_SAVED_PC): If PC not saved, use SAVED_PC_AFTER_CALL.
+       * rs6000-tdep.c (skip_prologue): Handle gcc generated stfd
+       instructions as function_frame_info does.  Expand special case of
+       st r31,-4(r1) to be st r31,NUM(r1), since gcc can generate offsets
+       other than -4.
+       (pop_frame): Add 4 rather than sizeof (int) to avoid host
+       dependence.
+       (function_frame_info): Set frameless if the function has no frame,
+       and set nosavedpc if the PC was not saved.  Handle gcc generated
+       stfd 31,-4(31); st 31, -12(31) correctly.
+       (frameless_function_invocation): New second argument pcsaved; if 0
+       return whether the function has a frame, if 1 return whether the
+       function saved PC.
+       (frame_initial_stack_address): Correct typo: cache registers for
+       callee_fi, not for fi, (avoids reading garbage memory locations).
+
 Mon Nov 16 15:58:07 1992  Stu Grossman  (grossman at cygnus.com)
 
+       * infrun.c (wait_for_inferior (just before step_over_function
+       label)):  Change test for stepping into subroutine to check for the
+       presence of line number info.  This makes stuff compiled with -g1
+       cause GDB to not lose control when stepping.
+
        * symtab.c (find_pc_line):  Improve code per gnu's suggestions.
        Improve comments as well.
 
index 80deb81600199d500b1ce3cdd84cce26a678275a..14c88a45fb617cc43f521647c7f54c1786ea9f52 100644 (file)
@@ -210,6 +210,11 @@ CORE_ADDR pc;
       return pc - 4;                   /* don't skip over this branch */
   }
 
+  if ((op & 0xfc1f0000) == 0xd8010000) { /* stfd Rx,NUM(r1) */
+    pc += 4;                            /* store floating register double */
+    op = read_memory_integer (pc, 4);
+  }
+
   if ((op & 0xfc1f0000) == 0xbc010000) { /* stm Rx, NUM(r1) */
     pc += 4;
     op = read_memory_integer (pc, 4);
@@ -217,7 +222,7 @@ CORE_ADDR pc;
 
   while (((tmp = op >> 16) == 0x9001) || /* st   r0, NUM(r1) */
         (tmp == 0x9421) ||             /* stu  r1, NUM(r1) */
-        (op == 0x93e1fffc))            /* st   r31,-4(r1) */
+        (tmp == 0x93e1))               /* st   r31,NUM(r1) */
   {
     pc += 4;
     op = read_memory_integer (pc, 4);
@@ -476,7 +481,7 @@ pop_frame ()
   if (fdata.saved_gpr != -1)
     for (ii=fdata.saved_gpr; ii <= 31; ++ii) {
       read_memory (addr, &registers [REGISTER_BYTE (ii)], 4);
-      addr += sizeof (int);
+      addr += 4;
     }
 
   if (fdata.saved_fpr != -1)
@@ -533,7 +538,8 @@ fix_call_dummy(dummyname, pc, fun, nargs, type)
 
 /* return information about a function frame.
    in struct aix_frameinfo fdata:
-    - frameless is TRUE, if function does not save %pc value in its frame.
+    - frameless is TRUE, if function does not have a frame.
+    - nosavedpc is TRUE, if function does not save %pc value in its frame.
     - offset is the number of bytes used in the frame to save registers.
     - saved_gpr is the number of the first saved gpr.
     - saved_fpr is the number of the first saved fpr.
@@ -550,20 +556,22 @@ function_frame_info (pc, fdata)
 
   fdata->offset = 0;
   fdata->saved_gpr = fdata->saved_fpr = fdata->alloca_reg = -1;
+  fdata->frameless = 1;
 
   op  = read_memory_integer (pc, 4);
   if (op == 0x7c0802a6) {              /* mflr r0 */
     pc += 4;
     op = read_memory_integer (pc, 4);
+    fdata->nosavedpc = 0;
     fdata->frameless = 0;
   }
-  else                         /* else, this is a frameless invocation */
-    fdata->frameless = 1;
-
+  else                         /* else, pc is not saved */
+    fdata->nosavedpc = 1;
 
   if ((op & 0xfc00003e) == 0x7c000026) { /* mfcr Rx */
     pc += 4;
     op = read_memory_integer (pc, 4);
+    fdata->frameless = 0;
   }
 
   if ((op & 0xfc000000) == 0x48000000) { /* bl foo, to save fprs??? */
@@ -577,11 +585,13 @@ function_frame_info (pc, fdata)
     if (op == 0x4def7b82 ||            /* crorc 15, 15, 15 */
        op == 0x0)
       return;                          /* prologue is over */
+    fdata->frameless = 0;
   }
 
   if ((op & 0xfc1f0000) == 0xd8010000) { /* stfd Rx,NUM(r1) */
     pc += 4;                            /* store floating register double */
     op = read_memory_integer (pc, 4);
+    fdata->frameless = 0;
   }
 
   if ((op & 0xfc1f0000) == 0xbc010000) { /* stm Rx, NUM(r1) */
@@ -589,7 +599,7 @@ function_frame_info (pc, fdata)
     fdata->saved_gpr = (op >> 21) & 0x1f;
     tmp2 = op & 0xffff;
     if (tmp2 > 0x7fff)
-      tmp2 = 0xffff0000 | tmp2;
+      tmp2 = (~0 &~ 0xffff) | tmp2;
 
     if (tmp2 < 0) {
       tmp2 = tmp2 * -1;
@@ -602,29 +612,43 @@ function_frame_info (pc, fdata)
     fdata->offset = tmp2;
     pc += 4;
     op = read_memory_integer (pc, 4);
+    fdata->frameless = 0;
   }
 
   while (((tmp = op >> 16) == 0x9001) ||       /* st   r0, NUM(r1) */
         (tmp == 0x9421) ||                     /* stu  r1, NUM(r1) */
-        (op == 0x93e1fffc))                    /* st   r31,-4(r1) */
+        (tmp == 0x93e1))                       /* st r31, NUM(r1) */
   {
+    int tmp2;
+
     /* gcc takes a short cut and uses this instruction to save r31 only. */
 
-    if (op == 0x93e1fffc) {
+    if (tmp == 0x93e1) {
       if (fdata->offset)
 /*        fatal ("Unrecognized prolog."); */
         printf ("Unrecognized prolog!\n");
 
       fdata->saved_gpr = 31;
-      fdata->offset = 4;
+      tmp2 = op & 0xffff;
+      if (tmp2 > 0x7fff) {
+       tmp2 = - ((~0 &~ 0xffff) | tmp2);
+       fdata->saved_fpr = (tmp2 - ((32 - 31) * 4)) / 8;
+       if ( fdata->saved_fpr > 0)
+         fdata->saved_fpr = 32 - fdata->saved_fpr;
+       else
+         fdata->saved_fpr = -1;
+      }
+      fdata->offset = tmp2;
     }
     pc += 4;
     op = read_memory_integer (pc, 4);
+    fdata->frameless = 0;
   }
 
   while ((tmp = (op >> 22)) == 0x20f) {        /* l    r31, ... or */
     pc += 4;                           /* l    r30, ...    */
     op = read_memory_integer (pc, 4);
+    fdata->frameless = 0;
   }
 
   /* store parameters into stack */
@@ -636,10 +660,13 @@ function_frame_info (pc, fdata)
     {
       pc += 4;                                 /* store fpr double */
       op = read_memory_integer (pc, 4);
+      fdata->frameless = 0;
     }
 
-  if (op == 0x603f0000)                                /* oril r31, r1, 0x0 */
+  if (op == 0x603f0000) {                      /* oril r31, r1, 0x0 */
     fdata->alloca_reg = 31;
+    fdata->frameless = 0;
+  }
 }
 
 
@@ -906,11 +933,14 @@ CORE_ADDR pc;
 
 
 /* Determines whether the function FI has a frame on the stack or not.
-   Called from the FRAMELESS_FUNCTION_INVOCATION macro in tm.h.  */
+   Called from the FRAMELESS_FUNCTION_INVOCATION macro in tm.h with a
+   second argument of 0, and from the FRAME_SAVED_PC macro with a
+   second argument of 1.  */
 
 int
-frameless_function_invocation (fi)
+frameless_function_invocation (fi, pcsaved)
 struct frame_info *fi;
+int pcsaved;
 {
   CORE_ADDR func_start;
   struct aix_framedata fdata;
@@ -924,7 +954,7 @@ struct frame_info *fi;
     return 0;
 
   function_frame_info (func_start, &fdata);
-  return fdata.frameless;
+  return pcsaved ? fdata.nosavedpc : fdata.frameless;
 }
 
 
@@ -1026,7 +1056,7 @@ frame_initial_stack_address (fi)
   for (callee_fi = fi->next; callee_fi; callee_fi = callee_fi->next) {
 
     if (!callee_fi->cache_fsr)
-      frame_get_cache_fsr (fi, NULL);
+      frame_get_cache_fsr (callee_fi, NULL);
 
     /* this is the address in which alloca register is saved. */
 
index 1b0ffdebd3446176ea6d0a6f6194b8d637dd157d..5dff65c6ded34894eaef23bfc909c7e82cdd9db3 100644 (file)
@@ -36,6 +36,9 @@ extern int    symtab_relocated;
 
 #define        PC_LOAD_SEGMENT(PC)     pc_load_segment_name(PC)
 
+/* AIX cc seems to get this right.  */
+
+#define BELIEVE_PCC_PROMOTION 1
 
 /* Conversion between a register number in stab string to actual register num. */
 
@@ -82,6 +85,7 @@ struct aix_framedata {
   int  saved_fpr;                      /* smallest # of saved fpr */
   int  alloca_reg;                     /* alloca register number (frame ptr) */
   char frameless;                      /* true if frameless functions. */
+  char nosavedpc;                      /* true if pc not saved. */
 };
 
 void 
@@ -174,13 +178,7 @@ extern int loadinfotextindex;
    the new frame is not set up until the new function executes
    some instructions.  */
 
-#define        SAVED_PC_AFTER_CALL(frame)      \
-       (register_valid [LR_REGNUM] ?   \
-         (*(int*)&registers[REGISTER_BYTE (LR_REGNUM)]) :      \
-         read_register (LR_REGNUM))
-
-/*#define SAVED_PC_AFTER_CALL(frame)   saved_pc_after_call(frame) */
-
+#define        SAVED_PC_AFTER_CALL(frame) read_register (LR_REGNUM)
 
 /* Address of end of stack space.  */
 
@@ -423,7 +421,7 @@ extern unsigned int rs6000_struct_return_address;
    does not, FRAMELESS is set to 1, else 0.  */
 
 #define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \
-       FRAMELESS = frameless_function_invocation (FI)
+       FRAMELESS = frameless_function_invocation (FI, 0)
 
 /* Functions calling alloca() change the value of the stack pointer. We
    need to use initial stack pointer (which is saved in r31 by gcc) in 
@@ -436,17 +434,19 @@ extern unsigned int rs6000_struct_return_address;
        CORE_ADDR initial_sp;                   /* initial stack pointer. */ \
        struct frame_saved_regs *cache_fsr;     /* saved registers        */
 
-/* Frameless function invocation in IBM RS/6000 is half-done. It perfectly
-   sets up a new frame, e.g. a new frame (in fact stack) pointer, etc, but it 
-   doesn't save the %pc. In the following, even though it is considered a 
-   frameless invocation, we still need to walk one frame up. */
+/* Frameless function invocation in IBM RS/6000 is sometimes
+   half-done. It perfectly sets up a new frame, e.g. a new frame (in
+   fact stack) pointer, etc, but it doesn't save the %pc.  We call
+   frameless_function_invocation to tell us how to get the %pc.  */
 
 #define        INIT_EXTRA_FRAME_INFO(fromleaf, fi)     \
        fi->initial_sp = 0;             \
        fi->cache_fsr = 0;
 
-#define FRAME_SAVED_PC(FRAME)          \
-       read_memory_integer (read_memory_integer ((FRAME)->frame, 4)+8, 4)
+#define FRAME_SAVED_PC(FRAME)                                  \
+       (frameless_function_invocation (FRAME, 1)               \
+        ? SAVED_PC_AFTER_CALL (FRAME)                          \
+        : read_memory_integer (read_memory_integer ((FRAME)->frame, 4)+8, 4))
 
 #define FRAME_ARGS_ADDRESS(FI) \
   (((struct frame_info*)(FI))->initial_sp ?            \