RS/6000 portability changes (for hosting cross-debuggers).
[deliverable/binutils-gdb.git] / gdb / i860-tdep.c
index 2742fbd6892e20278839df337a5a93b89fa26795..4919866e2a871f9837207a619cfe8e197cea01c6 100644 (file)
@@ -1,8 +1,7 @@
 /* Machine-dependent code which would otherwise be in inflow.c and core.c,
    for GDB, the GNU debugger.
-   Copyright (C) 1992 Free Software Foundation, Inc.
+   Copyright (C) 1986, 1987 Free Software Foundation, Inc.
    This code is for the i860 cpu.
-   Contributed by Peggy Fieland (pfieland@stratus.com)
    
    GDB is distributed in the hope that it will be useful, but WITHOUT ANY
    WARRANTY.  No author or distributor accepts responsibility to anyone
    In other words, go ahead and share GDB, but don't try to stop
    anyone else from sharing it farther.  Help stamp out software hoarding!
    */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
 
 #include "defs.h"
 #include "tm-i860.h"
 #include "symtab.h"
 #include "value.h"
 
-#include "tm-i860.h"
 #include "i860-opcode.h"
 
-#include <stdio.h>
-#include "break.h"
+#include "breakpoint.h"
+#include "i860-break.h"
+#include "command.h"
+#include "target.h"
 
 #ifdef notdef
-
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/dir.h>
-
 #endif
 
 #include <signal.h>
 
 #include <a.out.h>
 #include <sys/file.h>
-#include <sys/stat.h>
 #include <core.h>
 
 #include <sys/user.h>
-
 #include <elf.h>
 #include <sys/elftypes.h>
 #include <sys/elf_860.h>
 #include <libelf.h>
 
 
+extern int read_memory();
+extern int write_memory();
+extern int read_memory_integer();
+extern int print_insn();
+extern void bzero();
+extern void bcopy();
+
 int btdebug = 0;    /* change value to 1 to enable debugging code */
+int ansi_conformant;
 
 #define  BTDEBUG  if (btdebug) btdebug_message
 
-#include <stdarg.h>
+extern int errno;
+extern int attach_flag;
+extern char registers[];
+CORE_ADDR get_saved_basereg();
 
-int read_memory();
-int write_memory();
+#define INSTRUCTION_LENGTH 4
+#define REGISTER_LENGTH 4
+#define ALIGN_ARG(size,len)  ((size + (len-1))&(-len)) 
+#define NUM_FLOAT_ARG_REGS 8
+#define NUM_INT_ARG_REGS 12
 
-btdebug_message(char *format, ...)
+/* routine to print debugging messages */
+void btdebug_message(char *format, ...)
 {      
    va_list     arglist;
    va_start( arglist, format );
@@ -82,10 +97,590 @@ btdebug_message(char *format, ...)
    va_end  ( arglist     );
 }
 
