For d10v, do not sign-extend pointers.
[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
f6826586 209 return D10V_MAKE_DADDR (read_memory_unsigned_integer (fsr.regs[FP_REGNUM], REGISTER_RAW_SIZE (FP_REGNUM)));
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 355 if (!(fp & 0xffff))
f6826586 356 fp = D10V_MAKE_DADDR (read_register(SP_REGNUM));
21260fe1 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])
f6826586
AC
365 {
366 CORE_ADDR return_pc = read_memory_unsigned_integer (fsr->regs[LR_REGNUM], REGISTER_RAW_SIZE (LR_REGNUM));
367 fi->return_pc = D10V_MAKE_IADDR (return_pc);
368 }
81dc176f 369 else
f6826586
AC
370 {
371 fi->return_pc = D10V_MAKE_IADDR (read_register(LR_REGNUM));
372 }
21260fe1 373
3b1af95c 374 /* th SP is not normally (ever?) saved, but check anyway */
b70b03b0 375 if (!fsr->regs[SP_REGNUM])
3b1af95c
MH
376 {
377 /* if the FP was saved, that means the current FP is valid, */
378 /* otherwise, it isn't being used, so we use the SP instead */
21260fe1 379 if (uses_frame)
3b1af95c
MH
380 fsr->regs[SP_REGNUM] = read_register(FP_REGNUM) + fi->size;
381 else
21260fe1
MH
382 {
383 fsr->regs[SP_REGNUM] = fp + fi->size;
384 fi->frameless = 1;
385 fsr->regs[FP_REGNUM] = 0;
386 }
3b1af95c 387 }
7b3fa778
MH
388}
389
390void
391d10v_init_extra_frame_info (fromleaf, fi)
392 int fromleaf;
393 struct frame_info *fi;
394{
9961ca7a
AC
395 fi->frameless = 0;
396 fi->size = 0;
397 fi->return_pc = 0;
398
399 /* The call dummy doesn't save any registers on the stack, so we can
400 return now. */
401 if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
402 {
403 return;
404 }
405 else
406 {
407 struct frame_saved_regs dummy;
408 d10v_frame_find_saved_regs (fi, &dummy);
409 }
7b3fa778
MH
410}
411
412static void
413show_regs (args, from_tty)
414 char *args;
415 int from_tty;
416{
77636dea 417 LONGEST num1, num2;
7b3fa778 418 printf_filtered ("PC=%04x (0x%x) PSW=%04x RPT_S=%04x RPT_E=%04x RPT_C=%04x\n",
f6826586 419 read_register (PC_REGNUM), D10V_MAKE_IADDR (read_register (PC_REGNUM)),
7b3fa778
MH
420 read_register (PSW_REGNUM),
421 read_register (24),
422 read_register (25),
423 read_register (23));
424 printf_filtered ("R0-R7 %04x %04x %04x %04x %04x %04x %04x %04x\n",
425 read_register (0),
426 read_register (1),
427 read_register (2),
428 read_register (3),
429 read_register (4),
430 read_register (5),
431 read_register (6),
432 read_register (7));
433 printf_filtered ("R8-R15 %04x %04x %04x %04x %04x %04x %04x %04x\n",
434 read_register (8),
435 read_register (9),
436 read_register (10),
437 read_register (11),
438 read_register (12),
439 read_register (13),
440 read_register (14),
441 read_register (15));
19414cdf
MH
442 printf_filtered ("IMAP0 %04x IMAP1 %04x DMAP %04x\n",
443 read_register (IMAP0_REGNUM),
444 read_register (IMAP1_REGNUM),
445 read_register (DMAP_REGNUM));
7b3fa778
MH
446 read_register_gen (A0_REGNUM, (char *)&num1);
447 read_register_gen (A0_REGNUM+1, (char *)&num2);
448 printf_filtered ("A0-A1 %010llx %010llx\n",num1, num2);
81dc176f 449}
7b3fa778 450
19414cdf
MH
451CORE_ADDR
452d10v_read_pc (pid)
453 int pid;
454{
9961ca7a 455 int save_pid;
f6826586 456 CORE_ADDR pc;
9961ca7a 457 CORE_ADDR retval;
7b3fa778
MH
458
459 save_pid = inferior_pid;
460 inferior_pid = pid;
f6826586 461 pc = (int) read_register (PC_REGNUM);
7b3fa778 462 inferior_pid = save_pid;
f6826586 463 retval = D10V_MAKE_IADDR (pc);
9961ca7a 464 return retval;
7b3fa778
MH
465}
466
467void
19414cdf 468d10v_write_pc (val, pid)
21260fe1 469 CORE_ADDR val;
7b3fa778
MH
470 int pid;
471{
472 int save_pid;
473
7b3fa778
MH
474 save_pid = inferior_pid;
475 inferior_pid = pid;
f6826586 476 write_register (PC_REGNUM, D10V_CONVERT_IADDR_TO_RAW (val));
7b3fa778
MH
477 inferior_pid = save_pid;
478}
3b1af95c 479
19414cdf 480CORE_ADDR
21260fe1 481d10v_read_sp ()
19414cdf 482{
f6826586 483 return (D10V_MAKE_DADDR (read_register (SP_REGNUM)));
19414cdf
MH
484}
485
486void
21260fe1
MH
487d10v_write_sp (val)
488 CORE_ADDR val;
19414cdf 489{
f6826586 490 write_register (SP_REGNUM, D10V_CONVERT_DADDR_TO_RAW (val));
19414cdf 491}
3b1af95c 492
77636dea
FF
493void
494d10v_write_fp (val)
495 CORE_ADDR val;
496{
f6826586 497 write_register (FP_REGNUM, D10V_CONVERT_DADDR_TO_RAW (val));
77636dea
FF
498}
499
500CORE_ADDR
501d10v_read_fp ()
502{
f6826586 503 return (D10V_MAKE_DADDR (read_register(FP_REGNUM)));
77636dea
FF
504}
505
9961ca7a
AC
506/* Function: push_return_address (pc)
507 Set up the return address for the inferior function call.
508 Needed for targets where we don't actually execute a JSR/BSR instruction */
509
21260fe1 510CORE_ADDR
9961ca7a
AC
511d10v_push_return_address (pc, sp)
512 CORE_ADDR pc;
513 CORE_ADDR sp;
3b1af95c 514{
f6826586 515 write_register (LR_REGNUM, D10V_CONVERT_IADDR_TO_RAW (CALL_DUMMY_ADDRESS ()));
21260fe1 516 return sp;
3b1af95c 517}
9961ca7a 518
19414cdf 519
3b1af95c
MH
520CORE_ADDR
521d10v_push_arguments (nargs, args, sp, struct_return, struct_addr)
522 int nargs;
523 value_ptr *args;
524 CORE_ADDR sp;
525 int struct_return;
526 CORE_ADDR struct_addr;
527{
608addd4 528 int i;
9961ca7a 529 int regnum = ARG1_REGNUM;
608addd4
AC
530
531 /* Fill in registers and arg lists */
81a6f5b2
MH
532 for (i = 0; i < nargs; i++)
533 {
534 value_ptr arg = args[i];
608addd4
AC
535 struct type *type = check_typedef (VALUE_TYPE (arg));
536 char *contents = VALUE_CONTENTS (arg);
537 int len = TYPE_LENGTH (type);
538 /* printf ("push: type=%d len=%d\n", type->code, len); */
539 if (TYPE_CODE (type) == TYPE_CODE_PTR)
81a6f5b2 540 {
608addd4
AC
541 /* pointers require special handling - first convert and
542 then store */
543 long val = extract_signed_integer (contents, len);
544 len = 2;
545 if (TYPE_TARGET_TYPE (type)
546 && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC))
547 {
548 /* function pointer */
549 val = D10V_CONVERT_IADDR_TO_RAW (val);
550 }
551 else if (D10V_IADDR_P (val))
552 {
553 /* also function pointer! */
554 val = D10V_CONVERT_DADDR_TO_RAW (val);
555 }
556 else
557 {
558 /* data pointer */
559 val &= 0xFFFF;
560 }
9961ca7a 561 if (regnum <= ARGN_REGNUM)
608addd4 562 write_register (regnum++, val & 0xffff);
81a6f5b2
MH
563 else
564 {
608addd4 565 char ptr[2];
81a6f5b2 566 sp -= 2;
608addd4
AC
567 store_address (ptr, val & 0xffff, 2);
568 write_memory (sp, ptr, 2);
81a6f5b2
MH
569 }
570 }
571 else
572 {
608addd4
AC
573 int aligned_regnum = (regnum + 1) & ~1;
574 if (len <= 2 && regnum <= ARGN_REGNUM)
575 /* fits in a single register, do not align */
77636dea 576 {
608addd4
AC
577 long val = extract_unsigned_integer (contents, len);
578 write_register (regnum++, val);
579 }
580 else if (len <= (ARGN_REGNUM - aligned_regnum + 1) * 2)
581 /* value fits in remaining registers, store keeping left
582 aligned */
583 {
584 int b;
585 regnum = aligned_regnum;
586 for (b = 0; b < (len & ~1); b += 2)
77636dea 587 {
608addd4
AC
588 long val = extract_unsigned_integer (&contents[b], 2);
589 write_register (regnum++, val);
77636dea 590 }
608addd4 591 if (b < len)
77636dea 592 {
608addd4
AC
593 long val = extract_unsigned_integer (&contents[b], 1);
594 write_register (regnum++, (val << 8));
77636dea
FF
595 }
596 }
81a6f5b2
MH
597 else
598 {
608addd4 599 /* arg goes straight on stack */
9961ca7a
AC
600 regnum = ARGN_REGNUM + 1;
601 sp = (sp - len) & ~1;
602 write_memory (sp, contents, len);
81a6f5b2
MH
603 }
604 }
3b1af95c 605 }
21260fe1 606 return sp;
3b1af95c
MH
607}
608
19414cdf 609
3b1af95c
MH
610/* Given a return value in `regbuf' with a type `valtype',
611 extract and copy its value into `valbuf'. */
612
613void
9961ca7a
AC
614d10v_extract_return_value (type, regbuf, valbuf)
615 struct type *type;
3b1af95c
MH
616 char regbuf[REGISTER_BYTES];
617 char *valbuf;
618{
77636dea 619 int len;
9961ca7a
AC
620 /* 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))); */
621 if (TYPE_CODE (type) == TYPE_CODE_PTR
622 && TYPE_TARGET_TYPE (type)
623 && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC))
624 {
625 /* pointer to function */
626 int num;
627 short snum;
628 snum = extract_address (regbuf + REGISTER_BYTE (RET1_REGNUM), REGISTER_RAW_SIZE (RET1_REGNUM));
629 store_address ( valbuf, 4, D10V_MAKE_IADDR(snum));
630 }
631 else if (TYPE_CODE(type) == TYPE_CODE_PTR)
77636dea 632 {
9961ca7a
AC
633 /* pointer to data */
634 int num;
77636dea 635 short snum;
9961ca7a 636 snum = extract_address (regbuf + REGISTER_BYTE (RET1_REGNUM), REGISTER_RAW_SIZE (RET1_REGNUM));
77636dea
FF
637 store_address ( valbuf, 4, D10V_MAKE_DADDR(snum));
638 }
639 else
640 {
9961ca7a 641 len = TYPE_LENGTH (type);
77636dea
FF
642 if (len == 1)
643 {
9961ca7a 644 unsigned short c = extract_unsigned_integer (regbuf + REGISTER_BYTE (RET1_REGNUM), REGISTER_RAW_SIZE (RET1_REGNUM));
77636dea
FF
645 store_unsigned_integer (valbuf, 1, c);
646 }
647 else
9961ca7a 648 memcpy (valbuf, regbuf + REGISTER_BYTE (RET1_REGNUM), len);
77636dea 649 }
48712b30
SS
650}
651
652/* The following code implements access to, and display of, the D10V's
653 instruction trace buffer. The buffer consists of 64K or more
654 4-byte words of data, of which each words includes an 8-bit count,
a9b9b407 655 an 8-bit segment number, and a 16-bit instruction address.
48712b30
SS
656
657 In theory, the trace buffer is continuously capturing instruction
658 data that the CPU presents on its "debug bus", but in practice, the
659 ROMified GDB stub only enables tracing when it continues or steps
660 the program, and stops tracing when the program stops; so it
661 actually works for GDB to read the buffer counter out of memory and
662 then read each trace word. The counter records where the tracing
663 stops, but there is no record of where it started, so we remember
664 the PC when we resumed and then search backwards in the trace
665 buffer for a word that includes that address. This is not perfect,
666 because you will miss trace data if the resumption PC is the target
667 of a branch. (The value of the buffer counter is semi-random, any
668 trace data from a previous program stop is gone.) */
669
670/* The address of the last word recorded in the trace buffer. */
671
672#define DBBC_ADDR (0xd80000)
673
674/* The base of the trace buffer, at least for the "Board_0". */
675
676#define TRACE_BUFFER_BASE (0xf40000)
677
678static void trace_command PARAMS ((char *, int));
679
680static void untrace_command PARAMS ((char *, int));
681
682static void trace_info PARAMS ((char *, int));
683
684static void tdisassemble_command PARAMS ((char *, int));
685
686static void display_trace PARAMS ((int, int));
687
688/* True when instruction traces are being collected. */
689
690static int tracing;
691
692/* Remembered PC. */
693
694static CORE_ADDR last_pc;
695
a9b9b407
SS
696/* True when trace output should be displayed whenever program stops. */
697
48712b30
SS
698static int trace_display;
699
a9b9b407
SS
700/* True when trace listing should include source lines. */
701
702static int default_trace_show_source = 1;
703
48712b30
SS
704struct trace_buffer {
705 int size;
706 short *counts;
707 CORE_ADDR *addrs;
708} trace_data;
709
710static void
711trace_command (args, from_tty)
712 char *args;
713 int from_tty;
714{
715 /* Clear the host-side trace buffer, allocating space if needed. */
716 trace_data.size = 0;
717 if (trace_data.counts == NULL)
718 trace_data.counts = (short *) xmalloc (65536 * sizeof(short));
719 if (trace_data.addrs == NULL)
720 trace_data.addrs = (CORE_ADDR *) xmalloc (65536 * sizeof(CORE_ADDR));
721
722 tracing = 1;
723
724 printf_filtered ("Tracing is now on.\n");
725}
726
727static void
728untrace_command (args, from_tty)
729 char *args;
730 int from_tty;
731{
732 tracing = 0;
733
734 printf_filtered ("Tracing is now off.\n");
735}
736
737static void
738trace_info (args, from_tty)
739 char *args;
740 int from_tty;
741{
742 int i;
743
a9b9b407 744 if (trace_data.size)
48712b30 745 {
a9b9b407
SS
746 printf_filtered ("%d entries in trace buffer:\n", trace_data.size);
747
748 for (i = 0; i < trace_data.size; ++i)
749 {
750 printf_filtered ("%d: %d instruction%s at 0x%x\n",
751 i, trace_data.counts[i],
752 (trace_data.counts[i] == 1 ? "" : "s"),
753 trace_data.addrs[i]);
754 }
48712b30 755 }
a9b9b407
SS
756 else
757 printf_filtered ("No entries in trace buffer.\n");
48712b30
SS
758
759 printf_filtered ("Tracing is currently %s.\n", (tracing ? "on" : "off"));
760}
761
762/* Print the instruction at address MEMADDR in debugged memory,
763 on STREAM. Returns length of the instruction, in bytes. */
764
765static int
766print_insn (memaddr, stream)
767 CORE_ADDR memaddr;
768 GDB_FILE *stream;
769{
770 /* If there's no disassembler, something is very wrong. */
771 if (tm_print_insn == NULL)
772 abort ();
773
774 if (TARGET_BYTE_ORDER == BIG_ENDIAN)
775 tm_print_insn_info.endian = BFD_ENDIAN_BIG;
776 else
777 tm_print_insn_info.endian = BFD_ENDIAN_LITTLE;
778 return (*tm_print_insn) (memaddr, &tm_print_insn_info);
779}
780
781void
782d10v_eva_prepare_to_trace ()
783{
784 if (!tracing)
785 return;
786
787 last_pc = read_register (PC_REGNUM);
788}
789
790/* Collect trace data from the target board and format it into a form
791 more useful for display. */
792
793void
794d10v_eva_get_trace_data ()
795{
796 int count, i, j, oldsize;
797 int trace_addr, trace_seg, trace_cnt, next_cnt;
798 unsigned int last_trace, trace_word, next_word;
799 unsigned int *tmpspace;
800
801 if (!tracing)
802 return;
803
804 tmpspace = xmalloc (65536 * sizeof(unsigned int));
805
806 last_trace = read_memory_unsigned_integer (DBBC_ADDR, 2) << 2;
807
48712b30
SS
808 /* Collect buffer contents from the target, stopping when we reach
809 the word recorded when execution resumed. */
810
811 count = 0;
812 while (last_trace > 0)
813 {
814 QUIT;
815 trace_word =
816 read_memory_unsigned_integer (TRACE_BUFFER_BASE + last_trace, 4);
817 trace_addr = trace_word & 0xffff;
48712b30
SS
818 last_trace -= 4;
819 /* Ignore an apparently nonsensical entry. */
820 if (trace_addr == 0xffd5)
821 continue;
822 tmpspace[count++] = trace_word;
823 if (trace_addr == last_pc)
824 break;
825 if (count > 65535)
826 break;
827 }
828
829 /* Move the data to the host-side trace buffer, adjusting counts to
830 include the last instruction executed and transforming the address
831 into something that GDB likes. */
832
833 for (i = 0; i < count; ++i)
834 {
835 trace_word = tmpspace[i];
836 next_word = ((i == 0) ? 0 : tmpspace[i - 1]);
837 trace_addr = trace_word & 0xffff;
838 next_cnt = (next_word >> 24) & 0xff;
839 j = trace_data.size + count - i - 1;
840 trace_data.addrs[j] = (trace_addr << 2) + 0x1000000;
841 trace_data.counts[j] = next_cnt + 1;
842 }
843
844 oldsize = trace_data.size;
845 trace_data.size += count;
846
847 free (tmpspace);
848
48712b30
SS
849 if (trace_display)
850 display_trace (oldsize, trace_data.size);
851}
852
853static void
854tdisassemble_command (arg, from_tty)
855 char *arg;
856 int from_tty;
857{
858 int i, count;
859 CORE_ADDR low, high;
860 char *space_index;
861
862 if (!arg)
863 {
864 low = 0;
865 high = trace_data.size;
866 }
867 else if (!(space_index = (char *) strchr (arg, ' ')))
868 {
869 low = parse_and_eval_address (arg);
870 high = low + 5;
871 }
872 else
873 {
874 /* Two arguments. */
875 *space_index = '\0';
876 low = parse_and_eval_address (arg);
877 high = parse_and_eval_address (space_index + 1);
a9b9b407
SS
878 if (high < low)
879 high = low;
48712b30
SS
880 }
881
a9b9b407 882 printf_filtered ("Dump of trace from %d to %d:\n", low, high);
48712b30
SS
883
884 display_trace (low, high);
885
886 printf_filtered ("End of trace dump.\n");
887 gdb_flush (gdb_stdout);
888}
889
890static void
891display_trace (low, high)
892 int low, high;
893{
a9b9b407 894 int i, count, trace_show_source, first, suppress;
48712b30
SS
895 CORE_ADDR next_address;
896
a9b9b407
SS
897 trace_show_source = default_trace_show_source;
898 if (!have_full_symbols () && !have_partial_symbols())
899 {
900 trace_show_source = 0;
901 printf_filtered ("No symbol table is loaded. Use the \"file\" command.\n");
902 printf_filtered ("Trace will not display any source.\n");
903 }
904
905 first = 1;
906 suppress = 0;
48712b30
SS
907 for (i = low; i < high; ++i)
908 {
909 next_address = trace_data.addrs[i];
910 count = trace_data.counts[i];
911 while (count-- > 0)
912 {
913 QUIT;
a9b9b407
SS
914 if (trace_show_source)
915 {
916 struct symtab_and_line sal, sal_prev;
917
918 sal_prev = find_pc_line (next_address - 4, 0);
919 sal = find_pc_line (next_address, 0);
920
921 if (sal.symtab)
922 {
923 if (first || sal.line != sal_prev.line)
924 print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
925 suppress = 0;
926 }
927 else
928 {
929 if (!suppress)
930 /* FIXME-32x64--assumes sal.pc fits in long. */
931 printf_filtered ("No source file for address %s.\n",
932 local_hex_string((unsigned long) sal.pc));
933 suppress = 1;
934 }
935 }
936 first = 0;
48712b30
SS
937 print_address (next_address, gdb_stdout);
938 printf_filtered (":");
939 printf_filtered ("\t");
940 wrap_here (" ");
941 next_address = next_address + print_insn (next_address, gdb_stdout);
942 printf_filtered ("\n");
943 gdb_flush (gdb_stdout);
944 }
945 }
3b1af95c 946}
48712b30 947
a9b9b407
SS
948extern void (*target_resume_hook) PARAMS ((void));
949extern void (*target_wait_loop_hook) PARAMS ((void));
950
48712b30
SS
951void
952_initialize_d10v_tdep ()
953{
954 tm_print_insn = print_insn_d10v;
955
a9b9b407
SS
956 target_resume_hook = d10v_eva_prepare_to_trace;
957 target_wait_loop_hook = d10v_eva_get_trace_data;
958
48712b30
SS
959 add_com ("regs", class_vars, show_regs, "Print all registers");
960
961 add_com ("trace", class_support, trace_command,
962 "Enable tracing of instruction execution.");
963
964 add_com ("untrace", class_support, untrace_command,
965 "Disable tracing of instruction execution.");
966
967 add_com ("tdisassemble", class_vars, tdisassemble_command,
968 "Disassemble the trace buffer.\n\
969Two optional arguments specify a range of trace buffer entries\n\
970as reported by info trace (NOT addresses!).");
971
972 add_info ("trace", trace_info,
973 "Display info about the trace data buffer.");
974
975 add_show_from_set (add_set_cmd ("tracedisplay", no_class,
976 var_integer, (char *)&trace_display,
977 "Set automatic display of trace.\n", &setlist),
978 &showlist);
a9b9b407
SS
979 add_show_from_set (add_set_cmd ("tracesource", no_class,
980 var_integer, (char *)&default_trace_show_source,
981 "Set display of source code with trace.\n", &setlist),
982 &showlist);
48712b30
SS
983
984}
This page took 0.112427 seconds and 4 git commands to generate.