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