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