diff -Nur gdb-6.8-orig/gdb/infcmd.c gdb-6.8/gdb/infcmd.c
--- gdb-6.8-orig/gdb/infcmd.c	2008-01-31 14:37:22.000000000 +0200
+++ gdb-6.8/gdb/infcmd.c	2008-09-18 10:42:21.750000000 +0300
@@ -1169,6 +1169,10 @@
   CHECK_TYPEDEF (value_type);
   gdb_assert (TYPE_CODE (value_type) != TYPE_CODE_VOID);
 
+  /* avoid printing the return value, since there is a bug
+   * this way the 'finish' should work */
+  return;
+
   /* FIXME: 2003-09-27: When returning from a nested inferior function
      call, it's possible (with no help from the architecture vector)
      to locate and return/print a "struct return" value.  This is just
diff -Nur gdb-6.8-orig/gdb/msp430-tdep.c gdb-6.8/gdb/msp430-tdep.c
--- gdb-6.8-orig/gdb/msp430-tdep.c	2008-09-18 16:51:30.531250000 +0300
+++ gdb-6.8/gdb/msp430-tdep.c	2008-09-18 16:57:15.453125000 +0300
@@ -49,6 +49,8 @@
 
 #define NUM_REGS 16
 
+#define RETADDR_SIZE_STACK 2
+
 struct gdbarch_tdep
 {
   int dummy;
@@ -140,6 +142,13 @@
 static unsigned short add_8     = 0x5235;
 static unsigned short init_sp   = 0x4031; /* followed by value ... XXX 
                                              assuming no stupid things happen */
+static unsigned short pushm_rd   = 0x1500; /* bitmask: pushm #n, rd */
+/* need constants for the case labels in switch */
+#define add_val_sp		0x5031 	/* add #imm, r1 */
+#define add_2_sp		0x5321
+#define add_4_sp		0x5221
+#define add_8_sp		0x5231
+
 
 /* The base of the current frame is actually in the stack pointer.
    This happens when there is no frame pointer (msp430 ABI does not
@@ -172,10 +181,11 @@
 
 static void msp430_get_trace_data (void);
 
+/*
 static CORE_ADDR msp430_analyze_prologue (struct frame_info *fi,
                                           CORE_ADDR pc,
                                           int skip_prologue);
-
+					  */
 static CORE_ADDR
 msp430_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
 {
@@ -326,14 +336,26 @@
 static int
 get_insn (CORE_ADDR pc)
 {
-  char buf[4];
-  int status = read_memory_nobpt (0xfffful & pc, buf, 2);
+ char buf[4];
+  int status = read_memory_nobpt (0xffffful & pc, buf, 2);
 
   if (status != 0)
     return 0;
   return extract_unsigned_integer (buf, 2);
 }
 
+/* size up to 4 */
+static ULONGEST
+msp430_memory_at(CORE_ADDR addr, int size)
+{
+  char buf[6];
+  int status = read_memory_nobpt (0xffffful & addr, buf, size);
+
+  if (status != 0)
+    return 0;
+  return extract_unsigned_integer (buf, size);
+}
+
 static CORE_ADDR
 msp430_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
@@ -361,11 +383,11 @@
   /* If the start of this function could not be found or if the debbuger
      is stopped at the first instruction of the prologue, do nothing. */
   if (status == 0)
-    return 0xfffful & pc;
+    return 0xffffful & pc;
 
   /* If the debugger is entry function, give up. */
   if (func_addr == entry_point_address ())
-    return 0xfffful & pc;
+    return 0xffffful & pc;
 
   /* At the start of a function, our frame is in the stack pointer. */
   flags = MY_FRAME_IN_SP;
@@ -551,80 +573,153 @@
   struct trad_frame_saved_reg *saved_regs;
 };
 
+/* determine register offsets and return the sp offset */
 static int
