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