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