* config/monitor.exp: Detect the "Couldn't establish connection"
[deliverable/binutils-gdb.git] / gdb / d10v-tdep.c
CommitLineData
7b3fa778
MH
1/* Target-dependent code for MItsubishi D10V, for GDB.
2 Copyright (C) 1996 Free Software Foundation, Inc.
3This file is part of GDB.
4This program is free software; you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation; either version 2 of the License, or
7(at your option) any later version.
8This program is distributed in the hope that it will be useful,
9but WITHOUT ANY WARRANTY; without even the implied warranty of
10MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11GNU General Public License for more details.
12You should have received a copy of the GNU General Public License
13along with this program; if not, write to the Free Software
14Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
15
16/* Contributed by Martin Hunt, hunt@cygnus.com */
17
18#include "defs.h"
19#include "frame.h"
20#include "obstack.h"
21#include "symtab.h"
22#include "gdbtypes.h"
23#include "gdbcmd.h"
24#include "gdbcore.h"
81dc176f 25#include "gdb_string.h"
7b3fa778
MH
26#include "value.h"
27#include "inferior.h"
28#include "dis-asm.h"
3b1af95c
MH
29#include "symfile.h"
30#include "objfiles.h"
7b3fa778 31
e05bda9f 32void d10v_frame_find_saved_regs PARAMS ((struct frame_info *fi, struct frame_saved_regs *fsr));
19414cdf 33static void d10v_pop_dummy_frame PARAMS ((struct frame_info *fi));
e05bda9f
MH
34
35/* Discard from the stack the innermost frame,
36 restoring all saved registers. */
37
7b3fa778
MH
38void
39d10v_pop_frame ()
40{
e05bda9f 41 struct frame_info *frame = get_current_frame ();
b70b03b0 42 CORE_ADDR fp;
e05bda9f
MH
43 int regnum;
44 struct frame_saved_regs fsr;
45 char raw_buffer[8];
46
b70b03b0 47 fp = FRAME_FP (frame);
19414cdf
MH
48 if (frame->dummy)
49 {
50 d10v_pop_dummy_frame(frame);
51 return;
52 }
53
e05bda9f
MH
54 /* fill out fsr with the address of where each */
55 /* register was stored in the frame */
56 get_frame_saved_regs (frame, &fsr);
57
e05bda9f
MH
58 /* now update the current registers with the old values */
59 for (regnum = A0_REGNUM; regnum < A0_REGNUM+2 ; regnum++)
60 {
61 if (fsr.regs[regnum])
62 {
81dc176f 63 read_memory (fsr.regs[regnum], raw_buffer, 8);
e05bda9f
MH
64 write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 8);
65 }
66 }
67 for (regnum = 0; regnum < SP_REGNUM; regnum++)
68 {
69 if (fsr.regs[regnum])
70 {
81dc176f 71 write_register (regnum, read_memory_unsigned_integer (fsr.regs[regnum], 2));
e05bda9f
MH
72 }
73 }
74 if (fsr.regs[PSW_REGNUM])
75 {
81dc176f 76 write_register (PSW_REGNUM, read_memory_unsigned_integer (fsr.regs[PSW_REGNUM], 2));
e05bda9f
MH
77 }
78
b70b03b0
MH
79 write_register (PC_REGNUM, read_register(13));
80 write_register (SP_REGNUM, fp + frame->size);
81 target_store_registers (-1);
e05bda9f
MH
82 flush_cached_frames ();
83}
84
85static int
86check_prologue (op)
87 unsigned short op;
88{
89 /* st rn, @-sp */
90 if ((op & 0x7E1F) == 0x6C1F)
91 return 1;
92
93 /* st2w rn, @-sp */
94 if ((op & 0x7E3F) == 0x6E1F)
95 return 1;
96
97 /* subi sp, n */
98 if ((op & 0x7FE1) == 0x01E1)
99 return 1;
100
101 /* mv r11, sp */
102 if (op == 0x417E)
103 return 1;
104
105 /* nop */
106 if (op == 0x5E00)
107 return 1;
108
109 /* st rn, @sp */
110 if ((op & 0x7E1F) == 0x681E)
111 return 1;
112
113 /* st2w rn, @sp */
114 if ((op & 0x7E3F) == 0x3A1E)
115 return 1;
116
e05bda9f 117 return 0;
7b3fa778
MH
118}
119
120CORE_ADDR
e05bda9f
MH
121d10v_skip_prologue (pc)
122 CORE_ADDR pc;
7b3fa778 123{
e05bda9f
MH
124 unsigned long op;
125 unsigned short op1, op2;
d716b33d
MH
126 CORE_ADDR func_addr, func_end;
127 struct symtab_and_line sal;
e05bda9f 128
d716b33d
MH
129 /* If we have line debugging information, then the end of the */
130 /* prologue should the first assembly instruction of the first source line */
131 if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
132 {
133 sal = find_pc_line (func_addr, 0);
294f72b2 134 if ( sal.end && sal.end < func_end)
d716b33d
MH
135 return sal.end;
136 }
137
e05bda9f
MH
138 if (target_read_memory (pc, (char *)&op, 4))
139 return pc; /* Can't access it -- assume no prologue. */
140
141 while (1)
142 {
81dc176f 143 op = (unsigned long)read_memory_integer (pc, 4);
e05bda9f
MH
144 if ((op & 0xC0000000) == 0xC0000000)
145 {
146 /* long instruction */
147 if ( ((op & 0x3FFF0000) != 0x01FF0000) && /* add3 sp,sp,n */
148 ((op & 0x3F0F0000) != 0x340F0000) && /* st rn, @(offset,sp) */
149 ((op & 0x3F1F0000) != 0x350F0000)) /* st2w rn, @(offset,sp) */
150 break;
151 }
152 else
153 {
154 /* short instructions */
21260fe1
MH
155 if ((op & 0xC0000000) == 0x80000000)
156 {
157 op2 = (op & 0x3FFF8000) >> 15;
158 op1 = op & 0x7FFF;
159 }
160 else
161 {
162 op1 = (op & 0x3FFF8000) >> 15;
163 op2 = op & 0x7FFF;
164 }
165 if (check_prologue(op1))
166 {
167 if (!check_prologue(op2))
168 {
169 /* if the previous opcode was really part of the prologue */
170 /* and not just a NOP, then we want to break after both instructions */
171 if (op1 != 0x5E00)
172 pc += 4;
173 break;
174 }
175 }
176 else
e05bda9f
MH
177 break;
178 }
179 pc += 4;
180 }
181 return pc;
7b3fa778 182}
19414cdf 183
e05bda9f
MH
184/* Given a GDB frame, determine the address of the calling function's frame.
185 This will be used to create a new GDB frame struct, and then
186 INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
81dc176f 187*/
e05bda9f 188
7b3fa778
MH
189CORE_ADDR
190d10v_frame_chain (frame)
191 struct frame_info *frame;
192{
e05bda9f 193 struct frame_saved_regs fsr;
3b1af95c 194
e05bda9f 195 d10v_frame_find_saved_regs (frame, &fsr);
3b1af95c 196
21260fe1
MH
197 if (frame->return_pc == IMEM_START)
198 return (CORE_ADDR)0;
199
3b1af95c
MH
200 if (!fsr.regs[FP_REGNUM])
201 {
21260fe1
MH
202 if (!fsr.regs[SP_REGNUM] || fsr.regs[SP_REGNUM] == STACK_START)
203 return (CORE_ADDR)0;
204
205 return fsr.regs[SP_REGNUM];
3b1af95c 206 }
21260fe1
MH
207
208 if (!read_memory_unsigned_integer(fsr.regs[FP_REGNUM],2))
209 return (CORE_ADDR)0;
210
211 return read_memory_unsigned_integer(fsr.regs[FP_REGNUM],2)| DMEM_START;
7b3fa778
MH
212}
213
21260fe1 214static int next_addr, uses_frame;
e05bda9f
MH
215
216static int
217prologue_find_regs (op, fsr, addr)
218 unsigned short op;
219 struct frame_saved_regs *fsr;
220 CORE_ADDR addr;
221{
222 int n;
223
224 /* st rn, @-sp */
225 if ((op & 0x7E1F) == 0x6C1F)
226 {
227 n = (op & 0x1E0) >> 5;
228 next_addr -= 2;
229 fsr->regs[n] = next_addr;
230 return 1;
231 }
232
233 /* st2w rn, @-sp */
234 else if ((op & 0x7E3F) == 0x6E1F)
235 {
236 n = (op & 0x1E0) >> 5;
237 next_addr -= 4;
238 fsr->regs[n] = next_addr;
239 fsr->regs[n+1] = next_addr+2;
240 return 1;
241 }
242
243 /* subi sp, n */
244 if ((op & 0x7FE1) == 0x01E1)
245 {
246 n = (op & 0x1E) >> 1;
247 if (n == 0)
248 n = 16;
249 next_addr -= n;
250 return 1;
251 }
252
253 /* mv r11, sp */
254 if (op == 0x417E)
21260fe1
MH
255 {
256 uses_frame = 1;
3b1af95c 257 return 1;
21260fe1 258 }
e05bda9f
MH
259
260 /* nop */
261 if (op == 0x5E00)
262 return 1;
263
264 /* st rn, @sp */
265 if ((op & 0x7E1F) == 0x681E)
266 {
267 n = (op & 0x1E0) >> 5;
268 fsr->regs[n] = next_addr;
269 return 1;
270 }
271
272 /* st2w rn, @sp */
273 if ((op & 0x7E3F) == 0x3A1E)
274 {
275 n = (op & 0x1E0) >> 5;
276 fsr->regs[n] = next_addr;
277 fsr->regs[n+1] = next_addr+2;
278 return 1;
279 }
280
281 return 0;
282}
283
7b3fa778
MH
284/* Put here the code to store, into a struct frame_saved_regs, the
285 addresses of the saved registers of frame described by FRAME_INFO.
286 This includes special registers such as pc and fp saved in special
287 ways in the stack frame. sp is even more special: the address we
288 return for it IS the sp for the next frame. */
289void
290d10v_frame_find_saved_regs (fi, fsr)
291 struct frame_info *fi;
292 struct frame_saved_regs *fsr;
e05bda9f
MH
293{
294 CORE_ADDR fp, pc;
295 unsigned long op;
296 unsigned short op1, op2;
297 int i;
298
299 fp = fi->frame;
300 memset (fsr, 0, sizeof (*fsr));
301 next_addr = 0;
302
303 pc = get_pc_function_start (fi->pc);
304
21260fe1 305 uses_frame = 0;
e05bda9f
MH
306 while (1)
307 {
81dc176f 308 op = (unsigned long)read_memory_integer (pc, 4);
e05bda9f
MH
309 if ((op & 0xC0000000) == 0xC0000000)
310 {
311 /* long instruction */
312 if ((op & 0x3FFF0000) == 0x01FF0000)
313 {
314 /* add3 sp,sp,n */
315 short n = op & 0xFFFF;
316 next_addr += n;
317 }
318 else if ((op & 0x3F0F0000) == 0x340F0000)
319 {
320 /* st rn, @(offset,sp) */
321 short offset = op & 0xFFFF;
322 short n = (op >> 20) & 0xF;
323 fsr->regs[n] = next_addr + offset;
324 }
325 else if ((op & 0x3F1F0000) == 0x350F0000)
326 {
327 /* st2w rn, @(offset,sp) */
328 short offset = op & 0xFFFF;
329 short n = (op >> 20) & 0xF;
330 fsr->regs[n] = next_addr + offset;
331 fsr->regs[n+1] = next_addr + offset + 2;
332 }
333 else
334 break;
335 }
336 else
337 {
338 /* short instructions */
21260fe1
MH
339 if ((op & 0xC0000000) == 0x80000000)
340 {
341 op2 = (op & 0x3FFF8000) >> 15;
342 op1 = op & 0x7FFF;
343 }
344 else
345 {
346 op1 = (op & 0x3FFF8000) >> 15;
347 op2 = op & 0x7FFF;
348 }
e05bda9f
MH
349 if (!prologue_find_regs(op1,fsr,pc) || !prologue_find_regs(op2,fsr,pc))
350 break;
351 }
352 pc += 4;
353 }
354
355 fi->size = -next_addr;
e05bda9f 356
21260fe1
MH
357 if (!(fp & 0xffff))
358 fp = read_register(SP_REGNUM) | DMEM_START;
359
3b1af95c 360 for (i=0; i<NUM_REGS-1; i++)
e05bda9f
MH
361 if (fsr->regs[i])
362 {
363 fsr->regs[i] = fp - (next_addr - fsr->regs[i]);
e05bda9f 364 }
81dc176f 365
21260fe1
MH
366 if (fsr->regs[LR_REGNUM])
367 fi->return_pc = ((read_memory_unsigned_integer(fsr->regs[LR_REGNUM],2) - 1) << 2) | IMEM_START;
81dc176f 368 else
21260fe1
MH
369 fi->return_pc = ((read_register(LR_REGNUM) - 1) << 2) | IMEM_START;
370
3b1af95c 371 /* th SP is not normally (ever?) saved, but check anyway */
b70b03b0 372 if (!fsr->regs[SP_REGNUM])
3b1af95c
MH
373 {
374 /* if the FP was saved, that means the current FP is valid, */
375 /* otherwise, it isn't being used, so we use the SP instead */
21260fe1 376 if (uses_frame)
3b1af95c
MH
377 fsr->regs[SP_REGNUM] = read_register(FP_REGNUM) + fi->size;
378 else
21260fe1
MH
379 {
380 fsr->regs[SP_REGNUM] = fp + fi->size;
381 fi->frameless = 1;
382 fsr->regs[FP_REGNUM] = 0;
383 }
3b1af95c 384 }
7b3fa778
MH
385}
386
387void
388d10v_init_extra_frame_info (fromleaf, fi)
389 int fromleaf;
390 struct frame_info *fi;
391{
392 struct frame_saved_regs dummy;
e05bda9f 393
21260fe1 394 if (fi->next && ((fi->pc & 0xffff) == 0))
81dc176f
MH
395 fi->pc = fi->next->return_pc;
396
21260fe1 397 d10v_frame_find_saved_regs (fi, &dummy);
7b3fa778
MH
398}
399
400static void
401show_regs (args, from_tty)
402 char *args;
403 int from_tty;
404{
405 long long num1, num2;
406 printf_filtered ("PC=%04x (0x%x) PSW=%04x RPT_S=%04x RPT_E=%04x RPT_C=%04x\n",
21260fe1 407 read_register (PC_REGNUM), (read_register (PC_REGNUM) << 2) + IMEM_START,
7b3fa778
MH
408 read_register (PSW_REGNUM),
409 read_register (24),
410 read_register (25),
411 read_register (23));
412 printf_filtered ("R0-R7 %04x %04x %04x %04x %04x %04x %04x %04x\n",
413 read_register (0),
414 read_register (1),
415 read_register (2),
416 read_register (3),
417 read_register (4),
418 read_register (5),
419 read_register (6),
420 read_register (7));
421 printf_filtered ("R8-R15 %04x %04x %04x %04x %04x %04x %04x %04x\n",
422 read_register (8),
423 read_register (9),
424 read_register (10),
425 read_register (11),
426 read_register (12),
427 read_register (13),
428 read_register (14),
429 read_register (15));
19414cdf
MH
430 printf_filtered ("IMAP0 %04x IMAP1 %04x DMAP %04x\n",
431 read_register (IMAP0_REGNUM),
432 read_register (IMAP1_REGNUM),
433 read_register (DMAP_REGNUM));
7b3fa778
MH
434 read_register_gen (A0_REGNUM, (char *)&num1);
435 read_register_gen (A0_REGNUM+1, (char *)&num2);
436 printf_filtered ("A0-A1 %010llx %010llx\n",num1, num2);
81dc176f 437}
7b3fa778 438
19414cdf
MH
439static CORE_ADDR
440d10v_xlate_addr (addr)
441 int addr;
7b3fa778 442{
19414cdf
MH
443 int imap;
444
445 if (addr < 0x20000)
446 imap = (int)read_register(IMAP0_REGNUM);
447 else
448 imap = (int)read_register(IMAP1_REGNUM);
7b3fa778 449
19414cdf
MH
450 if (imap & 0x1000)
451 return (CORE_ADDR)(addr + 0x1000000);
452 return (CORE_ADDR)(addr + (imap & 0xff)*0x20000);
453}
454
455
456CORE_ADDR
457d10v_read_pc (pid)
458 int pid;
459{
460 int save_pid, retval;
7b3fa778
MH
461
462 save_pid = inferior_pid;
463 inferior_pid = pid;
19414cdf 464 retval = (int)read_register (PC_REGNUM);
7b3fa778 465 inferior_pid = save_pid;
19414cdf 466 return d10v_xlate_addr(retval << 2);
7b3fa778
MH
467}
468
469void
19414cdf 470d10v_write_pc (val, pid)
21260fe1 471 CORE_ADDR val;
7b3fa778
MH
472 int pid;
473{
474 int save_pid;
475
7b3fa778
MH
476 save_pid = inferior_pid;
477 inferior_pid = pid;
19414cdf 478 write_register (PC_REGNUM, (val & 0x3ffff) >> 2);
7b3fa778
MH
479 inferior_pid = save_pid;
480}
3b1af95c 481
19414cdf 482CORE_ADDR
21260fe1 483d10v_read_sp ()
19414cdf 484{
21260fe1 485 return (read_register(SP_REGNUM) | DMEM_START);
19414cdf
MH
486}
487
488void
21260fe1
MH
489d10v_write_sp (val)
490 CORE_ADDR val;
19414cdf 491{
21260fe1 492 write_register (SP_REGNUM, (LONGEST)(val & 0xffff));
19414cdf 493}
3b1af95c 494
21260fe1 495CORE_ADDR
3b1af95c
MH
496d10v_fix_call_dummy (dummyname, start_sp, fun, nargs, args, type, gcc_p)
497 char *dummyname;
498 CORE_ADDR start_sp;
499 CORE_ADDR fun;
500 int nargs;
501 value_ptr *args;
502 struct type *type;
503 int gcc_p;
504{
21260fe1 505 int regnum;
3b1af95c
MH
506 CORE_ADDR sp;
507 char buffer[MAX_REGISTER_RAW_SIZE];
19414cdf 508 struct frame_info *frame = get_current_frame ();
81a6f5b2 509 frame->dummy = start_sp;
21260fe1
MH
510 start_sp |= DMEM_START;
511
3b1af95c 512 sp = start_sp;
21260fe1 513 for (regnum = 0; regnum < NUM_REGS; regnum++)
3b1af95c 514 {
21260fe1 515 sp -= REGISTER_RAW_SIZE(regnum);
3b1af95c
MH
516 store_address (buffer, REGISTER_RAW_SIZE(regnum), read_register(regnum));
517 write_memory (sp, buffer, REGISTER_RAW_SIZE(regnum));
3b1af95c 518 }
21260fe1 519 write_register (SP_REGNUM, (LONGEST)(sp & 0xffff));
19414cdf 520 /* now we need to load LR with the return address */
21260fe1
MH
521 write_register (LR_REGNUM, (LONGEST)(d10v_call_dummy_address() & 0xffff) >> 2);
522 return sp;
3b1af95c
MH
523}
524
19414cdf
MH
525static void
526d10v_pop_dummy_frame (fi)
527 struct frame_info *fi;
528{
81a6f5b2 529 CORE_ADDR sp = fi->dummy;
21260fe1
MH
530 int regnum;
531
81a6f5b2 532 for (regnum = 0; regnum < NUM_REGS; regnum++)
19414cdf 533 {
81a6f5b2 534 sp -= REGISTER_RAW_SIZE(regnum);
21260fe1 535 write_register(regnum, read_memory_unsigned_integer (sp, REGISTER_RAW_SIZE(regnum)));
19414cdf 536 }
81a6f5b2 537 flush_cached_frames (); /* needed? */
19414cdf
MH
538}
539
540
3b1af95c
MH
541CORE_ADDR
542d10v_push_arguments (nargs, args, sp, struct_return, struct_addr)
543 int nargs;
544 value_ptr *args;
545 CORE_ADDR sp;
546 int struct_return;
547 CORE_ADDR struct_addr;
548{
81a6f5b2
MH
549 int i, len, index=0, regnum=2;
550 char buffer[4], *contents;
19414cdf 551 LONGEST val;
81a6f5b2
MH
552 CORE_ADDR ptrs[10];
553
554 /* Pass 1. Put all large args on stack */
3b1af95c
MH
555 for (i = 0; i < nargs; i++)
556 {
557 value_ptr arg = args[i];
558 struct type *arg_type = check_typedef (VALUE_TYPE (arg));
81a6f5b2
MH
559 len = TYPE_LENGTH (arg_type);
560 contents = VALUE_CONTENTS(arg);
561 val = extract_signed_integer (contents, len);
562 if (len > 4)
563 {
564 /* put on stack and pass pointers */
565 sp -= len;
566 write_memory (sp, contents, len);
567 ptrs[index++] = sp;
3b1af95c 568 }
81a6f5b2
MH
569 }
570
571 index = 0;
572
573 for (i = 0; i < nargs; i++)
574 {
575 value_ptr arg = args[i];
576 struct type *arg_type = check_typedef (VALUE_TYPE (arg));
3b1af95c
MH
577 len = TYPE_LENGTH (arg_type);
578 contents = VALUE_CONTENTS(arg);
19414cdf 579 val = extract_signed_integer (contents, len);
81a6f5b2
MH
580 if (len > 4)
581 {
582 /* use a pointer to previously saved data */
583 if (regnum < 6)
584 write_register (regnum++, ptrs[index++]);
585 else
586 {
587 /* no more registers available. put it on the stack */
588 sp -= 2;
589 store_address (buffer, 2, ptrs[index++]);
590 write_memory (sp, buffer, 2);
591 }
592 }
593 else
594 {
595 if (regnum < 6 )
596 {
597 if (len == 4)
598 write_register (regnum++, val>>16);
599 write_register (regnum++, val & 0xffff);
600 }
601 else
602 {
603 sp -= len;
604 store_address (buffer, len, val);
605 write_memory (sp, buffer, len);
606 }
607 }
3b1af95c 608 }
21260fe1 609 return sp;
3b1af95c
MH
610}
611
19414cdf 612
81a6f5b2
MH
613/* pick an out-of-the-way place to set the return value */
614/* for an inferior function call. The link register is set to this */
615/* value and a momentary breakpoint is set there. When the breakpoint */
616/* is hit, the dummy frame is popped and the previous environment is */
617/* restored. */
618
3b1af95c
MH
619CORE_ADDR
620d10v_call_dummy_address ()
621{
19414cdf 622 CORE_ADDR entry;
3b1af95c
MH
623 struct minimal_symbol *sym;
624
625 entry = entry_point_address ();
626
627 if (entry != 0)
19414cdf 628 return entry;
3b1af95c
MH
629
630 sym = lookup_minimal_symbol ("_start", NULL, symfile_objfile);
631
632 if (!sym || MSYMBOL_TYPE (sym) != mst_text)
19414cdf 633 return 0;
3b1af95c 634 else
19414cdf 635 return SYMBOL_VALUE_ADDRESS (sym);
3b1af95c
MH
636}
637
638/* Given a return value in `regbuf' with a type `valtype',
639 extract and copy its value into `valbuf'. */
640
641void
642d10v_extract_return_value (valtype, regbuf, valbuf)
643 struct type *valtype;
644 char regbuf[REGISTER_BYTES];
645 char *valbuf;
646{
48712b30
SS
647 memcpy (valbuf, regbuf + REGISTER_BYTE (2), TYPE_LENGTH (valtype));
648}
649
650/* The following code implements access to, and display of, the D10V's
651 instruction trace buffer. The buffer consists of 64K or more
652 4-byte words of data, of which each words includes an 8-bit count,
653 and 8-bit segment number, and a 16-bit instruction address.
654
655 In theory, the trace buffer is continuously capturing instruction
656 data that the CPU presents on its "debug bus", but in practice, the
657 ROMified GDB stub only enables tracing when it continues or steps
658 the program, and stops tracing when the program stops; so it
659 actually works for GDB to read the buffer counter out of memory and
660 then read each trace word. The counter records where the tracing
661 stops, but there is no record of where it started, so we remember
662 the PC when we resumed and then search backwards in the trace
663 buffer for a word that includes that address. This is not perfect,
664 because you will miss trace data if the resumption PC is the target
665 of a branch. (The value of the buffer counter is semi-random, any
666 trace data from a previous program stop is gone.) */
667
668/* The address of the last word recorded in the trace buffer. */
669
670#define DBBC_ADDR (0xd80000)
671
672/* The base of the trace buffer, at least for the "Board_0". */
673
674#define TRACE_BUFFER_BASE (0xf40000)
675
676static void trace_command PARAMS ((char *, int));
677
678static void untrace_command PARAMS ((char *, int));
679
680static void trace_info PARAMS ((char *, int));
681
682static void tdisassemble_command PARAMS ((char *, int));
683
684static void display_trace PARAMS ((int, int));
685
686/* True when instruction traces are being collected. */
687
688static int tracing;
689
690/* Remembered PC. */
691
692static CORE_ADDR last_pc;
693
694static int trace_display;
695
696struct trace_buffer {
697 int size;
698 short *counts;
699 CORE_ADDR *addrs;
700} trace_data;
701
702static void
703trace_command (args, from_tty)
704 char *args;
705 int from_tty;
706{
707 /* Clear the host-side trace buffer, allocating space if needed. */
708 trace_data.size = 0;
709 if (trace_data.counts == NULL)
710 trace_data.counts = (short *) xmalloc (65536 * sizeof(short));
711 if (trace_data.addrs == NULL)
712 trace_data.addrs = (CORE_ADDR *) xmalloc (65536 * sizeof(CORE_ADDR));
713
714 tracing = 1;
715
716 printf_filtered ("Tracing is now on.\n");
717}
718
719static void
720untrace_command (args, from_tty)
721 char *args;
722 int from_tty;
723{
724 tracing = 0;
725
726 printf_filtered ("Tracing is now off.\n");
727}
728
729static void
730trace_info (args, from_tty)
731 char *args;
732 int from_tty;
733{
734 int i;
735
736 printf_filtered ("%d entries in trace buffer:\n", trace_data.size);
737
738 for (i = 0; i < trace_data.size; ++i)
739 {
740 printf_filtered ("%d: %d instruction%s at 0x%x\n",
741 i, trace_data.counts[i],
742 (trace_data.counts[i] == 1 ? "" : "s"),
743 trace_data.addrs[i]);
744 }
745
746 printf_filtered ("Tracing is currently %s.\n", (tracing ? "on" : "off"));
747}
748
749/* Print the instruction at address MEMADDR in debugged memory,
750 on STREAM. Returns length of the instruction, in bytes. */
751
752static int
753print_insn (memaddr, stream)
754 CORE_ADDR memaddr;
755 GDB_FILE *stream;
756{
757 /* If there's no disassembler, something is very wrong. */
758 if (tm_print_insn == NULL)
759 abort ();
760
761 if (TARGET_BYTE_ORDER == BIG_ENDIAN)
762 tm_print_insn_info.endian = BFD_ENDIAN_BIG;
763 else
764 tm_print_insn_info.endian = BFD_ENDIAN_LITTLE;
765 return (*tm_print_insn) (memaddr, &tm_print_insn_info);
766}
767
768void
769d10v_eva_prepare_to_trace ()
770{
771 if (!tracing)
772 return;
773
774 last_pc = read_register (PC_REGNUM);
775}
776
777/* Collect trace data from the target board and format it into a form
778 more useful for display. */
779
780void
781d10v_eva_get_trace_data ()
782{
783 int count, i, j, oldsize;
784 int trace_addr, trace_seg, trace_cnt, next_cnt;
785 unsigned int last_trace, trace_word, next_word;
786 unsigned int *tmpspace;
787
788 if (!tracing)
789 return;
790
791 tmpspace = xmalloc (65536 * sizeof(unsigned int));
792
793 last_trace = read_memory_unsigned_integer (DBBC_ADDR, 2) << 2;
794
795#if 0
796 printf_filtered("Last pc is %x, is now %x\n",
797 last_pc, read_register (PC_REGNUM));
798#endif
799
800 /* Collect buffer contents from the target, stopping when we reach
801 the word recorded when execution resumed. */
802
803 count = 0;
804 while (last_trace > 0)
805 {
806 QUIT;
807 trace_word =
808 read_memory_unsigned_integer (TRACE_BUFFER_BASE + last_trace, 4);
809 trace_addr = trace_word & 0xffff;
810#if 0
811 trace_seg = (trace_word >> 16) & 0xff;
812 trace_cnt = (trace_word >> 24) & 0xff;
813 printf_filtered("Trace word at %x is %x %x %x\n", last_trace,
814 trace_cnt, trace_seg, trace_addr);
815#endif
816 last_trace -= 4;
817 /* Ignore an apparently nonsensical entry. */
818 if (trace_addr == 0xffd5)
819 continue;
820 tmpspace[count++] = trace_word;
821 if (trace_addr == last_pc)
822 break;
823 if (count > 65535)
824 break;
825 }
826
827 /* Move the data to the host-side trace buffer, adjusting counts to
828 include the last instruction executed and transforming the address
829 into something that GDB likes. */
830
831 for (i = 0; i < count; ++i)
832 {
833 trace_word = tmpspace[i];
834 next_word = ((i == 0) ? 0 : tmpspace[i - 1]);
835 trace_addr = trace_word & 0xffff;
836 next_cnt = (next_word >> 24) & 0xff;
837 j = trace_data.size + count - i - 1;
838 trace_data.addrs[j] = (trace_addr << 2) + 0x1000000;
839 trace_data.counts[j] = next_cnt + 1;
840 }
841
842 oldsize = trace_data.size;
843 trace_data.size += count;
844
845 free (tmpspace);
846
847#if 0
848 for (i = 0; i < trace_data.size; ++i)
849 {
850 printf_filtered("%d insns after %x\n",
851 trace_data.counts[i], trace_data.addrs[i]);
852 }
853#endif
854
855 if (trace_display)
856 display_trace (oldsize, trace_data.size);
857}
858
859static void
860tdisassemble_command (arg, from_tty)
861 char *arg;
862 int from_tty;
863{
864 int i, count;
865 CORE_ADDR low, high;
866 char *space_index;
867
868 if (!arg)
869 {
870 low = 0;
871 high = trace_data.size;
872 }
873 else if (!(space_index = (char *) strchr (arg, ' ')))
874 {
875 low = parse_and_eval_address (arg);
876 high = low + 5;
877 }
878 else
879 {
880 /* Two arguments. */
881 *space_index = '\0';
882 low = parse_and_eval_address (arg);
883 high = parse_and_eval_address (space_index + 1);
884 }
885
886 printf_filtered ("Dump of trace ");
887 printf_filtered ("from ");
888 print_address_numeric (low, 1, gdb_stdout);
889 printf_filtered (" to ");
890 print_address_numeric (high, 1, gdb_stdout);
891 printf_filtered (":\n");
892
893 display_trace (low, high);
894
895 printf_filtered ("End of trace dump.\n");
896 gdb_flush (gdb_stdout);
897}
898
899static void
900display_trace (low, high)
901 int low, high;
902{
903 int i, count;
904 CORE_ADDR next_address;
905
906 for (i = low; i < high; ++i)
907 {
908 next_address = trace_data.addrs[i];
909 count = trace_data.counts[i];
910 while (count-- > 0)
911 {
912 QUIT;
913 print_address (next_address, gdb_stdout);
914 printf_filtered (":");
915 printf_filtered ("\t");
916 wrap_here (" ");
917 next_address = next_address + print_insn (next_address, gdb_stdout);
918 printf_filtered ("\n");
919 gdb_flush (gdb_stdout);
920 }
921 }
3b1af95c 922}
48712b30
SS
923
924void
925_initialize_d10v_tdep ()
926{
927 tm_print_insn = print_insn_d10v;
928
929 add_com ("regs", class_vars, show_regs, "Print all registers");
930
931 add_com ("trace", class_support, trace_command,
932 "Enable tracing of instruction execution.");
933
934 add_com ("untrace", class_support, untrace_command,
935 "Disable tracing of instruction execution.");
936
937 add_com ("tdisassemble", class_vars, tdisassemble_command,
938 "Disassemble the trace buffer.\n\
939Two optional arguments specify a range of trace buffer entries\n\
940as reported by info trace (NOT addresses!).");
941
942 add_info ("trace", trace_info,
943 "Display info about the trace data buffer.");
944
945 add_show_from_set (add_set_cmd ("tracedisplay", no_class,
946 var_integer, (char *)&trace_display,
947 "Set automatic display of trace.\n", &setlist),
948 &showlist);
949
950}
This page took 0.083112 seconds and 4 git commands to generate.