improvements
[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{
9961ca7a
AC
539 int i, len;
540 int index;
541 int regnum = ARG1_REGNUM;
81a6f5b2 542 char buffer[4], *contents;
19414cdf 543 LONGEST val;
81a6f5b2
MH
544 CORE_ADDR ptrs[10];
545
9961ca7a
AC
546
547 /* Pass 1. Put all large args on stack, pass pointers */
548 index = 0;
3b1af95c
MH
549 for (i = 0; i < nargs; i++)
550 {
551 value_ptr arg = args[i];
552 struct type *arg_type = check_typedef (VALUE_TYPE (arg));
81a6f5b2
MH
553 len = TYPE_LENGTH (arg_type);
554 contents = VALUE_CONTENTS(arg);
81a6f5b2
MH
555 if (len > 4)
556 {
9961ca7a
AC
557 /* put on word aligned stack and pass pointers */
558 sp = (sp - len) & ~1;
81a6f5b2
MH
559 write_memory (sp, contents, len);
560 ptrs[index++] = sp;
3b1af95c 561 }
81a6f5b2
MH
562 }
563
9961ca7a 564 /* Pass 2. Fill in registers and arg lists */
81a6f5b2 565 index = 0;
81a6f5b2
MH
566 for (i = 0; i < nargs; i++)
567 {
568 value_ptr arg = args[i];
569 struct type *arg_type = check_typedef (VALUE_TYPE (arg));
3b1af95c 570 len = TYPE_LENGTH (arg_type);
81a6f5b2
MH
571 if (len > 4)
572 {
9961ca7a
AC
573 /* pass pointer to previously saved data */
574 if (regnum <= ARGN_REGNUM)
81a6f5b2
MH
575 write_register (regnum++, ptrs[index++]);
576 else
577 {
578 /* no more registers available. put it on the stack */
579 sp -= 2;
580 store_address (buffer, 2, ptrs[index++]);
581 write_memory (sp, buffer, 2);
582 }
583 }
584 else
585 {
9961ca7a 586 int even_regnum = (regnum + 1) & ~1;
77636dea
FF
587 contents = VALUE_CONTENTS(arg);
588 val = extract_signed_integer (contents, len);
589 /* printf("push: type=%d len=%d val=0x%x\n",arg_type->code,len,val); */
590 if (arg_type->code == TYPE_CODE_PTR)
591 {
592 if ( (val & 0x3000000) == 0x1000000)
593 {
594 /* function pointer */
595 val = (val & 0x3FFFF) >> 2;
596 len = 2;
597 }
598 else
599 {
600 /* data pointer */
601 val &= 0xFFFF;
602 len = 2;
603 }
604 }
605
9961ca7a
AC
606 if (regnum <= ARGN_REGNUM && len == 1)
607 {
608 write_register (regnum++, val & 0xff);
609 }
610 if (regnum <= ARGN_REGNUM && len == 2)
81a6f5b2 611 {
9961ca7a
AC
612 write_register (regnum++, val & 0xffff);
613 }
614 else if (even_regnum <= ARGN_REGNUM - 1 && len == 3)
615 {
616 /* next even reg and space for two */
617 /* TARGET_BYTE_ORDER == BIG_ENDIAN */
618 regnum = even_regnum;
619 write_register (regnum++, (val >> 8) & 0xffff);
620 write_register (regnum++, (val & 0xff) << 8);
621 }
622 else if (even_regnum <= ARGN_REGNUM - 1 && len == 4)
623 {
624 /* next even reg and space for two */
625 /* TARGET_BYTE_ORDER == BIG_ENDIAN */
626 regnum = even_regnum;
627 write_register (regnum++, (val >> 16) & 0xffff);
81a6f5b2
MH
628 write_register (regnum++, val & 0xffff);
629 }
630 else
631 {
9961ca7a
AC
632 regnum = ARGN_REGNUM + 1;
633 sp = (sp - len) & ~1;
634 write_memory (sp, contents, len);
81a6f5b2
MH
635 }
636 }
3b1af95c 637 }
21260fe1 638 return sp;
3b1af95c
MH
639}
640
19414cdf 641
3b1af95c
MH
642/* Given a return value in `regbuf' with a type `valtype',
643 extract and copy its value into `valbuf'. */
644
645void
9961ca7a
AC
646d10v_extract_return_value (type, regbuf, valbuf)
647 struct type *type;
3b1af95c
MH
648 char regbuf[REGISTER_BYTES];
649 char *valbuf;
650{
77636dea 651 int len;
9961ca7a
AC
652 /* 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))); */
653 if (TYPE_CODE (type) == TYPE_CODE_PTR
654 && TYPE_TARGET_TYPE (type)
655 && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC))
656 {
657 /* pointer to function */
658 int num;
659 short snum;
660 snum = extract_address (regbuf + REGISTER_BYTE (RET1_REGNUM), REGISTER_RAW_SIZE (RET1_REGNUM));
661 store_address ( valbuf, 4, D10V_MAKE_IADDR(snum));
662 }
663 else if (TYPE_CODE(type) == TYPE_CODE_PTR)
77636dea 664 {
9961ca7a
AC
665 /* pointer to data */
666 int num;
77636dea 667 short snum;
9961ca7a 668 snum = extract_address (regbuf + REGISTER_BYTE (RET1_REGNUM), REGISTER_RAW_SIZE (RET1_REGNUM));
77636dea
FF
669 store_address ( valbuf, 4, D10V_MAKE_DADDR(snum));
670 }
671 else
672 {
9961ca7a 673 len = TYPE_LENGTH (type);
77636dea
FF
674 if (len == 1)
675 {
9961ca7a 676 unsigned short c = extract_unsigned_integer (regbuf + REGISTER_BYTE (RET1_REGNUM), REGISTER_RAW_SIZE (RET1_REGNUM));
77636dea
FF
677 store_unsigned_integer (valbuf, 1, c);
678 }
679 else
9961ca7a 680 memcpy (valbuf, regbuf + REGISTER_BYTE (RET1_REGNUM), len);
77636dea 681 }
48712b30
SS
682}
683
684/* The following code implements access to, and display of, the D10V's
685 instruction trace buffer. The buffer consists of 64K or more
686 4-byte words of data, of which each words includes an 8-bit count,
a9b9b407 687 an 8-bit segment number, and a 16-bit instruction address.
48712b30
SS
688
689 In theory, the trace buffer is continuously capturing instruction
690 data that the CPU presents on its "debug bus", but in practice, the
691 ROMified GDB stub only enables tracing when it continues or steps
692 the program, and stops tracing when the program stops; so it
693 actually works for GDB to read the buffer counter out of memory and
694 then read each trace word. The counter records where the tracing
695 stops, but there is no record of where it started, so we remember
696 the PC when we resumed and then search backwards in the trace
697 buffer for a word that includes that address. This is not perfect,
698 because you will miss trace data if the resumption PC is the target
699 of a branch. (The value of the buffer counter is semi-random, any
700 trace data from a previous program stop is gone.) */
701
702/* The address of the last word recorded in the trace buffer. */
703
704#define DBBC_ADDR (0xd80000)
705
706/* The base of the trace buffer, at least for the "Board_0". */
707
708#define TRACE_BUFFER_BASE (0xf40000)
709
710static void trace_command PARAMS ((char *, int));
711
712static void untrace_command PARAMS ((char *, int));
713
714static void trace_info PARAMS ((char *, int));
715
716static void tdisassemble_command PARAMS ((char *, int));
717
718static void display_trace PARAMS ((int, int));
719
720/* True when instruction traces are being collected. */
721
722static int tracing;
723
724/* Remembered PC. */
725
726static CORE_ADDR last_pc;
727
a9b9b407
SS
728/* True when trace output should be displayed whenever program stops. */
729
48712b30
SS
730static int trace_display;
731
a9b9b407
SS
732/* True when trace listing should include source lines. */
733
734static int default_trace_show_source = 1;
735
48712b30
SS
736struct trace_buffer {
737 int size;
738 short *counts;
739 CORE_ADDR *addrs;
740} trace_data;
741
742static void
743trace_command (args, from_tty)
744 char *args;
745 int from_tty;
746{
747 /* Clear the host-side trace buffer, allocating space if needed. */
748 trace_data.size = 0;
749 if (trace_data.counts == NULL)
750 trace_data.counts = (short *) xmalloc (65536 * sizeof(short));
751 if (trace_data.addrs == NULL)
752 trace_data.addrs = (CORE_ADDR *) xmalloc (65536 * sizeof(CORE_ADDR));
753
754 tracing = 1;
755
756 printf_filtered ("Tracing is now on.\n");
757}
758
759static void
760untrace_command (args, from_tty)
761 char *args;
762 int from_tty;
763{
764 tracing = 0;
765
766 printf_filtered ("Tracing is now off.\n");
767}
768
769static void
770trace_info (args, from_tty)
771 char *args;
772 int from_tty;
773{
774 int i;
775
a9b9b407 776 if (trace_data.size)
48712b30 777 {
a9b9b407
SS
778 printf_filtered ("%d entries in trace buffer:\n", trace_data.size);
779
780 for (i = 0; i < trace_data.size; ++i)
781 {
782 printf_filtered ("%d: %d instruction%s at 0x%x\n",
783 i, trace_data.counts[i],
784 (trace_data.counts[i] == 1 ? "" : "s"),
785 trace_data.addrs[i]);
786 }
48712b30 787 }
a9b9b407
SS
788 else
789 printf_filtered ("No entries in trace buffer.\n");
48712b30
SS
790
791 printf_filtered ("Tracing is currently %s.\n", (tracing ? "on" : "off"));
792}
793
794/* Print the instruction at address MEMADDR in debugged memory,
795 on STREAM. Returns length of the instruction, in bytes. */
796
797static int
798print_insn (memaddr, stream)
799 CORE_ADDR memaddr;
800 GDB_FILE *stream;
801{
802 /* If there's no disassembler, something is very wrong. */
803 if (tm_print_insn == NULL)
804 abort ();
805
806 if (TARGET_BYTE_ORDER == BIG_ENDIAN)
807 tm_print_insn_info.endian = BFD_ENDIAN_BIG;
808 else
809 tm_print_insn_info.endian = BFD_ENDIAN_LITTLE;
810 return (*tm_print_insn) (memaddr, &tm_print_insn_info);
811}
812
813void
814d10v_eva_prepare_to_trace ()
815{
816 if (!tracing)
817 return;
818
819 last_pc = read_register (PC_REGNUM);
820}
821
822/* Collect trace data from the target board and format it into a form
823 more useful for display. */
824
825void
826d10v_eva_get_trace_data ()
827{
828 int count, i, j, oldsize;
829 int trace_addr, trace_seg, trace_cnt, next_cnt;
830 unsigned int last_trace, trace_word, next_word;
831 unsigned int *tmpspace;
832
833 if (!tracing)
834 return;
835
836 tmpspace = xmalloc (65536 * sizeof(unsigned int));
837
838 last_trace = read_memory_unsigned_integer (DBBC_ADDR, 2) << 2;
839
48712b30
SS
840 /* Collect buffer contents from the target, stopping when we reach
841 the word recorded when execution resumed. */
842
843 count = 0;
844 while (last_trace > 0)
845 {
846 QUIT;
847 trace_word =
848 read_memory_unsigned_integer (TRACE_BUFFER_BASE + last_trace, 4);
849 trace_addr = trace_word & 0xffff;
48712b30
SS
850 last_trace -= 4;
851 /* Ignore an apparently nonsensical entry. */
852 if (trace_addr == 0xffd5)
853 continue;
854 tmpspace[count++] = trace_word;
855 if (trace_addr == last_pc)
856 break;
857 if (count > 65535)
858 break;
859 }
860
861 /* Move the data to the host-side trace buffer, adjusting counts to
862 include the last instruction executed and transforming the address
863 into something that GDB likes. */
864
865 for (i = 0; i < count; ++i)
866 {
867 trace_word = tmpspace[i];
868 next_word = ((i == 0) ? 0 : tmpspace[i - 1]);
869 trace_addr = trace_word & 0xffff;
870 next_cnt = (next_word >> 24) & 0xff;
871 j = trace_data.size + count - i - 1;
872 trace_data.addrs[j] = (trace_addr << 2) + 0x1000000;
873 trace_data.counts[j] = next_cnt + 1;
874 }
875
876 oldsize = trace_data.size;
877 trace_data.size += count;
878
879 free (tmpspace);
880
48712b30
SS
881 if (trace_display)
882 display_trace (oldsize, trace_data.size);
883}
884
885static void
886tdisassemble_command (arg, from_tty)
887 char *arg;
888 int from_tty;
889{
890 int i, count;
891 CORE_ADDR low, high;
892 char *space_index;
893
894 if (!arg)
895 {
896 low = 0;
897 high = trace_data.size;
898 }
899 else if (!(space_index = (char *) strchr (arg, ' ')))
900 {
901 low = parse_and_eval_address (arg);
902 high = low + 5;
903 }
904 else
905 {
906 /* Two arguments. */
907 *space_index = '\0';
908 low = parse_and_eval_address (arg);
909 high = parse_and_eval_address (space_index + 1);
a9b9b407
SS
910 if (high < low)
911 high = low;
48712b30
SS
912 }
913
a9b9b407 914 printf_filtered ("Dump of trace from %d to %d:\n", low, high);
48712b30
SS
915
916 display_trace (low, high);
917
918 printf_filtered ("End of trace dump.\n");
919 gdb_flush (gdb_stdout);
920}
921
922static void
923display_trace (low, high)
924 int low, high;
925{
a9b9b407 926 int i, count, trace_show_source, first, suppress;
48712b30
SS
927 CORE_ADDR next_address;
928
a9b9b407
SS
929 trace_show_source = default_trace_show_source;
930 if (!have_full_symbols () && !have_partial_symbols())
931 {
932 trace_show_source = 0;
933 printf_filtered ("No symbol table is loaded. Use the \"file\" command.\n");
934 printf_filtered ("Trace will not display any source.\n");
935 }
936
937 first = 1;
938 suppress = 0;
48712b30
SS
939 for (i = low; i < high; ++i)
940 {
941 next_address = trace_data.addrs[i];
942 count = trace_data.counts[i];
943 while (count-- > 0)
944 {
945 QUIT;
a9b9b407
SS
946 if (trace_show_source)
947 {
948 struct symtab_and_line sal, sal_prev;
949
950 sal_prev = find_pc_line (next_address - 4, 0);
951 sal = find_pc_line (next_address, 0);
952
953 if (sal.symtab)
954 {
955 if (first || sal.line != sal_prev.line)
956 print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
957 suppress = 0;
958 }
959 else
960 {
961 if (!suppress)
962 /* FIXME-32x64--assumes sal.pc fits in long. */
963 printf_filtered ("No source file for address %s.\n",
964 local_hex_string((unsigned long) sal.pc));
965 suppress = 1;
966 }
967 }
968 first = 0;
48712b30
SS
969 print_address (next_address, gdb_stdout);
970 printf_filtered (":");
971 printf_filtered ("\t");
972 wrap_here (" ");
973 next_address = next_address + print_insn (next_address, gdb_stdout);
974 printf_filtered ("\n");
975 gdb_flush (gdb_stdout);
976 }
977 }
3b1af95c 978}
48712b30 979
a9b9b407
SS
980extern void (*target_resume_hook) PARAMS ((void));
981extern void (*target_wait_loop_hook) PARAMS ((void));
982
48712b30
SS
983void
984_initialize_d10v_tdep ()
985{
986 tm_print_insn = print_insn_d10v;
987
a9b9b407
SS
988 target_resume_hook = d10v_eva_prepare_to_trace;
989 target_wait_loop_hook = d10v_eva_get_trace_data;
990
48712b30
SS
991 add_com ("regs", class_vars, show_regs, "Print all registers");
992
993 add_com ("trace", class_support, trace_command,
994 "Enable tracing of instruction execution.");
995
996 add_com ("untrace", class_support, untrace_command,
997 "Disable tracing of instruction execution.");
998
999 add_com ("tdisassemble", class_vars, tdisassemble_command,
1000 "Disassemble the trace buffer.\n\
1001Two optional arguments specify a range of trace buffer entries\n\
1002as reported by info trace (NOT addresses!).");
1003
1004 add_info ("trace", trace_info,
1005 "Display info about the trace data buffer.");
1006
1007 add_show_from_set (add_set_cmd ("tracedisplay", no_class,
1008 var_integer, (char *)&trace_display,
1009 "Set automatic display of trace.\n", &setlist),
1010 &showlist);
a9b9b407
SS
1011 add_show_from_set (add_set_cmd ("tracesource", no_class,
1012 var_integer, (char *)&default_trace_show_source,
1013 "Set display of source code with trace.\n", &setlist),
1014 &showlist);
48712b30
SS
1015
1016}
This page took 0.11321 seconds and 4 git commands to generate.