-prologue_find_regs (struct msp430_unwind_cache *info,
-                    unsigned short op,
-                    CORE_ADDR addr)
+msp430_do_analyze_prologue (CORE_ADDR pc, CORE_ADDR pc_current, int *register_offsets) 
 {
-  int n;
+  CORE_ADDR stack_size;
+  int insn, rn;
+  int flags;
+  int framesize;
+  int ro;
+  int vpc = 0;
+  int i;
+  int reti = 0; 
+  
+  /* Get the first insn from memory (all msp430 instructions are 16 bits) */
+  insn = get_insn(pc + vpc);
 
-  /* st  rn, @-sp */
-  if ((op & 0x7E1F) == 0x6C1F)
-    {
-      n = (op & 0x1E0) >> 5;
-      info->sp_offset -= 2;
-      info->saved_regs[n].addr = info->sp_offset;
-      return 1;
-    }
+  /* REGISTER_OFFSETS will contain offsets, from the top of the frame
+     (NOT the frame pointer), for the various saved registers or -1
+     if the register is not saved. */
+  for (rn = 0; rn < NUM_REGS; rn++)
+    register_offsets[rn] = -1; 
 
-  /* st2w  rn, @-sp */
-  else if ((op & 0x7E3F) == 0x6E1F)
-    {
-      n = (op & 0x1E0) >> 5;
-      info->sp_offset -= 4;
-      info->saved_regs[n + 0].addr = info->sp_offset + 0;
-      info->saved_regs[n + 1].addr = info->sp_offset + 2;
-      return 1;
-    }
+  /* Analyze the prologue. Things we determine from analyzing the
+     prologue include:
+     * the size of the frame
+     * where saved registers are located (and which are saved)
+     * FP used? */
+  framesize = 0; 
 
-  /* subi  sp, n */
-  if ((op & 0x7FE1) == 0x01E1)
-    {
-      n = (op & 0x1E) >> 1;
-      if (n == 0)
-        n = 16;
-      info->sp_offset -= n;
-      return 1;
-    }
+  /* check eint 
+     Actually, there is only way to check if this is an interrupt
+     is to check eint - enable nested.
+     Ordinary interrupts cannot be caught */
+  if (pc + vpc >= pc_current) /* if stopped in prolog, don/t go beyond current*/
+	  return 0;
+  insn = get_insn(pc + vpc);
 
-  /* mv  r11, sp */
-  if (op == 0x417E)
-    {
-      info->uses_frame = 1;
-      info->fp_offset = info->sp_offset;
-      return 1;
-    }
+  if (insn == eint)
+    vpc += 2;
+    
+  /* check pushes */
+  i = 4;
+  ro = 0;
 
-  /* st  rn, @r11 */
-  if ((op & 0x7E1F) == 0x6816)
+  for (i = 15;  i >= 2;  i--)
+  {
+    int rn;
+    int n, j;
+  if (pc + vpc >= pc_current) /* if stopped in prolog, don/t go beyond current*/
+	  return (ro*2 + framesize);
+    insn = get_insn(pc + vpc);
+    if ((insn & 0xfff0) == push_rn)
     {
-      n = (op & 0x1E0) >> 5;
-      info->saved_regs[n].addr = info->fp_offset;
-      return 1;
+    	rn  = insn & 15;
+	vpc += 2;
+    	ro++;
+    	register_offsets[rn] = ro*2;
+    }
+    else if ((insn & 0xff00) == pushm_rd)
+    {
+	rn  = insn & 0x000f;		/* start destination register */
+	n = ((insn & 0x00f0) >> 4) + 1;	/* actually n-1 was stored */
+	vpc += 2;	
+	for (j=0; j<n; j++)
+	{
+	   ro++;
+	   register_offsets[rn-j] = ro*2;
+	}
     }
+    else
+	break;
+  }
+    
+  /* now check if there is an arg pointer */
+  if (pc + vpc >= pc_current) /* if stopped in prolog, don/t go beyond current*/
+	  return (ro*2 + framesize);
 
-  /* nop */
-  if (op == 0x5E00)
-    return 1;
-
-  /* st  rn, @sp */
-  if ((op & 0x7E1F) == 0x681E)
+  insn = get_insn(pc + vpc);
+  if (insn == load_ap)
+  {
+    vpc += 2;
+    if (pc + vpc >= pc_current) /* if stopped in prolog, don/t go beyond current*/
+	  return (ro*2 + framesize);
+    insn = get_insn(pc + vpc);
+    if (insn == add_val)
     {
-      n = (op & 0x1E0) >> 5;
-      info->saved_regs[n].addr = info->sp_offset;
-      return 1;
+      vpc += 2; /* insn */
+      vpc += 2; /* actual value */
+      if (pc + vpc >= pc_current) /* if stopped in prolog, don/t go beyond current*/
+	  return (ro*2 + framesize);
+      insn = get_insn(pc + vpc);
     }
-
-  /* st2w  rn, @sp */
-  if ((op & 0x7E3F) == 0x3A1E)
+    else if (insn == add_2 || insn == add_4 || insn == add_8)
     {
-      n = (op & 0x1E0) >> 5;
-      info->saved_regs[n + 0].addr = info->sp_offset + 0;
-      info->saved_regs[n + 1].addr = info->sp_offset + 2;
-      return 1;
+      vpc += 2; 
+      if (pc + vpc >= pc_current) /* if stopped in prolog, don/t go beyond current*/
+	  return (ro*2 + framesize);
+      insn = get_insn(pc + vpc);
     }
+  }
+    
+  /* check if stack pointer has been adjusted */
+    
+  if (insn == sub_val)
+  {
+    vpc += 2;
+    if (pc + vpc >= pc_current) /* if stopped in prolog, don/t go beyond current*/
+	  return (ro*2 + framesize);
+    framesize = get_insn(pc + vpc);
+    vpc += 2;
+    insn = get_insn(pc + vpc);
+  }
+  else if (insn == sub_2)
+  {
+    framesize = 2;
+    vpc += 2;
+    if (pc + vpc >= pc_current) /* if stopped in prolog, don/t go beyond current*/
+	  return (ro*2 + framesize);  
+    insn = get_insn(pc + vpc);
+  }
+  else if (insn == sub_4)
+  {
+    framesize = 4;
+    vpc += 2;
+    if (pc + vpc >= pc_current) /* if stopped in prolog, don/t go beyond current*/
+	  return (ro*2 + framesize);    
+    insn = get_insn(pc + vpc);
+  }
+  else if (insn == sub_8)
+  {
+    framesize = 8;
+    vpc += 2;
+    if (pc + vpc >= pc_current) /* if stopped in prolog, don/t go beyond current*/
+	  return (ro*2 + framesize);    
+    insn = get_insn(pc + vpc);
+  }
+    
+  /* check if fp loaded */
+  if (insn == load_fp)
+  {
+    msp430_real_fp = E_SP_REGNUM;
+    flags = MY_FRAME_IN_FP;
+    vpc += 2;
+  }
 
-  return 0;
+  /* Return prev SP addr */
+  return (ro*2 + framesize);
 }
 
 /* Put here the code to store, into fi->saved_regs, the addresses of
@@ -638,7 +733,7 @@
                            void **this_prologue_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (next_frame);
-  CORE_ADDR pc;
+  CORE_ADDR pc, func_addr, prolog_end;
   ULONGEST prev_sp;
   ULONGEST this_base;
   unsigned long op;
@@ -646,6 +741,11 @@
   unsigned short op2;
   int i;
   struct msp430_unwind_cache *info;
+  /* add the prev_pc */
+  ULONGEST prev_pc;
+  /* register memory offset table */
+  int register_offsets[NUM_REGS];
+  int insn;
 
   if ((*this_prologue_cache))
     return (*this_prologue_cache);
