Add several new files for stratus (i860* and *-stratus.h). Also add
[external/binutils.git] / gdb / i860-tdep.c
1 /* Machine-dependent code which would otherwise be in inflow.c and core.c,
2    for GDB, the GNU debugger.
3    Copyright (C) 1992 Free Software Foundation, Inc.
4    This code is for the i860 cpu.
5    Contributed by Peggy Fieland (pfieland@stratus.com)
6    
7    GDB is distributed in the hope that it will be useful, but WITHOUT ANY
8    WARRANTY.  No author or distributor accepts responsibility to anyone
9    for the consequences of using it or for whether it serves any
10    particular purpose or works at all, unless he says so in writing.
11    Refer to the GDB General Public License for full details.
12    
13    Everyone is granted permission to copy, modify and redistribute GDB,
14    but only under the conditions described in the GDB General Public
15    License.  A copy of this license is supposed to have been given to you
16    along with GDB so you can know your rights and responsibilities.  It
17    should be in a file named COPYING.  Among other things, the copyright
18    notice and this notice must be preserved on all copies.
19    
20    In other words, go ahead and share GDB, but don't try to stop
21    anyone else from sharing it farther.  Help stamp out software hoarding!
22    */
23
24 #include "defs.h"
25 #include "tm-i860.h"
26 #include "frame.h"
27 #include "inferior.h"
28 #include "obstack.h"
29 #include "symtab.h"
30 #include "value.h"
31
32 #include "tm-i860.h"
33 #include "i860-opcode.h"
34
35 #include <stdio.h>
36 #include "break.h"
37
38 #ifdef notdef
39
40 #include <sys/types.h>
41 #include <sys/param.h>
42 #include <sys/dir.h>
43
44 #endif
45
46 #include <signal.h>
47 #include <sys/ioctl.h>
48 #include <fcntl.h>
49
50 /* #include <sys/reg.h> */
51 #include "i860_reg.h"
52
53 #include <a.out.h>
54 #include <sys/file.h>
55 #include <sys/stat.h>
56 #include <core.h>
57
58 #include <sys/user.h>
59
60 #include <elf.h>
61 #include <sys/elftypes.h>
62 #include <sys/elf_860.h>
63 #include <libelf.h>
64
65
66 int btdebug = 0;    /* change value to 1 to enable debugging code */
67
68 #define  BTDEBUG  if (btdebug) btdebug_message
69
70 #include <stdarg.h>
71
72 int read_memory();
73 int write_memory();
74
75 btdebug_message(char *format, ...)
76 {       
77    va_list      arglist;
78    va_start( arglist, format );
79    
80    if( btdebug )
81       vfprintf (stderr,  format, arglist );
82    va_end  ( arglist      );
83 }
84
85 extern int errno;
86 extern int attach_flag;
87
88
89 /* This is used when GDB is exiting.  It gives less chance of error.*/
90
91
92 /* Simulate single-step ptrace call for sun4.  Code written by Gary
93    Beihl (beihl@mcc.com).  */
94 /* Modified for i860 by Jim Hanko (hanko@orc.olivetti.com) */
95
96
97 static struct breakpoint brk;
98 typedef char binsn_quantum[sizeof break_insn];
99 static binsn_quantum break_mem[2];
100
101 /* Non-zero if we just simulated a single-step ptrace call.  This is
102    needed because we cannot remove the breakpoints in the inferior
103    process until after the `wait' in `wait_for_inferior'.  Used for
104    i860. */
105
106 int one_stepped;
107 void
108    single_step (signal)
109 int signal;
110 {
111    CORE_ADDR pc;
112    branch_type place_brk();
113    
114    pc = read_register (PC_REGNUM);
115    
116    if (!one_stepped)
117       {
118          brk.address = pc;
119          place_brk (pc, SINGLE_STEP_MODE, &brk);
120          brk.shadow_contents[0] = brk.shadow_contents[1] = 0;
121          brk.shadow_contents[2] = brk.shadow_contents[3] = 0;
122          
123          if (brk.mode == DIM)
124             {
125                if ( brk.address1 )
126                   { 
127                      printf(" DIM1 ->");
128                      printf(" %x : ", brk.act_addr[3]);
129                      print_insn( brk.act_addr[3], stdout);
130                      printf("\t -|- ");
131                      printf(" %x : ", brk.act_addr[2]);
132                      print_insn( brk.act_addr[2], stdout);
133                      printf("\n");
134                      fflush(stdout);
135                      
136                      adj_read_memory  (brk.act_addr[2], &brk.shadow_contents[2],        4);
137                      adj_write_memory (brk.act_addr[2], break_insn,             4);
138                      adj_read_memory  (brk.act_addr[3], &brk.shadow_contents[3],        4);
139                      /*         adj_write_memory (brk.act_addr[3], float_insn,          4); */
140                      
141                   }
142                if ( brk.address1)
143                   printf(" DIM2 ->");
144                else
145                   printf(" DIM1 ->");
146                
147                printf(" %x : ", brk.act_addr[1]);
148                print_insn( brk.act_addr[1], stdout);
149                printf("\t -|- ");
150                printf(" %x : ", brk.act_addr[0]);
151                print_insn( brk.act_addr[0], stdout);
152                printf("\n");
153                fflush(stdout);
154                
155                adj_read_memory  (brk.act_addr[0], &brk.shadow_contents[0],      4);
156                adj_write_memory (brk.act_addr[0], break_insn,           4);
157                adj_read_memory  (brk.act_addr[1], &brk.shadow_contents[1],      4);
158                /*               adj_write_memory (brk.act_addr[1], float_insn,          4); */
159                
160             } 
161          else   {
162             if (brk.address1)
163                {
164                   if (btdebug)
165                      {
166                         printf(" SIM1 ->");
167                         printf(" %x : ", brk.act_addr[2]);
168                         print_insn( brk.act_addr[2], stdout);
169                         printf("\n");
170                         fflush(stdout);
171                      }
172                   adj_read_memory  (brk.act_addr[2], &brk.shadow_contents[2],   4);
173                   adj_write_memory (brk.act_addr[2], break_insn,                4);
174                }
175             if (btdebug)
176                {
177                   if ( brk.address1)
178                      printf(" SIM2 ->");
179                   else
180                      printf(" SIM1 ->");
181                   
182                   printf(" %x : ", brk.act_addr[0]);
183                   print_insn( brk.act_addr[0], stdout);
184                   printf("\n");
185                   fflush(stdout);
186                }
187             adj_read_memory  (brk.act_addr[0], &brk.shadow_contents[0], 4);
188             adj_write_memory (brk.act_addr[0], break_insn,              4);
189          }
190          
191          /* Let it go */
192          one_stepped = 1;
193          return;
194       }
195    else
196       {
197          /* Remove breakpoints */
198          if (brk.mode == DIM)
199             {
200                adj_write_memory (brk.act_addr[0], &brk.shadow_contents[0], 4);
201                adj_write_memory (brk.act_addr[1], &brk.shadow_contents[1], 4);
202             } else      {
203                adj_write_memory (brk.act_addr[0], &brk.shadow_contents[0], 4);
204             }
205          
206          if (brk.address1)
207             {
208                if (brk.mode == DIM)
209                   {
210                      adj_write_memory (brk.act_addr[2], &brk.shadow_contents[2], 4);
211                      adj_write_memory (brk.act_addr[3], &brk.shadow_contents[3], 4);
212                   } else        {
213                      adj_write_memory (brk.act_addr[2], &brk.shadow_contents[2], 4);
214                   }
215             }
216          one_stepped = 0;
217       }
218 }
219
220
221 \f
222
223 /* return nonzero if the routine containing pc has been 
224  * compiled with -g. We assume -g if the first instruction is 
225  * an  addu|adds -X,sp and the second is st.l fp,XX(sp) 
226  *
227  *      based on  skip_prologue();
228  */
229
230 g_routine(pc)
231      CORE_ADDR pc;
232 {
233    long instr;
234    int regno;
235    CORE_ADDR top_pc;
236    
237    top_pc = get_pc_function_start(pc);
238    if (top_pc)
239       {
240          instr = adj_read_memory_integer (top_pc);
241          /* Recognize "addu|adds -X,sp,sp" insn. */
242    
243          if ((instr & 0xEFFF0000) == 0x84420000) 
244             {
245                top_pc += 4;
246                instr = adj_read_memory_integer (top_pc);
247       
248                if( (instr & 0xFFE0F801) == 0x1C401801 )    /* st.l fp,X(sp) */
249                   return(1);
250             } 
251       }
252    return(0);
253 }
254
255
256 /* Written for i860 by Jim Hanko (hanko@orc.olivetti.com) */
257 /* This code was based on SPARC code written by Gary Beihl (beihl@mcc.com),
258    by Michael Tiemann (tiemann@corto.inria.fr).  */
259
260 struct command_line *get_breakpoint_commands ();
261
262 CORE_ADDR 
263    skip_prologue (pc)
264 CORE_ADDR pc;
265 {
266    long instr;
267    int regno;
268    
269    instr = adj_read_memory_integer (pc);
270    
271    /* Recognize "addu|adds -X,sp,sp" insn. */
272    if ((instr & 0xEFFF0000) == 0x84420000)
273       {
274          pc += 4;
275          instr = adj_read_memory_integer (pc);
276       }
277    else
278       return(pc);                                       /* No frame! */
279    
280    /* Recognize store of return addr and frame pointer into frame */
281    while (1)
282       {
283          if ((instr & 0xFFE0F801) == 0x1C400801 ||  /* st.l r1,X(sp) */
284              (instr & 0xFFE0F801) == 0x1C401801)    /* st.l fp,X(sp) */
285             {
286                pc += 4;
287                instr = adj_read_memory_integer (pc);
288             }
289          else
290             break;
291       }
292    
293    /* Recognize "addu|adds X,sp,fp" insn. */
294    if ((instr & 0xEFFF0000) == 0x84430000)
295       {
296          pc += 4;
297          instr = adj_read_memory_integer (pc);
298       }
299    
300    /* Now recognize stores into the frame from the registers. */
301    
302    while (1)
303       {
304          if ((instr & 0xFFA00003) == 0x1C200001 ||      /* st.l rn,X(fp|sp) */
305              (instr & 0xFFA00001) == 0x4C200000)        /* fst.y fn,X(fp|sp) */
306             {
307                regno = (instr >> 11) & 0x1f;
308                if (regno == 0)                  /* source reg == 0? quit */
309                   break;
310                pc += 4;
311                instr = adj_read_memory_integer (pc);
312             }
313          else
314             break;
315       }
316    
317    return(pc);
318 }
319
320
321 /* Set *nextpc to branch target if we find a branch.  If it is not a branch, 
322    set it to the next instruction (addr + 4) */
323
324
325 branch_type
326    isabranch (addr,  nextpc)
327 CORE_ADDR addr, *nextpc;
328 {
329    long instr;
330    branch_type val = not_branch;
331    long offset; /* Must be signed for sign-extend */
332    
333    printf(" isabranch\n");
334    *nextpc = addr;
335    instr = adj_read_memory_integer (addr);
336    
337    if ((instr & 0xE0000000) == 0x60000000 &&            /* CTRL format */
338        (instr & 0xF8000000) != 0x60000000)              /* not pfld.y  */
339       {
340          if ((instr & 0xF8000000) == 0x68000000)                /* br or call */
341             val = uncond_d;
342          else if ((instr & 0xF4000000) == 0x74000000)   /* bc.t or bnc.t */
343             val = cond_d;
344          else if ((instr & 0xF4000000) == 0x70000000)   /* bc or bnc */
345             val = cond;
346          
347          offset = (instr & 0x03ffffff);
348          if (offset & 0x02000000)       /* sign extend? */
349             offset |= 0xFC000000;
350          *nextpc = addr + 4 + (offset << 2);
351       }
352    else if ((instr & 0xFC00003F) == 0x4C000002 ||       /* calli */
353             (instr & 0xFC000000) == 0x40000000)         /* bri */
354       {
355          val = uncond_d;
356          offset = ((instr & 0x0000F800) >> 11);
357          *nextpc = (read_register(offset) & 0xFFFFFFFC);
358       }
359    else if ((instr & 0xF0000000) == 0x50000000)         /* bte or btne */
360       {
361          val = cond;
362          
363          offset = SIGN_EXT16(((instr & 0x001F0000) >> 5)  | (instr & 0x000007FF));
364          *nextpc = addr + 4 + (offset << 2);
365       }
366    else if ((instr & 0xFC000000) == 0xB4000000)         /* bla */
367       {
368          val = cond_d;
369          
370          offset = SIGN_EXT16(((instr & 0x001F0000) >> 5)  | (instr & 0x000007FF));
371          *nextpc = addr + 4 + (offset << 2);
372       }
373    
374    printf(" Final addr - %x\n", *nextpc);
375    /*printf("isabranch ret: %d\n",val); */
376    return val;
377 }
378
379 /* set in call_function() [valops.c] to the address of the "call dummy" code
380    so dummy frames can be easily recognized; also used in wait_for_inferior() 
381    [infrun.c]. When not used, it points into the ABI's 'reserved area' */
382
383 CORE_ADDR call_dummy_set = 0;   /* true if dummy call being done */
384 CORE_ADDR call_dummy_start;     /* address of call dummy code */
385
386 frame_find_saved_regs(frame_info, frame_saved_regs)
387      struct frame_info *frame_info;
388      struct frame_saved_regs *frame_saved_regs;
389 {
390    register CORE_ADDR pc;
391    long instr, spdelta = 0, offset;
392    int i, size, reg;
393    int r1_off = -1, fp_off = -1;
394    int framesize;
395    
396    bzero (frame_saved_regs, sizeof(*frame_saved_regs));
397    
398    if (call_dummy_set && frame_info->pc >= call_dummy_start && 
399        frame_info->pc <= call_dummy_start + CALL_DUMMY_LENGTH)
400       {
401          /* DUMMY frame - all registers stored in order at fp; old sp is
402             at fp + NUM_REGS*4 */
403          
404          for (i = 1; i < NUM_REGS; i++) /* skip reg 0 */
405             if (i != SP_REGNUM && i != FP0_REGNUM && i != FP0_REGNUM + 1)
406                frame_saved_regs->regs[i] = frame_info->frame + i*4;
407          
408          frame_saved_regs->regs[SP_REGNUM] = frame_info->frame + NUM_REGS*4;
409          
410          call_dummy_set = 0;
411          return;
412       }
413    
414    pc = get_pc_function_start (frame_info->pc); 
415    if (pc)
416       {
417          instr = adj_read_memory_integer (pc);
418          /* Recognize "addu|adds -X,sp,sp" insn. */
419          if ((instr & 0xEFFF0000) == 0x84420000)
420             {
421                framesize = -SIGN_EXT16(instr & 0x0000FFFF);
422                pc += 4;
423                instr = adj_read_memory_integer (pc);
424             }
425       }
426    else
427       goto punt;                                        /* No frame! */
428    
429    /* Recognize store of return addr and frame pointer into frame */
430    while (1)
431       {
432          if ((instr & 0xFFE0F801) == 0x1C400801)  /* st.l r1,X(sp) */
433             {
434                r1_off = SIGN_EXT16(((instr&0x001F0000) >> 5) | (instr&0x000007FE));
435                pc += 4;
436                instr = adj_read_memory_integer (pc);
437             }
438          else if ((instr & 0xFFE0F801) == 0x1C401801)    /* st.l fp,X(sp) */
439             {
440                fp_off = SIGN_EXT16(((instr&0x001F0000) >> 5) | (instr&0x000007FE));
441                pc += 4;
442                instr = adj_read_memory_integer (pc);
443             }
444          else
445             break;
446       }
447    
448    /* Recognize "addu|adds X,sp,fp" insn. */
449    if ((instr & 0xEFFF0000) == 0x84430000)
450       {
451          spdelta = SIGN_EXT16(instr & 0x0000FFFF);
452          pc += 4;
453          instr = adj_read_memory_integer (pc);
454       }
455    
456    /* Now recognize stores into the frame from the registers. */
457    
458    while (1)
459       {
460          if ((instr & 0xFFC00003) == 0x1C400001)        /* st.l rn,X(fp|sp) */
461             {
462                offset = SIGN_EXT16(((instr&0x001F0000) >> 5) | (instr&0x000007FE));
463                reg = (instr >> 11) & 0x1F;
464                if (reg == 0)
465                   break;
466                if ((instr & 0x00200000) == 0)   /* was this using sp? */
467                   if (spdelta)                  /* and we know sp-fp delta */
468                      offset -= spdelta;         /* if so, adjust the offset */
469                   else
470                      break;                             /* if not, give up */
471                
472                
473                /* Handle the case where the return address is stored after the fp 
474                   is adjusted */
475                
476                if (reg == 1)
477                   frame_saved_regs->regs[PC_REGNUM] = frame_info->frame + offset;
478                else
479                   frame_saved_regs->regs[reg] = frame_info->frame + offset;
480                
481                pc += 4;
482                instr = adj_read_memory_integer (pc);
483             }
484          else if ((instr & 0xFFC00001) == 0x2C400000) /* fst.y fn,X(fp|sp) */
485             {
486                /*
487                 * The number of words in a floating store based on 3 LSB of instr
488                 */
489                static int fst_sizes[] = {2, 0, 1, 0, 4, 0, 1, 0};
490                
491                size = fst_sizes[instr & 7];
492                reg = ((instr >> 16) & 0x1F) + FP0_REGNUM;
493                if (reg == 0)
494                   break;
495                
496                if (size > 1)                                    /* align the offset */
497                   offset = SIGN_EXT16(instr & 0x0000FFF8);      /* drop 3 bits */
498                else
499                   offset = SIGN_EXT16(instr & 0x0000FFFC);      /* drop 2 bits */
500                
501                if ((instr & 0x00200000) == 0)   /* was this using sp? */
502                   if (spdelta)                  /* and we know sp-fp delta */
503                      offset -= spdelta;         /* if so, adjust the offset */
504                   else
505                      break;                             /* if not, give up */
506                
507                for (i = 0; i < size; i++)
508                   {
509                      frame_saved_regs->regs[reg] = frame_info->frame + offset;
510                      
511                      offset += 4;
512                      reg++;
513                   }
514                
515                pc += 4;
516                instr = adj_read_memory_integer (pc);
517             }
518          else
519             break;
520       }
521    
522    punt: ;
523    if (framesize != 0 && spdelta != 0)
524       frame_saved_regs->regs[SP_REGNUM] = frame_info->frame+(framesize-spdelta);
525    else
526       frame_saved_regs->regs[SP_REGNUM] = frame_info->frame + 8;
527    
528    if (spdelta && fp_off != -1)
529       frame_saved_regs->regs[FP_REGNUM] = frame_info->frame - spdelta + fp_off;
530    else
531       frame_saved_regs->regs[FP_REGNUM] = frame_info->frame;
532    
533    if (spdelta && r1_off != -1)
534       frame_saved_regs->regs[PC_REGNUM] = frame_info->frame - spdelta + r1_off;
535    else
536       frame_saved_regs->regs[PC_REGNUM] = frame_info->frame + 4;
537 }
538
539 /* return the stack offset where the fp register is stored */
540 find_fp_offset(pc)
541 {
542    int fp_off,i;
543    long instr;
544    
545    /* look for the instruction and examine the offset */
546    
547    for(i=4; i<16; i+=4){
548       instr = adj_read_memory_integer(pc+i);
549       if( (instr & 0xFFE0F801) == 0x1C401801) {    /* st.l fp,X(sp) */
550          
551          fp_off = SIGN_EXT16(((instr&0x001F0000) >> 5) | 
552                              (instr&0x000007FE));
553          return(fp_off);
554       }
555    }
556    return(0);
557 }
558
559 /* return the stack offset where r1 (return linkage ) register is stored */
560
561 find_r1_offset(pc)
562 {
563    int r1_off,i;
564    long instr;
565    
566    /* look for the instruction and examine the offset */
567    
568    for(i=4; i<16; i+=4){
569       
570       instr = adj_read_memory_integer(pc+i);
571       if ((instr & 0xFFE0F801) == 0x1C400801) { /* st.l r1,X(sp) */
572          
573          r1_off = SIGN_EXT16(((instr&0x001F0000) >> 5) | 
574                              (instr&0x000007FE));
575          return(r1_off);
576       }
577    }
578    return(-1);
579 }
580
581
582 /* dose routine starting at pc build a stack frame of any kind?? */
583 has_a_frame(pc)
584 {
585    if( skip_prologue(pc) != pc )return(1);
586    else return(0);
587 }
588
589 /* get the frame pointer of the caller.
590  * note that only routines that have been compiled with
591  * -g have full (XX)fp style stack frames
592  * if we are not returning to a non -g caller then we
593  * return the sp at entry to us as it is the caller's
594  * frame reference.
595  */
596
597 frame_chain(thisframe)
598      FRAME thisframe;
599 {
600    unsigned long fp, sp, pc;
601    unsigned long func_start;
602    long instr;
603    int offset;
604    unsigned long thisfp = thisframe->frame;
605    
606    /* get the frame pointer actually sp for  a non -g
607     * for the routine that called us routine 
608     */
609    
610    BTDEBUG("FRAME_CHAIN(%x)\n",thisframe);
611    
612    if ( !read_memory_integer (thisframe->frame,4))
613       {
614          return (0);
615       }
616    
617    if( ! g_routine(thisframe->pc) ){
618       BTDEBUG( "non g at %x\n",thisframe->pc);
619       caller_pc(thisframe->pc,thisframe->sp,&pc,&fp);
620       BTDEBUG("caller_pc returned %x %x \n",pc,fp);
621       return(fp);
622       
623    }/* else a -g routine */
624    
625    
626    fp = read_memory_integer (thisfp, 4);
627    
628    if (fp < thisfp || fp > STACK_END_ADDR)
629       {
630          /* handle the Metaware-type pseudo-frame */
631          
632          func_start = get_pc_function_start(thisframe->pc);
633          
634          if (func_start)
635             {
636                
637                instr = adj_read_memory_integer (func_start);
638                /* Recognize "addu|adds -X,sp,sp" insn. */
639                if ((instr & 0xEFFF0000) == 0x84420000)
640                   offset = SIGN_EXT16(instr & 0x0000FFFF);
641                
642             }
643          
644          fp = 0;
645          if (offset < 0)
646             fp = thisfp - offset;
647       }
648    BTDEBUG("frame_chain returned %d\n",fp);
649    return(fp);
650 }
651
652 /* get the pc and frame pointer (or sp )
653  * for the routine that called us
654  * when we (this_pc) is not within a  -g routine
655  * if caller is non g we return sp for fp
656  */
657
658 /* note this is written for Metaware version R2.1d compiler */
659
660 caller_pc(this_pc,this_sp,to_pc,to_fp)
661      int * to_pc, *to_fp;
662      unsigned long this_pc,this_sp;
663 {
664    unsigned long func_start;
665    int sp_offset,offset;
666    unsigned long sp,pc,fp,instr;
667    
668    BTDEBUG("caller_pc %x sp = %x\n",this_pc,this_sp);
669    
670    func_start = get_pc_function_start(this_pc);
671
672    BTDEBUG("caller_pc func_start %x\n", func_start);
673
674    if (func_start)
675       {
676          if( has_a_frame(func_start) ){
677       
678             BTDEBUG("has_a_frame\n");
679       
680             /* if our caller has a preamble and 
681              * declares space for a stack frame
682              * then we must work to find our return address
683              */
684             instr = adj_read_memory_integer (func_start);
685             /* Recognize "addu|adds -X,sp,sp" insn. */
686       
687             if ((instr & 0xEFFF0000) == 0x84420000)
688                sp_offset=SIGN_EXT16(instr&0x0000FFFF);
689          }
690          else   { printf("error frame_chain\n");return(0); }
691       
692       BTDEBUG("sp_offset = %d %x\n",sp_offset,sp_offset);
693       
694       offset = find_r1_offset(func_start);
695       
696       if( offset < 0 ){
697          printf("cant find return address for routine at %x\n",
698                 func_start);
699          return(0);
700       }
701       pc = read_memory_integer(this_sp+offset,4);
702       sp= this_sp - sp_offset;
703       
704       BTDEBUG("callers pc = %x sp = %x\n",pc,sp);
705       
706       /* our caller a -g routine  ?
707        * if he is we have to find his real fp
708        * else provide the sp as his fp
709        */
710       
711       if( g_routine(pc) ){
712          
713          BTDEBUG("caller_a_g\n");
714          
715          if( ! (offset = find_fp_offset(func_start)) ) {
716             printf("error fp_offset\n");
717             return(0);
718          }
719          BTDEBUG("offset = %x %d\n",offset,offset);
720          
721          fp = read_memory_integer(this_sp+offset,4);
722          *to_pc = CLEAN_PC(pc);
723          *to_fp = fp;
724          return(1);
725       }else  
726          *to_pc = CLEAN_PC(pc);
727       *to_fp = sp;
728       return(1);
729    } else {
730 /*      pc = read_register(RP_REGNUM); */
731       pc = 0; 
732       BTDEBUG("read_register pc %x\n",pc);
733       if( g_routine(pc) ){
734          
735          *to_pc = CLEAN_PC(pc);
736          *to_fp = read_register(FP_REGNUM);
737          return(1);
738       }else  {
739          *to_pc = CLEAN_PC(pc);
740          *to_fp = this_sp;
741          return(1);
742       }
743    }
744 }
745
746 int outside_startup_file();
747
748 /* get the PC of the caller */
749 frame_saved_pc(frame_struct)
750 FRAME frame_struct;
751 {
752      unsigned long frame;
753      unsigned long pc;
754      unsigned long pc1;
755      unsigned long sp;
756
757      CORE_ADDR fp;
758      
759      CORE_ADDR rp;
760
761      frame = frame_struct->frame;
762      pc = frame_struct->pc;
763      BTDEBUG("frame_saved_pc input: frame %x, pc %x, sp %x ",
764            frame, pc, sp);
765
766      /* First see if this is the current frame. If it is, return the value in r1,
767         as it may not have been stored */
768
769      fp = read_register(FP_REGNUM);
770
771      /* check to see if we are in an entry sequence, where the return pointer has not yet been stored */
772      if (fp == frame &&  no_stored_rp(pc))
773         {
774            pc = read_register(RP_REGNUM);
775            frame_struct->rp = pc;
776         }
777      else if( ! g_routine(pc) )
778         {
779            caller_pc(pc,sp,&pc,&frame);
780         }
781      else 
782         {
783            
784            pc = read_memory_integer (frame + 4, 4); 
785    
786            if (!outside_startup_file(pc))
787               {
788                  
789                  BTDEBUG("pc %x outside startup file \n",pc);
790
791                  pc1 = read_memory_integer (frame, 4);
792                
793                  if (outside_startup_file(pc1))
794                     pc = pc1;
795                  else
796                     pc = 0;
797               }
798         } 
799      BTDEBUG(" returning pc %x\n", CLEAN_PC(pc));
800      return(CLEAN_PC(pc));
801
802   }
803
804 /* Pass arguments to a function in the inferior process - ABI compliant
805  */
806
807 pass_function_arguments(args, nargs, struct_return)
808      value *args;
809      int nargs;
810      int struct_return;
811 {
812    int ireg = (struct_return) ? 17 : 16;
813    int freg = FP0_REGNUM + 8;
814    int i;
815    struct type *type;
816    value arg;
817    long tmp;
818    value value_arg_coerce();
819    
820    
821    for (i = 0; i < nargs; i++) 
822       {
823          arg = value_arg_coerce(args[i]);
824          type = VALUE_TYPE(arg);
825          if (type == builtin_type_double) 
826             {
827                write_register_bytes(REGISTER_BYTE(freg), VALUE_CONTENTS(arg), 8);
828                freg += 2;
829             }
830          else
831             {
832                bcopy(VALUE_CONTENTS(arg), &tmp, 4);
833                write_register(ireg, tmp);
834                ireg++;
835             }
836       }
837    if (ireg >= 28 || freg >= FP0_REGNUM + 16)
838       error("Too many arguments to function");
839 }
840
841
842 #define SPACES          "       "
843 #define P_SPACES        "   "
844 #define BYTE 0xff
845
846 int screen_lines=24;
847
848 char *spec_reg[] = {
849    "fsr", "db", "dirbase", "fir", "psr", "epsr",
850 };
851
852 char *doro_reg[] = {
853    "scp", "cbsp", "pt_cs", "intmsk", "intack",
854 };
855 #define NREGS 32
856
857
858 get_reg(regno)
859 {
860    char raw_buffer[32];
861    int addr;
862    int virtual_buffer;
863    
864    read_relative_register_raw_bytes (regno, raw_buffer);
865    REGISTER_CONVERT_TO_VIRTUAL (addr, raw_buffer, &virtual_buffer);
866    return(virtual_buffer);
867 }
868
869 int jhdebug = 0;
870 /*
871  ** Figure out address to place next breakpoint. Avoid tricky spots, 
872  **     ie. delayed instruction slots etc.
873  ** Need to upgrade this later to allow delayed instruction breakpoints
874  **     with fix-up work done AFTER breakpoint.
875  ** Note that this routine DOES deal with dual instruction mode
876  */
877 #define BIM 0x8008
878
879 branch_type
880    place_brk (addr, mode, brk)
881 CORE_ADDR addr; 
882 int mode;
883 struct breakpoint *brk;
884 {
885    long nextadr, prevadr, instr;
886    int val = not_branch;
887    long offset; /* Must be signed for sign-extend */
888    extern char registers[];
889    prevadr = nextadr = 0;
890    
891    brk->address1 = 0;
892    
893    if (mode == SINGLE_STEP_MODE)
894       {
895          if (INDIM || ENDIM)
896             {
897                         nextadr = brk->address   = (addr + 8);
898                         instr   = adj_read_memory_integer ((addr + 4));
899                         brk->mode       = DIM;
900             }
901          else
902             {
903                         nextadr = brk->address   = (addr + 4);
904                         instr   = adj_read_memory_integer (addr);
905                         if (STDIM) 
906                   brk->mode = DIM;
907                         else
908                   brk->mode = SIM;
909             }
910          
911          
912          /*
913           ** For br/call one more sequential instruction gets executed and  then we
914           **    continue at the current addr + offset. We are definitely going to
915           **    the dest. We are NOT allowed to place a breakpoint in the "delay"
916           **    slot - (the next sequential instruction) so we only place 1 breakpoint
917           **    at the destination.
918           ** For the bc/bnc the next instruction executed is EITHER the next sequential
919           **    or the destination of the branch, we therefore place 2 breakpoints one
920           **    at each location.
921           ** For the bc.t/bnc.t either 1 more sequential instruction is performed
922           **    followed by a branch (like br/call) OR we skip the sequential 
923           **    instruction and keep going. We therefore place a breakpoint at the
924           **    destination of the branch AND the second sequential instruction after
925           **    the branch. Again a breakpoint is NOT allowed in the "delay slot"
926           */
927          if ((instr & 0xE0000000) == 0x60000000 &&      /* CTRL format */
928              (instr & 0xF8000000) != 0x60000000)                /* not pfld.y  */
929             {
930                if      ((instr & 0xF8000000) == 0x68000000)     /* br or call */
931                   val = uncond_d;
932                else if ((instr & 0xF4000000) == 0x74000000)     /* bc.t/bnc.t */
933                   val = cond_d;
934                else if ((instr & 0xF4000000) == 0x70000000)     /* bc or bnc  */
935                   val = cond;
936                offset = (instr & 0x03ffffff);
937                if (offset & 0x02000000)                 /*?sign extend*/
938                   offset |= 0xFC000000;
939                if (val == uncond_d)                     /* br/call*/
940                   prevadr = 0;
941                else if (val == cond_d)                  /* bc.t/bnc.t */
942                   {
943                      if ((INDIM) && !(ENDIM))
944                         prevadr = nextadr + 8;
945                      else
946                         prevadr = nextadr + 4;
947                   } else {                              /* bc  /bnc   */
948                      if ((INDIM) && !(ENDIM))
949                         prevadr = nextadr;
950                      else
951                         prevadr = nextadr;
952                   }
953                nextadr += (offset << 2);
954             }
955          /*
956           ** We treat the bri/calli the same way as the br/call case.
957           */
958          else if ((instr & 0xFC00003F) == 0x4C000002 ||         /* calli    */
959                   (instr & 0xFC000000) == 0x40000000)           /* bri      */
960             {
961                val      = uncond_d;
962                offset   = ((instr & 0x0000F800) >> 11);
963                nextadr  = (read_register(offset + R0) & 0xFFFFFFFC);
964                prevadr = 0;
965             }
966          /*
967           ** We treat the bte/btne the same way as the bc/bnc case.
968           */
969          else if ((instr & 0xF0000000) == 0x50000000)           /* bte/btne */
970             {
971                val = cond;
972                offset = SIGN_EXT16(((instr & 0x001F0000) >> 5)  | 
973                                    (instr & 0x000007FF));
974                if ((INDIM) && !(ENDIM))
975                   prevadr = nextadr;
976                else
977                   prevadr = nextadr;
978                
979                nextadr += (offset << 2);
980             }
981          /*
982           ** We treat the bte/btne the same way as the bc/bnc case.
983           **    With the caveat that the 2 breakpoints may turn out to be at the same
984           **    address in which case we ignore one of them.
985           */
986          else if ((instr & 0xFC000000) == 0xB4000000)           /* bla */
987             {
988                val      = cond_d;
989                offset   = SIGN_EXT16(((instr & 0x001F0000) >> 5)  | 
990                                       (instr & 0x000007FF));
991                if ((INDIM) && !(ENDIM))
992                   {
993                      prevadr = nextadr + 8;
994                   } else        {
995                      prevadr = nextadr + 4;
996                   }
997                nextadr += (offset << 2);
998                if (prevadr == nextadr) prevadr = 0;
999             }
1000       } else    {
1001          int adjust = 0;
1002          
1003          nextadr = addr;
1004          
1005          if (ISDIM(FOPADR(addr)))
1006             {
1007                if (ISDIM(FOPADR(nextadr-8)))
1008                   {
1009                      instr      = adj_read_memory_integer(CORADR(addr-8));
1010                      brk->mode  = DIM;
1011                   } else        {
1012                      instr      = adj_read_memory_integer(addr-4);
1013                      brk->mode  = RIM;
1014                   }
1015             } else {
1016                if (ISDIM(addr-4))
1017                   {
1018                      instr      = adj_read_memory_integer(addr-4);
1019                      brk->mode  = BIM;
1020                   } else        {
1021                      instr      = adj_read_memory_integer (addr-4);
1022                      brk->mode  = SIM;
1023                   }
1024             }
1025          
1026          /* examine the PREVIOUS instruction to determine if we are in a branch delay
1027             slot.  If we are, dont set a break here -- set it on the previous instruction.
1028             This code also accounts for dual instruction mode */
1029          if ((instr & 0xE0000000) == 0x60000000 &&
1030              (instr & 0xF8000000) != 0x60000000)                /* not pfld.y  */
1031             {
1032                adjust++;
1033                /* br    /call */
1034                /* bc     /bnc  */
1035                /* bc.t   /bnc.t*/
1036                if ((instr & 0xF8000000) == 0x68000000) /* br or call */
1037                   printf(" Breakpoint adjusted to avoid br/call delay slot and multiple breakpoints\n");
1038                
1039                if ((instr & 0xF4000000) == 0x74000000) /* bc.t or bnc.t */
1040                   printf(" Breakpoint adjusted to avoid bc.t/bnc.t delay slot and multiple breakpoints\n");
1041                /* it IS really OK to set a break on the instruction AFTER the conditional branch
1042                   -- it DOESN't have a delay slot */
1043                if ((instr & 0xF4000000) == 0x70000000) /* bc / bnc */
1044                   /* printf(" Breakpoint adjusted to avoid bc/bnc delay slot and multiple breakpoints\n"); */
1045                   adjust = 0; 
1046             } else if
1047                ((instr & 0xFC00003F) == 0x4C000002 ||   /* bri/  calli */
1048                 (instr & 0xFC000000) == 0x40000000)     
1049                   {
1050                      adjust++;
1051                      printf(" Breakpoint adjusted to avoid calli/bri delay slot and multiple breakpoints\n");
1052                   } else if
1053                      ((instr & 0xF0000000) == 0x50000000) /* bte - btne */
1054                         {
1055                            /* it's OK to set a break here -- we are NOT in aa branch delay slot */
1056                            /*
1057                            adjust++;
1058                            printf(" Breakpoint adjusted to avoid bte/btne multiple breakpoints\n");
1059                            */
1060                            adjust = 0;
1061                         } else if
1062                            ((instr & 0xFC000000) == 0xB4000000)
1063                               {
1064                                  adjust++;
1065                                  printf(" Breakpoint adjusted to avoid bla delay slot and multiple breakpoints\n");
1066                               }
1067          if (adjust)
1068             {
1069                if (brk->mode == DIM)
1070                   {
1071                      nextadr -= 8;
1072                      nextadr = CORADR(nextadr); 
1073                   }
1074                else
1075                   nextadr -=4;
1076             }
1077          
1078       }
1079    
1080    if (brk->mode == RIM) 
1081       brk->mode = DIM;
1082    if (brk->mode == BIM) 
1083       brk->mode = SIM;
1084    
1085    if (nextadr)
1086       {
1087          if (brk->mode == DIM)
1088             {
1089                brk->act_addr[0] = CORADR(nextadr);
1090                brk->act_addr[1] = FOPADR(nextadr);
1091             } else      {
1092                brk->act_addr[0] = nextadr;
1093                brk->act_addr[1] = 0;
1094             }
1095       }
1096    
1097    if (prevadr)
1098       {
1099          brk->address1 = prevadr;
1100          if (brk->mode == DIM)
1101             {
1102                brk->act_addr[2] = CORADR(prevadr);
1103                brk->act_addr[3] = FOPADR(prevadr);
1104             } else      {
1105                brk->act_addr[2] = prevadr;
1106                brk->act_addr[3] = 0;
1107             }
1108       } else    {
1109          brk->act_addr[2] = brk->act_addr[3] = 0;
1110       }
1111    return val;
1112 }
1113
1114 /*
1115  ** Figure out whether we are in a delayed slot and if so then take necessary
1116  **     action to resume properly - remember trap pre-empts instruction
1117  */
1118 int
1119    wasabranch (addr, nextpc, ss)
1120 CORE_ADDR addr, *nextpc;
1121 int ss;
1122 {
1123    long nextadr, instr;
1124    int val = not_branch;
1125    long offset; /* Must be signed for sign-extend */
1126    
1127    if (ss)
1128       {
1129          if (INDIM)
1130             {
1131                         nextadr = CORADR((int)(addr + 8));
1132                         instr   = adj_read_memory_integer (CORADR(addr));
1133             }
1134          else
1135             {
1136                         nextadr = addr + 4;
1137                         instr   = adj_read_memory_integer (addr);
1138             }
1139       } else    {
1140          if (ISDIM(addr))
1141             {
1142                         nextadr = CORADR(addr);
1143                         instr   = adj_read_memory_integer (nextadr);
1144             }
1145          else
1146             {
1147                         nextadr = addr;
1148                         instr   = adj_read_memory_integer (addr);
1149             }
1150       }
1151    
1152    
1153    if ((instr & 0xE0000000) == 0x60000000 &&            /* CTRL format */
1154        (instr & 0xF8000000) != 0x60000000)              /* not pfld.y  */
1155       {
1156          if ((instr & 0xF8000000) == 0x68000000)                /* br or call */
1157             val = uncond_d;
1158          else if ((instr & 0xF4000000) == 0x74000000)   /* bc.t or bnc.t */
1159             val = cond_d;
1160          else if ((instr & 0xF4000000) == 0x70000000)   /* bc or bnc */
1161             val = cond;
1162          
1163          offset = (instr & 0x03ffffff);
1164          if (offset & 0x02000000)       /* sign extend? */
1165             offset |= 0xFC000000;
1166          nextadr += (offset << 2);
1167       }
1168    else if ((instr & 0xFC00003F) == 0x4C000002 ||       /* calli */
1169             (instr & 0xFC000000) == 0x40000000)         /* bri */
1170       {
1171          if (ss)
1172             {
1173                val      = uncond_d;
1174                 offset  = ((instr & 0x0000F800) >> 11);
1175                 nextadr = (read_register(offset) & 0xFFFFFFFC);
1176             } else      {
1177                val      = uncond_d;
1178             }
1179       }
1180    else if ((instr & 0xF0000000) == 0x50000000)         /* bte or btne */
1181       {
1182          val = cond;
1183          
1184          offset = SIGN_EXT16(((instr & 0x001F0000) >> 5)  | (instr & 0x000007FF));
1185          nextadr += (offset << 2);
1186       }
1187    else if ((instr & 0xFC000000) == 0xB4000000)         /* bla */
1188       {
1189          val = cond_d;
1190          
1191          offset = SIGN_EXT16(((instr & 0x001F0000) >> 5)  | (instr & 0x000007FF));
1192          nextadr += (offset << 2);
1193       }
1194    
1195    *nextpc = nextadr;
1196    return val;
1197 }
1198
1199 extern char registers[];
1200
1201 i860_do_registers_info(regnum,fpregs)
1202      int regnum;
1203      int fpregs;
1204 {
1205    register int i;
1206    unsigned int val;
1207    unsigned int j,k;
1208    
1209    if (regnum == -1)
1210       printf_filtered (
1211                        "Register       Contents (relative to selected stack frame)\n\n");
1212    
1213    if (regnum != -1) /* print one register */
1214       {
1215          if ((regnum >=F0 ) && (regnum <= F31))
1216             bcopy (&registers[ADJ_FREG(regnum)<<2], &val, sizeof (long));
1217          else
1218             bcopy (&registers[regnum<<2], &val, sizeof (long));
1219          printf("%-4s 0x%08x\t", reg_names[regnum], val);
1220          printf("\n\t"); fflush(stdout);
1221       }
1222    else /* print all registers */
1223       {
1224          
1225          printf("\n Control/Status Registers :- \n\t");
1226          for (j=0; j<=DB; j++)
1227             {
1228                bcopy (&registers[j<<2], &val, sizeof (long));
1229                printf("%-4s 0x%08x\t", reg_names[j], val);
1230             }
1231          printf("\n\t"); fflush(stdout);
1232          
1233          /* EPSR */
1234          bcopy (&registers[EPSR<<2], &val, sizeof (long));
1235          printf("%-4s 0x%08x\t", reg_names[EPSR], val);
1236          
1237          /* FSR */
1238          bcopy (&registers[FSR<<2], &val, sizeof (long));
1239          printf("%-4s 0x%08x\t", reg_names[FSR], val);
1240          
1241          /* CCR */
1242          bcopy (&registers[CCR<<2], &val, sizeof (long));
1243          printf("%-4s 0x%08x\t", reg_names[CCR], val);
1244          /* BEAR*/
1245          bcopy (&registers[BEAR<<2], &val, sizeof (long));
1246          printf("%-4s 0x%08x\t", reg_names[BEAR], val);
1247          
1248          
1249 #ifdef JIM_ADD_PRIV
1250          for (j=P0; j<=P3; j++)
1251             {
1252                bcopy (&registers[j<<2], &val, sizeof (long));
1253                printf("%-4s 0x%08x\t", reg_names[j], val);
1254             }
1255 #endif
1256          
1257          printf("\n Integer Registers :- \n\t");
1258          for (j=R0; j<=R31; j++)
1259             {
1260                if (j != IREGS  && (j % 4 == 0)) 
1261                   {
1262                      printf("\n\t");  fflush(stdout);
1263                   }
1264                bcopy (&registers[j<<2], &val, sizeof (long));
1265                printf("%-4s 0x%08x\t", reg_names[j], val);
1266             }
1267          
1268          printf("\n Floating Registers :- \n\t");
1269          for (j=F0; j<=F31; j++)
1270             {
1271                if (j != FREGS && (j % 4 == 0)) 
1272                   {
1273                      printf("\n\t");  fflush(stdout);
1274                   }
1275                bcopy (&registers[ADJ_FREG(j)<<2], &val, sizeof (long));
1276                printf("%-4s 0x%08x\t", reg_names[j], val);
1277             }
1278          
1279          printf("\n Special Registers :- \n\t");
1280          for (j=SPC_KI; j<=SPC_MERGE; j+=2)
1281             {
1282                unsigned int valh;
1283                if (j == SPC_T)
1284                   {
1285                      printf("\n\t");  fflush(stdout);
1286                   }
1287                bcopy (&registers[j<<2], &val, sizeof (long));
1288                bcopy (&registers[(j+1)<<2], &valh, sizeof (long));
1289                printf("%-6s 0x%08x %08x\t", reg_names[j], val,valh);
1290             }
1291          
1292          printf("\n Graphics Pipeline :- \n");
1293          {
1294             unsigned int valh, val2,val3;
1295             j = PSV_I1;
1296             bcopy (&registers[j<<2], &val, sizeof (long));
1297             bcopy (&registers[(j+1)<<2], &valh, sizeof (long));
1298             printf("\t\t\t%-8s 0x%08x %08x \n", reg_names[j], val,valh);
1299          }
1300          
1301          printf(" Memory Load Pipeline :- \n");
1302          for (j=PSV_L1; j<=PSV_L3; j+=4)
1303             {
1304                unsigned int valh, val2,val3;
1305                bcopy (&registers[j<<2], &val, sizeof (long));
1306                bcopy (&registers[(j+1)<<2], &valh, sizeof (long));
1307                bcopy (&registers[(j+2)<<2], &val2, sizeof (long));
1308                bcopy (&registers[(j+3)<<2], &val3, sizeof (long));
1309                printf("\t\t%-8s 0x%08x %08x %08x %08x\n", reg_names[j], 
1310                       val,valh,val2,val3);
1311             }
1312          
1313          printf("\n Adder Pipeline :-\t\tMultiplier Pipeline :-\t\tFSR results :-\n");
1314          for (i=PSV_FSR1,j=PSV_A1,k=PSV_M1; j<=PSV_A3; i++,j+=2,k+=2)
1315             {
1316                unsigned int valh,val2,val3,val4;
1317                bcopy (&registers[i<<2], &val4, sizeof (long));
1318                bcopy (&registers[j<<2], &val, sizeof (long));
1319                bcopy (&registers[(j+1)<<2], &valh, sizeof (long));
1320                bcopy (&registers[k<<2], &val2, sizeof (long));
1321                bcopy (&registers[(k+1)<<2], &val3, sizeof (long));
1322                printf("  %-4s 0x%08x %08x\t", reg_names[j], val,valh);
1323                printf("%-4s 0x%08x %08x\t", reg_names[k], val2,val3);
1324                printf("%-4s 0x%08x\n", reg_names[i], val4);
1325             }
1326          
1327       }
1328    
1329    
1330 }
1331
1332 int has_stored_r1(CORE_ADDR prologue_start, CORE_ADDR prologue_end)
1333 {
1334    long instr;
1335    CORE_ADDR addr;
1336    
1337    BTDEBUG("has_stored_r1, prologue_start %x, prologue_end %x\n",
1338            prologue_start, prologue_end);
1339
1340    for (addr = prologue_start; addr <= prologue_end;  addr += 4)
1341       {
1342    
1343          instr = adj_read_memory_integer (addr);
1344          if   ((instr & 0xFFE0F801) == 0x1C400801 /* st.l r1,X(sp) */
1345             || (instr & 0xFFE0F801) == 0x1C600801) /* st.l r1,X(fp) */
1346             return (1);
1347       }
1348    return 0;
1349 }
1350
1351 /* This function returns 1 if there is no stored r1, 0 otherwise.
1352    The function returns 1 if the pc is in a function prologue,
1353    or the function prologue didn't save the return pointer in
1354    the stack frame,  0 otherwise */
1355
1356 int no_stored_rp(CORE_ADDR pc)
1357 {
1358    CORE_ADDR func_start, prologue_end;
1359    
1360    func_start = get_pc_function_start(pc);
1361    if (func_start)
1362       {
1363          prologue_end = func_start;
1364          SKIP_PROLOGUE(prologue_end);
1365          if ( (pc >= func_start) && (pc <= prologue_end))
1366             {
1367                BTDEBUG("no_stored_rp: pc %x is in prologue \n",pc);
1368                return 1;
1369             }
1370          /* otherwise, see if the entry sequence stored the return pointer.
1371             If it didn't, return 1 */
1372          /* Some procedures , at least, store the return pointer AFTER the prologue sequence! */
1373          if (!has_stored_r1(func_start, pc))
1374             {  
1375                BTDEBUG("no_stored_rp, for pc %x, prologue didn't store r1\n",pc);
1376                return 1;
1377             }
1378       }
1379    BTDEBUG("no_stored_rp for pc %x return pointer was stored \n", pc);
1380
1381    return 0; 
1382 }
1383
1384 /* The following set of routines was adapted from existing code previously
1385    in an i860-specific version of breakpoint.c by Peggy Fieland
1386    (Margaret_Fieland@vos.stratus.com) */
1387 unsigned int dbrkval, dbrkmod;
1388 void i860_dbrk_breakpoint()
1389 {
1390    BTDEBUG("i860_dbrk_breakpoint was called , dbrkval %x\n", dbrkval);
1391    
1392    if (dbrkval)
1393       {
1394          *(int *)&registers[DB<<2] = dbrkval;
1395       }
1396    else
1397       {
1398          *(int *)&registers[DB<<2] = 0;
1399       }
1400
1401    *(int *)&registers[PSR<<2] &= ~3;
1402    *(int *)&registers[PSR<<2] |= dbrkmod;
1403
1404    store_inferior_registers(DB);
1405    store_inferior_registers(PSR);
1406
1407 }
1408
1409 void
1410 d_ro_break_command(arg)
1411 char *arg;
1412 {
1413         dbrkval = strtoul(arg, NULL, 0);
1414         dbrkmod = 0x01;
1415 printf(" ro_dbreak - %x %x\n", dbrkval, dbrkmod);
1416 }
1417
1418 void
1419 d_wo_break_command(arg)
1420 char *arg;
1421 {
1422         dbrkval = strtoul(arg, NULL, 0);
1423         dbrkmod = 0x02;
1424 printf(" wo_dbreak - %x %x\n", dbrkval, dbrkmod);
1425 }
1426
1427 void
1428 d_rw_break_command(arg)
1429 char *arg;
1430 {
1431         dbrkval = strtoul(arg, NULL, 0);
1432         dbrkmod = 0x03;
1433 printf(" rw_dbreak - %x %x\n", dbrkval, dbrkmod);
1434 }
1435
1436 void
1437 clear_dbreak()
1438 {
1439         dbrkval = 0;
1440         dbrkmod = 0;
1441 }
1442
1443 void 
1444 i860_init_breakpoints()
1445 {
1446   dbrkval = dbrkmod = 0;
1447   add_com ("dbro", class_breakpoint, d_ro_break_command,
1448            "Set a data breakpoint READ ONLY, 32-bit data element.");
1449   add_com ("dbwo", class_breakpoint, d_wo_break_command,
1450            "Set a data breakpoint WRITE ONLY, 32-bit data element.");
1451   add_com ("dbrw", class_breakpoint, d_rw_break_command,
1452            "Set a data breakpoint READ/WRITE, 32-bit data element.");
1453   add_com ("dclear", class_breakpoint, clear_dbreak,
1454            "clear the current data breakpoint.");
1455   add_com_alias ("dc", "dclear", class_breakpoint, 1);
1456
1457 }
1458
1459 int i860_insert_breakpoint(b)
1460 struct breakpoint *b;
1461 {
1462    int val;
1463
1464    place_brk( b->address, BREAK_MODE, b );
1465    if (b->mode == DIM)
1466       {
1467          
1468          adj_read_memory (b->act_addr[0], &b->shadow_contents[0], 4);
1469          val =  adj_write_memory (b->act_addr[0], break_insn, 4);
1470          if (val) return val;
1471          adj_read_memory (b->act_addr[1], &b->shadow_contents[1], 4);
1472          /*     val = adj_write_memory (b->act_addr[1], float_insn, 4); */
1473          if (val) return val;
1474       } 
1475    else 
1476       {
1477          adj_read_memory (b->act_addr[0], &b->shadow_contents[0], 4);
1478          val = adj_write_memory (b->act_addr[0], break_insn, 4);
1479       }
1480    if (b->address1)
1481       {
1482          if (b->mode == DIM)
1483             {
1484
1485                adj_read_memory (b->act_addr[2], &b->shadow_contents[2], 4);
1486                val = adj_write_memory (b->act_addr[2], break_insn, 4);
1487                if (val) return val;
1488                adj_read_memory (b->act_addr[3], &b->shadow_contents[3], 4);
1489                /*       val = adj_write_memory (b->act_addr[3], float_insn, 4); */
1490                if (val) return val;
1491             }
1492          else   
1493             {
1494                adj_read_memory (b->act_addr[2], &b->shadow_contents[0], 4);
1495                val = adj_write_memory (b->act_addr[2], break_insn, 4);
1496             }
1497       }
1498    if (val)
1499       return val;
1500    BTDEBUG("Inserted breakpoint at 0x%x, shadow 0x%x, 0x%x.\n",
1501            b->address, b->shadow_contents[0], b->shadow_contents[1]);
1502    b->inserted = 1;
1503    return 0;
1504 }
1505
1506 int i860_remove_breakpoint(b)
1507 struct breakpoint *b;
1508 {
1509    int val;
1510
1511    if (b->inserted)
1512       {
1513          if (b->mode == DIM)
1514             {
1515                val =adj_write_memory (b->act_addr[0], &(b->shadow_contents[0]), 4);
1516                val =adj_write_memory (b->act_addr[1], &(b->shadow_contents[1]), 4);
1517                if (b->address1)
1518                   {
1519                      val =adj_write_memory (b->act_addr[2], &(b->shadow_contents[2]), 4);
1520                      val =adj_write_memory (b->act_addr[3], &(b->shadow_contents[3]), 4);
1521                   }
1522             } 
1523          else   
1524             {
1525                val =adj_write_memory (b->act_addr[0], b->shadow_contents, 4);
1526                if (b->address1)
1527                   {
1528                      val =adj_write_memory (b->act_addr[2], b->shadow_contents, 4);
1529                   }
1530             }
1531          if (val)
1532             return val;
1533          b->inserted = 0;
1534          BTDEBUG( "Removed breakpoint at 0x%x, shadow 0x%x, 0x%x.\n",
1535                  b->address, b->shadow_contents[0], b->shadow_contents[1]);
1536       }
1537
1538    return 0;
1539
1540
1541 }
1542
1543
1544 #ifdef USE_PROC_FS      /* Target dependent support for /proc */
1545
1546 #include <sys/procfs.h>
1547
1548 /* The following routines were added by Peggy Fieland (Margaret_Fieland@vos.stratus.com)
1549 They were adapted from the m-68k versions of the routines .*/
1550
1551 /*  Given a pointer to a floating point register set in /proc format
1552     (fpregset_t *), unpack the register contents and supply them as gdb's
1553     idea of the current floating point register values. */
1554
1555 void 
1556 supply_fpregset (fpregsetp)
1557 fpregset_t *fpregsetp;
1558 {
1559   register int regno;
1560   
1561   BTDEBUG("supply_fregset called \n");
1562   
1563   for (regno = F0 ; regno <= F31 ; regno++)
1564     {
1565       supply_register (regno, (char *) &(fpregsetp -> fpu.r_freg[regno-F0]));
1566     }
1567 }
1568
1569 /*  Given a pointer to a floating point register set in /proc format
1570     (fpregset_t *), update the register specified by REGNO from gdb's idea
1571     of the current floating point register set.  If REGNO is -1, update
1572     them all. */
1573
1574 void
1575 fill_fpregset (fpregsetp, regno)
1576 fpregset_t *fpregsetp;
1577 int regno;
1578 {
1579   int regi;
1580   char *to;
1581   char *from;
1582   extern char registers[];
1583   BTDEBUG("fill_fregset  regno %d\n",regno);
1584
1585   for (regi = F0 ; regi <= F31 ; regi++)
1586     {
1587       if ((regno == -1) || (regno == regi))
1588         {
1589           from = (char *) &registers[REGISTER_BYTE (regi)];
1590        to = (char *) &(fpregsetp -> fpu.r_freg[regi-F0]);
1591           bcopy (from, to, REGISTER_RAW_SIZE (regno));
1592         }
1593     }
1594 }
1595
1596
1597 /*  Given a pointer to a general register set in /proc format (gregset_t *),
1598     unpack the register contents and supply them as gdb's idea of the current
1599     register values. */
1600
1601 void
1602 supply_gregset (gregsetp)
1603 gregset_t *gregsetp;
1604 {
1605   register int regno;
1606   register greg_t *regp = (greg_t *) gregsetp;
1607
1608   BTDEBUG("supply_gregset called \n");
1609
1610   for (regno = 0 ; regno <= R31 ; regno++)
1611     {
1612       supply_register (regno, (char *) (regp + regno));
1613     }
1614 }
1615
1616 void
1617 fill_gregset (gregsetp, regno)
1618 gregset_t *gregsetp;
1619 int regno;
1620 {
1621   int regi;
1622   extern char registers[];
1623   register greg_t *regp = (greg_t *) gregsetp;
1624   BTDEBUG("fill_gregset regno %d \n",regno);
1625
1626   for (regi = 0 ; regi <= R31 ; regi++)
1627     {
1628       if ((regno == -1) || (regno == regi))
1629         {
1630         *(regp + regi) = *(int *) &registers[REGISTER_BYTE (regi)];
1631         }
1632
1633    }
1634 }
1635 #endif
1636