Add several new files for stratus (i860* and *-stratus.h). Also add
[deliverable/binutils-gdb.git] / gdb / i860-tdep.c
CommitLineData
be9a2362
FF
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
66int btdebug = 0; /* change value to 1 to enable debugging code */
67
68#define BTDEBUG if (btdebug) btdebug_message
69
70#include <stdarg.h>
71
72int read_memory();
73int write_memory();
74
75btdebug_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
85extern int errno;
86extern 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
97static struct breakpoint brk;
98typedef char binsn_quantum[sizeof break_insn];
99static 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
106int one_stepped;
107void
108 single_step (signal)
109int 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
230g_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
260struct command_line *get_breakpoint_commands ();
261
262CORE_ADDR
263 skip_prologue (pc)
264CORE_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
325branch_type
326 isabranch (addr, nextpc)
327CORE_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
383CORE_ADDR call_dummy_set = 0; /* true if dummy call being done */
384CORE_ADDR call_dummy_start; /* address of call dummy code */
385
386frame_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 */
540find_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
561find_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?? */
583has_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
597frame_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
660caller_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
746int outside_startup_file();
747
748/* get the PC of the caller */
749frame_saved_pc(frame_struct)
750FRAME 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
807pass_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
846int screen_lines=24;
847
848char *spec_reg[] = {
849 "fsr", "db", "dirbase", "fir", "psr", "epsr",
850};
851
852char *doro_reg[] = {
853 "scp", "cbsp", "pt_cs", "intmsk", "intack",
854};
855#define NREGS 32
856
857
858get_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
869int 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
879branch_type
880 place_brk (addr, mode, brk)
881CORE_ADDR addr;
882int mode;
883struct 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 */
1118int
1119 wasabranch (addr, nextpc, ss)
1120CORE_ADDR addr, *nextpc;
1121int 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
1199extern char registers[];
1200
1201i860_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
1332int 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
1356int 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) */
1387unsigned int dbrkval, dbrkmod;
1388void 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
1409void
1410d_ro_break_command(arg)
1411char *arg;
1412{
1413 dbrkval = strtoul(arg, NULL, 0);
1414 dbrkmod = 0x01;
1415printf(" ro_dbreak - %x %x\n", dbrkval, dbrkmod);
1416}
1417
1418void
1419d_wo_break_command(arg)
1420char *arg;
1421{
1422 dbrkval = strtoul(arg, NULL, 0);
1423 dbrkmod = 0x02;
1424printf(" wo_dbreak - %x %x\n", dbrkval, dbrkmod);
1425}
1426
1427void
1428d_rw_break_command(arg)
1429char *arg;
1430{
1431 dbrkval = strtoul(arg, NULL, 0);
1432 dbrkmod = 0x03;
1433printf(" rw_dbreak - %x %x\n", dbrkval, dbrkmod);
1434}
1435
1436void
1437clear_dbreak()
1438{
1439 dbrkval = 0;
1440 dbrkmod = 0;
1441}
1442
1443void
1444i860_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
1459int i860_insert_breakpoint(b)
1460struct 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
1506int i860_remove_breakpoint(b)
1507struct 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)
1549They 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
1555void
1556supply_fpregset (fpregsetp)
1557fpregset_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
1574void
1575fill_fpregset (fpregsetp, regno)
1576fpregset_t *fpregsetp;
1577int 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
1601void
1602supply_gregset (gregsetp)
1603gregset_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
1616void
1617fill_gregset (gregsetp, regno)
1618gregset_t *gregsetp;
1619int 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
This page took 0.080966 seconds and 4 git commands to generate.