@@ -654,62 +754,30 @@
   (*this_prologue_cache) = info;
   info->saved_regs = trad_frame_alloc_saved_regs (next_frame);
 
-  info->size = 0;
-  info->sp_offset = 0;
-
+  pc = frame_pc_unwind (next_frame); 
+  func_addr = frame_func_unwind (next_frame, NORMAL_FRAME);
+  info->sp_offset = msp430_do_analyze_prologue(func_addr, pc, register_offsets);
   info->uses_frame = 0;
-  for (pc = frame_func_unwind (next_frame, NORMAL_FRAME);
-       pc > 0 && pc < frame_pc_unwind (next_frame);
-       pc += 4)
-    {
-      op = get_frame_memory_unsigned (next_frame, pc, 4);
-      if ((op & 0xC0000000) == 0xC0000000)
-        {
-          /* long instruction */
-          if ((op & 0x3FFF0000) == 0x01FF0000)
-            {
-              /* add3 sp,sp,n */
-              short n = op & 0xFFFF;
-              info->sp_offset += n;
-            }
-          else if ((op & 0x3F0F0000) == 0x340F0000)
-            {
-              /* st  rn, @(offset,sp) */
-              short offset = op & 0xFFFF;
-              short n = (op >> 20) & 0xF;
-              info->saved_regs[n].addr = info->sp_offset + offset;
-            }
-          else if ((op & 0x3F1F0000) == 0x350F0000)
-            {
-              /* st2w  rn, @(offset,sp) */
-              short offset = op & 0xFFFF;
-              short n = (op >> 20) & 0xF;
-              info->saved_regs[n + 0].addr = info->sp_offset + offset + 0;
-              info->saved_regs[n + 1].addr = info->sp_offset + offset + 2;
-            }
-          else
-            break;
-        }
-      else
-        {
-          /* short instructions */
-          if ((op & 0xC0000000) == 0x80000000)
-            {
-              op2 = (op & 0x3FFF8000) >> 15;
-              op1 = op & 0x7FFF;
-            }
-          else
-            {
-              op1 = (op & 0x3FFF8000) >> 15;
-              op2 = op & 0x7FFF;
-            }
-          if (!prologue_find_regs (info, op1, pc) 
-              || !prologue_find_regs (info, op2, pc))
-            break;
-        }
-    }
 
-  info->size = -info->sp_offset;
+  info->size = info->sp_offset;
+
+  /* if the arguments were on the stack, the next instruction frees the space by adding back to the SP. Obtain the offset from there */
+  insn = get_insn(pc);
+  switch (insn)
+  {
+     case add_val_sp:
+      	info->sp_offset += get_insn(pc + 2); /* next word is the actual value */
+	break;
+     case add_2_sp:
+       	info->sp_offset += 2;
+	break;
+     case add_4_sp:
+        info->sp_offset += 4;
+	break;	
+     case add_8_sp:
+        info->sp_offset += 8;
+	break;		
+  }
 
   /* Compute the previous frame's stack pointer (which is also the
      frame's ID's stack address), and this frame's base pointer. */