-extern int errno;
-extern int attach_flag;
+\f
+/* Peggy Fieland. Routine that attempts to find the start of the entry sequence
+   for a routine. */
+/* maximum number of instrutions to search back */
+#define MAX_ROUTINE_SIZE 4096
+CORE_ADDR find_entry_start(pc)
+CORE_ADDR pc;
+{
+   CORE_ADDR instr, top_pc;
+   int i;
+   
+   top_pc = pc;
+   for (i = 0; i <  MAX_ROUTINE_SIZE; ++i)
+
+      {
+         instr = (unsigned)( adj_read_memory_integer (top_pc));
+         /* Recognize "addu|adds -X,sp,sp" insn. */
+
+         if ((instr & 0xEFFF0000) == 0x84420000) 
+            {
+             return (top_pc);
+            } 
+         top_pc -= INSTRUCTION_LENGTH;
+      }
+   return (0);
+}
+
+
+\f
+/* Written by Peggy Fieland (Margaret_Fieland@vos.stratus.com) */
+/* get the contents of a base register.  Used for dwarf OP_BASEREG */
+/* At present, only OP_BASEREG generated is for R28.  NOTE that for stuff based on R28,
+   the value we want is the VALUE AT PROCEDURE INVOKATION, and thus is the frame we
+   use to get the value is the caller's frame. */
+CORE_ADDR get_saved_basereg (frame, basereg)
+FRAME frame;
+int basereg;
+{
+   CORE_ADDR addr;
+   if (basereg == R28)   /* Unconditionally ??? */
+      {
+         frame = get_prev_frame (frame);
+         get_saved_register((char *) &addr, (int *) NULL,  (CORE_ADDR *) NULL, frame,
+                            basereg, (enum lval_type *)NULL);
+
+      }
+   else
+      get_saved_register((char *) &addr, (int *) NULL,  (CORE_ADDR *) NULL, frame,
+                         basereg, (enum lval_type *)NULL);
+
+   return (addr);
+}
+  
+\f
+
+/* return nonzero if the routine containing pc has been 
+ * compiled with -g. We assume -g if the first instruction is 
+ * an  addu|adds -X,sp and the second is st.l fp,XX(sp) 
+ *
+ *     based on  skip_prologue();
+ */
+
+static int g_routine(pc)
+
+     CORE_ADDR pc;
+{
+   CORE_ADDR instr;
+   CORE_ADDR top_pc;
+   
+   top_pc = get_pc_function_start(pc);
+   if (top_pc == NULL)
+     top_pc = find_entry_start (pc);
+
+   if (top_pc != NULL)
+      {
+         instr = (unsigned)( adj_read_memory_integer (top_pc));
+         /* Recognize "addu|adds -X,sp,sp" insn. */
+   
+         if ((instr & 0xEFFF0000) == 0x84420000) 
+            {
+               top_pc += INSTRUCTION_LENGTH;
+               instr =  (unsigned)(adj_read_memory_integer (top_pc));
+      
+               if( (instr & 0xFFE0F801) == 0x1C401801 )    /* st.l fp,X(sp) */
+                  return(1);
+            } 
+      }
+   return(0);
+}
+
+
+/* return the stack offset where the fp register is stored */
+static int find_fp_offset(pc)
+CORE_ADDR pc;
+{
+   int fp_off,i;
+   CORE_ADDR   instr;
+   
+   /* look for the instruction and examine the offset */
+   
+   for (i=INSTRUCTION_LENGTH*1; i< INSTRUCTION_LENGTH*4; i+=INSTRUCTION_LENGTH){
+      instr =   (unsigned)(adj_read_memory_integer(pc+i));
+      if( (instr & 0xFFE0F801) == 0x1C401801) {    /* st.l fp,X(sp) */
+         
+         fp_off = SIGN_EXT16(((instr&0x001F0000) >> 5) | 
+                             (instr&0x000007FE));
+         return(fp_off);
+      }
+   }
+   return(0);
+}
+
+
+/* return the stack offset where r1 (return linkage ) register is stored */
+static CORE_ADDR find_r1(pc,sp,fp)
+CORE_ADDR pc,sp, fp;
+{
+   int r1_off,i;
+   CORE_ADDR   instr, ret_pc;
+   
+   /* look for the instruction and examine the offset */
+   
+   for (i=INSTRUCTION_LENGTH*1; i< INSTRUCTION_LENGTH*4; i+=INSTRUCTION_LENGTH)
+      {
+         instr = (unsigned)( adj_read_memory_integer(pc+i));
+         if ((instr & 0xFFE0F801) == 0x1C400801) 
+            { 
+               /* st.l r1,X(sp) */
+         
+               r1_off = SIGN_EXT16(((instr&0x001F0000) >> 5) | 
+                                   (instr&0x000007FE));
+               ret_pc = read_memory_integer(sp+r1_off,sizeof(long));
+               return(ret_pc);
+            }
+         else if ((instr & 0xFFE0F801) == 0x1C600801) 
+         { 
+            /* st.l r1,X(fp) */
+            r1_off = SIGN_EXT16(((instr&0x001F0000) >> 5) | 
+                                (instr&0x000007FE));
+            ret_pc = read_memory_integer(fp+r1_off,sizeof(long));
+            return(ret_pc);
+         }
+      }
+   return(0);
+}
+
+CORE_ADDR skip_prologue(CORE_ADDR);
+
+/* does routine starting at pc build a stack frame of any kind?? */
+static int has_a_frame(pc)
+CORE_ADDR pc;
+{
+   if( skip_prologue(pc) != pc )return(1);
+   else return(0);
+}
+
+
+/* written by Peggy Fieland Margaret_Fieland@vos.stratus.com
+   Routine to validate the return register and the frame pointer
+   This routine is called when the routine we are in doesn't have a frame
+   In that case, we assume that the return address and frame pointer have 
+   not been touched.  In the following routine, we try to range check them 
+  to see if they are valid. */
+
+static int valid_regs (rp, fp)
+CORE_ADDR rp, fp;
+{
+   if ( ( (rp % 4) != 0) | ( (fp % 16) != 0) )
+      return (0);
+   else 
+      return (1);
+}
+/* get the pc and frame pointer (or sp )
+ * for the routine that called us
+ * when we (this_pc) is not within a  -g routine
+ * if caller is non g we return sp for fp
+ */
+
+/* note this is written for Metaware version R2.1d compiler */
+/* Modified by Peggy Fieland Margaret_Fieland@vos.stratus.com */
+static int caller_pc(this_pc,this_sp,this_fp,to_pc,to_fp, called_from_frame_chain)
+     CORE_ADDR this_pc,this_sp, this_fp;
+     CORE_ADDR *to_pc, *to_fp;
+     int called_from_frame_chain;
+{
+   CORE_ADDR func_start;
+   int sp_offset,offset;
+   CORE_ADDR sp,pc,fp,instr;
+   
+   BTDEBUG("caller_pc %x sp = %x\n",this_pc,this_sp);
+   
+   func_start = get_pc_function_start(this_pc);
+
+   if (func_start == NULL)
+      func_start = find_entry_start (this_pc);
+
+   BTDEBUG("caller_pc func_start %x\n", func_start);
+
+   if ((func_start == NULL))
+      {
+               /* error in traceback */
+               fprintf(stderr, "error, unable to find start of function\n");
+               return(0);
+               
+      }
+
+   if (func_start!= NULL)
+      {
+         if( has_a_frame(func_start) ){
+      
+            BTDEBUG("has_a_frame\n");
+      
+            /* if our caller has a preamble and 
+             * declares space for a stack frame
+             * then we must work to find our return address
+             */
+            instr = (unsigned)( adj_read_memory_integer (func_start));
+            /* Recognize "addu|adds -X,sp,sp" insn. */
+      
+            if ((instr & 0xEFFF0000) == 0x84420000)
+               sp_offset=SIGN_EXT16(instr&0x0000FFFF);
+         }
+         else  
+            { 
+               /* if we get here, procedure doesn't have a frame.  If we
+                  do anything weird, the frame pointer and return register have
+                  the values we want.  Check them to see if they are valid. */
+                  
+               CORE_ADDR temp_rp, temp_fp;
+
+               /* temporary warning, since at the moment we don't have support for
+                  the shared library */
+               
+               temp_rp = read_register(RP_REGNUM);
+               temp_fp = read_register(FP_REGNUM);
+
+               if (!valid_regs(temp_rp, temp_fp))
+                  {           
+                     fprintf(stderr, 
+                             "error - unable to find return address, traceback terminating\n");
+                     return(0);
+                  }
+               BTDEBUG("caller_pc no frame, using r1 %x and fp %x\n",
+                       temp_rp, temp_fp);
+               *to_pc = temp_rp;
+               *to_fp = temp_fp;
+               return (1);
+            }
+      
+      BTDEBUG("sp_offset = %d %x\n",sp_offset,sp_offset);
+      
+         pc = find_r1(func_start, this_sp, this_fp);
+      
+      if(pc == NULL)
+         {
+
+            /* r1 wasn't stored between pc and function start */
+            pc = read_register (RP_REGNUM);
+         }
+
+      sp= this_sp - sp_offset;
+      
+      BTDEBUG("callers pc = %x sp = %x\n",pc,sp);
+      
+      /* our caller a -g routine  ?
+       * if he is we have to find his real fp
+       * else provide the sp as his fp
+       */
+      
+      if( g_routine(pc) ){
+         
+         BTDEBUG("caller_a_g\n");
+         
+         if( ! (offset = find_fp_offset(func_start)) ) {
+            fprintf(stderr, "error - unable to find caller frame for routine at 0x%x, "
+                    "traceback terminating\n", func_start);
+            return(0);
+         }
+         BTDEBUG("offset = %x %d\n",offset,offset);
+         
+         fp = read_memory_integer(this_sp+offset,sizeof(long));
+         *to_pc = CLEAN_PC(pc);
+         *to_fp = fp;
+         return(1);
+      }else  
+         *to_pc = CLEAN_PC(pc);
+      *to_fp = sp;
+      return(1);
+   } else {
+/*      pc = read_register(RP_REGNUM); */
+/*       pc = 0;  */
+      /* if we get here, procedure doesn't have a frame.  If we didn't
+         do anything weird, the frame pointer and return register have
+         the values we want.  Check them to see if they are valid. */
+                  
+      CORE_ADDR temp_rp, temp_fp;
+      
+      temp_rp = read_register(RP_REGNUM);
+      temp_fp = read_register(FP_REGNUM);
+      
+      if (!valid_regs(temp_rp, temp_fp))
+         {           
+            fprintf(stderr, 
+                    "error - unable to find return address, traceback terminating\n");
+
+            return(0);
+         }
+      BTDEBUG("caller_pc no frame, using r1 %x and fp %x\n",
+              temp_rp, temp_fp);
+      *to_pc = temp_rp;
+      *to_fp = temp_fp;
+      return (1);
+   }
+}
+
+/*
+ ** Figure out address to place next breakpoint. Avoid tricky spots, 
+ **    ie. delayed instruction slots etc.
+ ** Need to upgrade this later to allow delayed instruction breakpoints
+ **    with fix-up work done AFTER breakpoint.
+ ** Note that this routine DOES deal with dual instruction mode
+ */
+#define BIM 0x8008
+
+static branch_type
+   place_brk (addr, mode, brk)
+CORE_ADDR addr; 
+int mode;
+struct breakpoint *brk;
+{
+   CORE_ADDR  instr;
+   CORE_ADDR nextadr, prevadr;
+   int val = not_branch;
+   long offset; /* Must be signed for sign-extend */
+   prevadr = nextadr = 0;
+   
+   brk->address1 = 0;
+   
+   if (mode == SINGLE_STEP_MODE)
+      {
+         if (INDIM || ENDIM)
+            {
+                       nextadr = brk->address   = (addr +  INSTRUCTION_LENGTH*2);
+                       instr   =  (unsigned)(adj_read_memory_integer ((addr + INSTRUCTION_LENGTH)));
+                       brk->mode       = DIM;
+            }
+         else
+            {
+                       nextadr = brk->address   = (addr + INSTRUCTION_LENGTH);
+                       instr   =  (unsigned)(adj_read_memory_integer (addr));
+                       if (STDIM) 
+                  brk->mode = DIM;
+                       else
+                  brk->mode = SIM;
+            }
+         
+         
+         /*
+          ** For br/call one more sequential instruction gets executed and  then we
+          **   continue at the current addr + offset. We are definitely going to
+          **   the dest. We are NOT allowed to place a breakpoint in the "delay"
+          **   slot - (the next sequential instruction) so we only place 1 breakpoint
+          **   at the destination.
+          ** For the bc/bnc the next instruction executed is EITHER the next sequential
+          **   or the destination of the branch, we therefore place 2 breakpoints one
+          **   at each location.
+          ** For the bc.t/bnc.t either 1 more sequential instruction is performed
+          **   followed by a branch (like br/call) OR we skip the sequential 
+          **   instruction and keep going. We therefore place a breakpoint at the
+          **   destination of the branch AND the second sequential instruction after
+          **   the branch. Again a breakpoint is NOT allowed in the "delay slot"
+          */
+         if ((instr & 0xE0000000) == 0x60000000 &&     /* CTRL format */
+             (instr & 0xF8000000) != 0x60000000)               /* not pfld.y  */
+            {
+               if      ((instr & 0xF8000000) == 0x68000000)    /* br or call */
+                  val = uncond_d;
+               else if ((instr & 0xF4000000) == 0x74000000)    /* bc.t/bnc.t */
+                  val = cond_d;
+               else if ((instr & 0xF4000000) == 0x70000000)    /* bc or bnc  */
+                  val = cond;
+               offset = (instr & 0x03ffffff);
+               if (offset & 0x02000000)                        /*?sign extend*/
+                  offset |= 0xFC000000;
+               if (val == uncond_d)                    /* br/call*/
+                  prevadr = 0;
+               else if (val == cond_d)                 /* bc.t/bnc.t */
+                  {
+                     if ((INDIM) && !(ENDIM))
+                        prevadr = nextadr + (2*INSTRUCTION_LENGTH);
+                     else
+                        prevadr = nextadr + INSTRUCTION_LENGTH;
+                  } else {                             /* bc  /bnc   */
+                     if ((INDIM) && !(ENDIM))
+                        prevadr = nextadr;
+                     else
+                        prevadr = nextadr;
+                  }
+               nextadr += (offset << 2);
+            }
+         /*
+          ** We treat the bri/calli the same way as the br/call case.
+          */
+         else if ((instr & 0xFC00003F) == 0x4C000002 ||                /* calli    */
+                  (instr & 0xFC000000) == 0x40000000)          /* bri      */
+            {
+               val     = uncond_d;
+               offset  = ((instr & 0x0000F800) >> 11);
+               nextadr = (read_register(offset + R0) & 0xFFFFFFFC);
+               prevadr = 0;
+            }
+         /*
+          ** We treat the bte/btne the same way as the bc/bnc case.
+          */
+         else if ((instr & 0xF0000000) == 0x50000000)          /* bte/btne */
+            {
+               val = cond;
+               offset = SIGN_EXT16(((instr & 0x001F0000) >> 5)  | 
+                                   (instr & 0x000007FF));
+               if ((INDIM) && !(ENDIM))
+                  prevadr = nextadr;
+               else
+                  prevadr = nextadr;
+               
+               nextadr += (offset << 2);
+            }
+         /*
+          ** We treat the bte/btne the same way as the bc/bnc case.
+          **   With the caveat that the 2 breakpoints may turn out to be at the same
+          **   address in which case we ignore one of them.
+          */
+         else if ((instr & 0xFC000000) == 0xB4000000)          /* bla */
+            {
+               val     = cond_d;
+               offset  = SIGN_EXT16(((instr & 0x001F0000) >> 5)  | 
+                                      (instr & 0x000007FF));
+               if ((INDIM) && !(ENDIM))
+                  {
+                     prevadr = nextadr + 2*INSTRUCTION_LENGTH;
+                  } else       {
+                     prevadr = nextadr + INSTRUCTION_LENGTH;
+                  }
+               nextadr += (offset << 2);
+               if (prevadr == nextadr) prevadr = 0;
+            }
+      } else   {
+         int adjust = 0;
+         
+         nextadr = addr;
+         
+         if (ISDIM(FOPADR(addr)))
+            {
+               if (ISDIM(FOPADR(nextadr- INSTRUCTION_LENGTH*2)))
+                  {
+                     instr     =  (unsigned)(adj_read_memory_integer(CORADR(addr
+                                                       -(INSTRUCTION_LENGTH*2))));
+                     brk->mode = DIM;
+                  } else       {
+                     instr     =  (unsigned)(adj_read_memory_integer(addr-INSTRUCTION_LENGTH));
+                     brk->mode = RIM;
+                  }
+            } else {
+               if (ISDIM(addr-INSTRUCTION_LENGTH))
+                  {
+                     instr     =  (unsigned)(adj_read_memory_integer(addr-INSTRUCTION_LENGTH));
+                     brk->mode = BIM;
+                  } else       {
+                     instr     =  (unsigned)(adj_read_memory_integer (addr-INSTRUCTION_LENGTH));
+                     brk->mode = SIM;
+                  }
+            }
+         
+         /* examine the PREVIOUS instruction to determine if we are in a branch delay
+            slot.  If we are, dont set a break here -- set it on the previous instruction.
+            This code also accounts for dual instruction mode */
+         if ((instr & 0xE0000000) == 0x60000000 &&
+             (instr & 0xF8000000) != 0x60000000)               /* not pfld.y  */
+            {
+               adjust++;
+               /* br    /call */
+               /* bc    /bnc  */
+               /* bc.t  /bnc.t*/
+               if ((instr & 0xF8000000) == 0x68000000) /* br or call */
+                  BTDEBUG(" Breakpoint adjusted to avoid br/call delay slot and multiple breakpoints\n");
+               
+               if ((instr & 0xF4000000) == 0x74000000) /* bc.t or bnc.t */
+                  BTDEBUG(" Breakpoint adjusted to avoid bc.t/bnc.t delay slot and"
+                          "multiple breakpoints\n");
+
+               /* it IS really OK to set a break on the instruction AFTER the conditional branch
+                  -- it DOESN't have a delay slot */
+               if ((instr & 0xF4000000) == 0x70000000) /* bc / bnc */
+                  adjust = 0; 
+            } else if
+               ((instr & 0xFC00003F) == 0x4C000002 ||  /* bri/  calli */
+                (instr & 0xFC000000) == 0x40000000)    
+                  {
+                     adjust++;
+                     BTDEBUG(" Breakpoint adjusted to avoid calli/bri delay slot and"
+                             " multiple breakpoints\n");
+                  } else if
+                     ((instr & 0xF0000000) == 0x50000000) /* bte - btne */
+                        {
+                           /* it's OK to set a break here -- we are NOT in aa branch delay slot */
+                           /*
+                           adjust++;
+                           printf(" Breakpoint adjusted to avoid bte/btne multiple breakpoints\n");
+                           */
+                           adjust = 0;
+                        } else if
+                           ((instr & 0xFC000000) == 0xB4000000)
+                              {
+                                 adjust++;
+                                 BTDEBUG(" Breakpoint adjusted to avoid bla delay slot and"
+                                         " multiple breakpoints\n");
+                              }
+         if (adjust != 0)
+            {
+               if (brk->mode == DIM)
+                  {
+                     nextadr -= INSTRUCTION_LENGTH*2;
+                     nextadr = CORADR(nextadr); 
+                  }
+               else
+                  nextadr -= INSTRUCTION_LENGTH;
+            }
+         
+      }
+   
+   if (brk->mode == RIM) 
+      brk->mode = DIM;
+   if (brk->mode == BIM) 
+      brk->mode = SIM;
+   
+   if (nextadr != NULL)
+      {
+         if (brk->mode == DIM)
+            {
+               brk->act_addr[0] = CORADR(nextadr);
+               brk->act_addr[1] = FOPADR(nextadr);
+            } else     {
+               brk->act_addr[0] = nextadr;
+               brk->act_addr[1] = 0;
+            }
+      }
+   
+   if (prevadr != NULL)
+      {
+         brk->address1 = prevadr;
+         if (brk->mode == DIM)
+            {
+               brk->act_addr[2] = CORADR(prevadr);
+               brk->act_addr[3] = FOPADR(prevadr);
+            } else     {
+               brk->act_addr[2] = prevadr;
+               brk->act_addr[3] = 0;
+            }
+      } else   {
+         brk->act_addr[2] = brk->act_addr[3] = 0;
+      }
+   return val;
+}
 
+/* This routine checks to see if r1 has been stored into the frame between
+   the addresses prologue_start and prologue_end. Recognize stores of r1 
+   relative to both the sp and fp registers. */
+static int has_stored_r1(CORE_ADDR prologue_start, CORE_ADDR prologue_end)
+{
+   CORE_ADDR instr;
+   CORE_ADDR addr;
+   
+   BTDEBUG("has_stored_r1, prologue_start %x, prologue_end %x\n",
+           prologue_start, prologue_end);
 
+   for (addr = prologue_start; addr <= prologue_end;  addr += INSTRUCTION_LENGTH)
+      {
+   
+         instr =  (unsigned)(adj_read_memory_integer (addr));
+         if   ((instr & 0xFFE0F801) == 0x1C400801 /* st.l r1,X(sp) */
+            || (instr & 0xFFE0F801) == 0x1C600801) /* st.l r1,X(fp) */
+            return (1);
+      }
+   return 0;
+}
 /* This is used when GDB is exiting.  It gives less chance of error.*/
 
 
@@ -96,7 +691,6 @@ extern int attach_flag;
 
 static struct breakpoint brk;
 typedef char binsn_quantum[sizeof break_insn];
-static binsn_quantum break_mem[2];
 
 /* Non-zero if we just simulated a single-step ptrace call.  This is
    needed because we cannot remove the breakpoints in the inferior
@@ -104,88 +698,108 @@ static binsn_quantum break_mem[2];
    i860. */
 
 int one_stepped;
+
+/* single_step() is called just before we want to resume the inferior,
+   if we want to single-step it but there is no hardware or kernel single-step
+   support.  We find all the possible targets of the coming instruction and 
+   breakpoint them.
+
+   single_step is also called just after the inferior stops.  If we had
+   set up a simulated single-step, we undo our damage.  */
+/* Note that we don't need the parameter, but it's dictated as part of the interface. */
 void
    single_step (signal)
 int signal;
 {
    CORE_ADDR pc;
    branch_type place_brk();
-   
+   int *shadow0, *shadow1, *shadow2, *shadow3;
+
+   shadow0 = (int *) &brk.shadow_contents[0];
+   shadow1 = (int *) &brk.shadow_contents[4];
+   shadow2 = (int *) &brk.shadow_contents[8];
+   shadow3 = (int *) &brk.shadow_contents[12];
    pc = read_register (PC_REGNUM);
    
    if (!one_stepped)
       {
          brk.address = pc;
          place_brk (pc, SINGLE_STEP_MODE, &brk);
-         brk.shadow_contents[0] = brk.shadow_contents[1] = 0;
-         brk.shadow_contents[2] = brk.shadow_contents[3] = 0;
+        *shadow0 = *shadow1 = *shadow2 = *shadow3 = 0;
          
          if (brk.mode == DIM)
             {
-               if ( brk.address1 )
+               if (btdebug != 0)
+                  {
+                     btdebug_message(" DIM1 -> %x : ", brk.act_addr[3]);
+                     print_insn( brk.act_addr[3], stderr);
+                     btdebug_message("\t -|-  %x : ", brk.act_addr[2]);
+                     print_insn( brk.act_addr[2], stderr);
+                     btdebug_message("\n");
+                  }
+               if (( brk.address1 != NULL))
                   { 
-                     printf(" DIM1 ->");
-                     printf(" %x : ", brk.act_addr[3]);
-                     print_insn( brk.act_addr[3], stdout);
-                     printf("\t -|- ");
-                     printf(" %x : ", brk.act_addr[2]);
-                     print_insn( brk.act_addr[2], stdout);
-                     printf("\n");
-                     fflush(stdout);
-                     
-                     adj_read_memory  (brk.act_addr[2], &brk.shadow_contents[2],       4);
-                     adj_write_memory (brk.act_addr[2], break_insn,            4);
-                     adj_read_memory  (brk.act_addr[3], &brk.shadow_contents[3],       4);
-                     /*                adj_write_memory (brk.act_addr[3], float_insn,          4); */
+                     adj_read_memory  (brk.act_addr[2], shadow2,
+                                       INSTRUCTION_LENGTH);
+                     adj_write_memory (brk.act_addr[2], break_insn, INSTRUCTION_LENGTH);
+                     adj_read_memory  (brk.act_addr[3], shadow3,
+                                       INSTRUCTION_LENGTH);
+                     /*                adj_write_memory (brk.act_addr[3], float_insn,
+                              INSTRUCTION_LENGTH); */
                      
                   }
-               if ( brk.address1)
-                  printf(" DIM2 ->");
-               else
-                  printf(" DIM1 ->");
+               if (btdebug != 0)
+                  {
+                     if ( brk.address1 != 0)
+                        btdebug_message(" DIM2 ->");
+                     else
+                        btdebug_message(" DIM1 ->");
                
-               printf(" %x : ", brk.act_addr[1]);
-               print_insn( brk.act_addr[1], stdout);
-               printf("\t -|- ");
-               printf(" %x : ", brk.act_addr[0]);
-               print_insn( brk.act_addr[0], stdout);
-               printf("\n");
-               fflush(stdout);
+                     btdebug_message(" %x : ", brk.act_addr[1]);
+                     print_insn( brk.act_addr[1], stderr);
+                     btdebug_message("\t -|-  %x : ", brk.act_addr[0]);
+                     print_insn( brk.act_addr[0], stderr);
+                     btdebug_message("\n");
+                  }
                
-               adj_read_memory  (brk.act_addr[0], &brk.shadow_contents[0],     4);
-               adj_write_memory (brk.act_addr[0], break_insn,          4);
-               adj_read_memory  (brk.act_addr[1], &brk.shadow_contents[1],     4);
-               /*              adj_write_memory (brk.act_addr[1], float_insn,          4); */
+               adj_read_memory  (brk.act_addr[0], shadow0,
+                                 INSTRUCTION_LENGTH);
+               adj_write_memory (brk.act_addr[0], break_insn,
+                                 INSTRUCTION_LENGTH);
+               adj_read_memory  (brk.act_addr[1], shadow1,
+                                 INSTRUCTION_LENGTH);
+               /*              adj_write_memory (brk.act_addr[1], float_insn,
+                                 INSTRUCTION_LENGTH); */
                
             } 
          else  {
-            if (brk.address1)
+            if (brk.address1 != NULL)
                {
                   if (btdebug)
                      {
-                        printf(" SIM1 ->");
-                        printf(" %x : ", brk.act_addr[2]);
-                        print_insn( brk.act_addr[2], stdout);
-                        printf("\n");
-                        fflush(stdout);
+                        btdebug_message(" SIM1 ->");
+                        btdebug_message(" %x : ", brk.act_addr[2]);
+                        print_insn( brk.act_addr[2], stderr);
+                        btdebug_message("\n");
                      }
-                  adj_read_memory  (brk.act_addr[2], &brk.shadow_contents[2],  4);
-                  adj_write_memory (brk.act_addr[2], break_insn,               4);
+                  adj_read_memory  (brk.act_addr[2], shadow2,
+                                    INSTRUCTION_LENGTH);
+                  adj_write_memory (brk.act_addr[2], break_insn, INSTRUCTION_LENGTH);
                }
             if (btdebug)
                {
-                  if ( brk.address1)
-                     printf(" SIM2 ->");
+                  if ( brk.address1 != NULL)
+                     btdebug_message(" SIM2 ->");
                   else
-                     printf(" SIM1 ->");
+                     btdebug_message(" SIM1 ->");
                   
-                  printf(" %x : ", brk.act_addr[0]);
-                  print_insn( brk.act_addr[0], stdout);
-                  printf("\n");
-                  fflush(stdout);
+                  btdebug_message(" %x : ", brk.act_addr[0]);
+                  print_insn( brk.act_addr[0], stderr);
+                  btdebug_message("\n");
                }
-            adj_read_memory  (brk.act_addr[0], &brk.shadow_contents[0],        4);
-            adj_write_memory (brk.act_addr[0], break_insn,             4);
+            adj_read_memory  (brk.act_addr[0], shadow0,
+                              INSTRUCTION_LENGTH);
+            adj_write_memory (brk.act_addr[0], break_insn,INSTRUCTION_LENGTH);
          }
          
          /* Let it go */
@@ -197,20 +811,26 @@ int signal;
          /* Remove breakpoints */
          if (brk.mode == DIM)
             {
-               adj_write_memory (brk.act_addr[0], &brk.shadow_contents[0], 4);
-               adj_write_memory (brk.act_addr[1], &brk.shadow_contents[1], 4);
+               adj_write_memory (brk.act_addr[0], shadow0,
+                                 INSTRUCTION_LENGTH);
+               adj_write_memory (brk.act_addr[1], shadow1,
+                                 INSTRUCTION_LENGTH);
             } else     {
-               adj_write_memory (brk.act_addr[0], &brk.shadow_contents[0], 4);
+               adj_write_memory (brk.act_addr[0], shadow0,
+                                 INSTRUCTION_LENGTH);
             }
          
-         if (brk.address1)
+         if (brk.address1 != NULL)
             {
                if (brk.mode == DIM)
                   {
-                     adj_write_memory (brk.act_addr[2], &brk.shadow_contents[2], 4);
-                     adj_write_memory (brk.act_addr[3], &brk.shadow_contents[3], 4);
+                     adj_write_memory (brk.act_addr[2], shadow2,
+                                 INSTRUCTION_LENGTH);
+                     adj_write_memory (brk.act_addr[3], shadow3,
+                                 INSTRUCTION_LENGTH);
                   } else       {
-                     adj_write_memory (brk.act_addr[2], &brk.shadow_contents[2], 4);
+                     adj_write_memory (brk.act_addr[2], shadow2,
+                                 INSTRUCTION_LENGTH);
                   }
             }
          one_stepped = 0;
@@ -218,44 +838,12 @@ int signal;
 }
 
 
-\f
-
-/* return nonzero if the routine containing pc has been 
- * compiled with -g. We assume -g if the first instruction is 
- * an  addu|adds -X,sp and the second is st.l fp,XX(sp) 
- *
- *     based on  skip_prologue();
- */
-
-g_routine(pc)
-     CORE_ADDR pc;
-{
-   long instr;
-   int regno;
-   CORE_ADDR top_pc;
-   
-   top_pc = get_pc_function_start(pc);
-   if (top_pc)
-      {
-         instr = adj_read_memory_integer (top_pc);
-         /* Recognize "addu|adds -X,sp,sp" insn. */
-   
-         if ((instr & 0xEFFF0000) == 0x84420000) 
-            {
-               top_pc += 4;
-               instr = adj_read_memory_integer (top_pc);
-      
-               if( (instr & 0xFFE0F801) == 0x1C401801 )    /* st.l fp,X(sp) */
-                  return(1);
-            } 
-      }
-   return(0);
-}
-
 
 /* Written for i860 by Jim Hanko (hanko@orc.olivetti.com) */
 /* This code was based on SPARC code written by Gary Beihl (beihl@mcc.com),
    by Michael Tiemann (tiemann@corto.inria.fr).  */
+/* This routine returns the first memory address following the prologue code,
+   if there is a prologue. */
 
 struct command_line *get_breakpoint_commands ();
 
@@ -263,28 +851,28 @@ CORE_ADDR
    skip_prologue (pc)
 CORE_ADDR pc;
 {
-   long instr;
+   CORE_ADDR instr;
    int regno;
    
-   instr = adj_read_memory_integer (pc);
+   instr =  (unsigned)(adj_read_memory_integer (pc));
    
    /* Recognize "addu|adds -X,sp,sp" insn. */
    if ((instr & 0xEFFF0000) == 0x84420000)
       {
-         pc += 4;
-         instr = adj_read_memory_integer (pc);
+         pc += INSTRUCTION_LENGTH;
+         instr =  (unsigned)(adj_read_memory_integer (pc));
       }
    else
       return(pc);                                      /* No frame! */
    
    /* Recognize store of return addr and frame pointer into frame */
-   while (1)
+   for (; ;)
       {
          if ((instr & 0xFFE0F801) == 0x1C400801 ||  /* st.l r1,X(sp) */
              (instr & 0xFFE0F801) == 0x1C401801)    /* st.l fp,X(sp) */
             {
-               pc += 4;
-               instr = adj_read_memory_integer (pc);
+               pc += INSTRUCTION_LENGTH;
+               instr =  (unsigned)(adj_read_memory_integer (pc));
             }
          else
             break;
@@ -293,13 +881,13 @@ CORE_ADDR pc;
    /* Recognize "addu|adds X,sp,fp" insn. */
    if ((instr & 0xEFFF0000) == 0x84430000)
       {
-         pc += 4;
-         instr = adj_read_memory_integer (pc);
+         pc += INSTRUCTION_LENGTH;
+         instr =  (unsigned)(adj_read_memory_integer (pc));
       }
    
    /* Now recognize stores into the frame from the registers. */
    
-   while (1)
+   for (; ;)
       {
          if ((instr & 0xFFA00003) == 0x1C200001 ||     /* st.l rn,X(fp|sp) */
              (instr & 0xFFA00001) == 0x4C200000)       /* fst.y fn,X(fp|sp) */
@@ -307,8 +895,8 @@ CORE_ADDR pc;
                regno = (instr >> 11) & 0x1f;
                if (regno == 0)                 /* source reg == 0? quit */
                   break;
-               pc += 4;
-               instr = adj_read_memory_integer (pc);
+               pc += INSTRUCTION_LENGTH;
+               instr =  (unsigned)(adj_read_memory_integer (pc));
             }
          else
             break;
@@ -317,7 +905,8 @@ CORE_ADDR pc;
    return(pc);
 }
 
-
+#if 0
+/* This routine is uncalled.  Remove it sometime. */
 /* Set *nextpc to branch target if we find a branch.  If it is not a branch, 
    set it to the next instruction (addr + 4) */
 
@@ -326,13 +915,13 @@ branch_type
    isabranch (addr,  nextpc)
 CORE_ADDR addr, *nextpc;
 {
-   long instr;
+   CORE_ADDR instr;
    branch_type val = not_branch;
    long offset; /* Must be signed for sign-extend */
    
-   printf(" isabranch\n");
+   BTDEBUG(" isabranch\n");
    *nextpc = addr;
-   instr = adj_read_memory_integer (addr);
+   instr =  (unsigned)(adj_read_memory_integer (addr));
    
    if ((instr & 0xE0000000) == 0x60000000 &&           /* CTRL format */
        (instr & 0xF8000000) != 0x60000000)             /* not pfld.y  */
@@ -371,10 +960,11 @@ CORE_ADDR addr, *nextpc;
          *nextpc = addr + 4 + (offset << 2);
       }
    
-   printf(" Final addr - %x\n", *nextpc);
-   /*printf("isabranch ret: %d\n",val); */
+   BTDEBUG(" Final addr - %x\n", *nextpc);
+   /*BTDEBUG("isabranch ret: %d\n",val); */
    return val;
 }
+#endif
 
 /* set in call_function() [valops.c] to the address of the "call dummy" code
    so dummy frames can be easily recognized; also used in wait_for_inferior() 
@@ -383,12 +973,17 @@ CORE_ADDR addr, *nextpc;
 CORE_ADDR call_dummy_set = 0;  /* true if dummy call being done */
 CORE_ADDR call_dummy_start;    /* address of call dummy code */
 
+/* this routine routine gets the values of the registers stored in the frame
+   and stores their values into the frame_saved_regs structure. */
+
+void 
 frame_find_saved_regs(frame_info, frame_saved_regs)
      struct frame_info *frame_info;
      struct frame_saved_regs *frame_saved_regs;
 {
    register CORE_ADDR pc;
-   long instr, spdelta = 0, offset;
+   CORE_ADDR instr;
+   long offset, spdelta = 0;
    int i, size, reg;
    int r1_off = -1, fp_off = -1;
    int framesize;
@@ -402,44 +997,46 @@ frame_find_saved_regs(frame_info, frame_saved_regs)
             at fp + NUM_REGS*4 */
          
          for (i = 1; i < NUM_REGS; i++) /* skip reg 0 */
-            if (i != SP_REGNUM && i != FP0_REGNUM && i != FP0_REGNUM + 1)
-               frame_saved_regs->regs[i] = frame_info->frame + i*4;
-         
-         frame_saved_regs->regs[SP_REGNUM] = frame_info->frame + NUM_REGS*4;
+            /* the register numbers used in the instruction and the ones used to index
+            the regs array are not the same -- compensate */
+            frame_saved_regs->regs[i+R0] = frame_info->frame + i*REGISTER_LENGTH;
          
          call_dummy_set = 0;
          return;
       }
    
    pc = get_pc_function_start (frame_info->pc); 
-   if (pc)
+   if (pc == NULL)
+     pc = find_entry_start (frame_info->pc);
+
+   if (pc != NULL)
       {
-         instr = adj_read_memory_integer (pc);
+         instr =  (unsigned)(adj_read_memory_integer (pc));
          /* Recognize "addu|adds -X,sp,sp" insn. */
          if ((instr & 0xEFFF0000) == 0x84420000)
             {
                framesize = -SIGN_EXT16(instr & 0x0000FFFF);
-               pc += 4;
-               instr = adj_read_memory_integer (pc);
+               pc += INSTRUCTION_LENGTH;
+               instr =  (unsigned)(adj_read_memory_integer (pc));
             }
       }
    else
       goto punt;                                       /* No frame! */
    
    /* Recognize store of return addr and frame pointer into frame */
-   while (1)
+   for (; ;)
       {
          if ((instr & 0xFFE0F801) == 0x1C400801)  /* st.l r1,X(sp) */
             {
                r1_off = SIGN_EXT16(((instr&0x001F0000) >> 5) | (instr&0x000007FE));
-               pc += 4;
-               instr = adj_read_memory_integer (pc);
+               pc += INSTRUCTION_LENGTH;
+               instr =  (unsigned)(adj_read_memory_integer (pc));
             }
          else if ((instr & 0xFFE0F801) == 0x1C401801)    /* st.l fp,X(sp) */
             {
                fp_off = SIGN_EXT16(((instr&0x001F0000) >> 5) | (instr&0x000007FE));
-               pc += 4;
-               instr = adj_read_memory_integer (pc);
+               pc += INSTRUCTION_LENGTH;
+               instr =  (unsigned)(adj_read_memory_integer (pc));
             }
          else
             break;
@@ -449,13 +1046,13 @@ frame_find_saved_regs(frame_info, frame_saved_regs)
    if ((instr & 0xEFFF0000) == 0x84430000)
       {
          spdelta = SIGN_EXT16(instr & 0x0000FFFF);
-         pc += 4;
-         instr = adj_read_memory_integer (pc);
+         pc += INSTRUCTION_LENGTH;
+         instr =  (unsigned)(adj_read_memory_integer (pc));
       }
    
    /* Now recognize stores into the frame from the registers. */
    
-   while (1)
+   for (; ;)
       {
          if ((instr & 0xFFC00003) == 0x1C400001)       /* st.l rn,X(fp|sp) */
             {
@@ -464,7 +1061,7 @@ frame_find_saved_regs(frame_info, frame_saved_regs)
                if (reg == 0)
                   break;
                if ((instr & 0x00200000) == 0)  /* was this using sp? */
-                  if (spdelta)                 /* and we know sp-fp delta */
+                  if (spdelta != 0)                    /* and we know sp-fp delta */
                      offset -= spdelta;                /* if so, adjust the offset */
                   else
                      break;                            /* if not, give up */
@@ -476,10 +1073,10 @@ frame_find_saved_regs(frame_info, frame_saved_regs)
                if (reg == 1)
                   frame_saved_regs->regs[PC_REGNUM] = frame_info->frame + offset;
                else
-                  frame_saved_regs->regs[reg] = frame_info->frame + offset;
+                  frame_saved_regs->regs[reg+R0] = frame_info->frame + offset;
                
-               pc += 4;
-               instr = adj_read_memory_integer (pc);
+               pc +=  INSTRUCTION_LENGTH;
+               instr =  (unsigned)(adj_read_memory_integer (pc));
             }
          else if ((instr & 0xFFC00001) == 0x2C400000) /* fst.y fn,X(fp|sp) */
             {
@@ -499,7 +1096,7 @@ frame_find_saved_regs(frame_info, frame_saved_regs)
                   offset = SIGN_EXT16(instr & 0x0000FFFC);     /* drop 2 bits */
                
                if ((instr & 0x00200000) == 0)  /* was this using sp? */
-                  if (spdelta)                 /* and we know sp-fp delta */
+                  if (spdelta != 0)                    /* and we know sp-fp delta */
                      offset -= spdelta;                /* if so, adjust the offset */
                   else
                      break;                            /* if not, give up */
@@ -508,12 +1105,12 @@ frame_find_saved_regs(frame_info, frame_saved_regs)
                   {
                      frame_saved_regs->regs[reg] = frame_info->frame + offset;
                      
-                     offset += 4;
+                     offset +=  REGISTER_LENGTH;
                      reg++;
                   }
                
-               pc += 4;
-               instr = adj_read_memory_integer (pc);
+               pc +=  INSTRUCTION_LENGTH;
+               instr =  (unsigned)(adj_read_memory_integer (pc));
             }
          else
             break;
@@ -525,67 +1122,18 @@ frame_find_saved_regs(frame_info, frame_saved_regs)
    else
       frame_saved_regs->regs[SP_REGNUM] = frame_info->frame + 8;
    
-   if (spdelta && fp_off != -1)
+   if ((spdelta != 0) && fp_off != -1)
       frame_saved_regs->regs[FP_REGNUM] = frame_info->frame - spdelta + fp_off;
    else
       frame_saved_regs->regs[FP_REGNUM] = frame_info->frame;
    
-   if (spdelta && r1_off != -1)
+   if ((spdelta != 0) && r1_off != -1)
       frame_saved_regs->regs[PC_REGNUM] = frame_info->frame - spdelta + r1_off;
    else
-      frame_saved_regs->regs[PC_REGNUM] = frame_info->frame + 4;
-}
-
-/* return the stack offset where the fp register is stored */
-find_fp_offset(pc)
-{
-   int fp_off,i;
-   long        instr;
-   
-   /* look for the instruction and examine the offset */
-   
-   for(i=4; i<16; i+=4){
-      instr = adj_read_memory_integer(pc+i);
-      if( (instr & 0xFFE0F801) == 0x1C401801) {    /* st.l fp,X(sp) */
-         
-         fp_off = SIGN_EXT16(((instr&0x001F0000) >> 5) | 
-                             (instr&0x000007FE));
-         return(fp_off);
-      }
-   }
-   return(0);
-}
-
-/* return the stack offset where r1 (return linkage ) register is stored */
-
-find_r1_offset(pc)
-{
-   int r1_off,i;
-   long        instr;
-   
-   /* look for the instruction and examine the offset */
-   
-   for(i=4; i<16; i+=4){
-      
-      instr = adj_read_memory_integer(pc+i);
-      if ((instr & 0xFFE0F801) == 0x1C400801) { /* st.l r1,X(sp) */
-         
-         r1_off = SIGN_EXT16(((instr&0x001F0000) >> 5) | 
-                             (instr&0x000007FE));
-         return(r1_off);
-      }
-   }
-   return(-1);
+      frame_saved_regs->regs[PC_REGNUM] = frame_info->frame + 4;
 }
 
 
-/* dose routine starting at pc build a stack frame of any kind?? */
-has_a_frame(pc)
-{
-   if( skip_prologue(pc) != pc )return(1);
-   else return(0);
-}
-
 /* get the frame pointer of the caller.
  * note that only routines that have been compiled with
  * -g have full (XX)fp style stack frames
@@ -597,44 +1145,50 @@ has_a_frame(pc)
 frame_chain(thisframe)
      FRAME thisframe;
 {
-   unsigned long fp, sp, pc;
-   unsigned long func_start;
-   long instr;
+   CORE_ADDR fp, pc;
+   CORE_ADDR func_start;
+   CORE_ADDR instr;
    int offset;
-   unsigned long thisfp = thisframe->frame;
-   
-   /* get the frame pointer actually sp for  a non -g
+   CORE_ADDR thisfp = thisframe->frame;
+   struct frame_saved_regs fsr;   
+   CORE_ADDR thissp;
+           
+      /* get the frame pointer actually sp for  a non -g
     * for the routine that called us routine 
     */
    
    BTDEBUG("FRAME_CHAIN(%x)\n",thisframe);
    
-   if ( !read_memory_integer (thisframe->frame,4))
+   if ( !read_memory_integer (thisframe->frame,sizeof(long)) )
       {
          return (0);
       }
    
    if( ! g_routine(thisframe->pc) ){
+      thissp = get_saved_basereg (thisframe, SP_REGNUM);
+
       BTDEBUG( "non g at %x\n",thisframe->pc);
-      caller_pc(thisframe->pc,thisframe->sp,&pc,&fp);
+      caller_pc(thisframe->pc, thissp, thisfp,&pc,&fp, 1);
       BTDEBUG("caller_pc returned %x %x \n",pc,fp);
       return(fp);
       
    }/* else a -g routine */
    
    
-   fp = read_memory_integer (thisfp, 4);
+   fp = read_memory_integer (thisfp, sizeof(long));
    
-   if (fp < thisfp || fp > STACK_END_ADDR)
+   if (fp < thisfp || fp > (unsigned) STACK_END_ADDR)
       {
          /* handle the Metaware-type pseudo-frame */
          
          func_start = get_pc_function_start(thisframe->pc);
-         
-         if (func_start)
+        if (func_start == NULL)
+          func_start = find_entry_start (thisframe->pc);
+
+         if (func_start != NULL)
             {
                
-               instr = adj_read_memory_integer (func_start);
+               instr =  (unsigned)(adj_read_memory_integer (func_start));
                /* Recognize "addu|adds -X,sp,sp" insn. */
                if ((instr & 0xEFFF0000) == 0x84420000)
                   offset = SIGN_EXT16(instr & 0x0000FFFF);
@@ -649,119 +1203,61 @@ frame_chain(thisframe)
    return(fp);
 }
 
-/* get the pc and frame pointer (or sp )
- * for the routine that called us
- * when we (this_pc) is not within a  -g routine
- * if caller is non g we return sp for fp
- */
-
-/* note this is written for Metaware version R2.1d compiler */
+/* This function returns 1 if there is no stored r1, 0 otherwise.
+   The function returns 1 if the pc is in a function prologue,
+   or the function prologue didn't save the return pointer in
+   the stack frame,  0 otherwise */
 
-caller_pc(this_pc,this_sp,to_pc,to_fp)
-     int * to_pc, *to_fp;
-     unsigned long this_pc,this_sp;
+int no_stored_rp(CORE_ADDR pc)
 {
-   unsigned long func_start;
-   int sp_offset,offset;
-   unsigned long sp,pc,fp,instr;
-   
-   BTDEBUG("caller_pc %x sp = %x\n",this_pc,this_sp);
+   CORE_ADDR func_start, prologue_end;
    
-   func_start = get_pc_function_start(this_pc);
-
-   BTDEBUG("caller_pc func_start %x\n", func_start);
+   func_start = get_pc_function_start(pc);
+   if (func_start == NULL)
+     func_start = find_entry_start (pc);
 
-   if (func_start)
+   if (func_start != NULL)
       {
-         if( has_a_frame(func_start) ){
-      
-            BTDEBUG("has_a_frame\n");
-      
-            /* if our caller has a preamble and 
-             * declares space for a stack frame
-             * then we must work to find our return address
-             */
-            instr = adj_read_memory_integer (func_start);
-            /* Recognize "addu|adds -X,sp,sp" insn. */
-      
-            if ((instr & 0xEFFF0000) == 0x84420000)
-               sp_offset=SIGN_EXT16(instr&0x0000FFFF);
-         }
-         else  { printf("error frame_chain\n");return(0); }
-      
-      BTDEBUG("sp_offset = %d %x\n",sp_offset,sp_offset);
-      
-      offset = find_r1_offset(func_start);
-      
-      if( offset < 0 ){
-         printf("cant find return address for routine at %x\n",
-                func_start);
-         return(0);
-      }
-      pc = read_memory_integer(this_sp+offset,4);
-      sp= this_sp - sp_offset;
-      
-      BTDEBUG("callers pc = %x sp = %x\n",pc,sp);
-      
-      /* our caller a -g routine  ?
-       * if he is we have to find his real fp
-       * else provide the sp as his fp
-       */
-      
-      if( g_routine(pc) ){
-         
-         BTDEBUG("caller_a_g\n");
-         
-         if( ! (offset = find_fp_offset(func_start)) ) {
-            printf("error fp_offset\n");
-            return(0);
-         }
-         BTDEBUG("offset = %x %d\n",offset,offset);
-         
-         fp = read_memory_integer(this_sp+offset,4);
-         *to_pc = CLEAN_PC(pc);
-         *to_fp = fp;
-         return(1);
-      }else  
-         *to_pc = CLEAN_PC(pc);
-      *to_fp = sp;
-      return(1);
-   } else {
-/*      pc = read_register(RP_REGNUM); */
-      pc = 0; 
-      BTDEBUG("read_register pc %x\n",pc);
-      if( g_routine(pc) ){
-         
-         *to_pc = CLEAN_PC(pc);
-         *to_fp = read_register(FP_REGNUM);
-         return(1);
-      }else  {
-         *to_pc = CLEAN_PC(pc);
-         *to_fp = this_sp;
-         return(1);
+         prologue_end = func_start;
+         SKIP_PROLOGUE(prologue_end);
+         if ( (pc >= func_start) && (pc <= prologue_end))
+            {
+               BTDEBUG("no_stored_rp: pc %x is in prologue \n",pc);
+               return 1;
+            }
+         /* otherwise, see if the entry sequence stored the return pointer.
+            If it didn't, return 1 */
+         /* Some procedures , at least, store the return pointer AFTER 
+            the prologue sequence, so check for stores from function start to
+            present pc value. */
+         if (!has_stored_r1(func_start, pc))
+            {  
+               BTDEBUG("no_stored_rp, for pc %x, prologue didn't store r1\n",pc);
+               return 1;
+            }
       }
-   }
-}
+   BTDEBUG("no_stored_rp for pc %x return pointer was stored \n", pc);
 
-int outside_startup_file();
+   return 0; 
+}
 
 /* get the PC of the caller */
-frame_saved_pc(frame_struct)
+CORE_ADDR frame_saved_pc(frame_struct)
 FRAME frame_struct;
 {
-     unsigned long frame;
-     unsigned long pc;
-     unsigned long pc1;
-     unsigned long sp;
-
+     CORE_ADDR frame;
+     CORE_ADDR pc;
+     CORE_ADDR pc1;
+     CORE_ADDR sp ;
      CORE_ADDR fp;
+     struct frame_saved_regs fsr;                                                 
      
-     CORE_ADDR rp;
-
      frame = frame_struct->frame;
      pc = frame_struct->pc;
-     BTDEBUG("frame_saved_pc input: frame %x, pc %x, sp %x ",
-           frame, pc, sp);
+     
+     
+     BTDEBUG("frame_saved_pc input: frame %x, pc %x",
+           frame, pc);
 
      /* First see if this is the current frame. If it is, return the value in r1,
         as it may not have been stored */
@@ -776,21 +1272,23 @@ FRAME frame_struct;
         }
      else if( ! g_routine(pc) )
         {
-           caller_pc(pc,sp,&pc,&frame);
+           sp = get_saved_basereg (frame_struct, SP_REGNUM);
+
+           caller_pc(pc,sp,frame_struct->frame, &pc,&frame, 0);
         }
      else 
         {
            
-           pc = read_memory_integer (frame + 4, 4); 
+           pc = read_memory_integer (frame + 4, sizeof(long)); 
    
-           if (!outside_startup_file(pc))
+           if (inside_entry_file(pc))
               {
                  
-                 BTDEBUG("pc %x outside startup file \n",pc);
+                 BTDEBUG("pc %x outside entry file \n",pc);
 
-                 pc1 = read_memory_integer (frame, 4);
+                 pc1 = read_memory_integer (frame, sizeof(long));
                
-                 if (outside_startup_file(pc1))
+                 if (!inside_entry_file(pc1))
                     pc = pc1;
                  else
                     pc = 0;
@@ -802,315 +1300,181 @@ FRAME frame_struct;
   }
 
 /* Pass arguments to a function in the inferior process - ABI compliant
- */
+   Modified by Peggy Fieland (Margaret_Fieland@vos.stratus.com) to account
+   for newer ABI conventions. Note that now, unfortunately, we MUST KNOW
+   if we expect a float or a double.  For now, we will assume that the
+   caller of this routine has the types of these arguments correct.... 
+   NOTE THAT THIS ROUTINE DOES NO ARGUMENT COERCION -- it's all in the
+   caller.
+   Modified by Peggy Fieland to handle memory argument lists.
+   */
 
-pass_function_arguments(args, nargs, struct_return)
+#define IS_EVEN_REG(fl) (((fl - FP0_REGNUM)%2) == 0)
+CORE_ADDR 
+pass_function_arguments(args, nargs, struct_return, struct_addr, sp)
      value *args;
      int nargs;
      int struct_return;
+     CORE_ADDR struct_addr;
+     CORE_ADDR sp;
 {
-   int ireg = (struct_return) ? 17 : 16;
-   int freg = FP0_REGNUM + 8;
+   int ireg = (struct_return) ? R17 : R16;
+   int freg = F8;
    int i;
    struct type *type;
    value arg;
-   long tmp;
-   value value_arg_coerce();
-   
-   
-   for (i = 0; i < nargs; i++) 
+   signed long tmp;
+   unsigned long ul_tmp;
+   signed short s_tmp;
+   unsigned short us_tmp;
+   signed char c_tmp;
+   unsigned char uc_tmp;
+   CORE_ADDR arg_ptr;
+   int len;
+
+   if (struct_return)
       {
-         arg = value_arg_coerce(args[i]);
-         type = VALUE_TYPE(arg);
-         if (type == builtin_type_double) 
-            {
-               write_register_bytes(REGISTER_BYTE(freg), VALUE_CONTENTS(arg), 8);
-               freg += 2;
-            }
-         else
-            {
-               bcopy(VALUE_CONTENTS(arg), &tmp, 4);
-               write_register(ireg, tmp);
-               ireg++;
-            }
+         write_register(R16, struct_addr);
       }
-   if (ireg >= 28 || freg >= FP0_REGNUM + 16)
-      error("Too many arguments to function");
-}
-
-
-#define SPACES         "       "
-#define P_SPACES       "   "
-#define BYTE 0xff
-
-int screen_lines=24;
 
-char *spec_reg[] = {
-   "fsr", "db", "dirbase", "fir", "psr", "epsr",
-};
-
-char *doro_reg[] = {
-   "scp", "cbsp", "pt_cs", "intmsk", "intack",
-};
-#define NREGS 32
-
-
-get_reg(regno)
-{
-   char raw_buffer[32];
-   int addr;
-   int virtual_buffer;
-   
-   read_relative_register_raw_bytes (regno, raw_buffer);
-   REGISTER_CONVERT_TO_VIRTUAL (addr, raw_buffer, &virtual_buffer);
-   return(virtual_buffer);
-}
-
-int jhdebug = 0;
-/*
- ** Figure out address to place next breakpoint. Avoid tricky spots, 
- **    ie. delayed instruction slots etc.
- ** Need to upgrade this later to allow delayed instruction breakpoints
- **    with fix-up work done AFTER breakpoint.
- ** Note that this routine DOES deal with dual instruction mode
- */
-#define BIM 0x8008
+   arg_ptr = sp; /* Space was allocated for memory argument list in i860_arg_coerce */
 
-branch_type
-   place_brk (addr, mode, brk)
-CORE_ADDR addr; 
-int mode;
-struct breakpoint *brk;
-{
-   long nextadr, prevadr, instr;
-   int val = not_branch;
-   long offset; /* Must be signed for sign-extend */
-   extern char registers[];
-   prevadr = nextadr = 0;
-   
-   brk->address1 = 0;
+   /* Loop through the arguments, putting the values in a register or memory as appropriate. */
    
-   if (mode == SINGLE_STEP_MODE)
-      {
-         if (INDIM || ENDIM)
-            {
-                       nextadr = brk->address   = (addr + 8);
-                       instr   = adj_read_memory_integer ((addr + 4));
-                       brk->mode       = DIM;
-            }
-         else
-            {
-                       nextadr = brk->address   = (addr + 4);
-                       instr   = adj_read_memory_integer (addr);
-                       if (STDIM) 
-                  brk->mode = DIM;
-                       else
-                  brk->mode = SIM;
-            }
-         
-         
-         /*
-          ** For br/call one more sequential instruction gets executed and  then we
-          **   continue at the current addr + offset. We are definitely going to
-          **   the dest. We are NOT allowed to place a breakpoint in the "delay"
-          **   slot - (the next sequential instruction) so we only place 1 breakpoint
-          **   at the destination.
-          ** For the bc/bnc the next instruction executed is EITHER the next sequential
-          **   or the destination of the branch, we therefore place 2 breakpoints one
-          **   at each location.
-          ** For the bc.t/bnc.t either 1 more sequential instruction is performed
-          **   followed by a branch (like br/call) OR we skip the sequential 
-          **   instruction and keep going. We therefore place a breakpoint at the
-          **   destination of the branch AND the second sequential instruction after
-          **   the branch. Again a breakpoint is NOT allowed in the "delay slot"
-          */
-         if ((instr & 0xE0000000) == 0x60000000 &&     /* CTRL format */
-             (instr & 0xF8000000) != 0x60000000)               /* not pfld.y  */
-            {
-               if      ((instr & 0xF8000000) == 0x68000000)    /* br or call */
-                  val = uncond_d;
-               else if ((instr & 0xF4000000) == 0x74000000)    /* bc.t/bnc.t */
-                  val = cond_d;
-               else if ((instr & 0xF4000000) == 0x70000000)    /* bc or bnc  */
-                  val = cond;
-               offset = (instr & 0x03ffffff);
-               if (offset & 0x02000000)                        /*?sign extend*/
-                  offset |= 0xFC000000;
-               if (val == uncond_d)                    /* br/call*/
-                  prevadr = 0;
-               else if (val == cond_d)                 /* bc.t/bnc.t */
-                  {
-                     if ((INDIM) && !(ENDIM))
-                        prevadr = nextadr + 8;
-                     else
-                        prevadr = nextadr + 4;
-                  } else {                             /* bc  /bnc   */
-                     if ((INDIM) && !(ENDIM))
-                        prevadr = nextadr;
-                     else
-                        prevadr = nextadr;
-                  }
-               nextadr += (offset << 2);
-            }
-         /*
-          ** We treat the bri/calli the same way as the br/call case.
-          */
-         else if ((instr & 0xFC00003F) == 0x4C000002 ||                /* calli    */
-                  (instr & 0xFC000000) == 0x40000000)          /* bri      */
-            {
-               val     = uncond_d;
-               offset  = ((instr & 0x0000F800) >> 11);
-               nextadr = (read_register(offset + R0) & 0xFFFFFFFC);
-               prevadr = 0;
-            }
-         /*
-          ** We treat the bte/btne the same way as the bc/bnc case.
-          */
-         else if ((instr & 0xF0000000) == 0x50000000)          /* bte/btne */
-            {
-               val = cond;
-               offset = SIGN_EXT16(((instr & 0x001F0000) >> 5)  | 
-                                   (instr & 0x000007FF));
-               if ((INDIM) && !(ENDIM))
-                  prevadr = nextadr;
-               else
-                  prevadr = nextadr;
-               
-               nextadr += (offset << 2);
-            }
-         /*
-          ** We treat the bte/btne the same way as the bc/bnc case.
-          **   With the caveat that the 2 breakpoints may turn out to be at the same
-          **   address in which case we ignore one of them.
-          */
-         else if ((instr & 0xFC000000) == 0xB4000000)          /* bla */
+   for (i = 0; i < nargs; i++) 
+      {
+         arg = args[i];
+         type = VALUE_TYPE(arg);
+         len = TYPE_LENGTH(type);
+         if (type == builtin_type_double) 
             {
-               val     = cond_d;
-               offset  = SIGN_EXT16(((instr & 0x001F0000) >> 5)  | 
-                                      (instr & 0x000007FF));
-               if ((INDIM) && !(ENDIM))
+               /* see ABI . Note freg MUST BE INCREMENTED even if arg goes into the
+                  memory argument list for this code to work correctly for subsequent
+                  arguments. */
+               if (!IS_EVEN_REG(freg))
+                  freg += 1;
+               /* see if argument can be put in a register, or whether it must go
+                  into the memory argument list */
+               if (freg < F8 + NUM_FLOAT_ARG_REGS)
                   {
-                     prevadr = nextadr + 8;
-                  } else       {
-                     prevadr = nextadr + 4;
+                     /* It can go in a register */
+                     bcopy(VALUE_CONTENTS(arg), &tmp, sizeof(double));
+                     write_register_bytes(REGISTER_BYTE(freg), (char *) &tmp, TYPE_LENGTH(type));
+                     freg += 2;
                   }
-               nextadr += (offset << 2);
-               if (prevadr == nextadr) prevadr = 0;
+               else
+                  {
+                     /* It goes into memory argument list */
+                     arg_ptr = ALIGN_ARG( arg_ptr, sizeof(double));
+                     write_memory (arg_ptr, VALUE_CONTENTS (arg), len);
+                     arg_ptr += len;
+                  }
+                  
             }
-      } else   {
-         int adjust = 0;
-         
-         nextadr = addr;
-         
-         if (ISDIM(FOPADR(addr)))
+         else if (type == builtin_type_float)
             {
-               if (ISDIM(FOPADR(nextadr-8)))
+               if (freg < F8 + NUM_FLOAT_ARG_REGS)
                   {
-                     instr     = adj_read_memory_integer(CORADR(addr-8));
-                     brk->mode = DIM;
-                  } else       {
-                     instr     = adj_read_memory_integer(addr-4);
-                     brk->mode = RIM;
+                     /* It can go in a register */
+                     bcopy(VALUE_CONTENTS(arg), &tmp, sizeof(long));
+                     write_register_bytes (REGISTER_BYTE(freg), (char *) &tmp, TYPE_LENGTH(type));
+                     freg++;
                   }
-            } else {
-               if (ISDIM(addr-4))
-                  {
-                     instr     = adj_read_memory_integer(addr-4);
-                     brk->mode = BIM;
-                  } else       {
-                     instr     = adj_read_memory_integer (addr-4);
-                     brk->mode = SIM;
+               else
+                  { 
+                     /* It goes into the memory argument list */
+                     arg_ptr = ALIGN_ARG(arg_ptr, sizeof(float));
+                     write_memory (arg_ptr, VALUE_CONTENTS (arg), len);
+                     arg_ptr += len;
                   }
             }
-         
-         /* examine the PREVIOUS instruction to determine if we are in a branch delay
-            slot.  If we are, dont set a break here -- set it on the previous instruction.
-            This code also accounts for dual instruction mode */
-         if ((instr & 0xE0000000) == 0x60000000 &&
-             (instr & 0xF8000000) != 0x60000000)               /* not pfld.y  */
+         else
             {
-               adjust++;
-               /* br    /call */
-               /* bc    /bnc  */
-               /* bc.t  /bnc.t*/
-               if ((instr & 0xF8000000) == 0x68000000) /* br or call */
-                  printf(" Breakpoint adjusted to avoid br/call delay slot and multiple breakpoints\n");
+               /* All structs are passed by value, and hence they all go into the memory
+                  argument list (see ABI); otherwise, as above, see if we have run
+                  out of registers */
                
-               if ((instr & 0xF4000000) == 0x74000000) /* bc.t or bnc.t */
-                  printf(" Breakpoint adjusted to avoid bc.t/bnc.t delay slot and multiple breakpoints\n");
-               /* it IS really OK to set a break on the instruction AFTER the conditional branch
-                  -- it DOESN't have a delay slot */
-               if ((instr & 0xF4000000) == 0x70000000) /* bc / bnc */
-                  /* printf(" Breakpoint adjusted to avoid bc/bnc delay slot and multiple breakpoints\n"); */
-                  adjust = 0; 
-            } else if
-               ((instr & 0xFC00003F) == 0x4C000002 ||  /* bri/  calli */
-                (instr & 0xFC000000) == 0x40000000)    
+               /* Cast value correctly so we can load it into a register or into the
+                  memory argument list  -- see ABI */
+               if (TYPE_LENGTH(type)    < sizeof(long))
                   {
-                     adjust++;
-                     printf(" Breakpoint adjusted to avoid calli/bri delay slot and multiple breakpoints\n");
-                  } else if
-                     ((instr & 0xF0000000) == 0x50000000) /* bte - btne */
-                        {
-                           /* it's OK to set a break here -- we are NOT in aa branch delay slot */
-                           /*
-                           adjust++;
-                           printf(" Breakpoint adjusted to avoid bte/btne multiple breakpoints\n");
-                           */
-                           adjust = 0;
-                        } else if
-                           ((instr & 0xFC000000) == 0xB4000000)
-                              {
-                                 adjust++;
-                                 printf(" Breakpoint adjusted to avoid bla delay slot and multiple breakpoints\n");
-                              }
-         if (adjust)
-            {
-               if (brk->mode == DIM)
+                     if (TYPE_FLAGS(type) & TYPE_FLAG_UNSIGNED)
+                        arg = value_cast(builtin_type_unsigned_int, arg);
+                     else 
+                        arg = value_cast (builtin_type_int, arg);
+                     type = VALUE_TYPE(arg);
+                     len = TYPE_LENGTH(type);
+                  }
+               
+               if ((TYPE_CODE(type) == TYPE_CODE_STRUCT) || (ireg >= R16 + NUM_INT_ARG_REGS))
                   {
-                     nextadr -= 8;
-                     nextadr = CORADR(nextadr); 
+                     /* It goes into the memory argument list. Minimum alignment requirements
+                        are on a 4-byte boundary */
+                     
+                     if  ((TYPE_CODE(type) == TYPE_CODE_INT) ||
+                          (TYPE_CODE(type) == TYPE_CODE_ENUM) ||
+                          (TYPE_CODE(type) == TYPE_CODE_CHAR) ||
+                          (TYPE_CODE(type) == TYPE_CODE_BOOL))
+                        arg_ptr = ALIGN_ARG(arg_ptr, len);
+                     else
+                        arg_ptr = ALIGN_ARG (arg_ptr, sizeof(long)); /* align on 4-byte boundary */
+                     write_memory (arg_ptr, VALUE_CONTENTS (arg), len);
+                     arg_ptr += len;
                   }
                else
-                  nextadr -=4;
+                  {
+
+                     bcopy(VALUE_CONTENTS(arg), &tmp, sizeof(long));
+                     write_register(ireg, tmp);
+                     ireg++;
+                  }
+                  
             }
-         
       }
    
-   if (brk->mode == RIM) 
-      brk->mode = DIM;
-   if (brk->mode == BIM) 
-      brk->mode = SIM;
-   
-   if (nextadr)
-      {
-         if (brk->mode == DIM)
-            {
-               brk->act_addr[0] = CORADR(nextadr);
-               brk->act_addr[1] = FOPADR(nextadr);
-            } else     {
-               brk->act_addr[0] = nextadr;
-               brk->act_addr[1] = 0;
-            }
-      }
    
-   if (prevadr)
-      {
-         brk->address1 = prevadr;
-         if (brk->mode == DIM)
-            {
-               brk->act_addr[2] = CORADR(prevadr);
-               brk->act_addr[3] = FOPADR(prevadr);
-            } else     {
-               brk->act_addr[2] = prevadr;
-               brk->act_addr[3] = 0;
-            }
-      } else   {
-         brk->act_addr[2] = brk->act_addr[3] = 0;
-      }
-   return val;
+   return (sp);
+
+}
+
+
+#define SPACES         "       "
+#define P_SPACES       "   "
+#define BYTE 0xff
+
+int screen_lines=24;
+
+char *spec_reg[] = {
+   "fsr", "db", "dirbase", "fir", "psr", "epsr",
+};
+
+char *doro_reg[] = {
+   "scp", "cbsp", "pt_cs", "intmsk", "intack",
+};
+#define NREGS 32
+
+
+get_reg(regno)
+{
+   char raw_buffer[32];
+   int addr;
+   int virtual_buffer;
+
+   /* NOTE that only  integer and floating point registers can be relative to a frame */
+
+   if ((regno >= R0) && (regno <= F31)) /* user register */
+      read_relative_register_raw_bytes (regno, raw_buffer);
+   else
+      bcopy (&registers[regno << 2], raw_buffer, sizeof (long));
+
+   REGISTER_CONVERT_TO_VIRTUAL (addr, raw_buffer, &virtual_buffer);
+   return(virtual_buffer);
 }
 
+
+#if 0
+/* This routine is uncalled.  Remove it sometime. */
+
 /*
  ** Figure out whether we are in a delayed slot and if so then take necessary
  **    action to resume properly - remember trap pre-empts instruction
@@ -1120,7 +1484,7 @@ int
 CORE_ADDR addr, *nextpc;
 int ss;
 {
-   long nextadr, instr;
+   CORE_ADDR nextadr, instr;
    int val = not_branch;
    long offset; /* Must be signed for sign-extend */
    
@@ -1128,24 +1492,24 @@ int ss;
       {
          if (INDIM)
             {
-                       nextadr = CORADR((int)(addr + 8));
-                       instr   = adj_read_memory_integer (CORADR(addr));
+                       nextadr = CORADR((int)(addr +  INSTRUCTION_LENGTH*2));
+                       instr   =  (unsigned)(adj_read_memory_integer (CORADR(addr)));
             }
          else
             {
-                       nextadr = addr + 4;
-                       instr   = adj_read_memory_integer (addr);
+                       nextadr = addr +  INSTRUCTION_LENGTH;
+                       instr   =  (unsigned)(adj_read_memory_integer (addr));
             }
       } else   {
          if (ISDIM(addr))
             {
                        nextadr = CORADR(addr);
-                       instr   = adj_read_memory_integer (nextadr);
+                       instr   =  (unsigned)(adj_read_memory_integer (nextadr));
             }
          else
             {
                        nextadr = addr;
-                       instr   = adj_read_memory_integer (addr);
+                       instr   =  (unsigned)(adj_read_memory_integer (addr));
             }
       }
    
@@ -1195,10 +1559,15 @@ int ss;
    *nextpc = nextadr;
    return val;
 }
+#endif
 
-extern char registers[];
 
-i860_do_registers_info(regnum,fpregs)
+/* i860-specific routine to print the register set. Note that we ALWAYS print information
+   on the floating point registers, so we ignore the parameter fpregs. 
+   NOTE also  that only  integer and floating point registers can be relative to a frame --
+   see subroutine get_reg (above ) */
+
+void i860_do_registers_info(regnum,fpregs)
      int regnum;
      int fpregs;
 {
@@ -1206,16 +1575,14 @@ i860_do_registers_info(regnum,fpregs)
    unsigned int val;
    unsigned int j,k;
    
+   
    if (regnum == -1)
       printf_filtered (
                        "Register       Contents (relative to selected stack frame)\n\n");
    
    if (regnum != -1) /* print one register */
       {
-         if ((regnum >=F0 ) && (regnum <= F31))
-            bcopy (&registers[ADJ_FREG(regnum)<<2], &val, sizeof (long));
-         else
-            bcopy (&registers[regnum<<2], &val, sizeof (long));
+         val = get_reg(regnum);
          printf("%-4s 0x%08x\t", reg_names[regnum], val);
          printf("\n\t"); fflush(stdout);
       }
@@ -1225,31 +1592,31 @@ i860_do_registers_info(regnum,fpregs)
          printf("\n Control/Status Registers :- \n\t");
          for (j=0; j<=DB; j++)
             {
-               bcopy (&registers[j<<2], &val, sizeof (long));
+               val = get_reg(j);
                printf("%-4s 0x%08x\t", reg_names[j], val);
             }
          printf("\n\t"); fflush(stdout);
          
          /* EPSR */
-         bcopy (&registers[EPSR<<2], &val, sizeof (long));
+         val = get_reg(EPSR);
          printf("%-4s 0x%08x\t", reg_names[EPSR], val);
          
          /* FSR */
-         bcopy (&registers[FSR<<2], &val, sizeof (long));
+         val = get_reg(FSR);
          printf("%-4s 0x%08x\t", reg_names[FSR], val);
          
          /* CCR */
-         bcopy (&registers[CCR<<2], &val, sizeof (long));
+         val = get_reg(CCR);
          printf("%-4s 0x%08x\t", reg_names[CCR], val);
          /* BEAR*/
-         bcopy (&registers[BEAR<<2], &val, sizeof (long));
+         val = get_reg(BEAR);
          printf("%-4s 0x%08x\t", reg_names[BEAR], val);
          
          
 #ifdef JIM_ADD_PRIV
          for (j=P0; j<=P3; j++)
             {
-               bcopy (&registers[j<<2], &val, sizeof (long));
+               val = get_reg(j);
                printf("%-4s 0x%08x\t", reg_names[j], val);
             }
 #endif
@@ -1257,22 +1624,22 @@ i860_do_registers_info(regnum,fpregs)
          printf("\n Integer Registers :- \n\t");
          for (j=R0; j<=R31; j++)
             {
-               if (j != IREGS  && (j % 4 == 0)) 
+               if (j != IREGS  && (j % REGISTER_LENGTH == 0)) 
                   {
                      printf("\n\t");  fflush(stdout);
                   }
-               bcopy (&registers[j<<2], &val, sizeof (long));
+               val = get_reg(j);
                printf("%-4s 0x%08x\t", reg_names[j], val);
             }
          
          printf("\n Floating Registers :- \n\t");
          for (j=F0; j<=F31; j++)
             {
-               if (j != FREGS && (j % 4 == 0)) 
+               if (j != FREGS && (j % REGISTER_LENGTH == 0)) 
                   {
                      printf("\n\t");  fflush(stdout);
                   }
-               bcopy (&registers[ADJ_FREG(j)<<2], &val, sizeof (long));
+               val = get_reg(j);
                printf("%-4s 0x%08x\t", reg_names[j], val);
             }
          
@@ -1284,28 +1651,30 @@ i860_do_registers_info(regnum,fpregs)
                   {
                      printf("\n\t");  fflush(stdout);
                   }
-               bcopy (&registers[j<<2], &val, sizeof (long));
-               bcopy (&registers[(j+1)<<2], &valh, sizeof (long));
+               val = get_reg(j);
+               valh = get_reg(j+1);
                printf("%-6s 0x%08x %08x\t", reg_names[j], val,valh);
             }
          
          printf("\n Graphics Pipeline :- \n");
          {
-            unsigned int valh, val2,val3;
+            unsigned int valh;
             j = PSV_I1;
-            bcopy (&registers[j<<2], &val, sizeof (long));
-            bcopy (&registers[(j+1)<<2], &valh, sizeof (long));
+            val = get_reg(j);
+            valh = get_reg(j+1);
             printf("\t\t\t%-8s 0x%08x %08x \n", reg_names[j], val,valh);
          }
          
          printf(" Memory Load Pipeline :- \n");
-         for (j=PSV_L1; j<=PSV_L3; j+=4)
+         for (j=PSV_L1; j<=PSV_L3; j+=REGISTER_LENGTH)
             {
                unsigned int valh, val2,val3;
-               bcopy (&registers[j<<2], &val, sizeof (long));
-               bcopy (&registers[(j+1)<<2], &valh, sizeof (long));
-               bcopy (&registers[(j+2)<<2], &val2, sizeof (long));
-               bcopy (&registers[(j+3)<<2], &val3, sizeof (long));
+               
+               val = get_reg(j);
+               valh = get_reg(j+1);
+               val2 = get_reg(j+2);
+               val3 = get_reg(j+3);
+
                printf("\t\t%-8s 0x%08x %08x %08x %08x\n", reg_names[j], 
                       val,valh,val2,val3);
             }
@@ -1314,11 +1683,13 @@ i860_do_registers_info(regnum,fpregs)
          for (i=PSV_FSR1,j=PSV_A1,k=PSV_M1; j<=PSV_A3; i++,j+=2,k+=2)
             {
                unsigned int valh,val2,val3,val4;
-               bcopy (&registers[i<<2], &val4, sizeof (long));
-               bcopy (&registers[j<<2], &val, sizeof (long));
-               bcopy (&registers[(j+1)<<2], &valh, sizeof (long));
-               bcopy (&registers[k<<2], &val2, sizeof (long));
-               bcopy (&registers[(k+1)<<2], &val3, sizeof (long));
+
+               val4 = get_reg(i);
+               val = get_reg(j);
+               valh = get_reg(j+1);
+               val2 = get_reg(k);
+               val3 = get_reg(k+1);
+
                printf("  %-4s 0x%08x %08x\t", reg_names[j], val,valh);
                printf("%-4s 0x%08x %08x\t", reg_names[k], val2,val3);
                printf("%-4s 0x%08x\n", reg_names[i], val4);
@@ -1329,67 +1700,20 @@ i860_do_registers_info(regnum,fpregs)
    
 }
 
-int has_stored_r1(CORE_ADDR prologue_start, CORE_ADDR prologue_end)
-{
-   long instr;
-   CORE_ADDR addr;
-   
-   BTDEBUG("has_stored_r1, prologue_start %x, prologue_end %x\n",
-           prologue_start, prologue_end);
-
-   for (addr = prologue_start; addr <= prologue_end;  addr += 4)
-      {
-   
-         instr = adj_read_memory_integer (addr);
-         if   ((instr & 0xFFE0F801) == 0x1C400801 /* st.l r1,X(sp) */
-            || (instr & 0xFFE0F801) == 0x1C600801) /* st.l r1,X(fp) */
-            return (1);
-      }
-   return 0;
-}
-
-/* This function returns 1 if there is no stored r1, 0 otherwise.
-   The function returns 1 if the pc is in a function prologue,
-   or the function prologue didn't save the return pointer in
-   the stack frame,  0 otherwise */
-
-int no_stored_rp(CORE_ADDR pc)
-{
-   CORE_ADDR func_start, prologue_end;
-   
-   func_start = get_pc_function_start(pc);
-   if (func_start)
-      {
-         prologue_end = func_start;
-         SKIP_PROLOGUE(prologue_end);
-         if ( (pc >= func_start) && (pc <= prologue_end))
-            {
-               BTDEBUG("no_stored_rp: pc %x is in prologue \n",pc);
-               return 1;
-            }
-         /* otherwise, see if the entry sequence stored the return pointer.
-            If it didn't, return 1 */
-         /* Some procedures , at least, store the return pointer AFTER the prologue sequence! */
-         if (!has_stored_r1(func_start, pc))
-            {  
-               BTDEBUG("no_stored_rp, for pc %x, prologue didn't store r1\n",pc);
-               return 1;
-            }
-      }
-   BTDEBUG("no_stored_rp for pc %x return pointer was stored \n", pc);
 
-   return 0; 
-}
 
 /* The following set of routines was adapted from existing code previously
    in an i860-specific version of breakpoint.c by Peggy Fieland
    (Margaret_Fieland@vos.stratus.com) */
+/* routines to set a data breakpoint by setting the value in the DB register. 
+   Note that "hitting" the breakpoint will generate a data access trap. We
+   do not have a special trap handler. */
 unsigned int dbrkval, dbrkmod;
 void i860_dbrk_breakpoint()
 {
    BTDEBUG("i860_dbrk_breakpoint was called , dbrkval %x\n", dbrkval);
    
-   if (dbrkval)
+   if (dbrkval != 0)
       {
          *(int *)&registers[DB<<2] = dbrkval;
       }
@@ -1406,43 +1730,44 @@ void i860_dbrk_breakpoint()
 
 }
 
+/* set a "read" data breakpoint. */
 void
-d_ro_break_command(arg)
-char *arg;
+d_ro_break_command(char *arg, int num)
 {
        dbrkval = strtoul(arg, NULL, 0);
        dbrkmod = 0x01;
-printf(" ro_dbreak - %x %x\n", dbrkval, dbrkmod);
+     BTDEBUG(" ro_dbreak - %x %x\n", dbrkval, dbrkmod);
 }
 
+/* set a "write" data breakpoint. */
 void
-d_wo_break_command(arg)
-char *arg;
+d_wo_break_command(char *arg, int num)
 {
        dbrkval = strtoul(arg, NULL, 0);
        dbrkmod = 0x02;
-printf(" wo_dbreak - %x %x\n", dbrkval, dbrkmod);
+     BTDEBUG(" wo_dbreak - %x %x\n", dbrkval, dbrkmod);
 }
 
+/* set a "read/write" data breakpoint. */
 void
-d_rw_break_command(arg)
-char *arg;
-{
-       dbrkval = strtoul(arg, NULL, 0);
-       dbrkmod = 0x03;
-printf(" rw_dbreak - %x %x\n", dbrkval, dbrkmod);
-}
-
-void
-clear_dbreak()
-{
-       dbrkval = 0;
-       dbrkmod = 0;
-}
-
-void 
-i860_init_breakpoints()
-{
+d_rw_break_command(char *arg, int num)
+{      
+  dbrkval  =  strtoul(arg, NULL,   0);
+  dbrkmod =  0x03;
+  BTDEBUG(" rw_dbreak - %x %x\n", dbrkval, dbrkmod);
+ }
+
+/* clear data breakpoint. */
+ void clear_dbreak(char *arg, int num)
+ { 
+   dbrkval  = 0;
+   dbrkmod = 0;
+ }
+
+/*   i860-specific  breakpoint initialization.    Includes  adding the
+i860-specific     data          breakpoint       commands.   */   
+void i860_init_breakpoints() 
+{ 
   dbrkval = dbrkmod = 0;
   add_com ("dbro", class_breakpoint, d_ro_break_command,
           "Set a data breakpoint READ ONLY, 32-bit data element.");
@@ -1456,49 +1781,56 @@ i860_init_breakpoints()
 
 }
 
+/* i860-specific code to insert a breakpoint. */
 int i860_insert_breakpoint(b)
 struct breakpoint *b;
 {
    int val;
+   int *shadow0, *shadow1, *shadow2, *shadow3;
+
+   shadow0 = (int *)&b->shadow_contents[0];
+   shadow1 = (int *)&b->shadow_contents[4];
+   shadow2 = (int *)&b->shadow_contents[8];
+   shadow3 = (int *)&b->shadow_contents[12];
 
    place_brk( b->address, BREAK_MODE, b );
+
    if (b->mode == DIM)
       {
          
-         adj_read_memory (b->act_addr[0], &b->shadow_contents[0], 4);
-         val =  adj_write_memory (b->act_addr[0], break_insn, 4);
-         if (val) return val;
-         adj_read_memory (b->act_addr[1], &b->shadow_contents[1], 4);
-         /*    val = adj_write_memory (b->act_addr[1], float_insn, 4); */
-         if (val) return val;
+         adj_read_memory (b->act_addr[0], shadow0,  INSTRUCTION_LENGTH);
+         val =  adj_write_memory (b->act_addr[0], break_insn,  INSTRUCTION_LENGTH);
+         if (val != 0 ) return val;
+         adj_read_memory (b->act_addr[1], shadow1,  INSTRUCTION_LENGTH);
+         /*    val = adj_write_memory (b->act_addr[1], float_insn,  INSTRUCTION_LENGTH); */
+         if (val != 0) return val;
       } 
    else        
       {
-         adj_read_memory (b->act_addr[0], &b->shadow_contents[0], 4);
-         val = adj_write_memory (b->act_addr[0], break_insn, 4);
+         adj_read_memory (b->act_addr[0], shadow0,  INSTRUCTION_LENGTH);
+         val = adj_write_memory (b->act_addr[0], break_insn,  INSTRUCTION_LENGTH);
       }
-   if (b->address1)
+   if (b->address1 != 0)
       {
          if (b->mode == DIM)
             {
 
-               adj_read_memory (b->act_addr[2], &b->shadow_contents[2], 4);
-               val = adj_write_memory (b->act_addr[2], break_insn, 4);
-               if (val) return val;
-               adj_read_memory (b->act_addr[3], &b->shadow_contents[3], 4);
-               /*      val = adj_write_memory (b->act_addr[3], float_insn, 4); */
+               adj_read_memory (b->act_addr[2], shadow2,  INSTRUCTION_LENGTH);
+               val = adj_write_memory (b->act_addr[2], break_insn,  INSTRUCTION_LENGTH);
                if (val) return val;
+               adj_read_memory (b->act_addr[3], shadow3,  INSTRUCTION_LENGTH);
+               /*      val = adj_write_memory (b->act_addr[3], float_insn,  INSTRUCTION_LENGTH); */
+               if (val != 0) return val;
             }
          else  
             {
-               adj_read_memory (b->act_addr[2], &b->shadow_contents[0], 4);
-               val = adj_write_memory (b->act_addr[2], break_insn, 4);
+               adj_read_memory (b->act_addr[2], shadow0,  INSTRUCTION_LENGTH);
+               val = adj_write_memory (b->act_addr[2], break_insn,  INSTRUCTION_LENGTH);
             }
       }
-   if (val)
+   if (val != 0)
       return val;
-   BTDEBUG("Inserted breakpoint at 0x%x, shadow 0x%x, 0x%x.\n",
-           b->address, b->shadow_contents[0], b->shadow_contents[1]);
+
    b->inserted = 1;
    return 0;
 }
@@ -1507,32 +1839,43 @@ int i860_remove_breakpoint(b)
 struct breakpoint *b;
 {
    int val;
+   int *shadow0, *shadow1, *shadow2, *shadow3;
+
+   shadow0 = (int *)&b->shadow_contents[0];
+   shadow1 = (int *)&b->shadow_contents[4];
+   shadow2 = (int *)&b->shadow_contents[8];
+   shadow3 = (int *)&b->shadow_contents[12];
+
 
    if (b->inserted)
       {
          if (b->mode == DIM)
             {
-               val =adj_write_memory (b->act_addr[0], &(b->shadow_contents[0]), 4);
-               val =adj_write_memory (b->act_addr[1], &(b->shadow_contents[1]), 4);
-               if (b->address1)
+               val =adj_write_memory (b->act_addr[0], shadow0,
+                                      INSTRUCTION_LENGTH);
+               val =adj_write_memory (b->act_addr[1],shadow1,
+                                       INSTRUCTION_LENGTH);
+               if (b->address1 != NULL)
                   {
-                     val =adj_write_memory (b->act_addr[2], &(b->shadow_contents[2]), 4);
-                     val =adj_write_memory (b->act_addr[3], &(b->shadow_contents[3]), 4);
+                     val =adj_write_memory (b->act_addr[2],shadow2,
+                                             INSTRUCTION_LENGTH);
+                     val =adj_write_memory (b->act_addr[3], shadow3,
+                                             INSTRUCTION_LENGTH);
                   }
             } 
          else  
             {
-               val =adj_write_memory (b->act_addr[0], b->shadow_contents, 4);
-               if (b->address1)
+               val =adj_write_memory (b->act_addr[0], shadow0,
+                                       INSTRUCTION_LENGTH);
+               if (b->address1 != NULL)
                   {
-                     val =adj_write_memory (b->act_addr[2], b->shadow_contents, 4);
+                     val =adj_write_memory (b->act_addr[2],shadow0,
+                                            INSTRUCTION_LENGTH);
                   }
             }
-         if (val)
+         if (val != 0)
             return val;
          b->inserted = 0;
-         BTDEBUG( "Removed breakpoint at 0x%x, shadow 0x%x, 0x%x.\n",
-                 b->address, b->shadow_contents[0], b->shadow_contents[1]);
       }
 
    return 0;
@@ -1613,6 +1956,11 @@ gregset_t *gregsetp;
     }
 }
 
+/*  Given a pointer to a general register set in /proc format (gregset_t *),
+    update the register specified by REGNO from gdb's idea
+    of the current general register set.  If REGNO is -1, update
+    them all. */
+
 void
 fill_gregset (gregsetp, regno)
 gregset_t *gregsetp;
@@ -1634,3 +1982,249 @@ int regno;
 }
 #endif
 
+
+/* Push an empty stack frame, to record the current PC, etc.  */
+/* We have this frame with fp pointing to a block where all GDB-visible
+   registers are stored in the order GDB knows them, and sp at the next
+   alignment point below fp.  Note: fp + NUM_REGS*4 was the old sp
+   */
+extern CORE_ADDR text_end;
+CORE_ADDR dummy_start_addr;
+void i860_push_frame()
+{    
+   register CORE_ADDR old_fp = read_register(FP_REGNUM);
+   register CORE_ADDR old_sp = read_register(SP_REGNUM);
+   register CORE_ADDR fp ;
+   extern char registers[];    
+                                        
+   fp = old_sp - REGISTER_BYTES;                                                        
+   write_memory(fp, registers, REGISTER_BYTES);  /* write out old register values */
+   /* reset FP and SP */
+   write_register(FP_REGNUM, fp);
+   write_register(SP_REGNUM, (fp &~ 15));      /* re-align */           
+   call_dummy_set = 1;
+}
+/* Discard from the stack the innermost frame, 
+   restoring all saved registers.  */
+
+void i860_pop_frame()
+{ register FRAME frame = get_current_frame ();                                
+  register CORE_ADDR fp;                                                      
+  struct frame_info *fi;                                                      
+  int i;
+  
+  fi = get_frame_info (frame);                                                 
+  fp = fi->frame;                                                              
+
+  if (call_dummy_set && fi -> pc >= call_dummy_start && 
+       fi -> pc <= call_dummy_start + CALL_DUMMY_LENGTH)
+     {
+  
+        read_memory(fp, registers, REGISTER_BYTES);
+
+        target_store_registers(-1);
+
+        {
+           /* since we stomped on code that will be executed when we exit the program,
+              restore it. */
+           extern REGISTER_TYPE call_save_code[4];
+     
+           write_memory     (call_dummy_start, (char *) call_save_code, 16);
+     
+        }
+        call_dummy_set = 0;
+     }
+  else
+     {
+        register int regnum;                                                         
+        struct frame_saved_regs fsr;                                                 
+        char raw_buffer[12];                                                         
+
+        get_frame_saved_regs (fi, &fsr);                                             
+        for (regnum = FP0_REGNUM + 31; regnum >= FP0_REGNUM; regnum--)               
+           if (fsr.regs[regnum])                                                      
+              write_register (regnum, read_memory_integer (fsr.regs[regnum], 4));      
+        for (regnum = R31; regnum >= 1; regnum--)                                     
+           if (fsr.regs[regnum])                                                      
+              if (regnum != SP_REGNUM)                                                 
+                 write_register (regnum, read_memory_integer (fsr.regs[regnum], 4));    
+              else                                                                     
+                 write_register (SP_REGNUM, fsr.regs[SP_REGNUM]);                       
+        if (fsr.regs[PS_REGNUM])                                                     
+           write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4));  
+        if (fsr.regs[FPS_REGNUM])                                                    
+           write_register (FPS_REGNUM, read_memory_integer (fsr.regs[FPS_REGNUM],4)); 
+        if (fsr.regs[PC_REGNUM])                                                     
+           write_register (PC_REGNUM,CLEAN_PC( read_memory_integer (fsr.regs[PC_REGNUM], 4)));  
+          }    
+  
+  flush_cached_frames ();                                                     
+  
+  set_current_frame (create_new_frame (read_register (FP_REGNUM),              
+                                        read_pc ()));
+
+}
+
+CORE_ADDR  i860_arg_coerce(nargs, args, struct_return, sp)
+     int nargs;
+     value *args;
+     int struct_return;
+     CORE_ADDR sp;
+{
+
+  register int scalar;
+  register enum type_code code2;
+  register struct type *type;
+  int i;
+  value arg;
+  int num_int_args = 0;
+  int num_float_args = 0;
+  int size = 0;
+  CORE_ADDR arg_ptr;
+  
+  /* if we return a structure, it's address is in R16, and thus it uses up one of the integer
+     argument registers. See the ABI. */
+  if (struct_return)     
+     num_int_args += 1;
+
+  /* loop to do the right thing with all the arguments and calculate the size of the memory
+     argument list. We keep count of the number of integer and the number of float parameters,
+     as well as the size of the memory argument list. */
+
+  for (i = 0; i < nargs; i++)
+     {    
+
+        /* NOTE that this is all hunky dory in spite of the fact that we don't actually
+           have the signature of the called procedure EXCEPT if we are passing in floats!
+           This is true, since registers are 4 bytes, and the minimum alignment in the
+           memory argument list is 4 bytes. See the ABI for more gory details. The switch
+           "ansi-conformant" is an attempt to get around this problem. */
+           
+        code2 = TYPE_CODE (VALUE_TYPE(args[i]));
+
+        /* Only coerce if we've got switch "ansi-conformant" off.
+           Actually, it's OK ( and probably helpful) to coerce ALL integer arguments
+           (see comment above), but never mind, we make them the right size in
+           pass_function_arguments. */
+
+        if ((!ansi_conformant) && (code2 != TYPE_CODE_STRUCT))
+           value_arg_coerce(args[i]);
+
+        arg = args[i];
+        type = VALUE_TYPE(args[i]);
+
+        /* All structures are passed by value in the memory argument list. */
+        if (code2 == TYPE_CODE_STRUCT)
+           {
+              size = ALIGN_ARG(size, sizeof(long));
+              size += TYPE_LENGTH(type);   
+           }
+        else if (type == builtin_type_float)
+           {
+              num_float_args += 1;
+              if (num_float_args > NUM_FLOAT_ARG_REGS)
+                 {
+                    size = ALIGN_ARG(size, TYPE_LENGTH(type)) ;
+                    size += TYPE_LENGTH(type);
+                 }
+           }
+        else if (type == builtin_type_double)
+           {
+              /* floating register alignment  -- see ABI */
+              if ((num_float_args%2) != 0)
+                 num_float_args += 1;
+
+              num_float_args += 2; /* use up two registers */
+
+              if (num_float_args > NUM_FLOAT_ARG_REGS)
+                 {
+                    size = ALIGN_ARG(size, TYPE_LENGTH(type)) ;
+                    size += TYPE_LENGTH(type);
+                 }
+           }
+        else
+           {
+              int len = max (sizeof(long), TYPE_LENGTH(type));
+              
+              num_int_args += 1;
+
+              if (num_int_args > NUM_INT_ARG_REGS)
+                 {
+                    /* see ABI -- in-memory arguments have AT LEAST word alignment */
+                    if  ((TYPE_CODE(type) == TYPE_CODE_INT) ||
+                         (TYPE_CODE(type) == TYPE_CODE_ENUM) ||
+                         (TYPE_CODE(type) == TYPE_CODE_CHAR) ||
+                         (TYPE_CODE(type) == TYPE_CODE_BOOL))
+                       size  = ALIGN_ARG(size, len);
+                    else
+                       size = ALIGN_ARG(size, sizeof(long));
+                    size += len;
+                 }
+           }
+                         
+     }
+  
+
+  /* recalculate the stack pointer, leaving enough space for the memory argument list and
+     realigning the stack pointer. */
+  if (size != 0)
+     {
+        arg_ptr = sp -  size;
+
+        arg_ptr = arg_ptr & (-16); /* realign stack */
+        write_register (R28,arg_ptr);
+        sp = arg_ptr;
+     }
+
+return (sp);
+
+}
+void i860_extract_return_value(type,regbuf,valbuf)
+struct type *type;
+char regbuf[REGISTER_BYTES];
+char *valbuf;
+{
+  register int len = TYPE_LENGTH (type);
+  double tmp_db;
+  float tmp_flt;
+
+   if ((TYPE_CODE(type) == TYPE_CODE_FLT))
+      {
+         if (len == sizeof (float))
+            {
+               /* FIXME 
+                  NOTE that this assumes that the function declaration was ANSI_CONFORMANT --
+                  at the present time I can't think of ANY WAY to disambiguate the two following
+                  cases:
+                  float really_does_return_a_float(float ff) 
+                  { ...}             
+                  and
+                  float actually_returns_a_double(ff)
+                  float ff;
+                  {...}
+                  */
+               bcopy ((char *) (regbuf) + REGISTER_BYTE(ADJ_FREG(F8)), (valbuf), TYPE_LENGTH (type)) ; 
+            }
+         else
+            bcopy ((char *) (regbuf) + REGISTER_BYTE(F8), (valbuf), TYPE_LENGTH (type)) ;
+      }
+   else 
+      bcopy ((char *) (regbuf) + REGISTER_BYTE(R16), (valbuf), TYPE_LENGTH (type));
+
+}
+void i860_store_return_value(type,valbuf)
+struct type *type;
+char *valbuf;
+{
+  register int len = TYPE_LENGTH (type);
+  double tmp_db;
+
+   if ((TYPE_CODE(type) == TYPE_CODE_FLT) )
+      {
+         write_register_bytes (REGISTER_BYTE (F8), valbuf, len);
+      }
+   else 
+      write_register_bytes (REGISTER_BYTE (R16), valbuf, TYPE_LENGTH (type));
+}
+
This page took 0.052948 seconds and 4 git commands to generate.