@@ -718,7 +786,7 @@
       /* The SP was moved to the FP.  This indicates that a new frame
          was created.  Get THIS frame's FP value by unwinding it from
          the next frame. */
-      this_base=frame_unwind_register_unsigned (next_frame, E_FP_REGNUM);
+      this_base = frame_unwind_register_unsigned (next_frame, E_FP_REGNUM);
       /* The FP points at the last saved register.  Adjust the FP back
          to before the first saved register giving the SP. */
       prev_sp = this_base + info->size;
@@ -726,32 +794,41 @@
   else
     {
       /* Assume that the FP is this frame's SP but with that pushed
-         stack space added back. */
-      this_base=frame_unwind_register_unsigned (next_frame, E_SP_REGNUM);
-      prev_sp = this_base + info->size;
+         stack space added back. */ 
+      this_base = frame_unwind_register_unsigned (next_frame, E_SP_REGNUM);
+      /* prev_sp is the base with the prolog stack space added back */
+      prev_sp = this_base + info->sp_offset;
     }
 
-  /* Convert that SP/BASE into real addresses. */
-  info->prev_sp = prev_sp;
+  /* return address pushed is at prev_sp for calla, 4 bytes for calla, 2 for call */
+  //  prev_pc = get_frame_memory_unsigned(next_frame, prev_sp, 4);
+  prev_pc = msp430_memory_at(prev_sp, RETADDR_SIZE_STACK);
+
+  /* previous pc address is one instruction ahead of return address */
+  //prev_pc -= 4;
+
+  //printf("\n\n-------- next_frame %p prev_pc: %x prev_sp: %x\n\n", next_frame, (unsigned int) prev_pc, (unsigned int) prev_sp);
+
+  /* Convert the SP/BASE into real addresses. */
+  info->prev_sp = prev_sp + RETADDR_SIZE_STACK; /* +2 or 4 due to the saved return addr */
   info->base = this_base;
 
   /* Adjust all the saved registers so that they contain addresses and
-     not offsets. */
+     not offsets compared to the frame base. */
   for (i = 0; i < NUM_REGS - 1; i++)
-    if (trad_frame_addr_p (info->saved_regs, i))
+    if (register_offsets[i] != -1)
       {
-        info->saved_regs[i].addr = (info->prev_sp + info->saved_regs[i].addr);
+	/* if reg value saved in prolog on stack, set the address where it can be read from */
+        info->saved_regs[i].addr = (prev_sp + register_offsets[i]);
       }
 
-  /* The call instruction moves the caller's PC in the callee's LR.
-     Since this is an unwind, do the reverse.  Copy the location of LR
-     into PC (the address / regnum) so that a request for PC will be
-     converted into a request for the LR. */
-  //info->saved_regs[E_PC_REGNUM] = info->saved_regs[LR_REGNUM];
 
   /* The previous frame's SP needed to be computed.  Save the computed
      value. */
-  trad_frame_set_value (info->saved_regs, E_SP_REGNUM, prev_sp);
+  trad_frame_set_value (info->saved_regs, E_SP_REGNUM, info->prev_sp);
+
+  /* store the prev PC value */
+  trad_frame_set_value(info->saved_regs, E_PC_REGNUM, prev_pc);
 
   return info;
 }
@@ -764,6 +841,9 @@
                              int all)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  /* obtain current frame's registers by unwinding them from the next */
+  struct frame_info *frame_next = get_next_frame(frame);
+
   if (regnum >= 0)
     {
       default_print_registers_info (gdbarch, file, frame, regnum, all);
@@ -773,9 +853,14 @@
     int r;
     for (r = 0; r < E_NUM_REGS; r++)
       {
-        ULONGEST tmp;
+        ULONGEST tmp;	
         //frame_read_unsigned_register (frame, r, &tmp);
-        regcache_cooked_read_unsigned(get_current_regcache(), r, &tmp);
+	//
+	/* if it is the innermost frame */
+	 if (!frame_next)
+            regcache_cooked_read_unsigned(get_current_regcache(), r, &tmp);
+	 else
+	    tmp = frame_unwind_register_unsigned(frame_next, r);
         switch (r)
         {
         case E_PC_REGNUM:
@@ -797,7 +882,7 @@
             fprintf_filtered (file, "  ");
           break;
         }
-        fprintf_filtered (file, "r%d: %04lx  ", r, (long) tmp);
+        fprintf_filtered (file, "r%d: %05lx  ", r, (long) tmp);
         if ((r%4) == 3)
           fprintf_filtered (file, "\n");
       }
